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 14:23:55 UTC

svn commit: r1333423 - in /karaf/cellar/branches/cellar-2.2.x: config/src/main/java/org/apache/karaf/cellar/config/ config/src/test/java/org/apache/karaf/cellar/config/ hazelcast/src/main/java/org/apache/karaf/cellar/hazelcast/

Author: jbonofre
Date: Thu May  3 12:23:55 2012
New Revision: 1333423

URL: http://svn.apache.org/viewvc?rev=1333423&view=rev
Log:
[KARAF-1405] Fix loop between the distributed config map and the local config

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/ConfigurationSupport.java
    karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/ConfigurationSynchronizer.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/test/java/org/apache/karaf/cellar/config/ConfigurationSupportTest.java
    karaf/cellar/branches/cellar-2.2.x/hazelcast/src/main/java/org/apache/karaf/cellar/hazelcast/HazelcastGroupManager.java

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=1333423&r1=1333422&r2=1333423&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 12:23:55 2012
@@ -41,18 +41,8 @@ public class ConfigurationEventHandler e
 
     private final Switch eventSwitch = new BasicSwitch(SWITCH_ID);
 
-    private Node node;
-
-    /**
-     * Handles a
-     *
-     * @param event
-     */
     public void handle(RemoteConfigurationEvent event) {
 
-        if (event == null || event.getSourceGroup() == null)
-            return;
-
         // check if the handler is ON
         if (eventSwitch.getStatus().equals(SwitchStatus.OFF)) {
             LOGGER.warn("CELLAR CONFIG: {} switch is OFF, cluster event not handled", SWITCH_ID);
@@ -73,12 +63,17 @@ public class ConfigurationEventHandler e
         String pid = event.getId();
         //Check if the pid is marked as local.
         if (isAllowed(event.getSourceGroup(), Constants.CATEGORY, pid, EventType.INBOUND)) {
-            Properties dictionary = configurationTable.get(pid);
+            Properties remoteDictionary = configurationTable.get(pid);
             Configuration conf;
             try {
                 // update the local configuration
                 conf = configurationAdmin.getConfiguration(pid);
-                conf.update(preparePull(dictionary));
+                if (conf != null && remoteDictionary != null) {
+                    Dictionary localDictionary = conf.getProperties();
+                    if (!this.equals(localDictionary, remoteDictionary)) {
+                        conf.update(remoteDictionary);
+                    }
+                }
             } catch (IOException ex) {
                 LOGGER.error("CELLAR CONFIG: failed to read distributed map", ex);
             }
@@ -89,9 +84,7 @@ public class ConfigurationEventHandler e
      * Initialization Method.
      */
     public void init() {
-        if (clusterManager != null) {
-            node = clusterManager.getNode();
-        }
+
     }
 
     /**

Modified: karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/ConfigurationSupport.java
URL: http://svn.apache.org/viewvc/karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/ConfigurationSupport.java?rev=1333423&r1=1333422&r2=1333423&view=diff
==============================================================================
--- karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/ConfigurationSupport.java (original)
+++ karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/ConfigurationSupport.java Thu May  3 12:23:55 2012
@@ -24,10 +24,6 @@ import java.util.Properties;
  */
 public class ConfigurationSupport extends CellarSupport {
 
-    private static String HOME_PLACEHOLDER = "karaf.home";
-    private static String RELATIVE_HOME = "${" + HOME_PLACEHOLDER + "}";
-    private static String HOME = System.getProperty("karaf.home");
-
     /**
      * Reads a {@code Dictionary} object and creates a property object out of it.
      *
@@ -50,57 +46,67 @@ public class ConfigurationSupport extend
     }
 
     /**
-     * Prepares a dictionary for push
+     * Check if two dictionaries are egal.
      *
-     * @param dictionary
-     * @return
+     * @param dict1 the source dictionary.
+     * @param dict2 the target dictionary.
+     * @return true if the two dictionaries are egal, false else
      */
-    public Dictionary preparePush(Dictionary dictionary) {
-        Dictionary properties = new Properties();
-        Enumeration keys = dictionary.keys();
-        while (keys.hasMoreElements()) {
-            String key = (String) keys.nextElement();
-            if (key != null && dictionary.get(key) != null) {
-                String value = String.valueOf(dictionary.get(key));
-                value = convertStrings(value, HOME, RELATIVE_HOME);
-                properties.put(key, value);
+    protected boolean equals(Dictionary dict1, Dictionary dict2) {
+        if (dict1 == null && dict2 == null)
+            return true;
+
+        if (dict1 == null && dict2 != null)
+            return false;
+
+        if (dict1 != null && dict2 == null)
+            return false;
+
+        if (dict1.size() != dict2.size())
+            return false;
+
+        for (Enumeration e = dict1.keys(); e.hasMoreElements(); ) {
+            Object key = e.nextElement();
+            if (!dict1.get(key).equals(dict2.get(key))) {
+                return false;
             }
         }
-        return properties;
-    }
 
-    /**
-     * Prepares a dictionary for Pull
-     *
-     * @param dictionary
-     * @return
-     */
-    public Dictionary preparePull(Dictionary dictionary) {
-        Dictionary properties = new Properties();
-        Enumeration keys = dictionary.keys();
-        while (keys.hasMoreElements()) {
-            String key = (String) keys.nextElement();
-            if (key != null && dictionary.get(key) != null) {
-                String value = String.valueOf(dictionary.get(key));
-                value = convertStrings(value, RELATIVE_HOME, HOME);
-                properties.put(key, value);
-            }
-        }
-        return properties;
+        return true;
     }
 
     /**
-     * Performs a string replacement on value.
+     * Returns true if target contains all source key/value pairs.
      *
-     * @param value
+     * @param source
+     * @param target
      * @return
      */
-    public String convertStrings(String value, String absolute, String relative) {
-        String result = value;
-        if (absolute != null && (absolute.trim().length() > 0) && value.contains(absolute)) {
-            result = value.replace(absolute, relative);
+    private boolean subDictionary(Dictionary source, Dictionary target) {
+        if (source == null && target == null) {
+            return true;
+        } else if (source == null || target == null) {
+            return false;
+        } else if (source.isEmpty() && target.isEmpty()) {
+            return true;
+        } else {
+            Enumeration keys = source.keys();
+            while (keys.hasMoreElements()) {
+                String key = (String) keys.nextElement();
+                String value1 = (String) source.get(key);
+                String value2 = (String) target.get(key);
+
+                if (value1 == null && value2 == null)
+                    continue;
+                else if (value1 == null)
+                    return false;
+                else if (value2 == null)
+                    return false;
+                else if (value1.equals(value2))
+                    continue;
+            }
+            return true;
         }
-        return result;
     }
 
 }

Modified: karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/ConfigurationSynchronizer.java
URL: http://svn.apache.org/viewvc/karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/ConfigurationSynchronizer.java?rev=1333423&r1=1333422&r2=1333423&view=diff
==============================================================================
--- karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/ConfigurationSynchronizer.java (original)
+++ karaf/cellar/branches/cellar-2.2.x/config/src/main/java/org/apache/karaf/cellar/config/ConfigurationSynchronizer.java Thu May  3 12:23:55 2012
@@ -83,20 +83,17 @@ public class ConfigurationSynchronizer e
                 Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
 
                 for (String pid : configurationTable.keySet()) {
-                    //Check if the pid is marked as local.
                     if (isAllowed(group, Constants.CATEGORY, pid, EventType.INBOUND)) {
-                        Properties dictionary = configurationTable.get(pid);
+                        Properties remoteDictionary = configurationTable.get(pid);
                         try {
+                            // update the local configuration if needed
                             Configuration conf = configurationAdmin.getConfiguration(pid);
-                            //Update the configuration.
-                            if (conf != null) {
-                                //Mark the remote configuration event.
-                                conf.update(preparePull(dictionary));
-                            }
+                            conf.update(remoteDictionary);
                         } catch (IOException ex) {
                             LOGGER.error("CELLAR CONFIG: failed to read from the distributed map", ex);
                         }
-                    } LOGGER.warn("CELLAR CONFIG: configuration with PID {} is marked as BLOCKED INBOUND", pid);
+                    }
+                    LOGGER.warn("CELLAR CONFIG: configuration with PID {} is marked as BLOCKED INBOUND", pid);
                 }
             } finally {
                 Thread.currentThread().setContextClassLoader(originalClassLoader);
@@ -127,33 +124,19 @@ public class ConfigurationSynchronizer e
                     configs = configurationAdmin.listConfigurations(null);
                     for (Configuration conf : configs) {
                         String pid = conf.getPid();
-                        // check if the pid is marked as local.
                         if (isAllowed(group, Constants.CATEGORY, pid, EventType.OUTBOUND)) {
-                            Properties source = dictionaryToProperties(preparePush(conf.getProperties()));
-                            Properties target = configurationTable.get(pid);
-                            if (target != null) {
-                                boolean requiresUpdate = false;
-                                if (source != null && source.keys() != null) {
-                                    Enumeration keys = source.keys();
-                                    while (keys.hasMoreElements()) {
-                                        String key = (String) keys.nextElement();
-                                        if (target.get(key) == null || target.get(key).equals(source.get(key))) {
-                                            requiresUpdate = true;
-                                            target.put(key, source.get(key));
-                                        }
-                                    }
-                                    configurationTable.put(pid, target);
-                                    if (requiresUpdate) {
-                                        RemoteConfigurationEvent event = new RemoteConfigurationEvent(conf.getPid());
-                                        eventProducer.produce(event);
-                                    }
-                                }
-                            } else {
+                            Properties localDictionary = dictionaryToProperties(conf.getProperties());
+                            Properties remoteDictionary = configurationTable.get(pid);
+                            if (!this.equals(localDictionary, remoteDictionary)) {
+                                // update the distributed map
+                                configurationTable.put(pid, localDictionary);
+                                // broadcast the cluster event
                                 RemoteConfigurationEvent event = new RemoteConfigurationEvent(conf.getPid());
-                                configurationTable.put(pid, source);
+                                event.setSourceGroup(group);
                                 eventProducer.produce(event);
                             }
-                        } else LOGGER.warn("CELLAR CONFIG: configuration with PID {} is marked as BLOCKED OUTBOUND", pid);
+                        } else
+                            LOGGER.warn("CELLAR CONFIG: configuration with PID {} is marked as BLOCKED OUTBOUND", pid);
                     }
                 } catch (IOException ex) {
                     LOGGER.error("CELLAR CONFIG: failed to read from the distributed map (IO error)", 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=1333423&r1=1333422&r2=1333423&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 12:23:55 2012
@@ -27,6 +27,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.IOException;
+import java.util.Dictionary;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
@@ -63,41 +64,27 @@ public class LocalConfigurationListener 
                 // check if the pid is allowed for outbound.
                 if (isAllowed(group, Constants.CATEGORY, pid, EventType.OUTBOUND)) {
 
-                    // update the distributed map
-                    push(pid, group);
+                    // update the distributed map if needed
+                    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);
+                        }
+                    } catch (Exception e) {
+                        LOGGER.error("CELLAR CONFIG: failed to push configuration with PID {} to the distributed map", pid, e);
+                    }
                     // broadcast the cluster event
-                    RemoteConfigurationEvent configurationEvent = new RemoteConfigurationEvent(pid);
-                    configurationEvent.setSourceGroup(group);
-                    configurationEvent.setSourceNode(clusterManager.getNode());
-                    eventProducer.produce(configurationEvent);
                 } else LOGGER.warn("CELLAR CONFIG: configuration with PID {} is marked as BLOCKED OUTBOUND", pid);
             }
         }
     }
 
     /**
-     * Push configuration with pid to the table.
-     *
-     * @param pid
-     */
-    protected void push(String pid, Group group) {
-        String groupName = group.getName();
-        Map<String, Properties> configurationTable = clusterManager.getMap(Constants.CONFIGURATION_MAP + Configurations.SEPARATOR + groupName);
-        try {
-            Configuration[] configurations = configurationAdmin.listConfigurations("(service.pid=" + pid + ")");
-            for (Configuration configuration : configurations) {
-                Properties properties = dictionaryToProperties(preparePush(configuration.getProperties()));
-                configurationTable.put(configuration.getPid(), properties);
-            }
-        } catch (IOException e) {
-            LOGGER.error("CELLAR CONFIG: failed to push configuration with PID {} to the distributed map", pid, e);
-        } catch (InvalidSyntaxException e) {
-            LOGGER.error("CELLAR CONFIG: failed to push configuration with PID {} to the distributed map", pid, e);
-        }
-    }
-
-    /**
      * Initialization Method.
      */
     public void init() {

Modified: karaf/cellar/branches/cellar-2.2.x/config/src/test/java/org/apache/karaf/cellar/config/ConfigurationSupportTest.java
URL: http://svn.apache.org/viewvc/karaf/cellar/branches/cellar-2.2.x/config/src/test/java/org/apache/karaf/cellar/config/ConfigurationSupportTest.java?rev=1333423&r1=1333422&r2=1333423&view=diff
==============================================================================
--- karaf/cellar/branches/cellar-2.2.x/config/src/test/java/org/apache/karaf/cellar/config/ConfigurationSupportTest.java (original)
+++ karaf/cellar/branches/cellar-2.2.x/config/src/test/java/org/apache/karaf/cellar/config/ConfigurationSupportTest.java Thu May  3 12:23:55 2012
@@ -27,57 +27,56 @@ public class ConfigurationSupportTest {
     ConfigurationSupport support = new ConfigurationSupport();
 
     @Test
-    public void testConvertStrings() throws Exception {
-        String absolutePath = "/somewehre/karaf/etc";
-        String home = "/somewehre/karaf";
-        String var = "${karaf.home}";
+    public void testEquals() throws Exception {
+        Dictionary source = new Properties();
+        Dictionary target = new Properties();
+
+        source.put("key1", "value1");
+        source.put("key2", 1);
+        source.put("key3", Boolean.FALSE);
+        source.put("key4", 12L);
 
-        String expectedResult = "${karaf.home}/etc";
+        target.put("key1", "value1");
+        target.put("key2", 1);
+        target.put("key3", Boolean.FALSE);
+        target.put("key4", 12L);
 
-        String result = support.convertStrings(absolutePath, home, var);
-        Assert.assertEquals(expectedResult, result);
+        Assert.assertEquals(true, support.equals(source, target));
     }
 
     @Test
-    public void testPreparePull() throws Exception {
-        Dictionary result = null;
+    public void testNotEquals() throws Exception {
         Dictionary source = new Properties();
-        Dictionary expectedResult = new Properties();
+        Dictionary target = new Properties();
 
         source.put("key1", "value1");
-        source.put("key2", 1);
+        source.put("key2", 2);
         source.put("key3", Boolean.FALSE);
         source.put("key4", 12L);
 
-        expectedResult.put("key1", "value1");
-        expectedResult.put("key2", "1");
-        expectedResult.put("key3", "false");
-        expectedResult.put("key4", "12");
-
-        result = support.preparePull(source);
+        target.put("key1", "value1");
+        target.put("key2", 1);
+        target.put("key3", Boolean.FALSE);
+        target.put("key4", 12L);
 
-        Assert.assertEquals(expectedResult, result);
+        Assert.assertEquals(false, support.equals(source, target));
     }
 
     @Test
-    public void testPreparePush() throws Exception {
-        Dictionary result = null;
+    public void testNotEqualsDueToSize() throws Exception {
         Dictionary source = new Properties();
-        Dictionary expectedResult = new Properties();
-        
+        Dictionary target = new Properties();
+
         source.put("key1", "value1");
-        source.put("key2", 1);
+        source.put("key2", 2);
         source.put("key3", Boolean.FALSE);
-        source.put("key4", 12L);
-        
-        expectedResult.put("key1", "value1");
-        expectedResult.put("key2", "1");
-        expectedResult.put("key3", "false");
-        expectedResult.put("key4", "12");
 
-        result = support.preparePush(source);
+        target.put("key1", "value1");
+        target.put("key2", 1);
+        target.put("key3", Boolean.FALSE);
+        target.put("key4", 12L);
 
-        Assert.assertEquals(expectedResult, result);
+        Assert.assertEquals(false, support.equals(source, target));
     }
 
 }

Modified: karaf/cellar/branches/cellar-2.2.x/hazelcast/src/main/java/org/apache/karaf/cellar/hazelcast/HazelcastGroupManager.java
URL: http://svn.apache.org/viewvc/karaf/cellar/branches/cellar-2.2.x/hazelcast/src/main/java/org/apache/karaf/cellar/hazelcast/HazelcastGroupManager.java?rev=1333423&r1=1333422&r2=1333423&view=diff
==============================================================================
--- karaf/cellar/branches/cellar-2.2.x/hazelcast/src/main/java/org/apache/karaf/cellar/hazelcast/HazelcastGroupManager.java (original)
+++ karaf/cellar/branches/cellar-2.2.x/hazelcast/src/main/java/org/apache/karaf/cellar/hazelcast/HazelcastGroupManager.java Thu May  3 12:23:55 2012
@@ -533,7 +533,6 @@ public class HazelcastGroupManager imple
      * @param entryEvent entry event
      */
     public void entryUpdated(EntryEvent entryEvent) {
-        LOGGER.info("Distributed Group configuration has been updated, updating local configuration.");
         try {
             Configuration conf = configurationAdmin.getConfiguration(GROUPS);
             Dictionary props = conf.getProperties();