| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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. |
| */ |
| package org.apache.tomee.arquillian.webapp; |
| |
| import org.apache.openejb.arquillian.common.ArquillianFilterRunner; |
| import org.apache.openejb.arquillian.common.Files; |
| import org.apache.openejb.arquillian.common.IO; |
| import org.apache.openejb.arquillian.common.Setup; |
| import org.apache.openejb.arquillian.common.TomEEContainer; |
| import org.apache.openejb.arquillian.common.Zips; |
| import org.apache.openejb.config.RemoteServer; |
| import org.apache.tomee.installer.Installer; |
| import org.apache.tomee.installer.Paths; |
| import org.jboss.arquillian.container.spi.client.container.LifecycleException; |
| import org.jboss.arquillian.protocol.servlet.ServletMethodExecutor; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.net.URL; |
| import java.net.URLConnection; |
| import java.util.Arrays; |
| import java.util.Map; |
| import java.util.TreeMap; |
| import java.util.logging.Level; |
| import java.util.logging.Logger; |
| |
| public class TomEEWebappContainer extends TomEEContainer<TomEEWebappConfiguration> { |
| |
| private static final Logger logger = Logger.getLogger(TomEEWebappContainer.class.getName()); |
| |
| private RemoteServer container; |
| private boolean shutdown; |
| private File openejbHome; |
| private boolean wereOpenejbHomeSet = true; |
| |
| @Override |
| protected String providerUrl() { |
| return String.format(configuration.getProviderUrlPattern(), super.providerUrl()); |
| } |
| |
| @Override |
| public void start() throws LifecycleException { |
| // see if TomEE is already running by checking the http port |
| final int httpPort = configuration.getHttpPort(); |
| if (Setup.isRunning(configuration.getHost(), httpPort)) { |
| |
| logger.info(String.format("Tomcat found running on port %s", httpPort)); |
| |
| return; |
| } |
| |
| shutdown = true; |
| |
| final String s = File.separator; |
| try { |
| final File workingDirectory = new File(configuration.getDir()); |
| |
| if (workingDirectory.exists()) { |
| |
| Files.assertDir(workingDirectory); |
| |
| } else { |
| |
| Files.mkdir(workingDirectory); |
| Files.deleteOnExit(workingDirectory); |
| } |
| |
| Files.readable(workingDirectory); |
| Files.writable(workingDirectory); |
| |
| openejbHome = Setup.findHome(workingDirectory); |
| Installer installer = null; |
| |
| if (openejbHome == null) { |
| |
| downloadTomcat(workingDirectory, configuration.getTomcatVersion(), configuration.getDir()); |
| |
| openejbHome = Setup.findHome(workingDirectory); |
| |
| Files.deleteOnExit(openejbHome); |
| |
| final File webapp = new File(openejbHome, "webapps" + s + "tomee"); |
| |
| Files.mkdir(webapp); |
| downloadOpenEJBWebapp(webapp, configuration.getDir()); |
| |
| System.setProperty("catalina.home", openejbHome.getAbsolutePath()); |
| System.setProperty("catalina.base", openejbHome.getAbsolutePath()); |
| |
| System.setProperty("openejb.deploymentId.format", System.getProperty("openejb.deploymentId.format", "{appId}/{ejbJarId}/{ejbName}")); |
| |
| final Paths paths = new Paths(webapp); |
| installer = new Installer(paths, true); |
| if (!configuration.isUseInstallerServlet()) { |
| installer.installAll(); |
| |
| } |
| |
| wereOpenejbHomeSet = false; |
| } |
| |
| Files.assertDir(openejbHome); |
| Files.readable(openejbHome); |
| Files.writable(openejbHome); |
| |
| Setup.configureServerXml(openejbHome, configuration); |
| Setup.configureSystemProperties(openejbHome, configuration); |
| |
| Setup.exportProperties(openejbHome, configuration, true); |
| |
| final URL logging = Thread.currentThread().getContextClassLoader().getResource("default.remote.logging.properties"); |
| if (logging != null) { |
| write(logging, new File(openejbHome, "conf" + s + "logging.properties")); |
| } |
| |
| if (configuration.isRemoveUnusedWebapps()) { |
| Setup.removeUselessWebapps(openejbHome, "tomee"); |
| } |
| |
| if (logger.isLoggable(Level.FINE)) { |
| final Map<Object, Object> map = new TreeMap<>(System.getProperties()); |
| for (final Map.Entry<Object, Object> entry : map.entrySet()) { |
| System.out.printf("%s = %s\n", entry.getKey(), entry.getValue()); |
| } |
| } |
| |
| Setup.installArquillianBeanDiscoverer(openejbHome); |
| |
| if (!wereOpenejbHomeSet && configuration.isUseInstallerServlet()) { |
| // instead of calling the Installer, let's just do like users do |
| // call the servlet installer instead |
| final String baseUrl = "http://" + configuration.getHost() + ":" + httpPort + "/tomee/installer"; |
| |
| assert installer != null; |
| installer.addTomEEAdminConfInTomcatUsers(true); |
| |
| final RemoteServer tmpContainer = new RemoteServer(); |
| tmpContainer.setPortStartup(httpPort); |
| |
| try { |
| tmpContainer.start(); |
| } catch (final Exception e) { |
| tmpContainer.destroy(); |
| throw e; |
| } |
| |
| final URL url = new URL(baseUrl); |
| logger.info("Calling TomEE Installer Servlet on " + url); |
| |
| for (int i = 0; i < Integer.getInteger("tomee.webapp.container.client.retries", 3); i++) { |
| final URLConnection uc = url.openConnection(); |
| // dG9tZWU6dG9tZWU= --> Base64 of tomee:tomee |
| final String authorizationString = "Basic dG9tZWU6dG9tZWU="; |
| final int timeout = Integer.getInteger("tomee.webapp.container.client.timeout", 60000); |
| uc.setConnectTimeout(timeout); |
| uc.setReadTimeout(timeout); |
| uc.setRequestProperty("Authorization", authorizationString); |
| try { |
| final InputStream is = uc.getInputStream(); |
| org.apache.openejb.loader.IO.slurp(is); |
| is.close(); |
| break; |
| } catch (final Exception e) { |
| logger.warning(e.getMessage()); |
| Thread.sleep(1000); |
| } |
| } |
| |
| tmpContainer.stop(); |
| tmpContainer.getServer().waitFor(); |
| } |
| |
| container = new RemoteServer(); |
| container.setPortStartup(httpPort); |
| container.start(Arrays.asList( |
| "-Dopenejb.system.apps=true", |
| "-Dtomee.remote.support=true", |
| "-Dorg.apache.openejb.servlet.filters=" + ArquillianFilterRunner.class.getName() + "=" + ServletMethodExecutor.ARQUILLIAN_SERVLET_MAPPING), "start", true); |
| container.killOnExit(); |
| } catch (final Exception e) { |
| if (null != container) { |
| container.destroy(); |
| } |
| throw new LifecycleException("Unable to start remote container on port: " + httpPort, e); |
| } |
| } |
| |
| private static void write(final URL resource, final File file) throws IOException { |
| if (file.exists()) { |
| Files.delete(file); |
| } |
| |
| try (final InputStream is = org.apache.openejb.loader.IO.read(resource)) { |
| IO.copy(is, file); |
| } |
| } |
| |
| protected void downloadOpenEJBWebapp(final File targetDirectory, final String defaultTempDir) throws LifecycleException { |
| final String artifactName = configuration.getArtifactName(); |
| final File zipFile = Setup.downloadFile(artifactName, null, defaultTempDir); |
| Zips.unzip(zipFile, targetDirectory); |
| } |
| |
| protected void downloadTomcat(final File catalinaDirectory, final String tomcatVersion, final String defaultTempDir) throws LifecycleException { |
| String source = null; |
| |
| try { |
| int v = Integer.parseInt(tomcatVersion.substring(0, tomcatVersion.indexOf('.'))); |
| source = "http://archive.apache.org/dist/tomcat/tomcat-" + v + "/v" + v + "/bin/apache-tomcat-" + tomcatVersion + ".zip"; |
| } catch (final Exception e) { |
| // no-op |
| } |
| |
| if (source == null) { |
| throw new LifecycleException("Unable to find URL for Tomcat " + tomcatVersion); |
| } |
| |
| final File zipFile = Setup.downloadFile("org.apache.tomcat:tomcat:" + tomcatVersion + ":zip", source, defaultTempDir); |
| Zips.unzip(zipFile, catalinaDirectory); |
| } |
| |
| @Override |
| public void stop() throws LifecycleException { |
| // only stop the container if we started it |
| if (shutdown) { |
| try { |
| Setup.removeArquillianBeanDiscoverer(openejbHome); |
| container.destroy(); |
| } finally { |
| resetSerialization(); |
| } |
| } |
| } |
| |
| @Override |
| public Class<TomEEWebappConfiguration> getConfigurationClass() { |
| return TomEEWebappConfiguration.class; |
| } |
| } |