You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by gn...@apache.org on 2016/09/05 12:19:33 UTC
svn commit: r1759245 - in /aries/trunk/blueprint:
blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/
blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/
Author: gnodet
Date: Mon Sep 5 12:19:33 2016
New Revision: 1759245
URL: http://svn.apache.org/viewvc?rev=1759245&view=rev
Log:
[ARIES-1578] blueprint-cm doesn't support org.osgi.service.cm.ConfigurationPlugin
Modified:
aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmManagedProperties.java
aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmProperties.java
aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmPropertyPlaceholder.java
aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmUtils.java
aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/ManagedObjectManager.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/CmManagedProperties.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmManagedProperties.java?rev=1759245&r1=1759244&r2=1759245&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmManagedProperties.java (original)
+++ aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmManagedProperties.java Mon Sep 5 12:19:33 2016
@@ -65,6 +65,7 @@ public class CmManagedProperties impleme
private final Object lock = new Object();
private final Set<Object> beans = new HashSet<Object>();
private Dictionary<String,Object> properties;
+ private boolean initialized;
public ExtendedBlueprintContainer getBlueprintContainer() {
return blueprintContainer;
@@ -137,11 +138,6 @@ public class CmManagedProperties impleme
synchronized (lock) {
managedObjectManager.register(this, props);
- Configuration config = CmUtils.getConfiguration(configAdmin, persistentId);
- if (config != null) {
- properties = config.getProperties();
- }
- updated(properties);
}
}
@@ -150,6 +146,11 @@ public class CmManagedProperties impleme
}
public void updated(final Dictionary props) {
+ if (!initialized) {
+ properties = props;
+ initialized = true;
+ return;
+ }
LOGGER.debug("Configuration updated for bean={} / pid={}", beanName, persistentId);
synchronized (lock) {
properties = props;
Modified: aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmProperties.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmProperties.java?rev=1759245&r1=1759244&r2=1759245&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmProperties.java (original)
+++ aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmProperties.java Mon Sep 5 12:19:33 2016
@@ -50,6 +50,7 @@ public class CmProperties implements Man
private final Object lock = new Object();
private final Set<ServicePropertiesUpdater> services = new HashSet<ServicePropertiesUpdater>();
private final Properties properties = new Properties();
+ private boolean initialized;
public ExtendedBlueprintContainer getBlueprintContainer() {
return blueprintContainer;
@@ -118,11 +119,6 @@ public class CmProperties implements Man
synchronized (lock) {
managedObjectManager.register(this, props);
- Configuration config = CmUtils.getConfiguration(configAdmin, persistentId);
- if (config != null) {
- properties.clear();
- JavaUtils.copy(properties, config.getProperties());
- }
}
}
@@ -135,10 +131,12 @@ public class CmProperties implements Man
}
public void updated(Dictionary props) {
- if (serviceId != null) {
- LOGGER.debug("Service properties updated for service={} / pid={}, {}", new Object[] {serviceId, persistentId, props});
- } else {
- LOGGER.debug("Service properties updated for pid={}, {}", new Object[] {persistentId, props});
+ if (initialized) {
+ if (serviceId != null) {
+ LOGGER.debug("Service properties updated for service={} / pid={}, {}", new Object[]{serviceId, persistentId, props});
+ } else {
+ LOGGER.debug("Service properties updated for pid={}, {}", new Object[]{persistentId, props});
+ }
}
synchronized (lock) {
@@ -146,7 +144,9 @@ public class CmProperties implements Man
if (props != null) {
JavaUtils.copy(properties, props);
}
- if (update) {
+ if (!initialized) {
+ initialized = true;
+ } else if (update) {
for (ServicePropertiesUpdater service : services) {
service.updateProperties(props);
}
@@ -163,9 +163,7 @@ public class CmProperties implements Man
synchronized (lock) {
services.add(service);
- if (properties != null) {
- JavaUtils.copy(props, properties);
- }
+ JavaUtils.copy(props, properties);
}
}
Modified: aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmPropertyPlaceholder.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmPropertyPlaceholder.java?rev=1759245&r1=1759244&r2=1759245&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmPropertyPlaceholder.java (original)
+++ aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmPropertyPlaceholder.java Mon Sep 5 12:19:33 2016
@@ -46,6 +46,7 @@ public class CmPropertyPlaceholder exten
private String updateStrategy;
private ManagedObjectManager managedObjectManager;
private Dictionary<String,Object> properties;
+ private boolean initialized;
public ExtendedBlueprintContainer getBlueprintContainer() {
return blueprintContainer;
@@ -89,10 +90,6 @@ public class CmPropertyPlaceholder exten
public void init() throws Exception {
LOGGER.debug("Initializing CmPropertyPlaceholder");
- Configuration config = CmUtils.getConfiguration(configAdmin, persistentId);
- if (config != null) {
- properties = config.getProperties();
- }
Properties props = new Properties();
props.put(Constants.SERVICE_PID, persistentId);
Bundle bundle = blueprintContainer.getBundleContext().getBundle();
@@ -128,6 +125,11 @@ public class CmPropertyPlaceholder exten
}
public void updated(Dictionary props) {
+ if (!initialized) {
+ properties = props;
+ initialized = true;
+ return;
+ }
if ("reload".equalsIgnoreCase(updateStrategy) && !equals(properties, props)) {
LOGGER.debug("Configuration updated for pid={}", persistentId);
// Run in a separate thread to avoid re-entrance
Modified: aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmUtils.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmUtils.java?rev=1759245&r1=1759244&r2=1759245&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmUtils.java (original)
+++ aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmUtils.java Mon Sep 5 12:19:33 2016
@@ -19,11 +19,20 @@
package org.apache.aries.blueprint.compendium.cm;
import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.cm.ConfigurationPlugin;
public class CmUtils {
@@ -47,5 +56,179 @@ public class CmUtils {
return null;
}
}
-
+
+ public static Dictionary<String, Object> getProperties(ServiceReference service, String persistentId) throws IOException {
+ BundleContext bc = service.getBundle().getBundleContext();
+ ServiceReference<ConfigurationAdmin> caRef = bc.getServiceReference(ConfigurationAdmin.class);
+ try {
+ ConfigurationAdmin ca = bc.getService(caRef);
+ Configuration config = getConfiguration(ca, persistentId);
+ if (config != null) {
+ Dictionary<String, Object> props = new CaseInsensitiveDictionary(config.getProperties());
+ BundleContext caBc = caRef.getBundle().getBundleContext();
+ callPlugins(caBc, props, service, persistentId, null);
+ return props;
+ } else {
+ return null;
+ }
+ } finally {
+ bc.ungetService(caRef);
+ }
+ }
+
+ private static void callPlugins(final BundleContext bundleContext,
+ final Dictionary<String, Object> props,
+ final ServiceReference sr,
+ final String configPid,
+ final String factoryPid) {
+ ServiceReference[] plugins = null;
+ try {
+ final String targetPid = (factoryPid == null) ? configPid : factoryPid;
+ String filter = "(|(!(cm.target=*))(cm.target=" + targetPid + "))";
+ plugins = bundleContext.getServiceReferences(ConfigurationPlugin.class.getName(), filter);
+ } catch (InvalidSyntaxException ise) {
+ // no filter, no exception ...
+ }
+
+ // abort early if there are no plugins
+ if (plugins == null || plugins.length == 0) {
+ return;
+ }
+
+ // sort the plugins by their service.cmRanking
+ if (plugins.length > 1) {
+ Arrays.sort(plugins, CM_RANKING);
+ }
+
+ // call the plugins in order
+ for (ServiceReference pluginRef : plugins) {
+ ConfigurationPlugin plugin = (ConfigurationPlugin) bundleContext.getService(pluginRef);
+ if (plugin != null) {
+ try {
+ plugin.modifyConfiguration(sr, props);
+ } catch (Throwable t) {
+ // Ignore
+ } finally {
+ // ensure ungetting the plugin
+ bundleContext.ungetService(pluginRef);
+ }
+ setAutoProperties(props, configPid, factoryPid);
+ }
+ }
+ }
+
+ private static void setAutoProperties( Dictionary<String, Object> properties, String pid, String factoryPid )
+ {
+ replaceProperty(properties, Constants.SERVICE_PID, pid);
+ replaceProperty(properties, ConfigurationAdmin.SERVICE_FACTORYPID, factoryPid);
+ properties.remove(ConfigurationAdmin.SERVICE_BUNDLELOCATION);
+ }
+
+ private static void replaceProperty(Dictionary<String, Object> properties, String key, String value) {
+ if (value == null) {
+ properties.remove(key);
+ } else {
+ properties.put(key, value);
+ }
+ }
+
+ private static Comparator<ServiceReference> CM_RANKING = new Comparator<ServiceReference>() {
+ @Override
+ public int compare(ServiceReference sr1, ServiceReference sr2) {
+ final long rank1 = getLong(sr1, ConfigurationPlugin.CM_RANKING);
+ final long rank2 = getLong(sr2, ConfigurationPlugin.CM_RANKING);
+ if (rank1 == rank2) {
+ return 0;
+ }
+ return (rank1 < rank2) ? -1 : 1;
+ }
+
+ protected long getLong(ServiceReference sr, String property) {
+ Object rankObj = sr.getProperty(property);
+ if (rankObj instanceof Number) {
+ return ((Number) rankObj).longValue();
+ }
+ return 0;
+ }
+ };
+
+ private static class CaseInsensitiveDictionary extends Dictionary<String, Object> {
+ private final Hashtable<String, Object> internalMap = new Hashtable<String, Object>();
+ private final Hashtable<String, String> originalKeys = new Hashtable<String, String>();
+
+ public CaseInsensitiveDictionary(Dictionary<String, Object> props) {
+ if (props != null) {
+ Enumeration<String> keys = props.keys();
+ while (keys.hasMoreElements()) {
+ // check the correct syntax of the key
+ String key = checkKey(keys.nextElement());
+ // check uniqueness of key
+ String lowerCase = key.toLowerCase();
+ if (internalMap.containsKey(lowerCase)) {
+ throw new IllegalArgumentException("Key [" + key + "] already present in different case");
+ }
+ // check the value
+ Object value = props.get(key);
+ checkValue(value);
+ // add the key/value pair
+ internalMap.put(lowerCase, value);
+ originalKeys.put(lowerCase, key);
+ }
+ }
+ }
+
+ public Enumeration<Object> elements() {
+ return Collections.enumeration(internalMap.values());
+ }
+
+ public Object get(Object keyObj) {
+ String lowerCase = checkKey(keyObj == null ? null : keyObj.toString()).toLowerCase();
+ return internalMap.get(lowerCase);
+ }
+
+ public boolean isEmpty() {
+ return internalMap.isEmpty();
+ }
+
+ public Enumeration<String> keys() {
+ return Collections.enumeration(originalKeys.values());
+ }
+
+ public Object put(String key, Object value) {
+ String lowerCase = checkKey(key).toLowerCase();
+ checkValue(value);
+ originalKeys.put(lowerCase, key);
+ return internalMap.put(lowerCase, value);
+ }
+
+ public Object remove(Object keyObj) {
+ String lowerCase = checkKey(keyObj == null ? null : keyObj.toString()).toLowerCase();
+ originalKeys.remove(lowerCase);
+ return internalMap.remove(lowerCase);
+ }
+
+ public int size() {
+ return internalMap.size();
+ }
+
+ static String checkKey(String key) {
+ if (key == null || key.length() == 0) {
+ throw new IllegalArgumentException("Key must not be null nor an empty string");
+ }
+ return key;
+ }
+
+ static Object checkValue(Object value) {
+ if (value == null) {
+ throw new IllegalArgumentException("Value must not be null");
+ }
+ return value;
+ }
+
+ public String toString() {
+ return internalMap.toString();
+ }
+
+ }
+
}
Modified: aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/ManagedObjectManager.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/ManagedObjectManager.java?rev=1759245&r1=1759244&r2=1759245&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/ManagedObjectManager.java (original)
+++ aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/ManagedObjectManager.java Mon Sep 5 12:19:33 2016
@@ -25,6 +25,8 @@ import java.util.Properties;
import java.util.concurrent.CopyOnWriteArrayList;
import org.apache.aries.util.AriesFrameworkUtil;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.cm.ManagedService;
@@ -51,6 +53,13 @@ public class ManagedObjectManager {
map.put(key, reg);
}
reg.add(cm);
+
+ try {
+ Dictionary<String, Object> config = CmUtils.getProperties(reg.getRegistration().getReference(), key);
+ cm.updated(config);
+ } catch (Throwable t) {
+ // Ignore
+ }
}
public synchronized void unregister(ManagedObject cm) {
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=1759245&r1=1759244&r2=1759245&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 Mon Sep 5 12:19:33 2016
@@ -117,6 +117,13 @@ public class TestConfigAdmin extends Abs
assertEquals("Multiple services were registered for the same pid.", 1, refs.length);
}
+ @Test
+ public void testPlaceholder() throws Exception {
+ Configuration cf = ca.getConfiguration("blueprint-sample-placeholder", null);
+ cf.update(getConfig3());
+ startTestBundle();
+ }
+
private Hashtable<String, String> getConfig1() {
Hashtable<String,String> props = new Hashtable<String,String>();
props.put("a", "5");
@@ -132,6 +139,13 @@ public class TestConfigAdmin extends Abs
return props;
}
+ private Hashtable<String, String> getConfig3() {
+ Hashtable<String, String> props;
+ props = new Hashtable<String,String>();
+ props.put("key.b", "10");
+ return props;
+ }
+
private <T>T getComponent(String componentId) {
BlueprintContainer blueprintContainer = Helper.getBlueprintContainerForBundle(context(), "org.apache.aries.blueprint.sample");
assertNotNull(blueprintContainer);