Package org.jboss.arquillian.container.glassfish.remote_3_1

Source Code of org.jboss.arquillian.container.glassfish.remote_3_1.GlassFishRestDeployableContainer

/*
* JBoss, Home of Professional Open Source
* Copyright 2011, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
*
* @author <a href="http://community.jboss.org/people/LightGuard">Jason Porter</a>
*/
package org.jboss.arquillian.container.glassfish.remote_3_1;

import java.io.File;
import java.io.StringReader;

import javax.ws.rs.core.MediaType;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.multipart.FormDataMultiPart;
import com.sun.jersey.multipart.file.FileDataBodyPart;
import org.jboss.arquillian.spi.client.container.DeployableContainer;
import org.jboss.arquillian.spi.client.container.DeploymentException;
import org.jboss.arquillian.spi.client.container.LifecycleException;
import org.jboss.arquillian.spi.client.protocol.ProtocolDescription;
import org.jboss.arquillian.spi.client.protocol.metadata.HTTPContext;
import org.jboss.arquillian.spi.client.protocol.metadata.ProtocolMetaData;
import org.jboss.arquillian.spi.client.protocol.metadata.Servlet;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.exporter.ZipExporter;
import org.jboss.shrinkwrap.descriptor.api.Descriptor;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

/**
* Glassfish v3.1 remote container using REST deployment.
*
* @author <a href="http://community.jboss.org/people/LightGuard">Jason Porter</a>
*/
@SuppressWarnings({"HardcodedFileSeparator"})
public class GlassFishRestDeployableContainer implements DeployableContainer<GlassFishRestConfiguration> {
    private static final String APPLICATION = "/applications/application";

    private static final String LIST_SUB_COMPONENTS = "/applications/application/list-sub-components?id=";

    private static final String SUCCESS = "SUCCESS";

    private String adminBaseUrl;

    private String applicationBaseUrl;

    private String deploymentName;

    private GlassFishRestConfiguration configuration;

    public Class<GlassFishRestConfiguration> getConfigurationClass() {
        return GlassFishRestConfiguration.class;
    }

    public void setup(GlassFishRestConfiguration configuration) {
        if (configuration == null) {
            throw new IllegalArgumentException("configuration must not be null");
        }

        this.configuration = configuration;

        final StringBuilder adminUrlBuilder = new StringBuilder();

        if (this.configuration.isRemoteServerAdminHttps()) {
            adminUrlBuilder.append("https://");
        } else {
            adminUrlBuilder.append("http://");
        }

        adminUrlBuilder.append(this.configuration.getRemoteServerAddress()).append(":")
                .append(this.configuration.getRemoteServerAdminPort()).append("/management/domain");

        this.adminBaseUrl = adminUrlBuilder.toString();

        final StringBuilder applicationUrlBuilder = new StringBuilder();

        if (this.configuration.isRemoteServerHttps()) {
            applicationUrlBuilder.append("https://");
        } else {
            applicationUrlBuilder.append("http://");
        }

        applicationUrlBuilder.append(this.configuration.getRemoteServerAddress()).append(":")
                .append(this.configuration.getRemoteServerHttpPort()).append("/");

        this.applicationBaseUrl = applicationUrlBuilder.toString();
    }

    public void start() throws LifecycleException {
        final String xmlResponse = prepareClient().get(String.class);

        try {
            if (!isCallSuccessful(xmlResponse)) {
                throw new LifecycleException("Server is not running");
            }
        } catch (XPathExpressionException e) {
            throw new LifecycleException("Error verifying the sever is running", e);
        }
    }

    public void stop() throws LifecycleException {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    public ProtocolDescription getDefaultProtocol() {
        return new ProtocolDescription("Servlet 3.0");
    }

    public ProtocolMetaData deploy(Archive<?> archive) throws DeploymentException {
        if (archive == null) {
            throw new IllegalArgumentException("archive must not be null");
        }

        final String archiveName = archive.getName();

        try {
            // Export to a file so we can send it over the wire
            final File archiveFile = new File(new File(System.getProperty("java.io.tmpdir")), archiveName);
            archive.as(ZipExporter.class).exportZip(archiveFile, true);

            // Build up the POST form to send to Glassfish
            final FormDataMultiPart form = new FormDataMultiPart();
            form.getBodyParts().add(new FileDataBodyPart("id", archiveFile));
            form.field("contextroot", archiveName.substring(0, archiveName.lastIndexOf(".")), MediaType.TEXT_PLAIN_TYPE);
            deploymentName = archiveName.substring(0, archiveName.lastIndexOf("."));
            form.field("name", deploymentName, MediaType.TEXT_PLAIN_TYPE);
            final String xmlResponse = prepareClient(APPLICATION).type(MediaType.MULTIPART_FORM_DATA_TYPE)
                    .post(String.class, form);

            try {
                if (!isCallSuccessful(xmlResponse)) {
                    throw new DeploymentException(getMessage(xmlResponse));
                }
            } catch (XPathExpressionException e) {
                throw new DeploymentException("Error finding exit code or message", e);
            }

            // Call has been successful, now we need another call to get the list of servlets
            final String subComponentsResponse = prepareClient(LIST_SUB_COMPONENTS + this.deploymentName).get(String.class);

            return this.parseForProtocolMetaData(subComponentsResponse);
        } catch (XPathExpressionException e) {
            throw new DeploymentException("Error in creating / deploying archive", e);
        }
    }

    public void undeploy(Archive<?> archive) throws DeploymentException {
        final String xmlResponse = prepareClient(APPLICATION + "/" + this.deploymentName).delete(String.class);

        try {
            if (!isCallSuccessful(xmlResponse)) {
                throw new DeploymentException(getMessage(xmlResponse));
            }
        } catch (XPathExpressionException e) {
            throw new DeploymentException("Error finding exit code or message", e);
        }
    }

    public void deploy(Descriptor descriptor) throws DeploymentException {
        throw new UnsupportedOperationException("Not implemented");
    }

    public void undeploy(Descriptor descriptor) throws DeploymentException {
        throw new UnsupportedOperationException("Not implemented");
    }

    /**
     * Basic REST call preparation
     *
     * @return the resource builder to execute
     */
    private WebResource.Builder prepareClient() {
        return prepareClient("");
    }

    /**
     * Basic REST call preparation, with the additional resource url appended
     *
     * @param additionalResourceUrl url portion past the base to use
     * @return the resource builder to execute
     */
    private WebResource.Builder prepareClient(String additionalResourceUrl) {
        final Client client = Client.create();
        return client.resource(this.adminBaseUrl + additionalResourceUrl).accept(MediaType.APPLICATION_XML_TYPE);
    }

    /**
     * Looks for a successful exit code given the response of the call
     *
     * @param xmlResponse XML response from the REST call
     * @return true if call was successful, false otherwise
     * @throws XPathExpressionException if the xpath query could not be executed
     */
    private boolean isCallSuccessful(String xmlResponse) throws XPathExpressionException {
        final XPath xpath = XPathFactory.newInstance().newXPath();

        final String exitCode = xpath.evaluate("/map/entry[@key = 'exit_code']/@value",
                new InputSource(new StringReader(xmlResponse)));

        return !(exitCode == null || !SUCCESS.equals(exitCode));

    }

    /**
     * Finds the message from the response.
     *
     * @param xmlResponse XML response from the REST call
     * @return true if call was successful, false otherwise
     * @throws XPathExpressionException if the xpath query could not be executed
     */
    private String getMessage(String xmlResponse) throws XPathExpressionException {
        final XPath xpath = XPathFactory.newInstance().newXPath();
        return xpath.evaluate("/map/entry[@key = 'message']/@value", new InputSource(new StringReader(xmlResponse)));
    }

    private ProtocolMetaData parseForProtocolMetaData(String xmlResponse) throws XPathExpressionException {
        final ProtocolMetaData protocolMetaData = new ProtocolMetaData();
        final HTTPContext httpContext = new HTTPContext(this.configuration.getRemoteServerAddress(),
                this.configuration.getRemoteServerHttpPort());

        final XPath xpath = XPathFactory.newInstance().newXPath();

        NodeList servlets = (NodeList) xpath.evaluate("/map/entry[@key = 'properties']/map/entry[@value = 'Servlet']",
                new InputSource(new StringReader(xmlResponse)), XPathConstants.NODESET);

        for (int i = 0; i < servlets.getLength(); i++) {
            httpContext.add(new Servlet(servlets.item(i).getAttributes().getNamedItem("key").getNodeValue(), this.deploymentName));
        }

        protocolMetaData.addContext(httpContext);
        return protocolMetaData;
    }
}
TOP

Related Classes of org.jboss.arquillian.container.glassfish.remote_3_1.GlassFishRestDeployableContainer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.