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 2010/09/28 20:47:49 UTC

svn commit: r1002318 - in /incubator/aries/trunk/blueprint: blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/ blueprint-cm/src/main/resources/org/apache/aries/blueprint/compendium/cm/ blueprint-core/src/main/java/org/apache/aries/blu...

Author: gnodet
Date: Tue Sep 28 18:47:49 2010
New Revision: 1002318

URL: http://svn.apache.org/viewvc?rev=1002318&view=rev
Log:
[ARIES-429] Add an option on the <cm:property-placeholder/> element to reload the whole blueprint container if the configuration changes

Modified:
    incubator/aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java
    incubator/aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmPropertyPlaceholder.java
    incubator/aries/trunk/blueprint/blueprint-cm/src/main/resources/org/apache/aries/blueprint/compendium/cm/blueprint-cm.xsd
    incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ExtendedBlueprintContainer.java
    incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java
    incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/namespace/ComponentDefinitionRegistryImpl.java

Modified: incubator/aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java?rev=1002318&r1=1002317&r2=1002318&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java (original)
+++ incubator/aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java Tue Sep 28 18:47:49 2010
@@ -186,6 +186,8 @@ public class CmNamespaceHandler implemen
         metadata.setId(getId(context, element));
         metadata.setScope(BeanMetadata.SCOPE_SINGLETON);
         metadata.setRuntimeClass(CmPropertyPlaceholder.class);
+        metadata.setInitMethod("init");
+        metadata.setDestroyMethod("destroy");
         metadata.addProperty("blueprintContainer", createRef(context, "blueprintContainer"));
         metadata.addProperty("configAdmin", createConfigAdminProxy(context));
         metadata.addProperty("persistentId", createValue(context, element.getAttribute(PERSISTENT_ID_ATTRIBUTE)));
@@ -212,6 +214,11 @@ public class CmNamespaceHandler implemen
             systemProperties = ExtNamespaceHandler.SYSTEM_PROPERTIES_NEVER;
         }
         metadata.addProperty("systemProperties", createValue(context, systemProperties));
+        String updateStrategy = element.getAttribute(UPDATE_STRATEGY_ATTRIBUTE);
+        if (updateStrategy != null) {
+            metadata.addProperty("updateStrategy", createValue(context, updateStrategy));
+        }
+        metadata.addProperty("managedObjectManager", createRef(context, MANAGED_OBJECT_MANAGER_NAME));
         // Parse elements
         List<String> locations = new ArrayList<String>();
         NodeList nl = element.getChildNodes();

Modified: incubator/aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmPropertyPlaceholder.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmPropertyPlaceholder.java?rev=1002318&r1=1002317&r2=1002318&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmPropertyPlaceholder.java (original)
+++ incubator/aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmPropertyPlaceholder.java Tue Sep 28 18:47:49 2010
@@ -19,11 +19,13 @@
 package org.apache.aries.blueprint.compendium.cm;
 
 import java.io.IOException;
-import java.util.Dictionary;
-import java.util.Map;
+import java.util.*;
 
+import org.apache.aries.blueprint.ExtendedBlueprintContainer;
 import org.apache.aries.blueprint.ext.AbstractPropertyPlaceholder;
 import org.apache.aries.blueprint.ext.PropertyPlaceholder;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
 import org.osgi.service.blueprint.container.BlueprintContainer;
 import org.osgi.service.blueprint.container.ComponentDefinitionException;
 import org.osgi.service.cm.Configuration;
@@ -36,20 +38,22 @@ import org.slf4j.LoggerFactory;
  *
  * @version $Rev$, $Date$
  */
-public class CmPropertyPlaceholder extends PropertyPlaceholder {
+public class CmPropertyPlaceholder extends PropertyPlaceholder implements ManagedObject {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(CmPropertyPlaceholder.class);
 
-    private BlueprintContainer blueprintContainer;
+    private ExtendedBlueprintContainer blueprintContainer;
     private ConfigurationAdmin configAdmin; 
     private String persistentId;
-    private transient Configuration config;
+    private String updateStrategy;
+    private ManagedObjectManager managedObjectManager;
+    private Dictionary<String,Object> properties;
 
-    public BlueprintContainer getBlueprintContainer() {
+    public ExtendedBlueprintContainer getBlueprintContainer() {
         return blueprintContainer;
     }
 
-    public void setBlueprintContainer(BlueprintContainer blueprintContainer) {
+    public void setBlueprintContainer(ExtendedBlueprintContainer blueprintContainer) {
         this.blueprintContainer = blueprintContainer;
     }
 
@@ -69,21 +73,50 @@ public class CmPropertyPlaceholder exten
         this.persistentId = persistentId;
     }
 
+    public String getUpdateStrategy() {
+        return updateStrategy;
+    }
+
+    public void setUpdateStrategy(String updateStrategy) {
+        this.updateStrategy = updateStrategy;
+    }
+
+    public ManagedObjectManager getManagedObjectManager() {
+        return managedObjectManager;
+    }
+
+    public void setManagedObjectManager(ManagedObjectManager managedObjectManager) {
+        this.managedObjectManager = managedObjectManager;
+    }
+
+    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();
+        props.put(Constants.BUNDLE_SYMBOLICNAME, bundle.getSymbolicName());
+        props.put(Constants.BUNDLE_VERSION, bundle.getHeaders().get(Constants.BUNDLE_VERSION));
+        managedObjectManager.register(this, props);
+    }
+
+    public void destroy() {
+        LOGGER.debug("Destroying CmPropertyPlaceholder");
+        managedObjectManager.unregister(this);
+    }
+
     protected String getProperty(String val) {
         LOGGER.debug("Retrieving property value {} from configuration with pid {}", val, persistentId);
-        Configuration config = getConfig();
         Object v = null;
-        if (config != null) {
-            Dictionary props = config.getProperties();
-            if (props != null) {
-                v = props.get(val);
-                if (v != null) {
-                    LOGGER.debug("Found property value {}", v);
-                } else {
-                    LOGGER.debug("Property not found in configuration");
-                }
+        if (properties != null) {
+            v = properties.get(val);
+            if (v != null) {
+                LOGGER.debug("Found property value {}", v);
             } else {
-                LOGGER.debug("No dictionary available from configuration");
+                LOGGER.debug("Property not found in configuration");
             }
         }
         if (v == null) {
@@ -92,15 +125,44 @@ public class CmPropertyPlaceholder exten
         return v != null ? v.toString() : null;
     }
 
-    protected synchronized Configuration getConfig() {
-        if (config == null) {
-            try {
-                config = CmUtils.getConfiguration(configAdmin, persistentId);
-            } catch (IOException e) {
-                // ignore
+    public Bundle getBundle() {
+        return blueprintContainer.getBundleContext().getBundle();
+    }
+
+    public void updated(Dictionary props) {
+        if ("reload".equalsIgnoreCase(updateStrategy) && !equals(properties, props)) {
+            LOGGER.debug("Configuration updated for pid={}", persistentId);
+            // Run in a separate thread to avoid re-entrance
+            new Thread() {
+                public void run() {
+                    blueprintContainer.reload();
+                }
+            }.start();
+        }
+    }
+
+    private <T,U> boolean equals(Dictionary<T,U> d1, Dictionary<T,U> d2) {
+        if (d1 == null || d1.isEmpty()) {
+            return d2 == null || d2.isEmpty();
+        } else if (d2 == null || d1.size() != d2.size()) {
+            return false;
+        } else {
+            for (Enumeration<T> e = d1.keys(); e.hasMoreElements();) {
+                T k = e.nextElement();
+                U v1 = d1.get(k);
+                U v2 = d2.get(k);
+                if (v1 == null) {
+                    if (v2 != null) {
+                        return false;
+                    }
+                } else {
+                    if (!v1.equals(v2)) {
+                        return false;
+                    }
+                }
             }
+            return true;
         }
-        return config;
     }
 
 }

Modified: incubator/aries/trunk/blueprint/blueprint-cm/src/main/resources/org/apache/aries/blueprint/compendium/cm/blueprint-cm.xsd
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-cm/src/main/resources/org/apache/aries/blueprint/compendium/cm/blueprint-cm.xsd?rev=1002318&r1=1002317&r2=1002318&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-cm/src/main/resources/org/apache/aries/blueprint/compendium/cm/blueprint-cm.xsd (original)
+++ incubator/aries/trunk/blueprint/blueprint-cm/src/main/resources/org/apache/aries/blueprint/compendium/cm/blueprint-cm.xsd Tue Sep 28 18:47:49 2010
@@ -45,9 +45,17 @@
                 <xsd:attribute name="placeholder-prefix" type="xsd:string" use="optional" default="${"/>
                 <xsd:attribute name="placeholder-suffix" type="xsd:string" use="optional" default="}"/>
                 <xsd:attribute name="defaults-ref" type="bp:Tidref" use="optional"/>
+                <xsd:attribute name="update-strategy" type="TplaceholderUpdateStrategyType" use="optional" default="none"/>
             </xsd:extension>
         </xsd:complexContent>
     </xsd:complexType>
+    
+    <xsd:simpleType name="TplaceholderUpdateStrategyType">
+        <xsd:restriction base="xsd:NMTOKEN">
+            <xsd:enumeration value="none"/>
+            <xsd:enumeration value="reload"/>
+        </xsd:restriction>
+    </xsd:simpleType>
 
 
     <!-- #### is this the correct type here?  This is defining placeholder properties,

Modified: incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ExtendedBlueprintContainer.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ExtendedBlueprintContainer.java?rev=1002318&r1=1002317&r2=1002318&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ExtendedBlueprintContainer.java (original)
+++ incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ExtendedBlueprintContainer.java Tue Sep 28 18:47:49 2010
@@ -58,5 +58,7 @@ public interface ExtendedBlueprintContai
     Object getService(ServiceReference reference);
     
     AccessControlContext getAccessControlContext();
+
+    void reload();
             
 }

Modified: incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java?rev=1002318&r1=1002317&r2=1002318&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java (original)
+++ incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java Tue Sep 28 18:47:49 2010
@@ -203,7 +203,21 @@ public class BlueprintContainerImpl impl
             executors.submit(this);
         }
     }
-    
+
+    public void reload() {
+        unregisterServices();
+        untrackServiceReferences();
+        destroyComponents();
+        this.componentDefinitionRegistry.reset();
+        this.repository = null;
+        this.processors = new ArrayList<Processor>();
+        timeout = 5 * 60 * 1000;
+        waitForDependencies = true;
+        xmlValidation = true;
+        state = State.Unknown;
+        schedule();
+    }
+
     public void run() {
         scheduled.set(false);
         synchronized (scheduled) {
@@ -313,7 +327,6 @@ public class BlueprintContainerImpl impl
                         timeoutFuture.cancel(false);
                         registerServices();
                         instantiateEagerComponents();
-
                         // Register the BlueprintContainer in the OSGi registry
                         if (registration == null) {
                             Properties props = new Properties();
@@ -322,9 +335,9 @@ public class BlueprintContainerImpl impl
                             props.put(BlueprintConstants.CONTAINER_VERSION_PROPERTY,
                                       JavaUtils.getBundleVersion(bundleContext.getBundle()));
                             registration = registerService(new String [] { BlueprintContainer.class.getName() }, this, props);
-                            eventDispatcher.blueprintEvent(new BlueprintEvent(BlueprintEvent.CREATED, getBundleContext().getBundle(), getExtenderBundle()));
-                            state = State.Created;
                         }
+                        eventDispatcher.blueprintEvent(new BlueprintEvent(BlueprintEvent.CREATED, getBundleContext().getBundle(), getExtenderBundle()));
+                        state = State.Created;
                         break;
                     case Created:
                     case Failed:

Modified: incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/namespace/ComponentDefinitionRegistryImpl.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/namespace/ComponentDefinitionRegistryImpl.java?rev=1002318&r1=1002317&r2=1002318&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/namespace/ComponentDefinitionRegistryImpl.java (original)
+++ incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/namespace/ComponentDefinitionRegistryImpl.java Tue Sep 28 18:47:49 2010
@@ -56,6 +56,12 @@ public class ComponentDefinitionRegistry
         interceptors = Collections.synchronizedMap(new HashMap<ComponentMetadata, List<Interceptor>>());
     }
 
+    public void reset() {
+        components.clear();
+        typeConverters.clear();
+        interceptors.clear();
+    }
+
     public boolean containsComponentDefinition(String name) {
         return components.containsKey(name);
     }