You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by cu...@apache.org on 2012/07/21 15:49:06 UTC
svn commit: r1364094 - in /aries/trunk/blueprint:
blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmManagedServiceFactory.java
blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/TestConfigAdmin.java
Author: cumminsh
Date: Sat Jul 21 13:49:05 2012
New Revision: 1364094
URL: http://svn.apache.org/viewvc?rev=1364094&view=rev
Log:
[ARIES-584] Go synchronized through most of the updated() method on the service factory to make sure we don't risk two services with the same pid, and a bit of extra testing
Modified:
aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmManagedServiceFactory.java
aries/trunk/blueprint/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/TestConfigAdmin.java
Modified: aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmManagedServiceFactory.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmManagedServiceFactory.java?rev=1364094&r1=1364093&r2=1364094&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmManagedServiceFactory.java (original)
+++ aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmManagedServiceFactory.java Sat Jul 21 13:49:05 2012
@@ -76,8 +76,8 @@ public class CmManagedServiceFactory {
private final Object lock = new Object();
private ServiceRegistration registration;
- private Map<String, ServiceRegistration> pids = new ConcurrentHashMap<String, ServiceRegistration>();
- private Map<ServiceRegistration, Object> services = new ConcurrentHashMap<ServiceRegistration, Object>();
+ private final Map<String, ServiceRegistration> pids = new ConcurrentHashMap<String, ServiceRegistration>();
+ private final Map<ServiceRegistration, Object> services = new ConcurrentHashMap<ServiceRegistration, Object>();
public void init() throws Exception {
LOGGER.debug("Initializing CmManagedServiceFactory for factoryPid={}", factoryPid);
@@ -170,33 +170,46 @@ public class CmManagedServiceFactory {
}
protected void updated(String pid, Dictionary props) {
- LOGGER.debug("Updated configuration {} with props {}", pid, props);
- ServiceRegistration reg = pids.get(pid);
- if (reg == null) {
+ LOGGER.debug("Updated configuration {} with props {}", pid, props);
+
+ Hashtable regProps = null;
+ Object component = null;
+
+ // This method might be multithreaded, so synchronize checking and
+ // creating the service
+ final ServiceRegistration existingReg;
+ synchronized (pids) {
+ existingReg = pids.get(pid);
+ if (existingReg == null) {
updateComponentProperties(props);
- Object component = blueprintContainer.getComponentInstance(managedComponentName);
-
- // TODO: call listeners, etc...
-
- Hashtable regProps = getRegistrationProperties(pid);
+ component = blueprintContainer.getComponentInstance(managedComponentName);
+
+ // TODO: call listeners, etc...
+
+ regProps = getRegistrationProperties(pid);
CmProperties cm = findServiceProcessor();
if (cm != null) {
- if ("".equals(cm.getPersistentId())) {
- JavaUtils.copy(regProps, props);
- }
- cm.updateProperties(new PropertiesUpdater(pid), regProps);
+ if ("".equals(cm.getPersistentId())) {
+ JavaUtils.copy(regProps, props);
+ }
+ cm.updateProperties(new PropertiesUpdater(pid), regProps);
}
-
+
Set<String> classes = getClasses(component);
String[] classArray = classes.toArray(new String[classes.size()]);
- reg = blueprintContainer.getBundleContext().registerService(classArray, component, regProps);
+ ServiceRegistration reg = blueprintContainer.getBundleContext().registerService(classArray, component, regProps);
+
+ LOGGER.debug("Service {} registered with interfaces {} and properties {}", new Object[] { component, classes, regProps });
- LOGGER.debug("Service {} registered with interfaces {} and properties {}", new Object [] { component, classes, regProps });
-
services.put(reg, component);
pids.put(pid, reg);
-
+ }
+ } // end of synchronization
+
+ // If we just registered a service, do the slower stuff outside the synchronized block
+ if (existingReg == null)
+ {
if (listeners != null) {
for (ServiceListener listener : listeners) {
listener.register(component, regProps);
@@ -207,7 +220,7 @@ public class CmManagedServiceFactory {
CmProperties cm = findServiceProcessor();
if (cm != null && "".equals(cm.getPersistentId())) {
- Dictionary regProps = getRegistrationProperties(pid);
+ regProps = getRegistrationProperties(pid);
JavaUtils.copy(regProps, props);
cm.updated(regProps);
}
Modified: aries/trunk/blueprint/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/TestConfigAdmin.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/TestConfigAdmin.java?rev=1364094&r1=1364093&r2=1364094&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/TestConfigAdmin.java (original)
+++ aries/trunk/blueprint/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/TestConfigAdmin.java Sat Jul 21 13:49:05 2012
@@ -31,6 +31,7 @@ import org.junit.runner.RunWith;
import org.ops4j.pax.exam.Option;
import org.ops4j.pax.exam.junit.JUnit4TestRunner;
import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceReference;
import org.osgi.service.blueprint.container.BlueprintContainer;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
@@ -145,21 +146,29 @@ public class TestConfigAdmin extends Abs
@Test
public void testManagedServiceFactory() throws Exception {
+
ConfigurationAdmin ca = context().getService(ConfigurationAdmin.class);
Configuration cf = ca.createFactoryConfiguration("blueprint-sample-managed-service-factory", null);
Hashtable<String,String> props = new Hashtable<String,String>();
props.put("a", "5");
props.put("currency", "PLN");
cf.update(props);
-
+
Bundle bundle = context().getBundleByName("org.apache.aries.blueprint.sample");
assertNotNull(bundle);
bundle.start();
-
+
BlueprintContainer blueprintContainer = Helper.getBlueprintContainerForBundle(context(), "org.apache.aries.blueprint.sample");
assertNotNull(blueprintContainer);
+
+ // Make sure only one service is registered
+ // Ask the service registry, not the container, since the container might have got it wrong :)
+ ServiceReference[] refs = context().getAllServiceReferences(Foo.class.getName(), "(service.pid=blueprint-sample-managed-service-factory.*)");
+
+ assertNotNull("No services were registered for the managed service factory", refs);
+ assertEquals("Multiple services were registered for the same pid.", 1, refs.length);
+
- Thread.sleep(5000);
}
@org.ops4j.pax.exam.junit.Configuration