diff --git wlp-managed-8.5/src/main/java/org/jboss/arquillian/container/was/wlp_managed_8_5/WLPManagedContainer.java wlp-managed-8.5/src/main/java/org/jboss/arquillian/container/was/wlp_managed_8_5/WLPManagedContainer.java index 4bb6a58..93d4fb5 100644 --- wlp-managed-8.5/src/main/java/org/jboss/arquillian/container/was/wlp_managed_8_5/WLPManagedContainer.java +++ wlp-managed-8.5/src/main/java/org/jboss/arquillian/container/was/wlp_managed_8_5/WLPManagedContainer.java @@ -18,9 +18,12 @@ package org.jboss.arquillian.container.was.wlp_managed_8_5; import static java.util.logging.Level.FINER; +import java.io.Closeable; import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.nio.file.Files; import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -29,18 +32,22 @@ import java.util.logging.Logger; import javax.management.MBeanServerConnection; import javax.management.MalformedObjectNameException; -import javax.management.ObjectName; import javax.management.ObjectInstance; +import javax.management.ObjectName; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathFactory; import org.jboss.arquillian.container.spi.client.container.DeployableContainer; import org.jboss.arquillian.container.spi.client.container.DeploymentException; @@ -49,13 +56,19 @@ import org.jboss.arquillian.container.spi.client.protocol.ProtocolDescription; import org.jboss.arquillian.container.spi.client.protocol.metadata.HTTPContext; import org.jboss.arquillian.container.spi.client.protocol.metadata.ProtocolMetaData; import org.jboss.arquillian.container.spi.client.protocol.metadata.Servlet; +import org.jboss.arquillian.container.test.api.Testable; import org.jboss.shrinkwrap.api.Archive; +import org.jboss.shrinkwrap.api.ArchivePath; import org.jboss.shrinkwrap.api.exporter.ZipExporter; +import org.jboss.shrinkwrap.api.spec.EnterpriseArchive; +import org.jboss.shrinkwrap.api.spec.WebArchive; import org.jboss.shrinkwrap.descriptor.api.Descriptor; +import org.w3c.dom.DOMException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; import com.sun.tools.attach.VirtualMachine; import com.sun.tools.attach.VirtualMachineDescriptor; @@ -68,10 +81,14 @@ import com.sun.tools.attach.VirtualMachineDescriptor; */ public class WLPManagedContainer implements DeployableContainer { + private static final String className = WLPManagedContainer.class.getName(); private static Logger log = Logger.getLogger(className); + private static final String javaVmArgumentsDelimiter = " "; + private static final String javaVmArgumentsIndicator = "-"; + private WLPManagedContainerConfiguration containerConfiguration; private JMXConnector jmxConnector; @@ -148,8 +165,9 @@ public class WLPManagedContainer implements DeployableContainer parseJvmArgs(String javaVmArguments) { + List parsedJavaVmArgumetns = new ArrayList(); + String[] splitJavaVmArguments = javaVmArguments.split(javaVmArgumentsDelimiter); + if (splitJavaVmArguments.length > 1) { + for (String javaVmArgument : splitJavaVmArguments) { + if (javaVmArgument.trim().length() > 0) { + // remove precessing spaces + if(javaVmArgument.startsWith(javaVmArgumentsIndicator)) { + // vm argument without spaces + parsedJavaVmArgumetns.add(javaVmArgument); + } else { + // space handling -> concat with the precessing argument + String javaVmArgumentExtension = javaVmArgument; + javaVmArgument = parsedJavaVmArgumetns.remove(parsedJavaVmArgumetns.size() - 1) + javaVmArgumentsDelimiter + javaVmArgumentExtension; + parsedJavaVmArgumetns.add(javaVmArgument); + } + } + } + } else { + parsedJavaVmArgumetns.add(javaVmArguments); + } + return parsedJavaVmArgumetns; + } + private String getVMLocalConnectorAddress(VirtualMachine wlpvm) throws IOException { String serviceURL; @@ -328,7 +370,16 @@ public class WLPManagedContainer implements DeployableContainer contextRoots = new ArrayList(); + if (archive instanceof EnterpriseArchive) { + contextRoots = findArquillianContextRoots((EnterpriseArchive)archive, deployName); + } else { + contextRoots.add(deployName); + } + // register ArquillianServletRunner + for(String contextRoot : contextRoots) { + httpContext.add(new Servlet("ArquillianServletRunner", contextRoot)); + } metaData.addContext(httpContext); if (log.isLoggable(Level.FINER)) { @@ -341,6 +392,64 @@ public class WLPManagedContainer implements DeployableContainer findArquillianContextRoots(final EnterpriseArchive ear, String deployName) throws DeploymentException { + List contextRoots = new ArrayList(); + int testableWarCounter = 0; + int totalWarCounter = 0; + WebArchive latestWar = null; + for (ArchivePath path : ear.getContent().keySet()) { + if (path.get().endsWith("war")) { + WebArchive war = ear.getAsType(WebArchive.class, path); + totalWarCounter++; + if (Testable.isArchiveToTest(war)) { + contextRoots.add(getContextRoot(ear, war)); + testableWarCounter++; + } + latestWar = war; + } + } + if(testableWarCounter == 0) { + if(totalWarCounter == 1) { // fallback only one war + contextRoots.add(getContextRoot(ear, latestWar)); + } else { // default fallback + contextRoots.add(deployName); + } + } + return contextRoots; + } + + private String getContextRoot(EnterpriseArchive ear, WebArchive war) throws DeploymentException { + org.jboss.shrinkwrap.api.Node applicationXmlNode = ear.get("META-INF/application.xml"); + if(applicationXmlNode != null && applicationXmlNode.getAsset() != null) { + InputStream input = null; + try { + input = ear.get("META-INF/application.xml").getAsset().openStream(); + Document applicationXml = readXML(input); + XPath xPath = XPathFactory.newInstance().newXPath(); + XPathExpression ctxRootSelector = xPath.compile("//module/web[web-uri/text()='"+ war.getName() +"']/context-root"); + String ctxRoot = ctxRootSelector.evaluate(applicationXml); + if(ctxRoot != null && ctxRoot.trim().length() > 0) { + return ctxRoot; + } + } catch (Exception e) { + throw new DeploymentException("Unable to delete archive from dropIn directory"); + } finally { + closeQuiently(input); + } + } + return createDeploymentName(war.getName()); + } + + + private static void closeQuiently(Closeable closable) { + try { + if (closable != null) + closable.close(); + } catch (IOException e) { + log.log(Level.WARNING, "Exception while closing Closeable", e); + } + } + private int getHttpPort() throws DeploymentException { if (log.isLoggable(Level.FINER)) { log.entering(className, "getHttpPort"); @@ -426,8 +535,22 @@ public class WLPManagedContainer implements DeployableContainer failsafe -> file marked for delete on exit", e); + exportedArchiveLocation.deleteOnExit(); + } + } } else { // Remove archive from the dropIn directory, which causes undeploy @@ -501,13 +624,21 @@ public class WLPManagedContainer implements DeployableContainer 0) { + File securityConfigFile = new File(securityConfiguration); + if(!securityConfigFile.exists()) + throw new ConfigurationException("securityConfiguration provided is not valid: " + securityConfiguration); + } + // Validate serverName if (!serverName.matches("^[A-Za-z][A-Za-z0-9]*$")) throw new ConfigurationException("serverName provided is not valid: '" + serverName + "'"); @@ -190,4 +198,21 @@ public class WLPManagedContainerConfiguration implements public void setAddLocalConnector(boolean addLocalConnector) { this.addLocalConnector = addLocalConnector; } + + public String getSecurityConfiguration() { + return securityConfiguration; + } + + public void setSecurityConfiguration(String securityConfiguration) { + this.securityConfiguration = securityConfiguration; + } + + public boolean isFailSafeUndeployment() { + return failSafeUndeployment; + } + + public void setFailSafeUndeployment(boolean failSafeUndeployment) { + this.failSafeUndeployment = failSafeUndeployment; + } + }