You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by jb...@apache.org on 2012/05/03 17:12:24 UTC

svn commit: r1333496 - in /karaf/cellar/branches/cellar-2.2.x: config/src/main/java/org/apache/karaf/cellar/config/ config/src/main/java/org/apache/karaf/cellar/config/shell/ config/src/main/resources/OSGI-INF/blueprint/ management/src/main/java/org/ap...

Author: jbonofre
Date: Thu May  3 15:12:24 2012
New Revision: 1333496

URL: http://svn.apache.org/viewvc?rev=1333496&view=rev
Log:
[KARAF-1344] Add support of config deletion

Added:
    karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/shell/DeleteCommand.java
Modified:
    karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/ConfigurationEventHandler.java
    karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/LocalConfigurationListener.java
    karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/RemoteConfigurationEvent.java
    karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/shell/ListCommand.java
    karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/shell/PropListCommand.java
    karaf/cellar/branches/cellar-2.2.x/config/src/main/resources/OSGI-INF/blueprint/shell-config.xml
    karaf/cellar/branches/cellar-2.2.x/management/src/main/java/org/apache/karaf/cellar/management/CellarConfigMBean.java
    karaf/cellar/branches/cellar-2.2.x/management/src/main/java/org/apache/karaf/cellar/management/internal/CellarConfigMBeanImpl.java
    karaf/cellar/branches/cellar-2.2.x/management/src/main/resources/OSGI-INF/blueprint/blueprint.xml

Modified: karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/ConfigurationEventHandler.java
URL: http://svn.apache.org/viewvc/karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/ConfigurationEventHandler.java?rev=1333496&r1=1333495&r2=1333496&view=diff
==============================================================================
--- karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/ConfigurationEventHandler.java (original)
+++ karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/ConfigurationEventHandler.java Thu May  3 15:12:24 2012
@@ -22,6 +22,7 @@ import org.apache.karaf.cellar.core.cont
 import org.apache.karaf.cellar.core.event.EventHandler;
 import org.apache.karaf.cellar.core.event.EventType;
 import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationEvent;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -61,17 +62,23 @@ public class ConfigurationEventHandler e
         Map<String, Properties> configurationTable = clusterManager.getMap(Constants.CONFIGURATION_MAP + Configurations.SEPARATOR + groupName);
 
         String pid = event.getId();
-        //Check if the pid is marked as local.
+
         if (isAllowed(event.getSourceGroup(), Constants.CATEGORY, pid, EventType.INBOUND)) {
             Properties remoteDictionary = configurationTable.get(pid);
             Configuration conf;
             try {
                 // update the local configuration
                 conf = configurationAdmin.getConfiguration(pid);
-                if (conf != null && remoteDictionary != null) {
-                    Dictionary localDictionary = conf.getProperties();
-                    if (!this.equals(localDictionary, remoteDictionary)) {
-                        conf.update(remoteDictionary);
+                if (conf != null) {
+                    if (event.getType() == ConfigurationEvent.CM_DELETED) {
+                        conf.delete();
+                    } else {
+                        if (remoteDictionary != null) {
+                            Dictionary localDictionary = conf.getProperties();
+                            if (!this.equals(localDictionary, remoteDictionary)) {
+                                conf.update(remoteDictionary);
+                            }
+                        }
                     }
                 }
             } catch (IOException ex) {

Modified: karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/LocalConfigurationListener.java
URL: http://svn.apache.org/viewvc/karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/LocalConfigurationListener.java?rev=1333496&r1=1333495&r2=1333496&view=diff
==============================================================================
--- karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/LocalConfigurationListener.java (original)
+++ karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/LocalConfigurationListener.java Thu May  3 15:12:24 2012
@@ -68,12 +68,17 @@ public class LocalConfigurationListener 
                     Map<String, Properties> configurationTable = clusterManager.getMap(Constants.CONFIGURATION_MAP + Configurations.SEPARATOR + group.getName());
 
                     try {
-                        Configuration conf = configurationAdmin.getConfiguration(pid);
-                        Properties localDictionary = dictionaryToProperties(conf.getProperties());
-                        Dictionary remoteDictionary = configurationTable.get(pid);
-                        if (!equals(localDictionary, remoteDictionary)) {
-                            // update the distributed map
-                            configurationTable.put(pid, localDictionary);
+                        if (event.getType() == ConfigurationEvent.CM_DELETED) {
+                            configurationTable.remove(pid);
+                        } else {
+                            Configuration conf = configurationAdmin.getConfiguration(pid);
+                            Properties localDictionary = dictionaryToProperties(conf.getProperties());
+                            Dictionary remoteDictionary = configurationTable.get(pid);
+                            if (!equals(localDictionary, remoteDictionary)) {
+                                // update the distributed map
+                                configurationTable.put(pid, localDictionary);
+                                // TODO broadcast a cluster event but it creates a loop
+                            }
                         }
                     } catch (Exception e) {
                         LOGGER.error("CELLAR CONFIG: failed to push configuration with PID {} to the distributed map", pid, e);

Modified: karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/RemoteConfigurationEvent.java
URL: http://svn.apache.org/viewvc/karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/RemoteConfigurationEvent.java?rev=1333496&r1=1333495&r2=1333496&view=diff
==============================================================================
--- karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/RemoteConfigurationEvent.java (original)
+++ karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/RemoteConfigurationEvent.java Thu May  3 15:12:24 2012
@@ -20,8 +20,18 @@ import org.apache.karaf.cellar.core.even
  */
 public class RemoteConfigurationEvent extends Event {
 
+    private int type;
+
     public RemoteConfigurationEvent(String id) {
         super(id);
     }
 
+    public int getType() {
+        return type;
+    }
+
+    public void setType(int type) {
+        this.type = type;
+    }
+
 }

Added: karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/shell/DeleteCommand.java
URL: http://svn.apache.org/viewvc/karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/shell/DeleteCommand.java?rev=1333496&view=auto
==============================================================================
--- karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/shell/DeleteCommand.java (added)
+++ karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/shell/DeleteCommand.java Thu May  3 15:12:24 2012
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+package org.apache.karaf.cellar.config.shell;
+
+import org.apache.felix.gogo.commands.Argument;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.karaf.cellar.config.Constants;
+import org.apache.karaf.cellar.config.RemoteConfigurationEvent;
+import org.apache.karaf.cellar.core.Configurations;
+import org.apache.karaf.cellar.core.Group;
+import org.apache.karaf.cellar.core.control.SwitchStatus;
+import org.apache.karaf.cellar.core.event.EventProducer;
+import org.osgi.service.cm.ConfigurationEvent;
+
+import java.util.Map;
+import java.util.Properties;
+
+@Command(scope = "cluster", name = "config-delete", description = "Delete a configuration from the cluster")
+public class DeleteCommand extends ConfigCommandSupport {
+
+    @Argument(index = 0, name = "group", description = "The cluster group name", required = true, multiValued = false)
+    String groupName;
+
+    @Argument(index = 1, name = "pid", description = "The configuration PID", required = true, multiValued = false)
+    String pid;
+
+    private EventProducer eventProducer;
+
+    @Override
+    protected Object doExecute() throws Exception {
+        // check if the group exists
+        Group group = groupManager.findGroupByName(groupName);
+        if (group == null) {
+            System.err.println("Cluster group " + groupName + " doesn't exist");
+            return null;
+        }
+
+        // check if the producer is ON
+        if (eventProducer.getSwitch().getStatus().equals(SwitchStatus.OFF)) {
+            System.err.println("Cluster event producer is OFF");
+            return null;
+        }
+
+        Map<String, Properties> configurationMap = clusterManager.getMap(Constants.CONFIGURATION_MAP + Configurations.SEPARATOR + groupName);
+        if (configurationMap != null) {
+            // update the distributed map
+            Properties properties = configurationMap.remove(pid);
+
+            // broadcast the cluster event
+            RemoteConfigurationEvent event = new RemoteConfigurationEvent(pid);
+            event.setSourceGroup(group);
+            event.setType(ConfigurationEvent.CM_DELETED);
+            eventProducer.produce(event);
+        } else {
+            System.out.println("Configuration distributed map not found for cluster group " + groupName);
+        }
+
+        return null;
+    }
+
+    public EventProducer getEventProducer() {
+        return eventProducer;
+    }
+
+    public void setEventProducer(EventProducer eventProducer) {
+        this.eventProducer = eventProducer;
+    }
+
+}

Modified: karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/shell/ListCommand.java
URL: http://svn.apache.org/viewvc/karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/shell/ListCommand.java?rev=1333496&r1=1333495&r2=1333496&view=diff
==============================================================================
--- karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/shell/ListCommand.java (original)
+++ karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/shell/ListCommand.java Thu May  3 15:12:24 2012
@@ -35,27 +35,23 @@ public class ListCommand extends ConfigC
 
     @Override
     protected Object doExecute() throws Exception {
+        // check if the group exists
         Group group = groupManager.findGroupByName(groupName);
         if (group == null) {
-            System.err.println("Cluster group " + groupName + " doesn't exist.");
+            System.err.println("Cluster group " + groupName + " doesn't exist");
             return null;
         }
-        ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
-        try {
-            Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
 
-            Map<String, Properties> configurationTable = clusterManager.getMap(Constants.CONFIGURATION_MAP + Configurations.SEPARATOR + groupName);
+        Map<String, Properties> configurationTable = clusterManager.getMap(Constants.CONFIGURATION_MAP + Configurations.SEPARATOR + groupName);
+
+        if (configurationTable != null && !configurationTable.isEmpty()) {
+            System.out.println(String.format("Configuration PIDs for group " + groupName));
+            System.out.println(String.format(OUTPUT_FORMAT, "PID"));
+            for (String pid : configurationTable.keySet()) {
+                System.out.println(String.format(OUTPUT_FORMAT, pid));
+            }
+        } else System.err.println("No configuration PID found for group " + groupName);
 
-            if (configurationTable != null && !configurationTable.isEmpty()) {
-                System.out.println(String.format("Configuration PIDs for group " + groupName));
-                System.out.println(String.format(OUTPUT_FORMAT, "PID"));
-                for (String pid : configurationTable.keySet()) {
-                    System.out.println(String.format(OUTPUT_FORMAT, pid));
-                }
-            } else System.err.println("No configuration PID found for group " + groupName);
-        } finally {
-            Thread.currentThread().setContextClassLoader(originalClassLoader);
-        }
         return null;
     }
 

Modified: karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/shell/PropListCommand.java
URL: http://svn.apache.org/viewvc/karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/shell/PropListCommand.java?rev=1333496&r1=1333495&r2=1333496&view=diff
==============================================================================
--- karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/shell/PropListCommand.java (original)
+++ karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/shell/PropListCommand.java Thu May  3 15:12:24 2012
@@ -44,28 +44,23 @@ public class PropListCommand extends Cel
             System.err.println("Cluster group " + groupName + " doesn't exist.");
             return null;
         }
-        ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
-        try {
-            Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
 
-            Map<String, Properties> configurationMap = clusterManager.getMap(Constants.CONFIGURATION_MAP + Configurations.SEPARATOR + groupName);
+        Map<String, Properties> configurationMap = clusterManager.getMap(Constants.CONFIGURATION_MAP + Configurations.SEPARATOR + groupName);
 
-            if (configurationMap != null && !configurationMap.isEmpty()) {
-                Properties properties = configurationMap.get(pid);
-                if (properties == null || properties.isEmpty()) {
-                    System.err.println("No configuration PID found for group " + groupName);
-                } else {
-                    System.out.println(String.format("Property list for configuration PID " + pid + " for group " + groupName));
-                    System.out.println(String.format(OUTPUT_FORMAT, "Key", "Value"));
-                    for (Object key : properties.keySet()) {
-                        String value = properties.getProperty((String) key);
-                        System.out.println(String.format(OUTPUT_FORMAT, key, value));
-                    }
+        if (configurationMap != null && !configurationMap.isEmpty()) {
+            Properties properties = configurationMap.get(pid);
+            if (properties == null || properties.isEmpty()) {
+                System.err.println("No configuration PID found for group " + groupName);
+            } else {
+                System.out.println(String.format("Property list for configuration PID " + pid + " for group " + groupName));
+                System.out.println(String.format(OUTPUT_FORMAT, "Key", "Value"));
+                for (Object key : properties.keySet()) {
+                    String value = properties.getProperty((String) key);
+                    System.out.println(String.format(OUTPUT_FORMAT, key, value));
                 }
-            } else System.err.println("No configuration PID found for group " + groupName);
-        } finally {
-            Thread.currentThread().setContextClassLoader(originalClassLoader);
-        }
+            }
+        } else System.err.println("No configuration PID found for group " + groupName);
+
         return null;
     }
 

Modified: karaf/cellar/branches/cellar-2.2.x/config/src/main/resources/OSGI-INF/blueprint/shell-config.xml
URL: http://svn.apache.org/viewvc/karaf/cellar/branches/cellar-2.2.x/config/src/main/resources/OSGI-INF/blueprint/shell-config.xml?rev=1333496&r1=1333495&r2=1333496&view=diff
==============================================================================
--- karaf/cellar/branches/cellar-2.2.x/config/src/main/resources/OSGI-INF/blueprint/shell-config.xml (original)
+++ karaf/cellar/branches/cellar-2.2.x/config/src/main/resources/OSGI-INF/blueprint/shell-config.xml Thu May  3 15:12:24 2012
@@ -45,6 +45,16 @@
                 <ref component-id="allGroupCompleter"/>
             </completers>
         </command>
+        <command name="cluster/config-delete">
+            <action class="org.apache.karaf.cellar.config.shell.DeleteCommand">
+                <property name="clusterManager" ref="clusterManager"/>
+                <property name="groupManager" ref="groupManager"/>
+                <property name="eventProducer" ref="eventProducer"/>
+            </action>
+            <completers>
+                <ref component-id="allGroupCompleter"/>
+            </completers>
+        </command>
 
     </command-bundle>
 

Modified: karaf/cellar/branches/cellar-2.2.x/management/src/main/java/org/apache/karaf/cellar/management/CellarConfigMBean.java
URL: http://svn.apache.org/viewvc/karaf/cellar/branches/cellar-2.2.x/management/src/main/java/org/apache/karaf/cellar/management/CellarConfigMBean.java?rev=1333496&r1=1333495&r2=1333496&view=diff
==============================================================================
--- karaf/cellar/branches/cellar-2.2.x/management/src/main/java/org/apache/karaf/cellar/management/CellarConfigMBean.java (original)
+++ karaf/cellar/branches/cellar-2.2.x/management/src/main/java/org/apache/karaf/cellar/management/CellarConfigMBean.java Thu May  3 15:12:24 2012
@@ -21,6 +21,7 @@ import javax.management.openmbean.Tabula
 public interface CellarConfigMBean {
 
     String[] listConfig(String group) throws Exception;
+    void deleteConfig(String group, String pid) throws Exception;
     TabularData listProperties(String group, String pid) throws Exception;
     void setProperty(String group, String pid, String key, String value) throws Exception;
 

Modified: karaf/cellar/branches/cellar-2.2.x/management/src/main/java/org/apache/karaf/cellar/management/internal/CellarConfigMBeanImpl.java
URL: http://svn.apache.org/viewvc/karaf/cellar/branches/cellar-2.2.x/management/src/main/java/org/apache/karaf/cellar/management/internal/CellarConfigMBeanImpl.java?rev=1333496&r1=1333495&r2=1333496&view=diff
==============================================================================
--- karaf/cellar/branches/cellar-2.2.x/management/src/main/java/org/apache/karaf/cellar/management/internal/CellarConfigMBeanImpl.java (original)
+++ karaf/cellar/branches/cellar-2.2.x/management/src/main/java/org/apache/karaf/cellar/management/internal/CellarConfigMBeanImpl.java Thu May  3 15:12:24 2012
@@ -14,9 +14,15 @@
 package org.apache.karaf.cellar.management.internal;
 
 import org.apache.karaf.cellar.config.Constants;
+import org.apache.karaf.cellar.config.RemoteConfigurationEvent;
 import org.apache.karaf.cellar.core.ClusterManager;
 import org.apache.karaf.cellar.core.Configurations;
+import org.apache.karaf.cellar.core.Group;
+import org.apache.karaf.cellar.core.GroupManager;
+import org.apache.karaf.cellar.core.control.SwitchStatus;
+import org.apache.karaf.cellar.core.event.EventProducer;
 import org.apache.karaf.cellar.management.CellarConfigMBean;
+import org.osgi.service.cm.ConfigurationEvent;
 
 import javax.management.NotCompliantMBeanException;
 import javax.management.StandardMBean;
@@ -26,80 +32,135 @@ import java.util.Map;
 import java.util.Properties;
 
 /**
- *  Implementation of the Cellar Config MBean allowing to manipulate Cellar config admin layer.
+ * Implementation of the Cellar Config MBean allowing to manipulate Cellar config admin layer.
  */
 public class CellarConfigMBeanImpl extends StandardMBean implements CellarConfigMBean {
 
     private ClusterManager clusterManager;
+    private GroupManager groupManager;
+    private EventProducer eventProducer;
 
     public CellarConfigMBeanImpl() throws NotCompliantMBeanException {
         super(CellarConfigMBean.class);
     }
 
-    public ClusterManager getClusterManager() {
-        return this.clusterManager;
-    }
 
-    public void setClusterManager(ClusterManager clusterManager) {
-        this.clusterManager = clusterManager;
+    public String[] listConfig(String groupName) throws Exception {
+        // check if the group exists
+        Group group = groupManager.findGroupByName(groupName);
+        if (group == null) {
+            throw new IllegalArgumentException("Cluster group " + groupName + " doesn't exist");
+        }
+
+        Map<String, Properties> config = clusterManager.getMap(Constants.CONFIGURATION_MAP + Configurations.SEPARATOR + group);
+        return config.keySet().toArray(new String[config.keySet().size()]);
     }
 
-    public String[] listConfig(String group) throws Exception {
-        ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
-        Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
-        try {
-            Map<String, Properties> config = clusterManager.getMap(Constants.CONFIGURATION_MAP + Configurations.SEPARATOR + group);
-            return config.keySet().toArray(new String[config.keySet().size()]);
-        } finally {
-            Thread.currentThread().setContextClassLoader(originalClassLoader);
+    public void deleteConfig(String groupName, String pid) throws Exception {
+        // check if the group exists
+        Group group = groupManager.findGroupByName(groupName);
+        if (group == null) {
+            throw new IllegalArgumentException("Cluster group " + groupName + " doesn't exist");
+        }
+
+        // check if the producer is ON
+        if (eventProducer.getSwitch().getStatus().equals(SwitchStatus.OFF)) {
+            throw new IllegalStateException("Cluster event producer is OFF");
+        }
+
+        Map<String, Properties> configurationMap = clusterManager.getMap(Constants.CONFIGURATION_MAP + Configurations.SEPARATOR + groupName);
+        if (configurationMap != null) {
+            // update the distributed map
+            Properties properties = configurationMap.remove(pid);
+
+            // broadcast the cluster event
+            RemoteConfigurationEvent event = new RemoteConfigurationEvent(pid);
+            event.setSourceGroup(group);
+            event.setType(ConfigurationEvent.CM_DELETED);
+            eventProducer.produce(event);
+        } else {
+            throw new IllegalStateException("Configuration distributed map not found for cluster group " + groupName);
         }
     }
 
     public TabularData listProperties(String group, String pid) throws Exception {
         CompositeType compositeType = new CompositeType("Property", "Karaf Cellar Config property",
-                new String[]{ "key", "value" },
-                new String[]{ "Property key", "Property value" },
-                new OpenType[]{ SimpleType.STRING, SimpleType.STRING });
+                new String[]{"key", "value"},
+                new String[]{"Property key", "Property value"},
+                new OpenType[]{SimpleType.STRING, SimpleType.STRING});
         TabularType tableType = new TabularType("Properties", "Table of all properties in the config PID",
-                compositeType, new String[]{ "key" });
+                compositeType, new String[]{"key"});
         TabularData table = new TabularDataSupport(tableType);
 
-        ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
-        Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
-        try {
-            Map<String, Properties> config = clusterManager.getMap(Constants.CONFIGURATION_MAP + Configurations.SEPARATOR + group);
-            Properties properties = config.get(pid);
-            if (properties != null) {
-                Enumeration propertyNames = properties.propertyNames();
-                while (propertyNames.hasMoreElements()) {
-                    String key = (String) propertyNames.nextElement();
-                    String value = (String) properties.get(key);
-                    CompositeDataSupport data = new CompositeDataSupport(compositeType,
-                            new String[]{ "key", "value" },
-                            new String[]{ key, value });
-                    table.put(data);
-                }
+        Map<String, Properties> config = clusterManager.getMap(Constants.CONFIGURATION_MAP + Configurations.SEPARATOR + group);
+        Properties properties = config.get(pid);
+        if (properties != null) {
+            Enumeration propertyNames = properties.propertyNames();
+            while (propertyNames.hasMoreElements()) {
+                String key = (String) propertyNames.nextElement();
+                String value = (String) properties.get(key);
+                CompositeDataSupport data = new CompositeDataSupport(compositeType,
+                        new String[]{"key", "value"},
+                        new String[]{key, value});
+                table.put(data);
             }
-            return table;
-        } finally {
-            Thread.currentThread().setContextClassLoader(originalClassLoader);
         }
+        return table;
     }
 
-    public void setProperty(String group, String pid, String key, String value) throws Exception {
-        ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
-        Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
-        try {
-            Map<String, Properties> config = clusterManager.getMap(Constants.CONFIGURATION_MAP + Configurations.SEPARATOR + group);
-            Properties properties = config.get(pid);
+    public void setProperty(String groupName, String pid, String key, String value) throws Exception {
+        // check if the group exists
+        Group group = groupManager.findGroupByName(groupName);
+        if (group == null) {
+            throw new IllegalArgumentException("Cluster group " + groupName + " doesn't exist");
+        }
+
+        // check if the producer is ON
+        if (eventProducer.getSwitch().getStatus().equals(SwitchStatus.OFF)) {
+            throw new IllegalStateException("Cluster event producer is OFF");
+        }
+
+        Map<String, Properties> configurationMap = clusterManager.getMap(Constants.CONFIGURATION_MAP + Configurations.SEPARATOR + groupName);
+        if (configurationMap != null) {
+            // update the distributed map
+            Properties properties = configurationMap.get(pid);
             if (properties == null) {
                 properties = new Properties();
             }
             properties.put(key, value);
-            config.put(pid, properties);
-        } finally {
-            Thread.currentThread().setContextClassLoader(originalClassLoader);
+            configurationMap.put(pid, properties);
+
+            // broadcast the cluster event
+            RemoteConfigurationEvent event = new RemoteConfigurationEvent(pid);
+            event.setSourceGroup(group);
+            eventProducer.produce(event);
+        } else {
+            throw new IllegalStateException("Configuration distributed map not found for cluster group " + groupName);
         }
     }
 
+    public ClusterManager getClusterManager() {
+        return this.clusterManager;
+    }
+
+    public void setClusterManager(ClusterManager clusterManager) {
+        this.clusterManager = clusterManager;
+    }
+
+    public GroupManager getGroupManager() {
+        return groupManager;
+    }
+
+    public void setGroupManager(GroupManager groupManager) {
+        this.groupManager = groupManager;
+    }
+
+    public EventProducer getEventProducer() {
+        return eventProducer;
+    }
+
+    public void setEventProducer(EventProducer eventProducer) {
+        this.eventProducer = eventProducer;
+    }
+
 }

Modified: karaf/cellar/branches/cellar-2.2.x/management/src/main/resources/OSGI-INF/blueprint/blueprint.xml
URL: http://svn.apache.org/viewvc/karaf/cellar/branches/cellar-2.2.x/management/src/main/resources/OSGI-INF/blueprint/blueprint.xml?rev=1333496&r1=1333495&r2=1333496&view=diff
==============================================================================
--- karaf/cellar/branches/cellar-2.2.x/management/src/main/resources/OSGI-INF/blueprint/blueprint.xml (original)
+++ karaf/cellar/branches/cellar-2.2.x/management/src/main/resources/OSGI-INF/blueprint/blueprint.xml Thu May  3 15:12:24 2012
@@ -36,6 +36,8 @@
 
     <bean id="cellarConfigMBean" class="org.apache.karaf.cellar.management.internal.CellarConfigMBeanImpl">
         <property name="clusterManager" ref="clusterManager"/>
+        <property name="groupManager" ref="groupManager"/>
+        <property name="eventProducer" ref="eventProducer"/>
     </bean>
 
     <bean id="cellarFeaturesMBean" class="org.apache.karaf.cellar.management.internal.CellarFeaturesMBeanImpl">