You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by fm...@apache.org on 2013/08/14 08:50:11 UTC

svn commit: r1513740 - in /felix/trunk/configadmin/src: main/java/org/apache/felix/cm/impl/ConfigurationAdminImpl.java main/java/org/apache/felix/cm/impl/ConfigurationImpl.java test/java/org/apache/felix/cm/integration/ConfigurationBindingTest.java

Author: fmeschbe
Date: Wed Aug 14 06:50:11 2013
New Revision: 1513740

URL: http://svn.apache.org/r1513740
Log:
FELIX-3360 Fix dynamic configuration binding

- getConfiguration(pid) binds dynamically
- createConfiguration(pid) binds dynamically
- add integration tests to validate removal of
  dynamic bindings
- make sure dynamic binding is cleared if
  static binding is set

Modified:
    felix/trunk/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationAdminImpl.java
    felix/trunk/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationImpl.java
    felix/trunk/configadmin/src/test/java/org/apache/felix/cm/integration/ConfigurationBindingTest.java

Modified: felix/trunk/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationAdminImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationAdminImpl.java?rev=1513740&r1=1513739&r2=1513740&view=diff
==============================================================================
--- felix/trunk/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationAdminImpl.java (original)
+++ felix/trunk/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationAdminImpl.java Wed Aug 14 06:50:11 2013
@@ -76,8 +76,9 @@ public class ConfigurationAdminImpl impl
         configurationManager.log( LogService.LOG_DEBUG, "createFactoryConfiguration(factoryPid={0})", new Object[]
             { factoryPid } );
 
-        ConfigurationImpl config = configurationManager.createFactoryConfiguration( factoryPid, this.getBundle()
-            .getLocation() );
+        // FELIX-3360: new factory configuration with implicit binding is dynamic
+        ConfigurationImpl config = configurationManager.createFactoryConfiguration( factoryPid, null );
+        config.setDynamicBundleLocation( this.getBundle().getLocation(), false );
         return this.wrap( config );
     }
 
@@ -114,7 +115,10 @@ public class ConfigurationAdminImpl impl
         ConfigurationImpl config = configurationManager.getConfiguration( pid );
         if ( config == null )
         {
-            config = configurationManager.createConfiguration( pid, getBundle().getLocation() );
+            config = configurationManager.createConfiguration( pid, null );
+
+            // FELIX-3360: configuration creation with implicit binding is dynamic
+            config.setDynamicBundleLocation( getBundle().getLocation(), false );
         }
         else
         {
@@ -125,7 +129,8 @@ public class ConfigurationAdminImpl impl
                         { config.getPid(), config.isNew() ? Boolean.TRUE : Boolean.FALSE,
                             this.getBundle().getLocation() } );
 
-                config.setStaticBundleLocation( this.getBundle().getLocation() );
+                // FELIX-3360: first implicit binding is dynamic
+                config.setDynamicBundleLocation( getBundle().getLocation(), true );
             }
             else
             {

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=1513740&r1=1513739&r2=1513740&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 Aug 14 06:50:11 2013
@@ -258,14 +258,10 @@ public class ConfigurationImpl extends C
         this.staticBundleLocation = bundleLocation;
         storeSilently();
 
-        // check whether the dynamic bundle location is different from the
-        // static now. If so, the dynamic bundle location has to be
-        // removed.
-        if ( bundleLocation != null && getDynamicBundleLocation() != null
-            && !bundleLocation.equals( getDynamicBundleLocation() ) )
-        {
-            setDynamicBundleLocation( null, false );
-        }
+        // FELIX-3360: Always clear dynamic binding if a new static
+        // location is set. The static location is the relevant binding
+        // for a configuration unless it is not explicitly set.
+        setDynamicBundleLocation( null, false );
 
         // CM 1.4
         this.getConfigurationManager().locationChanged( this, oldBundleLocation );
@@ -295,7 +291,7 @@ public class ConfigurationImpl extends C
      * the case of this configuration to be dynamically bound a
      * <code>CM_LOCATION_CHANGED</code> event is dispatched.
      */
-    boolean tryBindLocation( final String bundleLocation )
+    void tryBindLocation( final String bundleLocation )
     {
         if ( this.getBundleLocation() == null )
         {
@@ -303,8 +299,6 @@ public class ConfigurationImpl extends C
                 { getPidString(), bundleLocation } );
             setDynamicBundleLocation( bundleLocation, true );
         }
-
-        return true;
     }
 
 

Modified: felix/trunk/configadmin/src/test/java/org/apache/felix/cm/integration/ConfigurationBindingTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/configadmin/src/test/java/org/apache/felix/cm/integration/ConfigurationBindingTest.java?rev=1513740&r1=1513739&r2=1513740&view=diff
==============================================================================
--- felix/trunk/configadmin/src/test/java/org/apache/felix/cm/integration/ConfigurationBindingTest.java (original)
+++ felix/trunk/configadmin/src/test/java/org/apache/felix/cm/integration/ConfigurationBindingTest.java Wed Aug 14 06:50:11 2013
@@ -32,8 +32,10 @@ import org.junit.runner.RunWith;
 import org.ops4j.pax.exam.junit.JUnit4TestRunner;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleException;
+import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
 import org.osgi.service.cm.ConfigurationEvent;
 import org.osgi.service.cm.ConfigurationListener;
 
@@ -1003,6 +1005,127 @@ public class ConfigurationBindingTest ex
         configListener.assertEvents( ConfigurationEvent.CM_LOCATION_CHANGED, 0 );
     }
 
+    /**
+     * Tests configuration dynamic binding. See FELIX-3360.
+     */
+    @SuppressWarnings({ "serial", "javadoc" })
+    @Test
+    public void test_dynamic_binding_getConfiguration_pid() throws BundleException, IOException {
+        String ignoredPid = "test_dynamic_binding_getConfiguration_pid_ignored";
+        String pid1 = "test_dynamic_binding_getConfiguration_pid_1";
+        String pid2 = "test_dynamic_binding_getConfiguration_pid_2";
+
+        // ensure configuration is unbound
+        configure( pid1 );
+        delay();
+        configListener.assertEvents( ConfigurationEvent.CM_UPDATED, 1 );
+
+        bundle = installBundle( ignoredPid );
+        bundle.start();
+        delay();
+
+        // ensure config1 unbound
+        Configuration config1 = getConfiguration( pid1 );
+        TestCase.assertNull( config1.getBundleLocation() );
+
+        ServiceReference<ConfigurationAdmin> sr = bundle.getBundleContext().getServiceReference( ConfigurationAdmin.class );
+        ConfigurationAdmin bundleCa = bundle.getBundleContext().getService( sr );
+
+        // ensure dynamic binding
+        Configuration bundleConfig1 = bundleCa.getConfiguration( pid1 );
+        TestCase.assertEquals( bundle.getLocation(), bundleConfig1.getBundleLocation() );
+        delay();
+        configListener.assertEvents( ConfigurationEvent.CM_LOCATION_CHANGED, 1 );
+
+        // create config2; ensure dynamic binding
+        Configuration bundleConfig2 = bundleCa.getConfiguration( pid2 );
+        TestCase.assertNull(bundleConfig2.getProperties());
+        TestCase.assertEquals( bundle.getLocation(), bundleConfig2.getBundleLocation() );
+        bundleConfig2.update( new Hashtable<String, String>()
+        {
+            {
+                put( "key", "value" );
+            }
+        } );
+
+        // uninstall the bundle, 2 dynamic locations changed
+        bundle.uninstall();
+        bundle = null;
+        delay();
+        configListener.assertEvents( ConfigurationEvent.CM_LOCATION_CHANGED, 2 );
+
+        bundleConfig1 = getConfiguration( pid1 );
+        TestCase.assertNull( bundleConfig1.getBundleLocation() );
+
+        bundleConfig2 = getConfiguration( pid2 );
+        TestCase.assertNull(bundleConfig2.getBundleLocation());
+
+        bundleConfig1.delete();
+        bundleConfig2.delete();
+    }
+
+    /**
+     * Tests factory configuration dynamic binding. See FELIX-3360.
+     */
+    @SuppressWarnings({ "javadoc", "serial" })
+    @Test
+    public void test_dynamic_binding_createFactoryConfiguration_pid() throws BundleException, IOException {
+        String ignoredPid = "test_dynamic_binding_createFactoryConfiguration_pid_ignored";
+        String pid1 = null;
+        String pid2 = null;
+        String factoryPid1 = "test_dynamic_binding_createFactoryConfiguration_pid_1";
+        String factoryPid2 = "test_dynamic_binding_createFactoryConfiguration_pid_2";
+
+        // ensure configuration is unbound
+        pid1 = createFactoryConfiguration( factoryPid1 ).getPid();
+        delay();
+        configListener.assertEvents( ConfigurationEvent.CM_UPDATED, 1 );
+
+        bundle = installBundle( ignoredPid );
+        bundle.start();
+        delay();
+
+        // ensure config1 unbound
+        Configuration config1 = getConfiguration( pid1 );
+        TestCase.assertNull( config1.getBundleLocation() );
+
+        ServiceReference<ConfigurationAdmin> sr = bundle.getBundleContext().getServiceReference( ConfigurationAdmin.class );
+        ConfigurationAdmin bundleCa = bundle.getBundleContext().getService( sr );
+
+        // ensure dynamic binding
+        Configuration bundleConfig1 = bundleCa.getConfiguration( pid1 );
+        TestCase.assertEquals( bundle.getLocation(), bundleConfig1.getBundleLocation() );
+        delay();
+        configListener.assertEvents( ConfigurationEvent.CM_LOCATION_CHANGED, 1 );
+
+        // create config2; ensure dynamic binding
+        Configuration bundleConfig2 = bundleCa.createFactoryConfiguration( factoryPid2 );
+        pid2 = bundleConfig2.getPid();
+        TestCase.assertNull(bundleConfig2.getProperties());
+        TestCase.assertEquals( bundle.getLocation(), bundleConfig2.getBundleLocation() );
+        bundleConfig2.update( new Hashtable<String, String>()
+        {
+            {
+                put( "key", "value" );
+            }
+        } );
+
+        // uninstall the bundle, 2 dynamic locations changed
+        bundle.uninstall();
+        bundle = null;
+        delay();
+        configListener.assertEvents( ConfigurationEvent.CM_LOCATION_CHANGED, 2 );
+
+        bundleConfig1 = getConfiguration( pid1 );
+        TestCase.assertNull( bundleConfig1.getBundleLocation() );
+
+        bundleConfig2 = getConfiguration( pid2 );
+        TestCase.assertNull(bundleConfig2.getBundleLocation());
+
+        bundleConfig1.delete();
+        bundleConfig2.delete();
+    }
+
     private static class ConfigListener implements ConfigurationListener {
 
         private int[] events = new int[3];
@@ -1018,5 +1141,14 @@ public class ConfigurationBindingTest ex
             TestCase.assertEquals( "Events of type " + type, numEvents, events[type - 1] );
             events[type - 1] = 0;
         }
+
+
+        void reset()
+        {
+            for ( int i = 0; i < events.length; i++ )
+            {
+                events[i] = 0;
+            }
+        }
     }
 }