org.jboss.wsf.test.JBossWSTestHelper.java Source code

Java tutorial

Introduction

Here is the source code for org.jboss.wsf.test.JBossWSTestHelper.java

Source

/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2015, Red Hat Middleware LLC, and individual contributors
 * as indicated by the @author tags. See the copyright.txt file in the
 * distribution for a full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.jboss.wsf.test;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.WeakHashMap;

import javax.management.MBeanServerConnection;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import javax.xml.namespace.QName;
import javax.xml.transform.Source;
import javax.xml.ws.Service;
import javax.xml.ws.Service.Mode;
import javax.xml.ws.soap.SOAPBinding;

import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.exporter.ZipExporter;
import org.jboss.shrinkwrap.api.spec.JavaArchive;

import org.apache.commons.validator.routines.InetAddressValidator;

/**
 * A JBossWS test helper that deals with test deployment/undeployment, etc.
 *
 * @author Thomas.Diesler@jboss.org
 * @author ropalka@redhat.com
 * @author alessio.soldano@jboss.com
 */
public class JBossWSTestHelper {
    private static final String SYSPROP_JBOSSWS_INTEGRATION_TARGET = "jbossws.integration.target";
    private static final String SYSPROP_JBOSS_BIND_ADDRESS = "jboss.bind.address";
    private static final String SYSPROP_JBOSS_REMOTING_PROTOCOL = "jboss.remoting.protocol";
    private static final String SYSPROP_INITIAL_CONTEXT_FACTORY = "jboss.initial.context.factory";
    private static final String SYSPROP_TEST_ARCHIVE_DIRECTORY = "test.archive.directory";
    private static final String SYSPROP_TEST_RESOURCES_DIRECTORY = "test.resources.directory";
    private static final String SYSPROP_DEFAULT_CONTAINER_QUALIFIER = "default.container.qualifier";
    private static final String SYSPROP_DEFAULT_CONTAINER_GROUP_QUALIFIER = "default.container.group.qualifier";
    private static final String SYSPROP_CONTAINER_PORT_OFFSET_PREFIX = "port-offset.";
    private static final String SYSPROP_AS_SERVER_CONN_RETRIEVAL_ATTEMPTS = "test.as.server.connection.retrieval.attempts";
    private static final String TEST_USERNAME = "test.username";
    private static final String TEST_PASSWORD = "test.password";
    private static final int AS_SERVER_CONN_RETRIEVAL_ATTEMPTS = Integer
            .getInteger(SYSPROP_AS_SERVER_CONN_RETRIEVAL_ATTEMPTS, 5);
    private static final String testArchiveDir = System.getProperty(SYSPROP_TEST_ARCHIVE_DIRECTORY);
    private static final String testResourcesDir = System.getProperty(SYSPROP_TEST_RESOURCES_DIRECTORY);
    private static final String integrationTarget;
    private static final String implInfo;
    private static final String serverHost = System.getProperty(SYSPROP_JBOSS_BIND_ADDRESS, "localhost");
    private static final String remotingProtocol = System.getProperty(SYSPROP_JBOSS_REMOTING_PROTOCOL);
    private static final String initialContextFactory = System.getProperty(SYSPROP_INITIAL_CONTEXT_FACTORY);

    private static WeakHashMap<ClassLoader, Hashtable<String, String>> containerEnvs = new WeakHashMap<ClassLoader, Hashtable<String, String>>();

    static {
        integrationTarget = System.getProperty(SYSPROP_JBOSSWS_INTEGRATION_TARGET);
        if (integrationTarget == null)
            throw new IllegalStateException("Cannot obtain system property: " + SYSPROP_JBOSSWS_INTEGRATION_TARGET);
        Object obj = getImplementationObject();
        implInfo = obj.getClass().getPackage().getName();
    }

    /** Deploy the given archive to the appclient.
     * Archive name is always in form archive.ear#appclient.jar
     */
    public static Process deployAppclient(final String archive, final OutputStream appclientOS,
            final String... appclientArgs) throws Exception {
        return AppclientHelper.deployAppclient(archive, appclientOS, appclientArgs);
    }

    /** Undeploy the given archive from the appclient
     * Archive name is always in form archive.ear#appclient.jar
     */
    public static void undeployAppclient(final String archive, boolean awaitShutdown) throws Exception {
        AppclientHelper.undeployAppclient(archive, awaitShutdown);
    }

    public static boolean isTargetWildFly9() {
        String target = getIntegrationTarget();
        return target.startsWith("wildfly9");
    }

    public static boolean isTargetWildFly10() {
        String target = getIntegrationTarget();
        return target.startsWith("wildfly10");
    }

    public static boolean isIntegrationCXF() {
        String vendor = getImplementationInfo();
        return vendor.toLowerCase().indexOf("apache") != -1;
    }

    private static String getImplementationInfo() {
        return implInfo;
    }

    private static Object getImplementationObject() {
        Service service = Service.create(new QName("dummyService"));
        Object obj = service.getHandlerResolver();
        if (obj == null) {
            service.addPort(new QName("dummyPort"), SOAPBinding.SOAP11HTTP_BINDING, "http://dummy-address");
            obj = service.createDispatch(new QName("dummyPort"), Source.class, Mode.PAYLOAD);
        }
        return obj;
    }

    public static String getRemotingProtocol() {
        return remotingProtocol;
    }

    public static String getInitialContextFactory() {
        return initialContextFactory;
    }

    /**
     * Get the JBoss server host from system property "jboss.bind.address"
     * This defaults to "localhost"
     */
    public static String getServerHost() {
        return toIPv6URLFormat(serverHost);
    }

    public static int getServerPort() {
        return getServerPort(null, null);
    }

    public static int getServerPort(String groupQualifier, String containerQualifier) {
        return 8080 + getContainerPortOffset(groupQualifier, containerQualifier);
    }

    public static int getSecureServerPort(String groupQualifier, String containerQualifier) {
        return 8443 + getContainerPortOffset(groupQualifier, containerQualifier);
    }

    protected static int getContainerPortOffset(String groupQualifier, String containerQualifier) {
        Hashtable<String, String> env = getContainerEnvironment();

        if (groupQualifier == null) {
            groupQualifier = env.get(SYSPROP_DEFAULT_CONTAINER_GROUP_QUALIFIER);
        }
        if (containerQualifier == null) {
            containerQualifier = env.get(SYSPROP_DEFAULT_CONTAINER_QUALIFIER);
        }
        String offset = env.get(SYSPROP_CONTAINER_PORT_OFFSET_PREFIX + groupQualifier + "." + containerQualifier);
        return offset != null ? Integer.valueOf(offset) : 0;
    }

    private static Hashtable<String, String> getContainerEnvironment() {
        Hashtable<String, String> env;
        ClassLoader tccl = Thread.currentThread().getContextClassLoader();
        synchronized (containerEnvs) {
            env = containerEnvs.get(tccl);
            if (env == null) {
                env = new Hashtable<String, String>();
                final InputStream is = tccl.getResourceAsStream("container.properties");
                try {
                    if (is != null) {
                        final Properties props = new Properties();
                        props.load(is);
                        Entry<Object, Object> entry;
                        final Iterator<Entry<Object, Object>> entries = props.entrySet().iterator();
                        while (entries.hasNext()) {
                            entry = entries.next();
                            env.put((String) entry.getKey(), (String) entry.getValue());
                        }
                    }
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                containerEnvs.put(tccl, env);
            }
            return env;
        }
    }

    public static String toIPv6URLFormat(final String host) {
        try {
            if (host.startsWith("[") || host.startsWith(":")) {
                if (System.getProperty("java.net.preferIPv4Stack") == null) {
                    throw new IllegalStateException(
                            "always provide java.net.preferIPv4Stack JVM property when using IPv6 address format");
                }
                if (System.getProperty("java.net.preferIPv6Addresses") == null) {
                    throw new IllegalStateException(
                            "always provide java.net.preferIPv6Addresses JVM property when using IPv6 address format");
                }
            }
            final boolean isIPv6Address = InetAddress.getByName(host) instanceof Inet6Address;
            final boolean isIPv6Literal = isIPv6Address && InetAddressValidator.getInstance()
                    .isValidInet6Address(host.replaceAll("^\\[(.*)\\]$", "$1"));
            final boolean isIPv6LiteralFormattedForURI = isIPv6Literal && host.startsWith("[");
            return isIPv6Literal && !isIPv6LiteralFormattedForURI ? "[" + host + "]" : host;
        } catch (final UnknownHostException e) {
            throw new RuntimeException(e);
        }
    }

    public static MBeanServerConnection getServer() {
        return getServer(null, null);
    }

    public static MBeanServerConnection getServer(String groupQualifier, String containerQualifier) {
        int portOffset = getContainerPortOffset(groupQualifier, containerQualifier);
        String integrationTarget = getIntegrationTarget();
        MBeanServerConnection server;
        if (integrationTarget.startsWith("wildfly")) {
            server = getServerConnection(
                    "service:jmx:http-remoting-jmx://" + getServerHost() + ":" + (9990 + portOffset));
        } else {
            throw new IllegalStateException("Unsupported target container: " + integrationTarget);
        }
        return server;
    }

    private static MBeanServerConnection getServerConnection(String jmxServiceUrl) {
        final String urlString = System.getProperty("jmx.service.url", jmxServiceUrl);
        JMXServiceURL serviceURL = null;
        JMXConnector connector = null;
        try {
            serviceURL = new JMXServiceURL(urlString);
        } catch (MalformedURLException e1) {
            throw new IllegalStateException(e1);
        }
        //add more tries to get the connection. Workaround to fix some test failures caused by connection is not established in 5 seconds
        for (int i = 0; i < AS_SERVER_CONN_RETRIEVAL_ATTEMPTS && connector == null; i++) {
            try {
                connector = JMXConnectorFactory.connect(serviceURL, null);
            } catch (IOException ex) {
                throw new IllegalStateException("Cannot obtain MBeanServerConnection to: " + urlString, ex);
            } catch (RuntimeException e) {
                if (e.getMessage().contains("WAITING") && i < AS_SERVER_CONN_RETRIEVAL_ATTEMPTS - 1) {
                    continue;
                } else {
                    throw e;
                }
            }
        }

        try {
            return connector.getMBeanServerConnection();
        } catch (Exception e) {
            throw new IllegalStateException("Cannot obtain MBeanServerConnection to: " + urlString, e);
        }
    }

    public static String getIntegrationTarget() {
        return integrationTarget;
    }

    /** Try to discover the URL for the deployment archive */
    public static URL getArchiveURL(String archive) throws MalformedURLException {
        return getArchiveFile(archive).toURI().toURL();
    }

    /** Try to discover the File for the deployment archive */
    public static File getArchiveFile(String archive) {
        File file = new File(archive);
        if (file.exists())
            return file;

        file = new File(getTestArchiveDir() + "/" + archive);
        if (file.exists())
            return file;

        String notSet = (getTestArchiveDir() == null
                ? " System property '" + SYSPROP_TEST_ARCHIVE_DIRECTORY + "' not set."
                : "");
        throw new IllegalArgumentException("Cannot obtain '" + getTestArchiveDir() + "/" + archive + "'." + notSet);
    }

    /** Try to discover the URL for the test resource */
    public static URL getResourceURL(String resource) throws MalformedURLException {
        return getResourceFile(resource).toURI().toURL();
    }

    /** Try to discover the File for the test resource */
    public static File getResourceFile(String resource) {
        File file = new File(resource);
        if (file.exists())
            return file;

        file = new File(getTestResourcesDir() + "/" + resource);
        if (file.exists())
            return file;

        String notSet = (getTestResourcesDir() == null
                ? " System property '" + SYSPROP_TEST_RESOURCES_DIRECTORY + "' not set."
                : "");
        throw new IllegalArgumentException(
                "Cannot obtain '" + getTestResourcesDir() + "/" + resource + "'." + notSet);
    }

    public static String getTestArchiveDir() {
        return testArchiveDir;
    }

    public static String getTestResourcesDir() {
        return testResourcesDir;
    }

    public static String getTestUsername() {
        String prop = System.getProperty(TEST_USERNAME);
        if (prop == null || "".equals(prop) || ("${" + TEST_USERNAME + "}").equals(prop)) {
            prop = "kermit";
        }
        return prop;
    }

    public static String getTestPassword() {
        String prop = System.getProperty(TEST_PASSWORD);
        if (prop == null || "".equals(prop) || ("${" + TEST_PASSWORD + "}").equals(prop)) {
            prop = "thefrog";
        }
        return prop;
    }

    @SuppressWarnings("rawtypes")
    public static void writeToFile(Archive archive) {
        File archiveDir = assertArchiveDirExists();
        File file = new File(archiveDir, archive.getName());
        archive.as(ZipExporter.class).exportTo(file, true);
    }

    public static abstract class BaseDeployment<T extends org.jboss.shrinkwrap.api.Archive<T>> {
        protected T archive;

        public BaseDeployment(Class<T> clazz, String name) {
            archive = ShrinkWrap.create(clazz, name);
        }

        public T create() {
            return archive;
        }

        public T writeToFile() {
            File archiveDir = assertArchiveDirExists();
            File file = new File(archiveDir, archive.getName());
            archive.as(ZipExporter.class).exportTo(file, true);
            return archive;
        }

        public String getName() {
            return archive.getName();
        }
    }

    public static File assertArchiveDirExists() {
        File archiveDir = new File(testArchiveDir);
        if (!archiveDir.exists()) {
            if (testArchiveDir == null)
                throw new IllegalArgumentException("Cannot create archive - system property '"
                        + JBossWSTestHelper.SYSPROP_TEST_ARCHIVE_DIRECTORY + "' not set.");
            if (!archiveDir.mkdirs() && !archiveDir.exists())
                throw new IllegalArgumentException("Cannot create archive - can not create test archive directory '"
                        + archiveDir.getAbsolutePath() + "'");
        }
        return archiveDir;
    }

    public static String writeToFile(BaseDeployment<?>... deps) {
        if (deps == null) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        for (BaseDeployment<?> dep : deps) {
            sb.append(dep.writeToFile().getName());
            sb.append(" ");
        }
        return sb.toString().trim();
    }

    public static abstract class JarDeployment extends BaseDeployment<JavaArchive> {
        public JarDeployment(String name) {
            super(JavaArchive.class, name);
        }
    }
}