You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ro...@apache.org on 2018/10/03 20:00:26 UTC

svn commit: r1842756 - in /felix/trunk/configadmin/src: main/java/org/apache/felix/cm/impl/ConfigurationImpl.java test/java/org/apache/felix/cm/MockNotCachablePersistenceManager.java test/java/org/apache/felix/cm/impl/ConfigurationManagerTest.java

Author: rotty3000
Date: Wed Oct  3 20:00:26 2018
New Revision: 1842756

URL: http://svn.apache.org/viewvc?rev=1842756&view=rev
Log:
FELIX-5949 Configuration _updates_ are ignored when using a NotCachablePersistenceManager

Signed-off-by: Raymond Auge <ro...@apache.org>

Modified:
    felix/trunk/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationImpl.java
    felix/trunk/configadmin/src/test/java/org/apache/felix/cm/MockNotCachablePersistenceManager.java
    felix/trunk/configadmin/src/test/java/org/apache/felix/cm/impl/ConfigurationManagerTest.java

Modified: felix/trunk/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationImpl.java?rev=1842756&r1=1842755&r2=1842756&view=diff
==============================================================================
--- felix/trunk/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationImpl.java (original)
+++ felix/trunk/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationImpl.java Wed Oct  3 20:00:26 2018
@@ -100,6 +100,8 @@ public class ConfigurationImpl
 
     private static final String PROPERTY_LOCKED = ":org.apache.felix.configadmin.locked:";
 
+    private static final String PROPERTY_REVISION = ":org.apache.felix.configadmin.revision:";
+
     /**
      * The factory PID of this configuration or <code>null</code> if this
      * is not a factory configuration.
@@ -138,9 +140,11 @@ public class ConfigurationImpl
     /**
      * Configuration revision counter incremented each time the
      * {@link #properties} is set (in the constructor or the
-     * {@link #configure(Dictionary)} method. This counter is transient
-     * and not persisted. Thus it is restarted from zero each time
-     * an instance of this class is created.
+     * {@link #configure(Dictionary)} method. This counter is
+     * persisted transparently so that {@link NotCachablePersistenceManager}
+     * can provide a proper change count. The persistence is forward
+     * compatible such that previously persisted configurations are
+     * handled gracefully.
      */
     private volatile long revision;
 
@@ -430,6 +434,8 @@ public class ConfigurationImpl
                     + ", got " + servicePid );
             }
 
+            // we're doing a local update, so override the properties revision
+            properties.put( PROPERTY_REVISION, Long.valueOf(getRevision()) );
             configureFromPersistence( properties );
         }
 
@@ -451,6 +457,7 @@ public class ConfigurationImpl
         setAutoProperties( newProperties, true );
 
         // persist new configuration
+        newProperties.put( PROPERTY_REVISION, Long.valueOf(getRevision()) );
         persistenceManager.store( getPidString(), newProperties );
 
         // finally assign the configuration for use
@@ -528,6 +535,7 @@ public class ConfigurationImpl
         Dictionary<String, Object> props = new Hashtable<>();
         setAutoProperties( props, true );
         props.put( CONFIGURATION_NEW, Boolean.TRUE );
+        props.put( PROPERTY_REVISION, Long.valueOf(getRevision()) );
         persistenceManager.store( getPidString(), props );
     }
 
@@ -562,6 +570,7 @@ public class ConfigurationImpl
             props.remove(PROPERTY_LOCKED);
         }
         // only store now, if this is not a new configuration
+        props.put( PROPERTY_REVISION, Long.valueOf(getRevision()) );
         persistenceManager.store( getPidString(), props );
     }
 
@@ -617,6 +626,7 @@ public class ConfigurationImpl
 
     private void configure( final Dictionary<String, Object> properties )
     {
+        final Object revisionValue = properties == null ? null : properties.get(PROPERTY_REVISION);
         final Object lockedValue = properties == null ? null : properties.get(PROPERTY_LOCKED);
         if ( lockedValue != null )
         {
@@ -646,7 +656,7 @@ public class ConfigurationImpl
         synchronized ( this )
         {
             this.properties = newProperties;
-            this.revision++;
+            this.revision = (revisionValue != null) ? 1 + ((Long)revisionValue).longValue() : ++revision ;
         }
     }
 
@@ -667,6 +677,7 @@ public class ConfigurationImpl
             properties.remove( ConfigurationAdmin.SERVICE_BUNDLELOCATION );
         }
         properties.remove( PROPERTY_LOCKED );
+        properties.remove( PROPERTY_REVISION );
     }
 
 
@@ -676,6 +687,7 @@ public class ConfigurationImpl
         replaceProperty( properties, ConfigurationAdmin.SERVICE_FACTORYPID, factoryPid );
         properties.remove( ConfigurationAdmin.SERVICE_BUNDLELOCATION );
         properties.remove( PROPERTY_LOCKED );
+        properties.remove( PROPERTY_REVISION );
     }
 
 
@@ -683,7 +695,7 @@ public class ConfigurationImpl
             Constants.SERVICE_PID,
             ConfigurationAdmin.SERVICE_FACTORYPID,
             ConfigurationAdmin.SERVICE_BUNDLELOCATION,
-            PROPERTY_LOCKED
+            PROPERTY_LOCKED, PROPERTY_REVISION
     };
 
     static void clearAutoProperties( Dictionary<String, Object> properties )

Modified: felix/trunk/configadmin/src/test/java/org/apache/felix/cm/MockNotCachablePersistenceManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/configadmin/src/test/java/org/apache/felix/cm/MockNotCachablePersistenceManager.java?rev=1842756&r1=1842755&r2=1842756&view=diff
==============================================================================
--- felix/trunk/configadmin/src/test/java/org/apache/felix/cm/MockNotCachablePersistenceManager.java (original)
+++ felix/trunk/configadmin/src/test/java/org/apache/felix/cm/MockNotCachablePersistenceManager.java Wed Oct  3 20:00:26 2018
@@ -26,6 +26,8 @@ import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.felix.cm.impl.CaseInsensitiveDictionary;
+
 
 public class MockNotCachablePersistenceManager implements NotCachablePersistenceManager
 {
@@ -77,7 +79,7 @@ public class MockNotCachablePersistenceM
     @Override
     public void store( String pid, @SuppressWarnings("rawtypes") Dictionary properties )
     {
-        configs.put( pid, properties );
+        configs.put( pid, new CaseInsensitiveDictionary( properties ) );
     }
 
 }

Modified: felix/trunk/configadmin/src/test/java/org/apache/felix/cm/impl/ConfigurationManagerTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/configadmin/src/test/java/org/apache/felix/cm/impl/ConfigurationManagerTest.java?rev=1842756&r1=1842755&r2=1842756&view=diff
==============================================================================
--- felix/trunk/configadmin/src/test/java/org/apache/felix/cm/impl/ConfigurationManagerTest.java (original)
+++ felix/trunk/configadmin/src/test/java/org/apache/felix/cm/impl/ConfigurationManagerTest.java Wed Oct  3 20:00:26 2018
@@ -140,6 +140,56 @@ public class ConfigurationManagerTest
         assertEquals("valueNotCached", conf[0].getProperties(true).get("property1"));
     }
 
+    @Test public void test_listConfigurations_notcached_handlesUpdates() throws Exception
+    {
+        String pid = "testDefaultPersistenceManager";
+        PersistenceManager pm = new MockNotCachablePersistenceManager();
+        Dictionary<String, Object> dictionary = new Hashtable<>();
+        dictionary.put( "property1", "value1" );
+        dictionary.put( Constants.SERVICE_PID, pid );
+        pm.store( pid, dictionary );
+
+        ConfigurationManager configMgr = new ConfigurationManager(new PersistenceManagerProxy(pm), null) {
+            @Override
+            void updated(ConfigurationImpl config, boolean fireEvent) {
+            }
+        };
+
+        ConfigurationImpl[] conf1 = configMgr.listConfigurations(new ConfigurationAdminImpl(configMgr, null), null);
+
+        assertEquals(1, conf1.length);
+        assertEquals(2, conf1[0].getProperties(true).size());
+
+        // internal changecount
+        long revision = conf1[0].getRevision();
+
+        dictionary = new Hashtable<>();
+        dictionary.put("property1", "valueNotCached");
+        dictionary.put( Constants.SERVICE_PID, pid );
+        conf1[0].update(dictionary);
+
+        assertEquals(revision + 1, conf1[0].getRevision());
+
+        ConfigurationImpl[] conf2 = configMgr.listConfigurations(new ConfigurationAdminImpl(configMgr, null), null);
+        assertEquals(1, conf2.length);
+        assertEquals(2, conf2[0].getProperties(true).size());
+
+        assertEquals(revision + 1, conf2[0].getRevision());
+
+        dictionary = new Hashtable<>();
+        dictionary.put("property1", "secondUpdate");
+        dictionary.put( Constants.SERVICE_PID, pid );
+        conf2[0].update(dictionary);
+
+        assertEquals(revision + 2, conf2[0].getRevision());
+
+        ConfigurationImpl[] conf3 = configMgr.listConfigurations(new ConfigurationAdminImpl(configMgr, null), null);
+        assertEquals(1, conf3.length);
+        assertEquals(2, conf3[0].getProperties(true).size());
+
+        assertEquals(revision + 2, conf3[0].getRevision());
+    }
+
     @Test public void testLogNoLogService() throws IOException
     {
         ConfigurationManager configMgr = createConfigurationManagerAndLog( null );