Merge pull request #12 from rotty3000/ARIES-1954

ARIES-1954 CDI SPI to share container configuration with Portable Extensions
diff --git a/cdi-extender/pom.xml b/cdi-extender/pom.xml
index a682fc6..0821749 100644
--- a/cdi-extender/pom.xml
+++ b/cdi-extender/pom.xml
@@ -117,6 +117,14 @@
 		</dependency>
 		<dependency>
 			<groupId>org.osgi</groupId>
+			<artifactId>org.osgi.service.jaxrs</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.osgi</groupId>
+			<artifactId>org.osgi.service.http.whiteboard</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.osgi</groupId>
 			<artifactId>org.osgi.service.log</artifactId>
 		</dependency>
 		<dependency>
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/BundleContextExtension.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/BundleContextExtension.java
index 50ad245..23cd786 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/BundleContextExtension.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/BundleContextExtension.java
@@ -16,9 +16,7 @@
 
 import javax.enterprise.event.Observes;
 import javax.enterprise.inject.spi.AfterBeanDiscovery;
-import javax.enterprise.inject.spi.BeanManager;
 import javax.enterprise.inject.spi.Extension;
-import javax.enterprise.inject.spi.configurator.BeanConfigurator;
 
 import org.osgi.framework.BundleContext;
 
@@ -28,10 +26,10 @@
 		_bundleContext = bundleContext;
 	}
 
-	void afterBeanDiscovery(@Observes AfterBeanDiscovery abd, BeanManager manager) {
-		BeanConfigurator<BundleContext> bean = abd.addBean();
-		bean.addType(BundleContext.class);
-		bean.createWith(c -> _bundleContext);
+	void afterBeanDiscovery(@Observes AfterBeanDiscovery abd) {
+		abd.addBean()
+			.addType(BundleContext.class)
+			.createWith(c -> _bundleContext);
 	}
 
 	private final BundleContext _bundleContext;
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ConfigurationExtension.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ConfigurationExtension.java
new file mode 100644
index 0000000..078d842
--- /dev/null
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ConfigurationExtension.java
@@ -0,0 +1,94 @@
+package org.apache.aries.cdi.container.internal.container;
+
+import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT;
+import static org.osgi.service.jaxrs.whiteboard.JaxrsWhiteboardConstants.JAX_RS_APPLICATION_SELECT;
+
+import java.util.AbstractMap;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.BeforeBeanDiscovery;
+import javax.enterprise.inject.spi.Extension;
+
+import org.apache.aries.cdi.spi.configuration.Configuration;
+
+public class ConfigurationExtension  extends AbstractMap<String, Object> implements Configuration, Extension {
+
+	public ConfigurationExtension(ContainerState containerState) {
+		_containerState = containerState;
+
+		Map<String, Object> configuration = new TreeMap<>();
+
+		if (_containerState.containerDTO().components != null &&
+			!_containerState.containerDTO().components.isEmpty() &&
+			_containerState.containerDTO().components.get(0).instances != null &&
+			!_containerState.containerDTO().components.get(0).instances.isEmpty() &&
+			_containerState.containerDTO().components.get(0).instances.get(0).configurations != null &&
+			!_containerState.containerDTO().components.get(0).instances.get(0).configurations.isEmpty()) {
+
+			configuration = new TreeMap<>(_containerState.containerDTO().components.get(0).instances.get(0).configurations.get(0).properties);
+		}
+
+		configuration.put(HTTP_WHITEBOARD_CONTEXT_SELECT, getSelectedContext(configuration));
+		configuration.put(JAX_RS_APPLICATION_SELECT, getSelectedApplication(configuration));
+
+		_configuration = Collections.unmodifiableMap(configuration);
+	}
+
+	@Override
+	public Set<Entry<String, Object>> entrySet() {
+		return _configuration.entrySet();
+	}
+
+	void fire(@Observes BeforeBeanDiscovery bbd, BeanManager beanManager) {
+		beanManager.fireEvent(this);
+	}
+
+	String getSelectedApplication(Map<String, Object> configuration) {
+		if (configuration.containsKey(JAX_RS_APPLICATION_SELECT)) {
+			return String.valueOf(_configuration.get(JAX_RS_APPLICATION_SELECT));
+		}
+
+		Map<String, Object> attributes = _containerState.cdiAttributes();
+
+		if (attributes.containsKey(JAX_RS_APPLICATION_SELECT)) {
+			return String.valueOf(attributes.get(JAX_RS_APPLICATION_SELECT));
+		}
+
+		return DEFAULT_APPLICATION_FILTER;
+	}
+
+	String getSelectedContext(Map<String, Object> configuration) {
+		if (configuration.containsKey(HTTP_WHITEBOARD_CONTEXT_SELECT)) {
+			return String.valueOf(_configuration.get(HTTP_WHITEBOARD_CONTEXT_SELECT));
+		}
+
+		Map<String, Object> attributes = _containerState.cdiAttributes();
+
+		if (attributes.containsKey(HTTP_WHITEBOARD_CONTEXT_SELECT)) {
+			return String.valueOf(attributes.get(HTTP_WHITEBOARD_CONTEXT_SELECT));
+		}
+
+		Dictionary<String,String> headers = _containerState.bundle().getHeaders();
+
+		if (headers != null && headers.get(WEB_CONTEXT_PATH) != null) {
+			return CONTEXT_PATH_PREFIX + headers.get(WEB_CONTEXT_PATH) + ')';
+		}
+
+		return DEFAULT_CONTEXT_FILTER;
+	}
+
+	private static final String CONTEXT_PATH_PREFIX = "(osgi.http.whiteboard.context.path=";
+	private static final String DEFAULT_APPLICATION_FILTER = "(osgi.jaxrs.name=.default)";
+	private static final String DEFAULT_CONTEXT_FILTER = "(osgi.http.whiteboard.context.name=default)";
+	private static final String WEB_CONTEXT_PATH = "Web-ContextPath";
+
+	private final ContainerState _containerState;
+	private final Map<String, Object> _configuration;
+
+}
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerBootstrap.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerBootstrap.java
index e0dc3c5..02afa09 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerBootstrap.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerBootstrap.java
@@ -160,6 +160,10 @@
 
 		// Add the internal extensions
 		initializer.addExtension(
+			new ConfigurationExtension(containerState),
+			Maps.of(Constants.SERVICE_ID, counter.decrementAndGet(),
+					Constants.SERVICE_DESCRIPTION, "Aries CDI ConfigurationExtension"));
+		initializer.addExtension(
 			new BundleContextExtension(containerState.bundleContext()),
 			Maps.of(Constants.SERVICE_ID, counter.decrementAndGet(),
 					Constants.SERVICE_DESCRIPTION, "Aries CDI BundleContextExtension"));
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerState.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerState.java
index 2a9d130..bb77503 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerState.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerState.java
@@ -106,6 +106,8 @@
 			}
 		}
 
+		_cdiAttributes = Collections.unmodifiableMap(cdiAttributes);
+
 		wires = bundleWiring.getRequiredWires(CDI_EXTENSION_PROPERTY);
 
 		List<String> extensionRequirements = new ArrayList<>();
@@ -138,7 +140,7 @@
 		_containerDTO.template.components = new CopyOnWriteArrayList<>();
 		_containerDTO.template.extensions = new CopyOnWriteArrayList<>();
 		_containerDTO.template.id = Optional.ofNullable(
-			(String)cdiAttributes.get(CDI_CONTAINER_ID)
+			(String)_cdiAttributes.get(CDI_CONTAINER_ID)
 		).orElse(
 			_bundle.getSymbolicName()
 		);
@@ -171,7 +173,7 @@
 		ExtendedConfigurationTemplateDTO configurationTemplate = new ExtendedConfigurationTemplateDTO();
 		configurationTemplate.maximumCardinality = MaximumCardinality.ONE;
 		configurationTemplate.pid = Optional.ofNullable(
-			(String)cdiAttributes.get(CDI_CONTAINER_ID)
+			(String)_cdiAttributes.get(CDI_CONTAINER_ID)
 		).map(
 			s -> s.replaceAll("-", ".")
 		).orElse(
@@ -185,7 +187,7 @@
 
 		_aggregateClassLoader = new BundleClassLoader(_bundle, _extenderBundle);
 
-		_beansModel = new BeansModelBuilder(this, _aggregateClassLoader, bundleWiring, cdiAttributes).build();
+		_beansModel = new BeansModelBuilder(this, _aggregateClassLoader, bundleWiring, _cdiAttributes).build();
 
 		try {
 			new Discovery(this).discover();
@@ -240,6 +242,10 @@
 		return _ccrLogs;
 	}
 
+	public Map<String, Object> cdiAttributes() {
+		return _cdiAttributes;
+	}
+
 	public BundleClassLoader classLoader() {
 		return _aggregateClassLoader;
 	}
@@ -368,6 +374,7 @@
 	private final ServiceTracker<ConfigurationAdmin, ConfigurationAdmin> _caTracker;
 	private final Logger _log;
 	private final Logs _ccrLogs;
+	private final Map<String, Object> _cdiAttributes;
 	private final ChangeCount _changeCount;
 	private final AtomicBoolean _closing = new AtomicBoolean(false);
 	private final ComponentContext _componentContext = new ComponentContext();
diff --git a/cdi-extension-http/pom.xml b/cdi-extension-http/pom.xml
index 66de4d2..03a4216 100644
--- a/cdi-extension-http/pom.xml
+++ b/cdi-extension-http/pom.xml
@@ -63,6 +63,11 @@
 			<version>${project.version}</version>
 		</dependency>
 		<dependency>
+			<groupId>org.apache.aries.cdi</groupId>
+			<artifactId>org.apache.aries.cdi.spi</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+		<dependency>
 			<groupId>org.apache.felix</groupId>
 			<artifactId>org.apache.felix.http.servlet-api</artifactId>
 		</dependency>
diff --git a/cdi-extension-http/src/main/java/org/apache/aries/cdi/extension/http/HttpExtension.java b/cdi-extension-http/src/main/java/org/apache/aries/cdi/extension/http/HttpExtension.java
index 5b0c55d..7459038 100644
--- a/cdi-extension-http/src/main/java/org/apache/aries/cdi/extension/http/HttpExtension.java
+++ b/cdi-extension-http/src/main/java/org/apache/aries/cdi/extension/http/HttpExtension.java
@@ -18,19 +18,15 @@
 import static org.osgi.framework.Constants.SERVICE_DESCRIPTION;
 import static org.osgi.framework.Constants.SERVICE_RANKING;
 import static org.osgi.framework.Constants.SERVICE_VENDOR;
-import static org.osgi.namespace.extender.ExtenderNamespace.EXTENDER_NAMESPACE;
-import static org.osgi.service.cdi.CDIConstants.CDI_CAPABILITY_NAME;
 import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT;
 import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER;
 
 import java.lang.annotation.Annotation;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Dictionary;
 import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
 
@@ -72,22 +68,23 @@
 import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardServletPattern;
 import org.apache.aries.cdi.extra.propertytypes.ServiceDescription;
 import org.apache.aries.cdi.extra.propertytypes.ServiceRanking;
+import org.apache.aries.cdi.spi.configuration.Configuration;
 import org.jboss.weld.module.web.servlet.WeldInitialListener;
-import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceRegistration;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRequirement;
-import org.osgi.framework.wiring.BundleWire;
-import org.osgi.framework.wiring.BundleWiring;
 import org.osgi.service.cdi.annotations.Service;
 
 public class HttpExtension implements Extension {
 
-	public HttpExtension(Bundle bundle) {
-		_bundle = bundle;
+	private volatile Configuration configuration;
+
+	void getConfiguration(@Observes Configuration configuration) {
+		this.configuration = configuration;
 	}
 
-	<X> void processWebFilter(@Observes @WithAnnotations(WebFilter.class) ProcessAnnotatedType<X> pat) {
+	<X> void processWebFilter(
+		@Observes @WithAnnotations(WebFilter.class) ProcessAnnotatedType<X> pat) {
+
 		final AnnotatedType<X> annotatedType = pat.getAnnotatedType();
 
 		WebFilter webFilter = annotatedType.getAnnotation(WebFilter.class);
@@ -99,7 +96,7 @@
 		}
 
 		if(!annotatedType.isAnnotationPresent(HttpWhiteboardContextSelect.class)) {
-			annotationsToAdd.add(HttpWhiteboardContextSelect.Literal.of(getSelectedContext()));
+			annotationsToAdd.add(HttpWhiteboardContextSelect.Literal.of((String)configuration.get(HTTP_WHITEBOARD_CONTEXT_SELECT)));
 		}
 
 		if (!webFilter.description().isEmpty()) {
@@ -132,7 +129,9 @@
 		}
 	}
 
-	<X> void processWebListener(@Observes @WithAnnotations(WebListener.class) ProcessAnnotatedType<X> pat) {
+	<X> void processWebListener(
+		@Observes @WithAnnotations(WebListener.class) ProcessAnnotatedType<X> pat) {
+
 		final AnnotatedType<X> annotatedType = pat.getAnnotatedType();
 
 		WebListener webListener = annotatedType.getAnnotation(WebListener.class);
@@ -170,7 +169,7 @@
 		}
 
 		if(!annotatedType.isAnnotationPresent(HttpWhiteboardContextSelect.class)) {
-			annotationsToAdd.add(HttpWhiteboardContextSelect.Literal.of(getSelectedContext()));
+			annotationsToAdd.add(HttpWhiteboardContextSelect.Literal.of((String)configuration.get(HTTP_WHITEBOARD_CONTEXT_SELECT)));
 		}
 
 		annotationsToAdd.add(HttpWhiteboardListener.Literal.INSTANCE);
@@ -184,7 +183,9 @@
 		}
 	}
 
-	<X> void processWebServlet(@Observes @WithAnnotations(WebServlet.class) ProcessAnnotatedType<X> pat) {
+	<X> void processWebServlet(
+		@Observes @WithAnnotations(WebServlet.class) ProcessAnnotatedType<X> pat) {
+
 		final AnnotatedType<X> annotatedType = pat.getAnnotatedType();
 
 		WebServlet webServlet = annotatedType.getAnnotation(WebServlet.class);
@@ -196,7 +197,7 @@
 		}
 
 		if(!annotatedType.isAnnotationPresent(HttpWhiteboardContextSelect.class)) {
-			annotationsToAdd.add(HttpWhiteboardContextSelect.Literal.of(getSelectedContext()));
+			annotationsToAdd.add(HttpWhiteboardContextSelect.Literal.of((String)configuration.get(HTTP_WHITEBOARD_CONTEXT_SELECT)));
 		}
 
 		if (!webServlet.name().isEmpty()) {
@@ -240,12 +241,14 @@
 		beanManager.getEvent().fireAsync(new Ready());
 	}
 
-	void ready(@ObservesAsync Ready ready, BeanManager beanManager) {
+	void ready(
+		@ObservesAsync Ready ready, BeanManager beanManager, BundleContext bundleContext) {
+
 		Dictionary<String, Object> properties = new Hashtable<>();
 
 		properties.put(SERVICE_DESCRIPTION, "Aries CDI - HTTP Portable Extension for Weld");
 		properties.put(SERVICE_VENDOR, "Apache Software Foundation");
-		properties.put(HTTP_WHITEBOARD_CONTEXT_SELECT, getSelectedContext());
+		properties.put(HTTP_WHITEBOARD_CONTEXT_SELECT, configuration.get(HTTP_WHITEBOARD_CONTEXT_SELECT));
 		properties.put(HTTP_WHITEBOARD_LISTENER, Boolean.TRUE.toString());
 		properties.put(SERVICE_RANKING, Integer.MAX_VALUE - 100);
 
@@ -255,7 +258,7 @@
 
 		WeldInitialListener initialListener = bean.create(beanManager.createCreationalContext(bean));
 
-		_listenerRegistration = _bundle.getBundleContext().registerService(
+		_listenerRegistration = bundleContext.registerService(
 			LISTENER_CLASSES, new ListenerWrapper<>(initialListener), properties);
 	}
 
@@ -270,63 +273,12 @@
 		}
 	}
 
-	private Map<String, Object> getAttributes() {
-		BundleWiring bundleWiring = _bundle.adapt(BundleWiring.class);
-
-		List<BundleWire> wires = bundleWiring.getRequiredWires(EXTENDER_NAMESPACE);
-
-		Map<String, Object> cdiAttributes = Collections.emptyMap();
-
-		for (BundleWire wire : wires) {
-			BundleCapability capability = wire.getCapability();
-			Map<String, Object> attributes = capability.getAttributes();
-			String extender = (String)attributes.get(EXTENDER_NAMESPACE);
-
-			if (extender.equals(CDI_CAPABILITY_NAME)) {
-				BundleRequirement requirement = wire.getRequirement();
-				cdiAttributes = requirement.getAttributes();
-				break;
-			}
-		}
-
-		return cdiAttributes;
-	}
-
-	private String getSelectedContext() {
-		if (_contextSelect != null) {
-			return _contextSelect;
-		}
-
-		return _contextSelect = getSelectedContext0();
-	}
-
-	private String getSelectedContext0() {
-		Map<String, Object> attributes = getAttributes();
-
-		if (attributes.containsKey(HTTP_WHITEBOARD_CONTEXT_SELECT)) {
-			return (String)attributes.get(HTTP_WHITEBOARD_CONTEXT_SELECT);
-		}
-
-		Dictionary<String,String> headers = _bundle.getHeaders();
-
-		if (headers.get(WEB_CONTEXT_PATH) != null) {
-			return CONTEXT_PATH_PREFIX + headers.get(WEB_CONTEXT_PATH) + ')';
-		}
-
-		return DEFAULT_CONTEXT_FILTER;
-	}
-
-	private static final String CONTEXT_PATH_PREFIX = "(osgi.http.whiteboard.context.path=";
-	private static final String DEFAULT_CONTEXT_FILTER = "(osgi.http.whiteboard.context.name=default)";
 	private static final String[] LISTENER_CLASSES = new String[] {
-		ServletContextListener.class.getName(),
-		ServletRequestListener.class.getName(),
-		HttpSessionListener.class.getName()
+			ServletContextListener.class.getName(),
+			ServletRequestListener.class.getName(),
+			HttpSessionListener.class.getName()
 	};
-	private static final String WEB_CONTEXT_PATH = "Web-ContextPath";
 
-	private final Bundle _bundle;
-	private String _contextSelect;
 	private volatile ServiceRegistration<?> _listenerRegistration;
 	private final AtomicBoolean destroyed = new AtomicBoolean(false);
 
diff --git a/cdi-extension-http/src/main/java/org/apache/aries/cdi/extension/http/HttpExtensionFactory.java b/cdi-extension-http/src/main/java/org/apache/aries/cdi/extension/http/HttpExtensionFactory.java
index 906b898..ff6a784 100644
--- a/cdi-extension-http/src/main/java/org/apache/aries/cdi/extension/http/HttpExtensionFactory.java
+++ b/cdi-extension-http/src/main/java/org/apache/aries/cdi/extension/http/HttpExtensionFactory.java
@@ -26,7 +26,7 @@
 	public Extension getService(
 		Bundle bundle, ServiceRegistration<Extension> registration) {
 
-		return new HttpExtension(bundle);
+		return new HttpExtension();
 	}
 
 	@Override
diff --git a/cdi-itests/pom.xml b/cdi-itests/pom.xml
index 9534981..4321005 100644
--- a/cdi-itests/pom.xml
+++ b/cdi-itests/pom.xml
@@ -106,6 +106,10 @@
 		</dependency>
 		<dependency>
 			<groupId>org.osgi</groupId>
+			<artifactId>org.osgi.service.jaxrs</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.osgi</groupId>
 			<artifactId>org.osgi.service.http.whiteboard</artifactId>
 		</dependency>
 		<dependency>
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/cases/BeanPropertyTypeTest.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/cases/BeanPropertyTypeTest.java
index 537c445..f729adc 100644
--- a/cdi-itests/src/main/java/org/apache/aries/cdi/test/cases/BeanPropertyTypeTest.java
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/cases/BeanPropertyTypeTest.java
@@ -15,14 +15,17 @@
 package org.apache.aries.cdi.test.cases;
 
 import static org.assertj.core.api.Assertions.assertThat;
-
-import javax.servlet.ServletContextListener;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
 import org.junit.After;
 import org.junit.AfterClass;
+import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.osgi.framework.Bundle;
+import org.osgi.service.http.runtime.HttpServiceRuntime;
+import org.osgi.service.http.runtime.dto.ServletContextDTO;
 import org.osgi.util.tracker.ServiceTracker;
 
 public class BeanPropertyTypeTest extends AbstractTestCase {
@@ -35,31 +38,61 @@
 	public static void afterClass() throws Exception {
 	}
 
-	@Override
-	public void setUp() throws Exception {
-	}
-
-	@After
-	@Override
-	public void tearDown() throws Exception {
-	}
-
 	@Test
-	public void usesMarkerAnnotation() throws Exception {
+	public void beanPropertyAnnotationsWereUsed() throws Exception {
 		Bundle tbBundle = installBundle("tb13.jar");
 
 		try {
 			getBeanManager(tbBundle);
 
-			ServiceTracker<ServletContextListener, ServletContextListener> oneTracker = track("(objectClass=%s)", ServletContextListener.class.getName());
-			oneTracker.open();
-			Object service = oneTracker.waitForService(timeout);
+			ServletContextDTO contextDTO = waitFor("customContext");
 
-			assertThat(service).isNotNull();
+			assertThat(contextDTO).isNotNull();
 		}
 		finally {
 			tbBundle.uninstall();
 		}
 	}
 
+	@Before
+	@Override
+	public void setUp() throws Exception {
+		hsrTracker = new ServiceTracker<>(bundleContext, HttpServiceRuntime.class, null);
+
+		hsrTracker.open();
+
+		hsr = hsrTracker.waitForService(timeout);
+
+		assertNotNull(hsr);
+	}
+
+	@After
+	@Override
+	public void tearDown() throws Exception {
+		hsrTracker.close();
+	}
+
+	private ServletContextDTO waitFor(String context) throws InterruptedException {
+		return waitFor(context, 20);
+	}
+
+	private ServletContextDTO waitFor(String context, int intervals) throws InterruptedException {
+		for (int j = intervals; j > 0; j--) {
+			for (ServletContextDTO scDTO : hsr.getRuntimeDTO().servletContextDTOs) {
+				if (scDTO.name.equals(context)) {
+					return scDTO;
+				}
+			}
+
+			Thread.sleep(50);
+		}
+
+		assertTrue(String.format("%s not found in time", context), false);
+
+		return null;
+	}
+
+	private HttpServiceRuntime hsr;
+	private ServiceTracker<HttpServiceRuntime, HttpServiceRuntime> hsrTracker;
+
 }
diff --git a/cdi-owb/src/main/java/org/apache/aries/cdi/owb/web/WebExtension.java b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/web/WebExtension.java
index d07a618..4a8f4c5 100644
--- a/cdi-owb/src/main/java/org/apache/aries/cdi/owb/web/WebExtension.java
+++ b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/web/WebExtension.java
@@ -19,20 +19,16 @@
 import static org.osgi.framework.Constants.SERVICE_DESCRIPTION;
 import static org.osgi.framework.Constants.SERVICE_RANKING;
 import static org.osgi.framework.Constants.SERVICE_VENDOR;
-import static org.osgi.namespace.extender.ExtenderNamespace.EXTENDER_NAMESPACE;
-import static org.osgi.service.cdi.CDIConstants.CDI_CAPABILITY_NAME;
 import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT;
 import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER;
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Dictionary;
 import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
 
@@ -70,23 +66,24 @@
 import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardServletPattern;
 import org.apache.aries.cdi.extra.propertytypes.ServiceDescription;
 import org.apache.aries.cdi.extra.propertytypes.ServiceRanking;
+import org.apache.aries.cdi.spi.configuration.Configuration;
 import org.apache.webbeans.config.WebBeansContext;
 import org.apache.webbeans.spi.ContainerLifecycle;
-import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceRegistration;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRequirement;
-import org.osgi.framework.wiring.BundleWire;
-import org.osgi.framework.wiring.BundleWiring;
 import org.osgi.service.cdi.annotations.Service;
 
 public class WebExtension implements Extension {
 
-	public WebExtension(Bundle bundle) {
-		_bundle = bundle;
+	private volatile Configuration configuration;
+
+	void getConfiguration(@Observes Configuration configuration) {
+		this.configuration = configuration;
 	}
 
-	<X> void processWebFilter(@Observes @WithAnnotations(WebFilter.class) ProcessAnnotatedType<X> pat) {
+	<X> void processWebFilter(
+		@Observes @WithAnnotations(WebFilter.class) ProcessAnnotatedType<X> pat) {
+
 		final AnnotatedType<X> annotatedType = pat.getAnnotatedType();
 
 		WebFilter webFilter = annotatedType.getAnnotation(WebFilter.class);
@@ -98,7 +95,7 @@
 		}
 
 		if(!annotatedType.isAnnotationPresent(HttpWhiteboardContextSelect.class)) {
-			annotationsToAdd.add(HttpWhiteboardContextSelect.Literal.of(getSelectedContext()));
+			annotationsToAdd.add(HttpWhiteboardContextSelect.Literal.of((String)configuration.get(HTTP_WHITEBOARD_CONTEXT_SELECT)));
 		}
 
 		if (!webFilter.description().isEmpty()) {
@@ -131,7 +128,9 @@
 		}
 	}
 
-	<X> void processWebListener(@Observes @WithAnnotations(WebListener.class) ProcessAnnotatedType<X> pat) {
+	<X> void processWebListener(
+		@Observes @WithAnnotations(WebListener.class) ProcessAnnotatedType<X> pat) {
+
 		final AnnotatedType<X> annotatedType = pat.getAnnotatedType();
 
 		WebListener webListener = annotatedType.getAnnotation(WebListener.class);
@@ -169,7 +168,7 @@
 		}
 
 		if(!annotatedType.isAnnotationPresent(HttpWhiteboardContextSelect.class)) {
-			annotationsToAdd.add(HttpWhiteboardContextSelect.Literal.of(getSelectedContext()));
+			annotationsToAdd.add(HttpWhiteboardContextSelect.Literal.of((String)configuration.get(HTTP_WHITEBOARD_CONTEXT_SELECT)));
 		}
 
 		annotationsToAdd.add(HttpWhiteboardListener.Literal.INSTANCE);
@@ -183,7 +182,9 @@
 		}
 	}
 
-	<X> void processWebServlet(@Observes @WithAnnotations(WebServlet.class) ProcessAnnotatedType<X> pat) {
+	<X> void processWebServlet(
+		@Observes @WithAnnotations(WebServlet.class) ProcessAnnotatedType<X> pat) {
+
 		final AnnotatedType<X> annotatedType = pat.getAnnotatedType();
 
 		WebServlet webServlet = annotatedType.getAnnotation(WebServlet.class);
@@ -195,7 +196,7 @@
 		}
 
 		if(!annotatedType.isAnnotationPresent(HttpWhiteboardContextSelect.class)) {
-			annotationsToAdd.add(HttpWhiteboardContextSelect.Literal.of(getSelectedContext()));
+			annotationsToAdd.add(HttpWhiteboardContextSelect.Literal.of((String)configuration.get(HTTP_WHITEBOARD_CONTEXT_SELECT)));
 		}
 
 		if (!webServlet.name().isEmpty()) {
@@ -234,16 +235,16 @@
 
 	void afterDeploymentValidation(
 		@Observes @Priority(LIBRARY_AFTER + 800)
-		AfterDeploymentValidation adv, BeanManager beanManager) {
+		AfterDeploymentValidation adv, BeanManager beanManager, BundleContext bundleContext) {
 
 		Dictionary<String, Object> properties = new Hashtable<>();
 		properties.put(SERVICE_DESCRIPTION, "Aries CDI - HTTP Portable Extension");
 		properties.put(SERVICE_VENDOR, "Apache Software Foundation");
-		properties.put(HTTP_WHITEBOARD_CONTEXT_SELECT, getSelectedContext());
+		properties.put(HTTP_WHITEBOARD_CONTEXT_SELECT, configuration.get(HTTP_WHITEBOARD_CONTEXT_SELECT));
 		properties.put(HTTP_WHITEBOARD_LISTENER, Boolean.TRUE.toString());
 		properties.put(SERVICE_RANKING, Integer.MAX_VALUE - 100);
 
-		_listenerRegistration = _bundle.getBundleContext().registerService(
+		_listenerRegistration = bundleContext.registerService(
 			LISTENER_CLASSES, new CdiListener(WebBeansContext.currentInstance()), properties);
 	}
 
@@ -258,63 +259,12 @@
 		}
 	}
 
-	private Map<String, Object> getAttributes() {
-		BundleWiring bundleWiring = _bundle.adapt(BundleWiring.class);
-
-		List<BundleWire> wires = bundleWiring.getRequiredWires(EXTENDER_NAMESPACE);
-
-		Map<String, Object> cdiAttributes = Collections.emptyMap();
-
-		for (BundleWire wire : wires) {
-			BundleCapability capability = wire.getCapability();
-			Map<String, Object> attributes = capability.getAttributes();
-			String extender = (String)attributes.get(EXTENDER_NAMESPACE);
-
-			if (extender.equals(CDI_CAPABILITY_NAME)) {
-				BundleRequirement requirement = wire.getRequirement();
-				cdiAttributes = requirement.getAttributes();
-				break;
-			}
-		}
-
-		return cdiAttributes;
-	}
-
-	private String getSelectedContext() {
-		if (_contextSelect != null) {
-			return _contextSelect;
-		}
-
-		return _contextSelect = getSelectedContext0();
-	}
-
-	private String getSelectedContext0() {
-		Map<String, Object> attributes = getAttributes();
-
-		if (attributes.containsKey(HTTP_WHITEBOARD_CONTEXT_SELECT)) {
-			return (String)attributes.get(HTTP_WHITEBOARD_CONTEXT_SELECT);
-		}
-
-		Dictionary<String,String> headers = _bundle.getHeaders();
-
-		if (headers.get(WEB_CONTEXT_PATH) != null) {
-			return CONTEXT_PATH_PREFIX + headers.get(WEB_CONTEXT_PATH) + ')';
-		}
-
-		return DEFAULT_CONTEXT_FILTER;
-	}
-
-	private static final String CONTEXT_PATH_PREFIX = "(osgi.http.whiteboard.context.path=";
-	private static final String DEFAULT_CONTEXT_FILTER = "(osgi.http.whiteboard.context.name=default)";
 	private static final String[] LISTENER_CLASSES = new String[] {
 		ServletContextListener.class.getName(),
 		ServletRequestListener.class.getName(),
 		HttpSessionListener.class.getName()
 	};
-	private static final String WEB_CONTEXT_PATH = "Web-ContextPath";
 
-	private final Bundle _bundle;
-	private String _contextSelect;
 	private volatile ServiceRegistration<?> _listenerRegistration;
 	private final AtomicBoolean destroyed = new AtomicBoolean(false);
 
diff --git a/cdi-owb/src/main/java/org/apache/aries/cdi/owb/web/WebExtensionFactory.java b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/web/WebExtensionFactory.java
index 8d1d045..3c02024 100644
--- a/cdi-owb/src/main/java/org/apache/aries/cdi/owb/web/WebExtensionFactory.java
+++ b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/web/WebExtensionFactory.java
@@ -26,7 +26,7 @@
 	public Extension getService(
 		Bundle bundle, ServiceRegistration<Extension> registration) {
 
-		return new WebExtension(bundle);
+		return new WebExtension();
 	}
 
 	@Override
diff --git a/cdi-spi/src/main/java/org/apache/aries/cdi/spi/configuration/Configuration.java b/cdi-spi/src/main/java/org/apache/aries/cdi/spi/configuration/Configuration.java
new file mode 100644
index 0000000..c12325c
--- /dev/null
+++ b/cdi-spi/src/main/java/org/apache/aries/cdi/spi/configuration/Configuration.java
@@ -0,0 +1,20 @@
+package org.apache.aries.cdi.spi.configuration;
+
+import java.util.Map;
+
+import org.osgi.annotation.versioning.ProviderType;
+
+/**
+ * An event type fired early by Aries CDI allowing extensions who observe it to get
+ * container configuration.
+ * <p>
+ * <pre>
+ * private volatile Configuration configuration;
+ * void getConfiguration(@Observes Configuration configuration) {
+ *   this.configuration = configuration;
+ * }
+ * </pre>
+ */
+@ProviderType
+public interface Configuration extends Map<String, Object> {
+}
diff --git a/cdi-spi/src/main/java/org/apache/aries/cdi/spi/configuration/package-info.java b/cdi-spi/src/main/java/org/apache/aries/cdi/spi/configuration/package-info.java
new file mode 100644
index 0000000..8ecf64d
--- /dev/null
+++ b/cdi-spi/src/main/java/org/apache/aries/cdi/spi/configuration/package-info.java
@@ -0,0 +1,17 @@
+/**
+ * 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.
+ */
+
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0.0")
+package org.apache.aries.cdi.spi.configuration;
diff --git a/pom.xml b/pom.xml
index ee07fbb..05065be 100644
--- a/pom.xml
+++ b/pom.xml
@@ -147,6 +147,11 @@
 			</dependency>
 			<dependency>
 				<groupId>org.osgi</groupId>
+				<artifactId>org.osgi.service.jaxrs</artifactId>
+				<version>1.0.0</version>
+			</dependency>
+			<dependency>
+				<groupId>org.osgi</groupId>
 				<artifactId>org.osgi.service.http.whiteboard</artifactId>
 				<version>1.0.0</version>
 				<scope>provided</scope>