All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ops4j.pax.web.itest.AbstractControlledTestBase Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2020 OPS4J.
 *
 * 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.
 */
package org.ops4j.pax.web.itest;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Dictionary;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.function.BiPredicate;
import java.util.function.Function;
import java.util.function.Predicate;
import javax.inject.Inject;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.rules.TestName;
import org.ops4j.pax.exam.Option;
import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
import org.ops4j.pax.exam.spi.reactors.PerClass;
import org.ops4j.pax.logging.PaxLoggingConstants;
import org.ops4j.pax.web.itest.utils.VersionUtils;
import org.ops4j.pax.web.itest.utils.WaitCondition;
import org.ops4j.pax.web.service.PaxWebConstants;
import org.ops4j.pax.web.service.WebContainer;
import org.ops4j.pax.web.service.spi.model.events.FilterEventData;
import org.ops4j.pax.web.service.spi.model.events.ServerEvent;
import org.ops4j.pax.web.service.spi.model.events.ServerListener;
import org.ops4j.pax.web.service.spi.model.events.ServletEventData;
import org.ops4j.pax.web.service.spi.model.events.WebApplicationEvent;
import org.ops4j.pax.web.service.spi.model.events.WebApplicationEventListener;
import org.ops4j.pax.web.service.spi.model.events.WebElementEvent;
import org.ops4j.pax.web.service.spi.model.events.WebElementEventData;
import org.ops4j.pax.web.service.spi.model.events.WebElementEventListener;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.http.HttpService;
import org.osgi.util.tracker.ServiceTracker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.ops4j.pax.exam.Constants.START_LEVEL_SYSTEM_BUNDLES;
import static org.ops4j.pax.exam.Constants.START_LEVEL_TEST_BUNDLE;
import static org.ops4j.pax.exam.CoreOptions.bootDelegationPackages;
import static org.ops4j.pax.exam.CoreOptions.cleanCaches;
import static org.ops4j.pax.exam.CoreOptions.frameworkProperty;
import static org.ops4j.pax.exam.CoreOptions.frameworkStartLevel;
import static org.ops4j.pax.exam.CoreOptions.junitBundles;
import static org.ops4j.pax.exam.CoreOptions.linkBundle;
import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
import static org.ops4j.pax.exam.CoreOptions.systemPackages;
import static org.ops4j.pax.exam.CoreOptions.systemTimeout;
import static org.ops4j.pax.exam.CoreOptions.url;
import static org.ops4j.pax.exam.CoreOptions.workingDirectory;
import static org.ops4j.pax.exam.OptionUtils.combine;
import static org.ops4j.pax.web.itest.utils.WaitCondition.RETRY_DURATION_MILLIS;
import static org.ops4j.pax.web.itest.utils.WaitCondition.SLEEP_DURATION_MILLIS;

/**
 * 

Single base class for all Pax Exam integration tests. Subclasses may add specific helper methods.

* *

For now it's (almost) a duplicate of similar class from pax-web-itest-osgi, but the goal is to have one after * Pax Web 8 refactoring ends.

* *

{@link PerClass} strategy is needed. maven-failsafe-plugin's {@code reuseForks=false} and {@code forkCount=1} is * not enough to properly clean up JVM between methods and we may miss some URL handlers, etc. In other words - don't * use {@link org.ops4j.pax.exam.spi.reactors.PerMethod}.

* *

This class is part of a Maven module, which is just a jar, not a bundle. So it should be private-packaged * in any test-related bundle running in pax-exam-container-native/karaf.

*/ @ExamReactorStrategy(PerClass.class) public abstract class AbstractControlledTestBase { public static final Logger LOG = LoggerFactory.getLogger("org.ops4j.pax.web.itest"); public static final String PROBE_SYMBOLIC_NAME = "PaxExam-Probe"; // location of where pax-logging-api will have output file written according to // "org.ops4j.pax.logging.useFileLogFallback" system/context property // filename will match test class name with ".log" extension protected static final File LOG_DIR = new File("target/logs-default"); @Rule public TestName testName = new TestName(); @Inject protected BundleContext context; protected WebElementEventListener webElementEventListener; @Before public void beforeEach() { LOG.info("========== Running {}.{}() ==========", getClass().getName(), testName.getMethodName()); } @After public void afterEach() { LOG.info("========== Finished {}.{}() ==========", getClass().getName(), testName.getMethodName()); } protected Option[] baseConfigure() { LOG_DIR.mkdirs(); return new Option[] { // basic options bootDelegationPackages("sun.*", "com.sun.*"), systemPackages("sun.misc", "com.sun.xml.bind.annotation;version=2.3"), frameworkStartLevel(START_LEVEL_TEST_BUNDLE), workingDirectory("target/paxexam"), // needed for PerClass strategy and I had problems running more test classes without cleaning // caches (timeout waiting for ProbeInvoker with particular UUID) cleanCaches(true), systemTimeout(60 * 60 * 1000), // set to "4" to see Felix wiring information frameworkProperty("felix.log.level").value("0"), // added implicitly by pax-exam, if pax.exam.system=test // these resources are provided inside org.ops4j.pax.exam:pax-exam-link-mvn jar // for example, "link:classpath:META-INF/links/org.ops4j.base.link" = "mvn:org.ops4j.base/ops4j-base/1.5.0" url("link:classpath:META-INF/links/org.ops4j.base.link").startLevel(START_LEVEL_SYSTEM_BUNDLES), url("link:classpath:META-INF/links/org.ops4j.pax.swissbox.core.link").startLevel(START_LEVEL_SYSTEM_BUNDLES), url("link:classpath:META-INF/links/org.ops4j.pax.swissbox.extender.link").startLevel(START_LEVEL_SYSTEM_BUNDLES), url("link:classpath:META-INF/links/org.ops4j.pax.swissbox.framework.link").startLevel(START_LEVEL_SYSTEM_BUNDLES), url("link:classpath:META-INF/links/org.ops4j.pax.swissbox.lifecycle.link").startLevel(START_LEVEL_SYSTEM_BUNDLES), url("link:classpath:META-INF/links/org.ops4j.pax.swissbox.tracker.link").startLevel(START_LEVEL_SYSTEM_BUNDLES), url("link:classpath:META-INF/links/org.ops4j.pax.exam.link").startLevel(START_LEVEL_SYSTEM_BUNDLES), url("link:classpath:META-INF/links/org.ops4j.pax.exam.inject.link").startLevel(START_LEVEL_SYSTEM_BUNDLES), url("link:classpath:META-INF/links/org.ops4j.pax.extender.service.link").startLevel(START_LEVEL_SYSTEM_BUNDLES), // this bundle provides correct osgi.contract;osgi.contract=JavaInject linkBundle("org.apache.servicemix.bundles.javax-inject").startLevel(START_LEVEL_SYSTEM_BUNDLES), junitBundles(), // configadmin is not needed. Useful for better configuration, but not needed - both by // pax-logging and pax-web // mavenBundle("org.apache.felix", "org.apache.felix.configadmin") // .versionAsInProject().startLevel(START_LEVEL_SYSTEM_BUNDLES), mavenBundle("org.ops4j.pax.logging", "pax-logging-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ops4j.pax.logging", "pax-logging-log4j2") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.apache.felix", "org.apache.felix.metatype") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1) }; } /** * Reasonable defaults for default logging level (actually a threshold), framework logger level and usage * of file-based default/fallback logger. * @return */ protected Option[] defaultLoggingConfig() { String fileName; try { fileName = new File(LOG_DIR, getClass().getSimpleName() + ".log").getCanonicalPath(); } catch (IOException e) { LOG.error(e.getMessage(), e); throw new RuntimeException(e.getMessage(), e); } return new Option[] { // every log with level higher or equal to DEBUG (i.e., not TRACE) will be logged frameworkProperty(PaxLoggingConstants.LOGGING_CFG_DEFAULT_LOG_LEVEL).value("DEBUG"), // threshold for R7 Compendium 101.8 logging statements (from framework/bundle/service events) frameworkProperty(PaxLoggingConstants.LOGGING_CFG_FRAMEWORK_EVENTS_LOG_LEVEL).value("ERROR"), // default log will be written to file frameworkProperty(PaxLoggingConstants.LOGGING_CFG_USE_FILE_FALLBACK_LOGGER).value(fileName) }; } // --- methods that add logical sets of bundles (or just single bundles) to pax-exam-container-native /** * Installation of 3 Pax Web fundamental bundles: API, SPI + Annotation API + Servlet API. * @return */ protected Option[] paxWebCore() { return new Option[] { mavenBundle("jakarta.annotation", "jakarta.annotation-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ops4j.pax.web", "pax-web-compatibility-annotation13") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 2).noStart(), mavenBundle("jakarta.servlet", "jakarta.servlet-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ops4j.pax.web", "pax-web-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1).start(), mavenBundle("org.ops4j.pax.web", "pax-web-spi") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1).start() }; } /** * Installation of Pax Web Runtime - the first Pax Web bundle with an activator and implementation * of {@link org.osgi.service.http.HttpService} (though it needs an instance of * {@link org.ops4j.pax.web.service.spi.ServerControllerFactory} to actually register * {@link org.osgi.service.http.HttpService}. * @return */ protected Option[] paxWebRuntime() { return new Option[] { mavenBundle("org.ops4j.pax.web", "pax-web-tomcat-common") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ops4j.pax.web", "pax-web-runtime") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1) }; } protected Option[] paxWebTestSupport() { return new Option[] { mavenBundle("org.ops4j.pax.web.itest", "pax-web-itest-container-common") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ops4j.pax.web.itest", "pax-web-itest-utils") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1) }; } protected Option paxWebExtenderWhiteboard() { return mavenBundle("org.ops4j.pax.web", "pax-web-extender-whiteboard") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1); } protected Option[] paxWebExtenderWar() { return new Option[] { mavenBundle("org.ops4j.pax.web", "pax-web-tomcat-common") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ops4j.pax.web", "pax-web-extender-war") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), // pax-url-war requires osgi promise+function mavenBundle("org.osgi", "org.osgi.util.promise") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.osgi", "org.osgi.util.function") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ops4j.pax.url", "pax-url-war").classifier("uber") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1) }; } protected Option[] paxWebJsp() { return new Option[] { mavenBundle("jakarta.el", "jakarta.el-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ops4j.pax.web", "pax-web-compatibility-el2") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 2).noStart(), mavenBundle("org.ops4j.pax.web", "pax-web-tomcat-common") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.eclipse.jdt", "ecj") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ops4j.pax.web", "pax-web-jsp") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1) }; } protected Option[] paxWebJspForTomcatBundle() { return new Option[] { mavenBundle("jakarta.el", "jakarta.el-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ops4j.pax.web", "pax-web-compatibility-el2") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 2).noStart(), mavenBundle("org.eclipse.jdt", "ecj") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ops4j.pax.web", "pax-web-jsp") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1) }; } /** * Installation of all the bundles required by {@code pax-web-jetty} * @return */ protected Option[] paxWebJetty() { return new Option[] { mavenBundle("org.ops4j.pax.web", "pax-web-jetty") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle().groupId("org.eclipse.jetty") .artifactId("jetty-util").versionAsInProject(), // required since https://github.com/eclipse/jetty.project/issues/5539 mavenBundle().groupId("org.eclipse.jetty") .artifactId("jetty-util-ajax").versionAsInProject(), mavenBundle().groupId("org.eclipse.jetty") .artifactId("jetty-io").versionAsInProject(), mavenBundle().groupId("org.eclipse.jetty") .artifactId("jetty-http").versionAsInProject(), mavenBundle().groupId("org.eclipse.jetty") .artifactId("jetty-server").versionAsInProject(), mavenBundle().groupId("org.eclipse.jetty") .artifactId("jetty-xml").versionAsInProject(), mavenBundle().groupId("org.eclipse.jetty") .artifactId("jetty-servlet").versionAsInProject(), mavenBundle().groupId("org.eclipse.jetty") .artifactId("jetty-security").versionAsInProject(), mavenBundle().groupId("org.eclipse.jetty") .artifactId("jetty-jaas").versionAsInProject() }; } /** * Installation of all the bundles required by {@code pax-web-jetty} with HTTP2 support * @return */ protected Option[] paxWebJettyHttp2() { Option[] common = combine(paxWebJetty(), mavenBundle().groupId("org.eclipse.jetty.http2") .artifactId("http2-hpack").versionAsInProject(), mavenBundle().groupId("org.eclipse.jetty.http2") .artifactId("http2-common").versionAsInProject(), mavenBundle().groupId("org.eclipse.jetty.http2") .artifactId("http2-server").versionAsInProject(), mavenBundle().groupId("org.eclipse.jetty") .artifactId("jetty-alpn-server").versionAsInProject() ); return combine(common, mavenBundle().groupId("org.eclipse.jetty.alpn") .artifactId("alpn-api").versionAsInProject(), mavenBundle().groupId("org.eclipse.jetty") .artifactId("jetty-alpn-java-server").versionAsInProject() ); } protected Option[] jettyWebSockets() { return new Option[] { mavenBundle("jakarta.websocket", "jakarta.websocket-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle().groupId("org.eclipse.jetty") .artifactId("jetty-client").versionAsInProject(), mavenBundle().groupId("org.eclipse.jetty") .artifactId("jetty-alpn-client").versionAsInProject(), mavenBundle().groupId("org.eclipse.jetty.websocket") .artifactId("websocket-javax-common").versionAsInProject(), mavenBundle().groupId("org.eclipse.jetty.websocket") .artifactId("websocket-javax-client").versionAsInProject(), mavenBundle().groupId("org.eclipse.jetty.websocket") .artifactId("websocket-javax-server").versionAsInProject(), mavenBundle().groupId("org.eclipse.jetty.websocket") .artifactId("websocket-jetty-api").versionAsInProject(), mavenBundle().groupId("org.eclipse.jetty.websocket") .artifactId("websocket-core-common").versionAsInProject(), mavenBundle().groupId("org.eclipse.jetty.websocket") .artifactId("websocket-core-client").versionAsInProject(), mavenBundle().groupId("org.eclipse.jetty.websocket") .artifactId("websocket-core-server").versionAsInProject(), mavenBundle().groupId("org.eclipse.jetty.websocket") .artifactId("websocket-servlet").versionAsInProject(), mavenBundle("org.ops4j.pax.web", "pax-web-websocket") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1) }; } /** * Installation of all the bundles required by {@code pax-web-tomcat} * @return */ protected Option[] paxWebTomcat() { return new Option[] { mavenBundle("org.ops4j.pax.web", "pax-web-tomcat-common") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ops4j.pax.web", "pax-web-tomcat") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("jakarta.security.auth.message", "jakarta.security.auth.message-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1) }; } protected Option[] tomcatWebSockets() { return new Option[] { mavenBundle("jakarta.websocket", "jakarta.websocket-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ops4j.pax.web", "pax-web-tomcat-websocket") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ops4j.pax.web", "pax-web-websocket") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1) }; } /** * Installation of all the bundles required by {@code pax-web-undertow} * @return */ protected Option[] paxWebUndertow() { return new Option[] { mavenBundle("org.jboss.xnio", "xnio-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.jboss.xnio", "xnio-nio") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("io.undertow", "undertow-core") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("io.undertow", "undertow-servlet") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ops4j.pax.web", "pax-web-undertow") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1) }; } protected Option[] undertowWebSockets() { return new Option[] { mavenBundle("jakarta.websocket", "jakarta.websocket-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("io.undertow", "undertow-websockets-jsr") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ops4j.pax.web", "pax-web-undertow-websocket") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ops4j.pax.web", "pax-web-websocket") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1) }; } protected Option[] configAdmin() { return new Option[] { mavenBundle("org.apache.felix", "org.apache.felix.configadmin") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1) }; } protected Option[] eventAdmin() { return new Option[] { mavenBundle("org.apache.felix", "org.apache.felix.eventadmin") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1) }; } protected Option[] scr() { return new Option[] { mavenBundle("org.apache.felix", "org.apache.felix.scr") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.osgi", "org.osgi.util.promise") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.osgi", "org.osgi.util.function") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1) }; } protected Option[] jersey() { return new Option[] { mavenBundle("jakarta.validation", "jakarta.validation-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("com.sun.activation", "javax.activation") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.apache.servicemix.bundles", "org.apache.servicemix.bundles.aopalliance") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("jakarta.xml.bind", "jakarta.xml.bind-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("jakarta.ws.rs", "jakarta.ws.rs-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.glassfish.hk2", "hk2-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.glassfish.hk2", "hk2-locator") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.glassfish.hk2", "hk2-utils") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.glassfish.hk2", "osgi-resource-locator") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.glassfish.jersey.core", "jersey-common") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.glassfish.jersey.core", "jersey-server") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.glassfish.jersey.core", "jersey-client") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.glassfish.jersey.containers", "jersey-container-servlet-core") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.glassfish.jersey.containers", "jersey-container-servlet") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.glassfish.jersey.inject", "jersey-hk2") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.javassist", "javassist") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1) }; } protected Option[] myfacesDependencies() { Option[] options = new Option[] { mavenBundle("jakarta.websocket", "jakarta.websocket-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("jakarta.el", "jakarta.el-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ops4j.pax.web", "pax-web-compatibility-el2") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 2).noStart(), mavenBundle("jakarta.interceptor", "jakarta.interceptor-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ops4j.pax.web", "pax-web-compatibility-interceptor12") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 2).noStart(), // it has to be CDI 1.2 for Myfaces 2.3.x mavenBundle("jakarta.enterprise", "jakarta.enterprise.cdi-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), // but it's ok to have compatibility bundle mavenBundle("org.ops4j.pax.web", "pax-web-compatibility-cdi12") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 2).noStart(), }; if (javaMajorVersion() >= 9) { return combine(options, mavenBundle("jakarta.xml.bind", "jakarta.xml.bind-api").versionAsInProject(), mavenBundle("com.sun.activation", "javax.activation").versionAsInProject() ); } return options; } protected Option[] myfaces() { Option[] options = new Option[] { mavenBundle("jakarta.websocket", "jakarta.websocket-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("jakarta.el", "jakarta.el-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ops4j.pax.web", "pax-web-compatibility-el2") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 2).noStart(), mavenBundle("jakarta.interceptor", "jakarta.interceptor-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ops4j.pax.web", "pax-web-compatibility-interceptor12") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 2).noStart(), mavenBundle("jakarta.enterprise", "jakarta.enterprise.cdi-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1).noStart(), mavenBundle("org.ops4j.pax.web", "pax-web-compatibility-cdi12") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 2).noStart(), mavenBundle("commons-collections", "commons-collections") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("commons-beanutils", "commons-beanutils") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("commons-digester", "commons-digester") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.apache.myfaces.core", "myfaces-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.apache.myfaces.core", "myfaces-impl") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), }; if (javaMajorVersion() >= 9) { return combine(options, mavenBundle("jakarta.xml.bind", "jakarta.xml.bind-api").versionAsInProject(), mavenBundle("com.sun.activation", "javax.activation").versionAsInProject() ); } return options; } protected Option[] ariesCdiAndMyfaces() { return new Option[] { mavenBundle("jakarta.el", "jakarta.el-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ops4j.pax.web", "pax-web-compatibility-el2") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 2).noStart(), mavenBundle("jakarta.websocket", "jakarta.websocket-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), // it has to be CDI 1.2 for Myfaces 2.3.x, but can't conflict with CDI 2.0 needed by aries-cdi // mavenBundle("javax.enterprise", "cdi-api") // .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("commons-collections", "commons-collections") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("commons-beanutils", "commons-beanutils") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("commons-digester", "commons-digester") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.apache.myfaces.core", "myfaces-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.apache.myfaces.core", "myfaces-impl") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.apache.servicemix.bundles", "org.apache.servicemix.bundles.javax-inject") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 2), mavenBundle("org.ops4j.pax.web", "pax-web-fragment-myfaces-inject") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 2).noStart(), mavenBundle("org.ops4j.pax.web", "pax-web-fragment-myfaces-spifly") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 2).noStart(), // These 4 would be required because of osgi.contract capabilities. But Pax Web provides proper // compatibility bundles that fix _canonical_ jakarta API bundles // mavenBundle("org.apache.geronimo.specs", "geronimo-el_2.2_spec") // .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), // mavenBundle("org.apache.geronimo.specs", "geronimo-interceptor_1.2_spec") // .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), // mavenBundle("org.apache.geronimo.specs", "geronimo-jcdi_2.0_spec") // .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), // mavenBundle("org.apache.geronimo.specs", "geronimo-annotation_1.3_spec") // .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("jakarta.enterprise", "jakarta.enterprise.cdi-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1).noStart(), mavenBundle("org.ops4j.pax.web", "pax-web-compatibility-cdi12") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 2).noStart(), mavenBundle("jakarta.interceptor", "jakarta.interceptor-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ops4j.pax.web", "pax-web-compatibility-interceptor12") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 2).noStart(), // Aries CDI extension.servlet.weld and extension.el.jsp require JavaServlet 3.1 capability... mavenBundle("org.ops4j.pax.web", "pax-web-compatibility-servlet31") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1).noStart(), mavenBundle("org.osgi", "org.osgi.service.cdi") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.apache.felix", "org.apache.felix.converter") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.apache.aries.cdi", "org.apache.aries.cdi.spi") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.apache.aries.cdi", "org.apache.aries.cdi.extension.spi") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.apache.aries.cdi", "org.apache.aries.cdi.extender") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.apache.aries.cdi", "org.apache.aries.cdi.weld") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.apache.aries.cdi", "org.apache.aries.cdi.extension.servlet.common") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.apache.aries.cdi", "org.apache.aries.cdi.extension.servlet.weld") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.apache.aries.cdi", "org.apache.aries.cdi.extension.el.jsp") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.apache.aries.cdi", "org.apache.aries.cdi.extra") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.jboss.weld", "weld-osgi-bundle") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.jboss.classfilewriter", "jboss-classfilewriter") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.apache.aries.spifly", "org.apache.aries.spifly.dynamic.bundle") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ow2.asm", "asm") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ow2.asm", "asm-commons") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ow2.asm", "asm-util") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ow2.asm", "asm-tree") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ow2.asm", "asm-analysis") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("jakarta.validation", "jakarta.validation-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.jboss.classfilewriter", "jboss-classfilewriter") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1) }; } protected Option[] ariesJaxrs() { return new Option[] { mavenBundle("org.ops4j.pax.web", "pax-web-compatibility-jaxrs2") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 2).noStart(), mavenBundle("jakarta.ws.rs", "jakarta.ws.rs-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("jakarta.xml.bind", "jakarta.xml.bind-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("jakarta.xml.ws", "jakarta.xml.ws-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("jakarta.xml.soap", "jakarta.xml.soap-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("com.sun.activation", "javax.activation") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ops4j.pax.web", "pax-web-compatibility-servlet31") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1).noStart(), mavenBundle("org.osgi", "org.osgi.service.jaxrs") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.apache.aries.spifly", "org.apache.aries.spifly.dynamic.bundle") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ow2.asm", "asm") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ow2.asm", "asm-commons") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ow2.asm", "asm-util") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ow2.asm", "asm-tree") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ow2.asm", "asm-analysis") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.apache.aries.component-dsl", "org.apache.aries.component-dsl.component-dsl") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.apache.aries.jax.rs", "org.apache.aries.jax.rs.whiteboard") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.apache.cxf", "cxf-core") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.apache.cxf", "cxf-rt-frontend-jaxrs") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.apache.cxf", "cxf-rt-security") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.apache.cxf", "cxf-rt-transports-http") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.apache.cxf", "cxf-rt-rs-client") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.apache.cxf", "cxf-rt-rs-sse") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.apache.ws.xmlschema", "xmlschema-core") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.codehaus.woodstox", "stax2-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("com.fasterxml.woodstox", "woodstox-core") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), }; } protected Option[] primefaces() { return combine(myfaces(), mavenBundle("jakarta.persistence", "jakarta.persistence-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ops4j.pax.web", "pax-web-compatibility-jpa2") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 2).noStart(), mavenBundle("jakarta.xml.bind", "jakarta.xml.bind-api") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("com.sun.activation", "javax.activation") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.apache.aries.spifly", "org.apache.aries.spifly.dynamic.bundle") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ow2.asm", "asm") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ow2.asm", "asm-commons") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ow2.asm", "asm-util") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ow2.asm", "asm-tree") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.ow2.asm", "asm-analysis") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1), mavenBundle("org.primefaces", "primefaces") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 1) ); } protected Option jasypt() { return mavenBundle("org.apache.servicemix.bundles", "org.apache.servicemix.bundles.jasypt") .versionAsInProject().startLevel(START_LEVEL_TEST_BUNDLE - 2); } // --- helper methods to be used in all the tests /** * Returns {@code mvn:} URI for standard Pax Web sample with version set as current version of Pax Web. * * @param artifactId * @return */ protected String sampleURI(String artifactId) { return "mvn:org.ops4j.pax.web.samples/" + artifactId + "/" + VersionUtils.getProjectVersion(); } /** * Returns {@code mvn:} URI for standard Pax Web sample with version set as current version of Pax Web. * * @param artifactId * @return */ protected String sampleWarURI(String artifactId) { return "mvn:org.ops4j.pax.web.samples/" + artifactId + "/" + VersionUtils.getProjectVersion() + "/war"; } protected Bundle installAndStartBundle(String uri) { try { final Bundle bundle = context.installBundle(uri); bundle.start(); new WaitCondition("Starting bundle " + uri) { @Override protected boolean isFulfilled() { return bundle.getState() == Bundle.ACTIVE; } }.waitForCondition(); return bundle; } catch (InterruptedException | BundleException e) { throw new RuntimeException(e); } } /** * Installs a bundle using {@code webbundle:} protocol * @param artifactId * @param contextPath * @return */ protected Bundle installAndStartWebBundle(String artifactId, String contextPath) { String uri = String.format("webbundle:%s?%s=%s&%s=org.ops4j.pax.web.samples.%s", sampleWarURI(artifactId), PaxWebConstants.HEADER_CONTEXT_PATH, contextPath, Constants.BUNDLE_SYMBOLICNAME, artifactId); return installAndStartBundle(uri); } /** * Installs a bundle using {@code webbundle:} protocol * @param groupId * @param artifactId * @param version * @param symbolicName * @param contextPath * @return */ protected Bundle installAndStartWebBundle(String groupId, String artifactId, String version, String symbolicName, String contextPath, Function convertURI) { String uri = String.format("webbundle:mvn:%s/%s/%s/war?%s=%s&%s=%s", groupId, artifactId, version, PaxWebConstants.HEADER_CONTEXT_PATH, contextPath, Constants.BUNDLE_SYMBOLICNAME, symbolicName); return installAndStartBundle(convertURI == null ? uri : convertURI.apply(uri)); } /** * Get a bundle by symbolic name. * @param symbolicName * @return */ protected Bundle bundle(String symbolicName) { return Arrays.stream(context.getBundles()) .filter(b -> symbolicName.equals(b.getSymbolicName())).findFirst().orElse(null); } /** * Get a sample Bundle by its artifactId. * @param sample * @return */ protected Bundle sampleBundle(String sample) { return bundle("org.ops4j.pax.web.samples." + sample); } // --- helper methods to be used in all the tests /** * Creates a listener for generic {@link WebElementEvent} events with * associated {@link org.ops4j.pax.web.itest.utils.WaitCondition} fulfilled after satisfying passed * {@link java.util.function.BiPredicate} operating on single {@link WebElementEvent}. This method sets up * the listener, calls the passed {@code action} and waits for the condition that's satisfied according * to passed {@code expectation}. */ protected void configureAndWait(Runnable action, final BiPredicate expectation) { final List events = new CopyOnWriteArrayList<>(); webElementEventListener = events::add; ServiceRegistration reg = context.registerService(WebElementEventListener.class, webElementEventListener, null); action.run(); try { new WaitCondition("Waiting for " + expectation) { @Override protected boolean isFulfilled() { return events.stream().anyMatch(e -> expectation.test(e.getType(), e.getData())); } }.waitForCondition(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new RuntimeException(e.getMessage(), e); } finally { if (reg != null) { reg.unregister(); } } } /** * "configure and wait" method that allows to check entire stream of {@link WebElementEvent}s. * @param action * @param expectation */ protected void configureAndWait(Runnable action, final Predicate> expectation) { final List events = new CopyOnWriteArrayList<>(); webElementEventListener = events::add; ServiceRegistration reg = context.registerService(WebElementEventListener.class, webElementEventListener, null); action.run(); try { new WaitCondition("Waiting for " + expectation) { @Override protected boolean isFulfilled() { return expectation.test(events); } }.waitForCondition(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new RuntimeException(e.getMessage(), e); } finally { if (reg != null) { reg.unregister(); } } } /** * Creates a listener for deployment of named {@link javax.servlet.Servlet}. * @param servletName * @param action */ protected void configureAndWaitForNamedServlet(final String servletName, Action action) throws Exception { final List events = new CopyOnWriteArrayList<>(); webElementEventListener = events::add; ServiceRegistration reg = context.registerService(WebElementEventListener.class, webElementEventListener, null); action.run(); try { new WaitCondition("Waiting for " + servletName + " servlet") { @Override protected boolean isFulfilled() { return events.stream().anyMatch(e -> e.getType() == WebElementEvent.State.DEPLOYED && e.getData() instanceof ServletEventData && ((ServletEventData) e.getData()).getServletName().equals(servletName)); } }.waitForCondition(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new RuntimeException(e.getMessage(), e); } finally { if (reg != null) { reg.unregister(); } } } /** * Creates a listener for deployment of a {@link javax.servlet.Servlet} mapped to some URL. * @param mapping * @param action */ protected void configureAndWaitForServletWithMapping(final String mapping, Action action) throws Exception { final List events = new CopyOnWriteArrayList<>(); webElementEventListener = events::add; ServiceRegistration reg = context.registerService(WebElementEventListener.class, webElementEventListener, null); action.run(); try { new WaitCondition("Waiting for servlet mapped to " + mapping) { @Override protected boolean isFulfilled() { return events.stream().anyMatch(e -> e.getType() == WebElementEvent.State.DEPLOYED && e.getData() instanceof ServletEventData && Arrays.asList(((ServletEventData) e.getData()).getUrlPatterns()).contains(mapping)); } }.waitForCondition(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new RuntimeException(e.getMessage(), e); } finally { if (reg != null) { reg.unregister(); } } } /** * Creates a listener for deployment of a {@link javax.servlet.Filter} mapped to some URL. * @param mapping * @param action */ protected void configureAndWaitForFilterWithMapping(final String mapping, Action action) throws Exception { final List events = new CopyOnWriteArrayList<>(); webElementEventListener = events::add; ServiceRegistration reg = context.registerService(WebElementEventListener.class, webElementEventListener, null); action.run(); try { new WaitCondition("Waiting for filter mapped to " + mapping) { @Override protected boolean isFulfilled() { return events.stream().anyMatch(e -> e.getType() == WebElementEvent.State.DEPLOYED && e.getData() instanceof FilterEventData && Arrays.asList(((FilterEventData) e.getData()).getUrlPatterns()).contains(mapping)); } }.waitForCondition(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new RuntimeException(e.getMessage(), e); } finally { if (reg != null) { reg.unregister(); } } } /** * Performs an action and waits for {@link org.ops4j.pax.web.service.spi.model.events.WebApplicationEvent} related * to started WAB * @param action */ protected void configureAndWaitForDeployment(Action action) throws Exception { configureAndWaitForDeployment(action, RETRY_DURATION_MILLIS); } /** * Performs an action and waits for {@link org.ops4j.pax.web.service.spi.model.events.WebApplicationEvent} related * to started WAB * @param action * @param timeoutInMs */ protected void configureAndWaitForDeployment(Action action, long timeoutInMs) throws Exception { final CountDownLatch latch = new CountDownLatch(1); WebApplicationEventListener listener = event -> { if (event.getType() == WebApplicationEvent.State.DEPLOYED) { latch.countDown(); } }; ServiceRegistration reg = context.registerService(WebApplicationEventListener.class, listener, null); action.run(); try { new WaitCondition("Waiting for deployment") { @Override protected boolean isFulfilled() { return latch.getCount() == 0L; } }.waitForCondition(timeoutInMs, SLEEP_DURATION_MILLIS); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new RuntimeException(e.getMessage(), e); } finally { if (reg != null) { reg.unregister(); } } } /** * Performs an action and waits for {@link org.ops4j.pax.web.service.spi.model.events.WebApplicationEvent} related * to started WAB, but only if the provided sample bundle is not ACTIVE. * @param sample * @param action */ protected Bundle configureAndWaitForDeploymentUnlessInstalled(String sample, Action action) throws Exception { Bundle b = sampleBundle(sample); if (b != null && b.getState() == Bundle.ACTIVE) { return b; } configureAndWaitForDeployment(action); return sampleBundle(sample); } /** * Performs an action and waits for {@link org.ops4j.pax.web.service.spi.model.events.ServerEvent} related * to started container at given port * @param port * @param actions */ protected void configureAndWaitForListener(int port, Action ... actions) throws Exception { final List events = new CopyOnWriteArrayList<>(); ServerListener listener = events::add; ServiceRegistration reg = context.registerService(ServerListener.class, listener, null); if (actions != null) { for (Action a : actions) { a.run(); } } try { new WaitCondition("Waiting for server listening at " + port) { @Override protected boolean isFulfilled() { return events.stream().anyMatch(e -> e.getState() == ServerEvent.State.STARTED && Arrays.stream(e.getAddresses()).map(a -> a.getAddress().getPort()) .anyMatch(p -> p == port)); } }.waitForCondition(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new RuntimeException(e.getMessage(), e); } finally { if (reg != null) { reg.unregister(); } } } /** * Checks whether an event is for {@link org.ops4j.pax.web.service.spi.model.elements.ElementModel} registration * to all the passed context names. * @param data * @param names * @return */ public static boolean usesContexts(WebElementEventData data, String ... names) { Set used = new HashSet<>(data.getContextNames()); return used.containsAll(Arrays.asList(names)); } public static HttpService getHttpService(final BundleContext bundleContext) { ServiceTracker tracker = new ServiceTracker<>(bundleContext, HttpService.class, null); tracker.open(); try { return tracker.waitForService(5000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new IllegalStateException(e.getMessage(), e); } } public static WebContainer getWebContainer(final BundleContext bundleContext) { ServiceTracker tracker = new ServiceTracker<>(bundleContext, WebContainer.class, null); tracker.open(); try { return tracker.waitForService(5000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new IllegalStateException(e.getMessage(), e); } } /** * Creates {@link javax.servlet.Servlet} init parameters with legacy name that can be (which is deprecated, but * the only way with pure {@link HttpService} to specify servlet name) used to configure {@link javax.servlet.Servlet} * name. * @param servletName * @return */ @SuppressWarnings("deprecation") protected Dictionary legacyName(String servletName) { Dictionary initParams = new Hashtable<>(); initParams.put(PaxWebConstants.INIT_PARAM_SERVLET_NAME, servletName); return initParams; } protected int javaMajorVersion() { String v = System.getProperty("java.specification.version"); if (v.contains(".")) { // before Java 9 v = v.split("\\.")[1]; } return Integer.parseInt(v); } @FunctionalInterface public interface Action { void run() throws Exception; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy