Fix FELIX-2581 White Board Pattern onActivate called before @Validate
The handler must wait until the instance is started before opening the tracker.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@996284 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/handler/whiteboard/pom.xml b/ipojo/handler/whiteboard/pom.xml
index 8628924..8ea52a8 100644
--- a/ipojo/handler/whiteboard/pom.xml
+++ b/ipojo/handler/whiteboard/pom.xml
@@ -29,19 +29,19 @@
<artifactId> org.apache.felix.ipojo.handler.whiteboard </artifactId>
<groupId>org.apache.felix</groupId>
<version>1.5.0-SNAPSHOT</version>
-
+
<description>
iPOJO extension to easily implement a white-board pattern (host).
</description>
<url>
http://felix.apache.org/site/white-board-pattern-handler.html
</url>
-
+
<dependencies>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.ipojo</artifactId>
- <version>${project.version}</version>
+ <version>1.6.4</version>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
@@ -68,7 +68,7 @@
<Private-Package> org.apache.felix.ipojo.handler.wbp
</Private-Package>
<Bundle-Name>${project.name}</Bundle-Name>
- <Include-Resource>
+ <Include-Resource>
META-INF/LICENSE=LICENSE,
META-INF/NOTICE=NOTICE,
META-INF/DEPENDENCIES=DEPENDENCIES
diff --git a/ipojo/handler/whiteboard/src/main/java/org/apache/felix/ipojo/handler/wbp/WhiteBoardManager.java b/ipojo/handler/whiteboard/src/main/java/org/apache/felix/ipojo/handler/wbp/WhiteBoardManager.java
index 47c34aa..d5077a2 100644
--- a/ipojo/handler/whiteboard/src/main/java/org/apache/felix/ipojo/handler/wbp/WhiteBoardManager.java
+++ b/ipojo/handler/whiteboard/src/main/java/org/apache/felix/ipojo/handler/wbp/WhiteBoardManager.java
@@ -1,4 +1,4 @@
-/*
+/*
* 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
@@ -32,37 +32,37 @@
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
public class WhiteBoardManager implements TrackerCustomizer {
-
+
/**
- * The monitored filter.
+ * The monitored filter.
*/
private Filter m_filter;
-
+
/**
- * The onArrival method.
+ * The onArrival method.
*/
private Callback m_onArrival;
-
+
/**
- * The onDeparture method.
+ * The onDeparture method.
*/
private Callback m_onDeparture;
-
+
/**
- * The onModify method.
+ * The onModify method.
*/
private Callback m_onModification;
-
+
/**
- * The service tracker.
+ * The service tracker.
*/
private Tracker m_tracker;
-
+
/**
- * The attached handler.
+ * The attached handler.
*/
private PrimitiveHandler m_handler;
-
+
/**
* Constructor.
* @param handler the attached handler
@@ -81,14 +81,17 @@
m_filter = filter;
m_tracker = new Tracker(handler.getInstanceManager().getContext(), m_filter, this);
}
-
+
+
+
/**
* Opens the tracker.
*/
public void start() {
+ // Calling several times open is no-effect.
m_tracker.open();
}
-
+
/**
* Closes the tracker.
*/
diff --git a/ipojo/handler/whiteboard/src/main/java/org/apache/felix/ipojo/handler/wbp/WhiteBoardPatternHandler.java b/ipojo/handler/whiteboard/src/main/java/org/apache/felix/ipojo/handler/wbp/WhiteBoardPatternHandler.java
index 0f3e3d7..778eae7 100644
--- a/ipojo/handler/whiteboard/src/main/java/org/apache/felix/ipojo/handler/wbp/WhiteBoardPatternHandler.java
+++ b/ipojo/handler/whiteboard/src/main/java/org/apache/felix/ipojo/handler/wbp/WhiteBoardPatternHandler.java
@@ -1,4 +1,4 @@
-/*
+/*
* 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
@@ -22,6 +22,7 @@
import java.util.Dictionary;
import java.util.List;
+import org.apache.felix.ipojo.ComponentInstance;
import org.apache.felix.ipojo.ConfigurationException;
import org.apache.felix.ipojo.PrimitiveHandler;
import org.apache.felix.ipojo.metadata.Element;
@@ -33,19 +34,19 @@
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
public class WhiteBoardPatternHandler extends PrimitiveHandler {
-
+
/**
* The handler namespace.
*/
public static final String NAMESPACE = "org.apache.felix.ipojo.whiteboard";
-
+
/**
- * The white board pattern to manage. By default just one.
+ * The white board pattern to manage. By default just one.
*/
private List m_managers = new ArrayList(1);
/**
- * Configure method. Parses the metadata to analyze white-board-pattern elements.
+ * Configure method. Parses the metadata to analyze white-board-pattern elements.
* @param elem the component type description
* @param dict the instance description
* @throws ConfigurationException if the description is not valid.
@@ -58,14 +59,14 @@
String onArrival = elems[i].getAttribute("onArrival");
String onDeparture = elems[i].getAttribute("onDeparture");
String onModification = elems[i].getAttribute("onModification");
-
+
if (filter == null) {
throw new ConfigurationException("The white board pattern element requires a filter attribute");
}
if (onArrival == null || onDeparture == null) {
throw new ConfigurationException("The white board pattern element requires the onArrival and onDeparture attributes");
}
-
+
try {
WhiteBoardManager wbm = new WhiteBoardManager(this, getInstanceManager().getContext().createFilter(filter), onArrival, onDeparture, onModification);
m_managers.add(wbm);
@@ -73,27 +74,38 @@
throw new ConfigurationException("The filter " + filter + " is invalid : " + e);
}
}
-
+
}
/**
- * Start method. Starts managers.
+ * Start method.
* @see org.apache.felix.ipojo.Handler#start()
*/
public void start() {
- for (int i = 0; i < m_managers.size(); i++) {
- ((WhiteBoardManager) m_managers.get(i)).start();
- }
}
+
+
/**
+ * Start managers if we're valid.
+ * @see org.apache.felix.ipojo.Handler#stateChanged(int)
+ */
+ public void stateChanged(int state) {
+ if (state == ComponentInstance.VALID) {
+ for (int i = 0; i < m_managers.size(); i++) {
+ ((WhiteBoardManager) m_managers.get(i)).start();
+ }
+ }
+ }
+
+ /**
* Stop method. Stops managers.
* @see org.apache.felix.ipojo.Handler#stop()
*/
public void stop() {
for (int i = 0; i < m_managers.size(); i++) {
((WhiteBoardManager) m_managers.get(i)).stop();
- }
+ }
}
}
diff --git a/ipojo/tests/handler/whiteboard/pom.xml b/ipojo/tests/handler/whiteboard/pom.xml
index 586b64e..1c56f54 100644
--- a/ipojo/tests/handler/whiteboard/pom.xml
+++ b/ipojo/tests/handler/whiteboard/pom.xml
@@ -34,6 +34,11 @@
<artifactId>org.apache.felix.ipojo</artifactId>
<version>1.7.0-SNAPSHOT</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.ipojo.handler.whiteboard</artifactId>
+ <version>1.5.0-SNAPSHOT</version>
+ </dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
@@ -105,6 +110,16 @@
/>
<provides/>
</component>
+
+ <component classname="org.apache.felix.ipojo.test.FooWhiteBoardPattern" name="under-providers-lifecycle">
+ <wbp:wbp
+ filter="(objectclass=org.apache.felix.ipojo.test.FooService)"
+ onArrival="onArrival" onDeparture="onDeparture" onModification="onModification"
+ />
+ <provides/>
+ <callback transition="validate" method="start"/>
+ <callback transition="invalidate" method="stop"/>
+ </component>
</ipojo>
]]>
</metadata>
@@ -112,6 +127,23 @@
</execution>
</executions>
</plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-junit4osgi-plugin</artifactId>
+ <version>1.1.0-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>test</goal>
+ </goals>
+ <configuration>
+ <configuration>
+ <org.osgi.http.port>8083</org.osgi.http.port>
+ </configuration>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
</plugins>
</build>
</project>
diff --git a/ipojo/tests/handler/whiteboard/src/main/java/org/apache/felix/ipojo/test/FooWhiteBoardPattern.java b/ipojo/tests/handler/whiteboard/src/main/java/org/apache/felix/ipojo/test/FooWhiteBoardPattern.java
index 787748e..4974e45 100644
--- a/ipojo/tests/handler/whiteboard/src/main/java/org/apache/felix/ipojo/test/FooWhiteBoardPattern.java
+++ b/ipojo/tests/handler/whiteboard/src/main/java/org/apache/felix/ipojo/test/FooWhiteBoardPattern.java
@@ -8,18 +8,35 @@
import org.osgi.framework.ServiceReference;
public class FooWhiteBoardPattern implements Observable {
-
+
List list = new ArrayList();
int modifications = 0;
-
+
+ long validate_time = 0;
+ long first_arrival_time = 0;
+ long first_departure_time = 0;
+ long invalidate_time = 0;
+
public void onArrival(ServiceReference ref) {
+ if (first_arrival_time == 0) {
+ first_arrival_time = System.currentTimeMillis();
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) { }
+ }
list.add(ref);
}
-
+
public void onDeparture(ServiceReference ref) {
list.remove(ref);
+ if (first_departure_time == 0) {
+ first_departure_time = System.currentTimeMillis();
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) { }
+ }
}
-
+
public void onModification(ServiceReference ref) {
modifications = modifications + 1;
}
@@ -28,9 +45,30 @@
Map map = new HashMap();
map.put("list", list);
map.put("modifications", new Integer(modifications));
+ map.put("validate", new Long(validate_time));
+ map.put("invalidate", new Long(invalidate_time));
+ map.put("arrival", new Long(first_arrival_time));
+ map.put("departure", new Long(first_departure_time));
return map;
}
-
-
+
+ public void start() {
+ if (validate_time == 0) {
+ validate_time = System.currentTimeMillis();
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) { }
+ }
+ }
+
+ public void stop() {
+ if (invalidate_time == 0) {
+ invalidate_time = System.currentTimeMillis();
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) { }
+ }
+ }
+
}
diff --git a/ipojo/tests/handler/whiteboard/src/main/java/org/apache/felix/ipojo/test/WbpTests.java b/ipojo/tests/handler/whiteboard/src/main/java/org/apache/felix/ipojo/test/WbpTests.java
index d25c1e1..e791e40 100644
--- a/ipojo/tests/handler/whiteboard/src/main/java/org/apache/felix/ipojo/test/WbpTests.java
+++ b/ipojo/tests/handler/whiteboard/src/main/java/org/apache/felix/ipojo/test/WbpTests.java
@@ -14,183 +14,209 @@
import org.osgi.framework.ServiceReference;
public class WbpTests extends OSGiTestCase {
-
+
Factory provFactory;
- Factory factory, factory2;
+ Factory factory, factory2, factory3;
public void setUp() {
provFactory = Utils.getFactoryByName(context, "fooprovider");
factory = Utils.getFactoryByName(context, "under-providers");
factory2 = Utils.getFactoryByName(context, "under-properties");
+ factory3 = Utils.getFactoryByName(context, "under-providers-lifecycle");
}
-
+
public void tearDown() {
-
+
}
-
+
public void testServiceProviders() throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
ComponentInstance ci = factory.createComponentInstance(new Properties());
-
+
ServiceReference ref = Utils.getServiceReferenceByName(context, Observable.class.getName(), ci.getInstanceName());
assertNotNull("Check Observable availability", ref);
Observable obs = (Observable) context.getService(ref);
-
+
Map map = obs.getObservations();
assertEquals("Check empty list" , ((List) map.get("list")).size(), 0);
-
+
Properties p1 = new Properties();
p1.put("foo", "foo");
ComponentInstance prov1 = provFactory.createComponentInstance(p1);
-
+
map = obs.getObservations();
assertEquals("Check list #1" , ((List) map.get("list")).size(), 1);
-
+
Properties p2 = new Properties();
p2.put("foo", "foo");
ComponentInstance prov2 = provFactory.createComponentInstance(p2);
-
+
map = obs.getObservations();
assertEquals("Check list #2" , ((List) map.get("list")).size(), 2);
-
+
prov1.stop();
-
+
map = obs.getObservations();
assertEquals("(1) Check list #1" , ((List) map.get("list")).size(), 1);
-
+
prov2.stop();
-
+
map = obs.getObservations();
assertEquals("(2) Check list #0" , ((List) map.get("list")).size(), 0);
-
+
prov2.start();
-
+
map = obs.getObservations();
assertEquals("(3) Check list #1" , ((List) map.get("list")).size(), 1);
-
+
prov1.start();
-
+
map = obs.getObservations();
assertEquals("(4) Check list #2" , ((List) map.get("list")).size(), 2);
-
+
prov1.dispose();
-
+
map = obs.getObservations();
assertEquals("(5) Check list #1" , ((List) map.get("list")).size(), 1);
-
+
prov2.dispose();
-
+
map = obs.getObservations();
assertEquals("(6) Check list #0" , ((List) map.get("list")).size(), 0);
-
+
context.ungetService(ref);
ci.dispose();
}
-
+
public void testPropertiesProviders() throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
ComponentInstance ci = factory2.createComponentInstance(new Properties());
-
+
ServiceReference ref = Utils.getServiceReferenceByName(context, Observable.class.getName(), ci.getInstanceName());
assertNotNull("Check Observable availability", ref);
Observable obs = (Observable) context.getService(ref);
-
+
Map map = obs.getObservations();
assertEquals("Check empty list" , ((List) map.get("list")).size(), 0);
-
+
Properties p1 = new Properties();
p1.put("foo", "foo");
ComponentInstance prov1 = provFactory.createComponentInstance(p1);
ServiceReference ref1 = Utils.getServiceReferenceByName(context, FooService.class.getName(), prov1.getInstanceName());
FooService fs1 = (FooService) context.getService(ref1);
-
+
map = obs.getObservations();
assertEquals("Check list #1" , ((List) map.get("list")).size(), 1);
-
+
Properties p2 = new Properties();
p2.put("foo", "foo");
ComponentInstance prov2 = provFactory.createComponentInstance(p2);
ServiceReference ref2 = Utils.getServiceReferenceByName(context, FooService.class.getName(), prov2.getInstanceName());
FooService fs2 = (FooService) context.getService(ref2);
-
+
map = obs.getObservations();
assertEquals("Check list #2" , ((List) map.get("list")).size(), 2);
-
+
fs1.foo();
-
+
map = obs.getObservations();
assertEquals("(1) Check list #1" , ((List) map.get("list")).size(), 1);
-
+
fs2.foo();
-
+
map = obs.getObservations();
assertEquals("(2) Check list #0" , ((List) map.get("list")).size(), 0);
-
+
fs2.foo();
-
+
map = obs.getObservations();
assertEquals("(3) Check list #1" , ((List) map.get("list")).size(), 1);
-
+
fs1.foo();
-
+
map = obs.getObservations();
assertEquals("(4) Check list #2" , ((List) map.get("list")).size(), 2);
-
+
prov1.dispose();
-
+
map = obs.getObservations();
assertEquals("(5) Check list #1" , ((List) map.get("list")).size(), 1);
-
+
prov2.dispose();
-
+
map = obs.getObservations();
assertEquals("(6) Check list #0" , ((List) map.get("list")).size(), 0);
-
+
context.ungetService(ref1);
context.ungetService(ref2);
context.ungetService(ref);
ci.dispose();
}
-
+
public void testModifications() throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
ComponentInstance ci = factory.createComponentInstance(new Properties());
-
+
ServiceReference ref = Utils.getServiceReferenceByName(context, Observable.class.getName(), ci.getInstanceName());
assertNotNull("Check Observable availability", ref);
Observable obs = (Observable) context.getService(ref);
-
+
Map map = obs.getObservations();
assertEquals("Check empty list" , ((List) map.get("list")).size(), 0);
-
+
Properties p1 = new Properties();
p1.put("foo", "foo");
ComponentInstance prov1 = provFactory.createComponentInstance(p1);
-
+
map = obs.getObservations();
assertEquals("Check list #1" , ((List) map.get("list")).size(), 1);
assertEquals("Check modification #0" , ((Integer) map.get("modifications")).intValue(), 0);
-
+
ServiceReference ref2 = Utils.getServiceReference(context, FooService.class.getName(), null);
assertNotNull("Check FooService availability", ref2);
-
+
FooService fs = (FooService) context.getService(ref2);
fs.foo();
-
+
map = obs.getObservations();
assertEquals("Check list #1" , ((List) map.get("list")).size(), 1);
assertEquals("Check modification #1 (" + map.get("modifications")+")" , ((Integer) map.get("modifications")).intValue(), 1);
-
+
fs.foo();
-
+
map = obs.getObservations();
assertEquals("Check list #1" , ((List) map.get("list")).size(), 1);
assertEquals("Check modification #2" , ((Integer) map.get("modifications")).intValue(), 2);
-
+
prov1.dispose();
map = obs.getObservations();
assertEquals("Check list #0" , ((List) map.get("list")).size(), 0);
assertEquals("Check modification #2" , ((Integer) map.get("modifications")).intValue(), 2);
-
+
context.ungetService(ref);
context.ungetService(ref2);
ci.dispose();
}
+
+ public void testLifecycleCompliance() throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
+ // First expose a service.
+ Properties p1 = new Properties();
+ p1.put("foo", "foo");
+ ComponentInstance prov1 = provFactory.createComponentInstance(p1);
+
+ ComponentInstance ci = factory3.createComponentInstance(new Properties());
+
+ ServiceReference ref = Utils.getServiceReferenceByName(context, Observable.class.getName(), ci.getInstanceName());
+ assertNotNull("Check Observable availability", ref);
+ Observable obs = (Observable) context.getService(ref);
+
+ Map map = obs.getObservations();
+ // Check time
+ Long validate = (Long) map.get("validate");
+ Long arrival = (Long) map.get("arrival");
+
+ // Validate must be call before.
+ assertTrue(validate.longValue() + " <?> " + arrival.longValue(), validate.longValue() < arrival.longValue());
+
+ prov1.dispose();
+ ci.dispose();
+
+ }
}