You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cz...@apache.org on 2017/02/01 11:01:35 UTC

svn commit: r1781220 - in /felix/trunk/osgi-r7/configadmin: pom.xml src/main/java/org/apache/felix/cm/impl/Activator.java src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java src/main/java/org/apache/felix/cm/impl/CoordinatorUtil.java

Author: cziegeler
Date: Wed Feb  1 11:01:35 2017
New Revision: 1781220

URL: http://svn.apache.org/viewvc?rev=1781220&view=rev
Log:
FELIX-5351 : 5.7 Coordinations

Added:
    felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/CoordinatorUtil.java   (with props)
Modified:
    felix/trunk/osgi-r7/configadmin/pom.xml
    felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/Activator.java
    felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java

Modified: felix/trunk/osgi-r7/configadmin/pom.xml
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/configadmin/pom.xml?rev=1781220&r1=1781219&r2=1781220&view=diff
==============================================================================
--- felix/trunk/osgi-r7/configadmin/pom.xml (original)
+++ felix/trunk/osgi-r7/configadmin/pom.xml Wed Feb  1 11:01:35 2017
@@ -96,6 +96,12 @@
             <version>1.3.0</version>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.service.coordinator</artifactId>
+            <version>1.0.2</version>
+            <scope>provided</scope>
+        </dependency>
         
         <!-- Integration Testing with Pax Exam -->
         <dependency>
@@ -178,16 +184,17 @@
                             <!-- when the spec version changes, update the service property that includes the spec version in ConfigurationManager -->
                             org.apache.felix.cm;
                             org.apache.felix.cm.file,
-                            org.osgi.service.cm;provide:=true;version=1.6
+                            org.osgi.service.cm;provide:=true
                         </Export-Package>
                         <Import-Package>
-                            org.osgi.service.cm;version="[1.6,1.7)",
-							org.osgi.service.log;resolution:=optional;version="1.3",
+                            org.osgi.service.cm,
+                            org.osgi.service.coordinator;resolution:=optional,
+							org.osgi.service.log;resolution:=optional,
                             *
                         </Import-Package>
                         <DynamicImport-Package>
-                            <!-- overwrite version from compendium bundle -->
-                            org.osgi.service.log;version="1.3"
+                            org.osgi.service.coordinator;version="[1.0,2)",                            
+                            org.osgi.service.log;version="[1.3,2)",
                         </DynamicImport-Package>
                         <Provide-Capability><![CDATA[
                             osgi.service;objectClass:List<String>="org.osgi.service.cm.ConfigurationAdmin";uses:="org.osgi.service.cm,org.apache.felix.cm",

Modified: felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/Activator.java
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/Activator.java?rev=1781220&r1=1781219&r2=1781220&view=diff
==============================================================================
--- felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/Activator.java (original)
+++ felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/Activator.java Wed Feb  1 11:01:35 2017
@@ -21,6 +21,8 @@ package org.apache.felix.cm.impl;
 import java.io.IOException;
 import java.util.Dictionary;
 import java.util.Hashtable;
+import java.util.SortedMap;
+import java.util.TreeMap;
 
 import org.apache.felix.cm.PersistenceManager;
 import org.apache.felix.cm.file.FilePersistenceManager;
@@ -31,6 +33,8 @@ import org.osgi.framework.ServiceReferen
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.cm.ConfigurationAdmin;
 import org.osgi.service.log.LogService;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
 
 /**
  * Activator for the configuration admin implementation.
@@ -64,6 +68,11 @@ public class Activator implements Bundle
     // the service registration of the default file persistence manager
     private volatile ServiceRegistration<PersistenceManager> filepmRegistration;
 
+    // service tracker for optional coordinator
+    @SuppressWarnings("rawtypes")
+    private volatile ServiceTracker coordinatorTracker;
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
     @Override
     public void start( final BundleContext bundleContext )
     {
@@ -95,8 +104,58 @@ public class Activator implements Bundle
             Log.logger.log( LogService.LOG_ERROR, "Cannot create the FilePersistenceManager", iae );
         }
 
-        // start configuration manager implementation
         this.manager = new ConfigurationManager();
+        // start coordinator tracker
+        coordinatorTracker = new ServiceTracker(bundleContext, "org.osgi.service.coordinator.Coordinator",
+                new ServiceTrackerCustomizer()
+        {
+            private final SortedMap<ServiceReference, Object> sortedServices = new TreeMap<ServiceReference, Object>();
+
+            @Override
+            public Object addingService(final ServiceReference reference)
+            {
+                final Object srv = bundleContext.getService(reference);
+                if ( srv != null )
+                {
+                    synchronized ( this.sortedServices )
+                    {
+                        sortedServices.put(reference, srv);
+                        manager.setCoordinator(sortedServices.get(sortedServices.lastKey()));
+                    }
+                }
+                return srv;
+            }
+
+            @Override
+            public void modifiedService(final ServiceReference reference, final Object srv) {
+                synchronized ( this.sortedServices )
+                {
+                    // update the map, service ranking might have changed
+                    sortedServices.remove(reference);
+                    sortedServices.put(reference, srv);
+                    manager.setCoordinator(sortedServices.get(sortedServices.lastKey()));
+                }
+            }
+
+            @Override
+            public void removedService(final ServiceReference reference, final Object service) {
+                synchronized ( this.sortedServices )
+                {
+                    sortedServices.remove(reference);
+                    if ( sortedServices.isEmpty() )
+                    {
+                        manager.setCoordinator(null);
+                    }
+                    else
+                    {
+                        manager.setCoordinator(sortedServices.get(sortedServices.lastKey()));
+                    }
+                }
+                bundleContext.ungetService(reference);
+            }
+        });
+        coordinatorTracker.open();
+        // start configuration manager implementation
         final ServiceReference<ConfigurationAdmin> ref = this.manager.start(dynamicBindings, bundleContext);
 
         // update log
@@ -109,12 +168,21 @@ public class Activator implements Bundle
     {
         // stop logger
         Log.logger.stop();
+
+        // stop configuration manager implementation
         if ( this.manager != null )
         {
             this.manager.stop(bundleContext);
             this.manager = null;
         }
 
+        // stop coordinator tracker
+        if ( this.coordinatorTracker != null )
+        {
+            this.coordinatorTracker.close();
+            this.coordinatorTracker = null;
+        }
+
         // shutdown the file persistence manager
         if ( filepmRegistration != null )
         {

Modified: felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java?rev=1781220&r1=1781219&r2=1781220&view=diff
==============================================================================
--- felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java (original)
+++ felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java Wed Feb  1 11:01:35 2017
@@ -156,6 +156,9 @@ public class ConfigurationManager implem
     // flag indicating whether the manager is considered alive
     private volatile boolean isActive;
 
+    // Coordinator service if available
+    private volatile Object coordinator;
+
     public ServiceReference<ConfigurationAdmin> start( final DynamicBindings dynBin, BundleContext bundleContext )
     {
         // set up some fields
@@ -166,7 +169,7 @@ public class ConfigurationManager implem
         configurationListenerTracker = new ServiceTracker<ConfigurationListener, ConfigurationListener>( bundleContext, ConfigurationListener.class, null );
         configurationListenerTracker.open();
         syncConfigurationListenerTracker = new ServiceTracker<SynchronousConfigurationListener, SynchronousConfigurationListener>( bundleContext,
-            SynchronousConfigurationListener.class, null );
+                SynchronousConfigurationListener.class, null );
         syncConfigurationListenerTracker.open();
 
         // initialize the asynchonous updater thread
@@ -306,7 +309,7 @@ public class ConfigurationManager implem
         synchronized ( configurations )
         {
             return configurations.values().toArray(
-                new ConfigurationImpl[configurations.size()] );
+                    new ConfigurationImpl[configurations.size()] );
         }
     }
 
@@ -377,7 +380,7 @@ public class ConfigurationManager implem
             catch ( IOException ioe )
             {
                 Log.logger.log( LogService.LOG_ERROR, "Failed storing dynamic configuration binding for {0} to {1}", new Object[]
-                    { pid, location, ioe } );
+                        { pid, location, ioe } );
             }
         }
     }
@@ -447,19 +450,19 @@ public class ConfigurationManager implem
                     // CM 1.4 / 104.13.2.2 / 104.5.3
                     // act as if there is no configuration
                     Log.logger.log(
-                        LogService.LOG_DEBUG,
-                        "Cannot use configuration {0} for {1}: No visibility to configuration bound to {2}; calling with null",
-                        new Object[]
-                            { config.getPid(), target , config.getBundleLocation() } );
+                            LogService.LOG_DEBUG,
+                            "Cannot use configuration {0} for {1}: No visibility to configuration bound to {2}; calling with null",
+                            new Object[]
+                                    { config.getPid(), target , config.getBundleLocation() } );
                 }
             }
         }
         else
         {
             Log.logger.log( LogService.LOG_INFO,
-                "Service for PID {0} seems to already have been unregistered, not updating with configuration",
-                new Object[]
-                    { rawPid } );
+                    "Service for PID {0} seems to already have been unregistered, not updating with configuration",
+                    new Object[]
+                            { rawPid } );
         }
 
         // service already unregistered, nothing to do really
@@ -483,7 +486,7 @@ public class ConfigurationManager implem
         if ( config != null )
         {
             Log.logger.log( LogService.LOG_DEBUG, "Found cached configuration {0} bound to {1}", new Object[]
-                { pid, config.getBundleLocation() } );
+                    { pid, config.getBundleLocation() } );
 
             config.ensureFactoryConfigPersisted();
 
@@ -498,7 +501,7 @@ public class ConfigurationManager implem
                 Dictionary props = pmList[i].load( pid );
                 config = new ConfigurationImpl( this, pmList[i], props );
                 Log.logger.log( LogService.LOG_DEBUG, "Found existing configuration {0} bound to {1}", new Object[]
-                    { pid, config.getBundleLocation() } );
+                        { pid, config.getBundleLocation() } );
                 return cacheConfiguration( config );
             }
         }
@@ -541,7 +544,7 @@ public class ConfigurationManager implem
 
 
     ConfigurationImpl[] listConfigurations( ConfigurationAdminImpl configurationAdmin, String filterString )
-        throws IOException, InvalidSyntaxException
+            throws IOException, InvalidSyntaxException
     {
         SimpleFilter filter = null;
         if ( filterString != null )
@@ -550,7 +553,7 @@ public class ConfigurationManager implem
         }
 
         Log.logger.log( LogService.LOG_DEBUG, "Listing configurations matching {0}", new Object[]
-            { filterString } );
+                { filterString } );
 
         List<ConfigurationImpl> configList = new ArrayList<ConfigurationImpl>();
 
@@ -569,14 +572,14 @@ public class ConfigurationManager implem
 
                 // CM 1.4 / 104.13.2.3 Permission required
                 if ( !configurationAdmin.hasPermission( this,
-                    ( String ) config.get( ConfigurationAdmin.SERVICE_BUNDLELOCATION ) ) )
+                        ( String ) config.get( ConfigurationAdmin.SERVICE_BUNDLELOCATION ) ) )
                 {
                     Log.logger.log(
-                        LogService.LOG_DEBUG,
-                        "Omitting configuration {0}: No permission for bundle {1} on configuration bound to {2}",
-                        new Object[]
-                            { pid, configurationAdmin.getBundle().getLocation(),
-                                config.get( ConfigurationAdmin.SERVICE_BUNDLELOCATION ) } );
+                            LogService.LOG_DEBUG,
+                            "Omitting configuration {0}: No permission for bundle {1} on configuration bound to {2}",
+                            new Object[]
+                                    { pid, configurationAdmin.getBundle().getLocation(),
+                                            config.get( ConfigurationAdmin.SERVICE_BUNDLELOCATION ) } );
                     continue;
                 }
 
@@ -598,13 +601,13 @@ public class ConfigurationManager implem
                 if ( !cfg.isNew() )
                 {
                     Log.logger.log( LogService.LOG_DEBUG, "Adding configuration {0}", new Object[]
-                        { pid } );
+                            { pid } );
                     configList.add( cfg );
                 }
                 else
                 {
                     Log.logger.log( LogService.LOG_DEBUG, "Omitting configuration {0}: Is new", new Object[]
-                        { pid } );
+                            { pid } );
                 }
             }
         }
@@ -614,7 +617,7 @@ public class ConfigurationManager implem
             return null;
         }
         return configList.toArray( new ConfigurationImpl[configList
-            .size()] );
+                                                         .size()] );
     }
 
 
@@ -623,9 +626,13 @@ public class ConfigurationManager implem
         // remove the configuration from the cache
         removeConfiguration( config );
         fireConfigurationEvent( ConfigurationEvent.CM_DELETED, config.getPidString(), config.getFactoryPidString() );
-        updateThread.schedule( new DeleteConfiguration( config ) );
+        final Runnable task = new DeleteConfiguration( config );
+        if ( this.coordinator == null || !CoordinatorUtil.addToCoordination(this.coordinator, updateThread, task) )
+        {
+            updateThread.schedule( task );
+        }
         Log.logger.log( LogService.LOG_DEBUG, "DeleteConfiguration({0}) scheduled", new Object[]
-            { config.getPid() } );
+                { config.getPid() } );
     }
 
 
@@ -635,9 +642,13 @@ public class ConfigurationManager implem
         {
             fireConfigurationEvent( ConfigurationEvent.CM_UPDATED, config.getPidString(), config.getFactoryPidString() );
         }
-        updateThread.schedule( new UpdateConfiguration( config ) );
+        final Runnable task = new UpdateConfiguration( config );
+        if ( this.coordinator == null || !CoordinatorUtil.addToCoordination(this.coordinator, updateThread, task) )
+        {
+            updateThread.schedule( task );
+        }
         Log.logger.log( LogService.LOG_DEBUG, "UpdateConfiguration({0}) scheduled", new Object[]
-            { config.getPid() } );
+                { config.getPid() } );
     }
 
 
@@ -646,15 +657,19 @@ public class ConfigurationManager implem
         fireConfigurationEvent( ConfigurationEvent.CM_LOCATION_CHANGED, config.getPidString(), config.getFactoryPidString() );
         if ( oldLocation != null && !config.isNew() )
         {
-            updateThread.schedule( new LocationChanged( config, oldLocation ) );
+            final Runnable task = new LocationChanged( config, oldLocation );
+            if ( this.coordinator == null || !CoordinatorUtil.addToCoordination(this.coordinator, updateThread, task) )
+            {
+                updateThread.schedule( task );
+            }
             Log.logger.log( LogService.LOG_DEBUG, "LocationChanged({0}, {1}=>{2}) scheduled", new Object[]
-                { config.getPid(), oldLocation, config.getBundleLocation() } );
+                    { config.getPid(), oldLocation, config.getBundleLocation() } );
         }
         else
         {
             Log.logger.log( LogService.LOG_DEBUG,
-                "LocationChanged not scheduled for {0} (old location is null or configuration is new)", new Object[]
-                    { config.getPid() } );
+                    "LocationChanged not scheduled for {0} (old location is null or configuration is new)", new Object[]
+                            { config.getPid() } );
         }
     }
 
@@ -663,9 +678,9 @@ public class ConfigurationManager implem
     {
         // prevent event senders
         FireConfigurationEvent asyncSender = new FireConfigurationEvent( this.configurationListenerTracker, type, pid,
-            factoryPid );
+                factoryPid );
         FireConfigurationEvent syncSender = new FireConfigurationEvent( this.syncConfigurationListenerTracker, type,
-            pid, factoryPid );
+                pid, factoryPid );
 
         // send synchronous events
         if ( syncSender.hasConfigurationEventListeners() )
@@ -675,18 +690,21 @@ public class ConfigurationManager implem
         else
         {
             Log.logger.log( LogService.LOG_DEBUG, "No SynchronousConfigurationListeners to send {0} event to.", new Object[]
-                { syncSender.getTypeName() } );
+                    { syncSender.getTypeName() } );
         }
 
         // schedule asynchronous events
         if ( asyncSender.hasConfigurationEventListeners() )
         {
-            eventThread.schedule( asyncSender );
+            if ( this.coordinator == null || !CoordinatorUtil.addToCoordination(this.coordinator, updateThread, asyncSender) )
+            {
+                eventThread.schedule( asyncSender );
+            }
         }
         else
         {
             Log.logger.log( LogService.LOG_DEBUG, "No ConfigurationListeners to send {0} event to.", new Object[]
-                { asyncSender.getTypeName() } );
+                    { asyncSender.getTypeName() } );
         }
     }
 
@@ -832,7 +850,7 @@ public class ConfigurationManager implem
         if ( Log.logger.isLogEnabled( LogService.LOG_DEBUG ) )
         {
             Log.logger.log( LogService.LOG_DEBUG, "configure(ManagedService {0})", new Object[]
-                { sr } );
+                    { sr } );
         }
 
         Runnable r;
@@ -844,9 +862,12 @@ public class ConfigurationManager implem
         {
             r = new ManagedServiceUpdate( pid, sr, configs );
         }
-        updateThread.schedule( r );
+        if ( this.coordinator == null || !CoordinatorUtil.addToCoordination(this.coordinator, updateThread, r) )
+        {
+            updateThread.schedule( r );
+        }
         Log.logger.log( LogService.LOG_DEBUG, "[{0}] scheduled", new Object[]
-            { r } );
+                { r } );
     }
 
 
@@ -875,7 +896,7 @@ public class ConfigurationManager implem
     ConfigurationImpl createConfiguration( String pid, String factoryPid, String bundleLocation ) throws IOException
     {
         Log.logger.log( LogService.LOG_DEBUG, "createConfiguration({0}, {1}, {2})", new Object[]
-            { pid, factoryPid, bundleLocation } );
+                { pid, factoryPid, bundleLocation } );
         return new ConfigurationImpl( this, getPersistenceManagers()[0], pid, factoryPid, bundleLocation );
     }
 
@@ -1022,7 +1043,7 @@ public class ConfigurationManager implem
      *          only for a factory configuration.
      */
     public void callPlugins( final Dictionary<String, Object> props, final ServiceReference<?> sr, final String configPid,
-        final String factoryPid )
+            final String factoryPid )
     {
         ServiceReference<?>[] plugins = null;
         try
@@ -1071,7 +1092,7 @@ public class ConfigurationManager implem
                 catch ( Throwable t )
                 {
                     Log.logger.log( LogService.LOG_ERROR, "Unexpected problem calling configuration plugin {0}", new Object[]
-                        { pluginRef , t } );
+                            { pluginRef , t } );
                 }
                 finally
                 {
@@ -1158,7 +1179,7 @@ public class ConfigurationManager implem
         if ( location == null )
         {
             Log.logger.log( LogService.LOG_DEBUG, "canReceive=true; bundle={0}; configuration=(unbound)", new Object[]
-                { bundle.getLocation() } );
+                    { bundle.getLocation() } );
             return true;
         }
         else if ( location.startsWith( "?" ) )
@@ -1167,16 +1188,16 @@ public class ConfigurationManager implem
             if ( System.getSecurityManager() != null )
             {
                 final boolean hasPermission = bundle.hasPermission( new ConfigurationPermission( location,
-                    ConfigurationPermission.TARGET ) );
+                        ConfigurationPermission.TARGET ) );
                 Log.logger.log( LogService.LOG_DEBUG, "canReceive={0}: bundle={1}; configuration={2} (SecurityManager check)",
-                    new Object[]
-                        { new Boolean( hasPermission ), bundle.getLocation(), location } );
+                        new Object[]
+                                { new Boolean( hasPermission ), bundle.getLocation(), location } );
                 return hasPermission;
             }
 
             Log.logger.log( LogService.LOG_DEBUG, "canReceive=true; bundle={0}; configuration={1} (no SecurityManager)",
-                new Object[]
-                    { bundle.getLocation(), location } );
+                    new Object[]
+                            { bundle.getLocation(), location } );
             return true;
         }
         else
@@ -1184,7 +1205,7 @@ public class ConfigurationManager implem
             // single location, must match
             final boolean hasPermission = location.equals( bundle.getLocation() );
             Log.logger.log( LogService.LOG_DEBUG, "canReceive={0}: bundle={1}; configuration={2}", new Object[]
-                { new Boolean( hasPermission ), bundle.getLocation(), location } );
+                    { new Boolean( hasPermission ), bundle.getLocation(), location } );
             return hasPermission;
         }
     }
@@ -1228,13 +1249,13 @@ public class ConfigurationManager implem
                 catch ( IOException ioe )
                 {
                     Log.logger.log( LogService.LOG_ERROR, "Error loading configuration for {0}", new Object[]
-                        { pid, ioe } );
+                            { pid, ioe } );
                 }
                 catch ( Exception e )
                 {
                     Log.logger.log( LogService.LOG_ERROR, "Unexpected problem providing configuration {0} to service {1}",
-                        new Object[]
-                            { pid, this.sr, e } );
+                            new Object[]
+                                    { pid, this.sr, e } );
                 }
             }
         }
@@ -1265,7 +1286,7 @@ public class ConfigurationManager implem
             }
 
             Log.logger.log( LogService.LOG_DEBUG, "Updating service {0} with configuration {1}@{2}", new Object[]
-                { servicePid, configPid, new Long( revision ) } );
+                    { servicePid, configPid, new Long( revision ) } );
 
             managedServiceTracker.provideConfiguration( sr, configPid, null, properties, revision, this.configs );
         }
@@ -1325,7 +1346,7 @@ public class ConfigurationManager implem
                                 catch ( IOException ioe )
                                 {
                                     Log.logger.log( LogService.LOG_ERROR, "Error loading configuration for {0}", new Object[]
-                                        { pid, ioe } );
+                                            { pid, ioe } );
                                     continue;
                                 }
 
@@ -1333,8 +1354,8 @@ public class ConfigurationManager implem
                                 if ( cfg == null )
                                 {
                                     Log.logger.log( LogService.LOG_ERROR,
-                                        "Configuration {0} referred to by factory {1} does not exist", new Object[]
-                                            { pid, factoryPid } );
+                                            "Configuration {0} referred to by factory {1} does not exist", new Object[]
+                                                    { pid, factoryPid } );
                                     factory.removePID( pid );
                                     factory.storeSilently();
                                     continue;
@@ -1348,7 +1369,7 @@ public class ConfigurationManager implem
                                     // this should not happen. We keep this for added stability
                                     // but raise the logging level to error.
                                     Log.logger.log( LogService.LOG_ERROR, "Ignoring new configuration pid={0}", new Object[]
-                                        { pid } );
+                                            { pid } );
                                     continue;
                                 }
 
@@ -1368,7 +1389,7 @@ public class ConfigurationManager implem
                                     factory.storeSilently();
                                     continue;
                                 }
-                                */
+                                 */
 
                                 provide( factoryPid, cfg );
                             }
@@ -1378,7 +1399,7 @@ public class ConfigurationManager implem
                 catch ( IOException ioe )
                 {
                     Log.logger.log( LogService.LOG_ERROR, "Cannot get factory mapping for factory PID {0}", new Object[]
-                        { factoryPid, ioe } );
+                            { factoryPid, ioe } );
                 }
             }
         }
@@ -1395,26 +1416,26 @@ public class ConfigurationManager implem
             }
 
             Log.logger.log( LogService.LOG_DEBUG, "Updating service {0} with configuration {1}/{2}@{3}", new Object[]
-                { factoryPid, config.getFactoryPid(), config.getPid(), new Long( revision ) } );
+                    { factoryPid, config.getFactoryPid(), config.getPid(), new Long( revision ) } );
 
             // CM 1.4 / 104.13.2.1
             final Bundle serviceBundle = this.sr.getBundle();
             if ( serviceBundle == null )
             {
                 Log.logger.log(
-                    LogService.LOG_INFO,
-                    "ManagedServiceFactory for factory PID {0} seems to already have been unregistered, not updating with factory",
-                    new Object[]
-                        { factoryPid } );
+                        LogService.LOG_INFO,
+                        "ManagedServiceFactory for factory PID {0} seems to already have been unregistered, not updating with factory",
+                        new Object[]
+                                { factoryPid } );
                 return;
             }
 
             if ( !canReceive( serviceBundle, config.getBundleLocation() ) )
             {
                 Log.logger.log( LogService.LOG_ERROR,
-                    "Cannot use configuration {0} for {1}: No visibility to configuration bound to {2}",
-                    new Object[]
-                        { config.getPid(), sr , config.getBundleLocation() } );
+                        "Cannot use configuration {0} for {1}: No visibility to configuration bound to {2}",
+                        new Object[]
+                                { config.getPid(), sr , config.getBundleLocation() } );
 
                 // no service, really, bail out
                 return;
@@ -1427,9 +1448,9 @@ public class ConfigurationManager implem
             if ( rawProperties != null )
             {
                 Log.logger.log( LogService.LOG_DEBUG, "{0}: Updating configuration pid={1}", new Object[]
-                    { sr, config.getPid() } );
+                        { sr, config.getPid() } );
                 managedServiceFactoryTracker.provideConfiguration( sr, config.getPid(), config.getFactoryPid(),
-                    rawProperties, revision, this.configs );
+                        rawProperties, revision, this.configs );
             }
         }
 
@@ -1477,7 +1498,7 @@ public class ConfigurationManager implem
             if ( this.helper == null )
             {
                 this.helper = ( BaseTracker<T> ) ( ( this.config.getFactoryPid() == null ) ? ConfigurationManager.this.managedServiceTracker
-                    : ConfigurationManager.this.managedServiceFactoryTracker );
+                        : ConfigurationManager.this.managedServiceFactoryTracker );
             }
             return this.helper;
         }
@@ -1514,13 +1535,13 @@ public class ConfigurationManager implem
                 catch ( IOException ioe )
                 {
                     Log.logger.log( LogService.LOG_ERROR, "Error loading configuration for {0}", new Object[]
-                        { this.config.getPid(), ioe } );
+                            { this.config.getPid(), ioe } );
                 }
                 catch ( Exception e )
                 {
                     Log.logger.log( LogService.LOG_ERROR, "Unexpected problem providing configuration {0} to service {1}",
-                        new Object[]
-                            { this.config.getPid(), sr, e } );
+                            new Object[]
+                                    { this.config.getPid(), sr, e } );
                 }
             }
 
@@ -1548,7 +1569,7 @@ public class ConfigurationManager implem
         public void run()
         {
             Log.logger.log( LogService.LOG_DEBUG, "Updating configuration {0} to revision #{1}", new Object[]
-                { config.getPid(), new Long( revision ) } );
+                    { config.getPid(), new Long( revision ) } );
 
             final List<ServiceReference<?>> srList = this.getHelper().getServices( getTargetedServicePid() );
             if ( !srList.isEmpty() )
@@ -1557,9 +1578,9 @@ public class ConfigurationManager implem
                 Bundle bundle = srList.get(0).getBundle();
                 if (bundle == null) {
                     Log.logger.log( LogService.LOG_DEBUG,
-                        "Service {0} seems to be unregistered concurrently (not providing configuration)",
-                        new Object[]
-                            { srList.get(0) } );
+                            "Service {0} seems to be unregistered concurrently (not providing configuration)",
+                            new Object[]
+                                    { srList.get(0) } );
                     return;
                 }
                 config.tryBindLocation( bundle.getLocation() );
@@ -1574,22 +1595,22 @@ public class ConfigurationManager implem
                     if ( refBundle == null )
                     {
                         Log.logger.log( LogService.LOG_DEBUG,
-                            "Service {0} seems to be unregistered concurrently (not providing configuration)",
-                            new Object[]
-                                { ref } );
+                                "Service {0} seems to be unregistered concurrently (not providing configuration)",
+                                new Object[]
+                                        { ref } );
                     }
                     else if ( canReceive( refBundle, configBundleLocation ) )
                     {
                         this.getHelper().provideConfiguration( ref, this.config.getPid(), this.config.getFactoryPid(),
-                            this.properties, this.revision, null );
+                                this.properties, this.revision, null );
                     }
                     else
                     {
                         // CM 1.4 / 104.13.2.2
                         Log.logger.log( LogService.LOG_ERROR,
-                            "Cannot use configuration {0} for {1}: No visibility to configuration bound to {2}",
-                            new Object[]
-                                { config.getPid(), ref, configBundleLocation } );
+                                "Cannot use configuration {0} for {1}: No visibility to configuration bound to {2}",
+                                new Object[]
+                                        { config.getPid(), ref, configBundleLocation } );
                     }
 
                 }
@@ -1597,8 +1618,8 @@ public class ConfigurationManager implem
             else if ( Log.logger.isLogEnabled( LogService.LOG_DEBUG ) )
             {
                 Log.logger.log( LogService.LOG_DEBUG, "No ManagedService[Factory] registered for updates to configuration {0}",
-                    new Object[]
-                        { config.getPid() } );
+                        new Object[]
+                                { config.getPid() } );
             }
         }
 
@@ -1646,9 +1667,9 @@ public class ConfigurationManager implem
                     if ( srBundle == null )
                     {
                         Log.logger.log( LogService.LOG_DEBUG,
-                            "Service {0} seems to be unregistered concurrently (not removing configuration)",
-                            new Object[]
-                                { sr } );
+                                "Service {0} seems to be unregistered concurrently (not removing configuration)",
+                                new Object[]
+                                        { sr } );
                     }
                     else if ( canReceive( srBundle, configLocation ) )
                     {
@@ -1663,9 +1684,9 @@ public class ConfigurationManager implem
                     {
                         // CM 1.4 / 104.13.2.2
                         Log.logger.log( LogService.LOG_ERROR,
-                            "Cannot remove configuration {0} for {1}: No visibility to configuration bound to {2}",
-                            new Object[]
-                                { config.getPid(), sr, configLocation } );
+                                "Cannot remove configuration {0} for {1}: No visibility to configuration bound to {2}",
+                                new Object[]
+                                        { config.getPid(), sr, configLocation } );
                     }
                 }
             }
@@ -1686,7 +1707,7 @@ public class ConfigurationManager implem
                 catch ( IOException ioe )
                 {
                     Log.logger.log( LogService.LOG_ERROR, "Failed removing {0} from the factory {1}", new Object[]
-                        { pid, factoryPid, ioe } );
+                            { pid, factoryPid, ioe } );
                 }
             }
         }
@@ -1722,8 +1743,8 @@ public class ConfigurationManager implem
                     if ( srBundle == null )
                     {
                         Log.logger.log( LogService.LOG_DEBUG,
-                            "Service {0} seems to be unregistered concurrently (not processing)", new Object[]
-                                { sr } );
+                                "Service {0} seems to be unregistered concurrently (not processing)", new Object[]
+                                        { sr } );
                         continue;
                     }
 
@@ -1745,23 +1766,23 @@ public class ConfigurationManager implem
                         {
                             this.getHelper().removeConfiguration( sr, this.config.getPid(), this.config.getFactoryPid() );
                             Log.logger.log( LogService.LOG_DEBUG, "Configuration {0} revoked from {1} (no more visibility)",
-                                new Object[]
-                                    { config.getPid(), sr } );
+                                    new Object[]
+                                            { config.getPid(), sr } );
                         }
                     }
                     else if ( !wasVisible && isVisible )
                     {
                         // call updated method
                         this.getHelper().provideConfiguration( sr, this.config.getPid(), this.config.getFactoryPid(),
-                            this.properties, this.revision, null );
+                                this.properties, this.revision, null );
                         Log.logger.log( LogService.LOG_DEBUG, "Configuration {0} provided to {1} (new visibility)", new Object[]
-                            { config.getPid(), sr } );
+                                { config.getPid(), sr } );
                     }
                     else
                     {
                         // same visibility as before
                         Log.logger.log( LogService.LOG_DEBUG, "Unmodified visibility to configuration {0} for {1}", new Object[]
-                            { config.getPid(), sr } );
+                                { config.getPid(), sr } );
                     }
                 }
             }
@@ -1772,7 +1793,7 @@ public class ConfigurationManager implem
         public String toString()
         {
             return "Location Changed (pid=" + config.getPid() + "): " + oldLocation + " ==> "
-                + config.getBundleLocation();
+                    + config.getBundleLocation();
         }
     }
 
@@ -1829,14 +1850,14 @@ public class ConfigurationManager implem
         {
             switch ( type )
             {
-                case ConfigurationEvent.CM_DELETED:
-                    return "CM_DELETED";
-                case ConfigurationEvent.CM_UPDATED:
-                    return "CM_UPDATED";
-                case ConfigurationEvent.CM_LOCATION_CHANGED:
-                    return "CM_LOCATION_CHANGED";
-                default:
-                    return "<UNKNOWN(" + type + ")>";
+            case ConfigurationEvent.CM_DELETED:
+                return "CM_DELETED";
+            case ConfigurationEvent.CM_UPDATED:
+                return "CM_UPDATED";
+            case ConfigurationEvent.CM_LOCATION_CHANGED:
+                return "CM_LOCATION_CHANGED";
+            default:
+                return "<UNKNOWN(" + type + ")>";
             }
         }
 
@@ -1874,7 +1895,7 @@ public class ConfigurationManager implem
                     && this.listeners[serviceIndex] != null )
             {
                 Log.logger.log( LogService.LOG_DEBUG, "Sending {0} event for {1} to {2}", new Object[]
-                    { getTypeName(), pid, listenerReferences[serviceIndex]} );
+                        { getTypeName(), pid, listenerReferences[serviceIndex]} );
 
                 try
                 {
@@ -1883,7 +1904,7 @@ public class ConfigurationManager implem
                 catch ( Throwable t )
                 {
                     Log.logger.log( LogService.LOG_ERROR, "Unexpected problem delivering configuration event to {0}", new Object[]
-                        { listenerReferences[serviceIndex], t } );
+                            { listenerReferences[serviceIndex], t } );
                 }
                 finally
                 {
@@ -1892,5 +1913,10 @@ public class ConfigurationManager implem
             }
         }
     }
+
+    public void setCoordinator(final Object service)
+    {
+        this.coordinator = service;
+    }
 }
 

Added: felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/CoordinatorUtil.java
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/CoordinatorUtil.java?rev=1781220&view=auto
==============================================================================
--- felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/CoordinatorUtil.java (added)
+++ felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/CoordinatorUtil.java Wed Feb  1 11:01:35 2017
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.felix.cm.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.osgi.service.coordinator.Coordination;
+import org.osgi.service.coordinator.Coordinator;
+import org.osgi.service.coordinator.Participant;
+
+/**
+ * Utility class for coordinations
+ */
+public class CoordinatorUtil
+{
+    public static final class Notifier implements Participant
+    {
+        private final List<Runnable> runnables = new ArrayList<Runnable>();
+
+        private final UpdateThread thread;
+
+        public Notifier(final UpdateThread t)
+        {
+            this.thread = t;
+        }
+
+        private void execute()
+        {
+            for(final Runnable r : runnables)
+            {
+                this.thread.schedule(r);
+            }
+            runnables.clear();
+        }
+
+        @Override
+        public void ended(Coordination coordination) throws Exception
+        {
+            execute();
+        }
+
+        @Override
+        public void failed(Coordination coordination) throws Exception
+        {
+            execute();
+        }
+
+        public void add(final Runnable t)
+        {
+            runnables.add(t);
+        }
+    }
+
+    public static boolean addToCoordination(final Object srv, final UpdateThread thread, final Runnable task)
+    {
+        final Coordinator coordinator = (Coordinator) srv;
+        Coordination c = coordinator.peek();
+        if ( c != null )
+        {
+            Notifier n = null;
+            for(final Participant p : c.getParticipants())
+            {
+                if ( p instanceof Notifier )
+                {
+                    n = (Notifier) p;
+                    break;
+                }
+            }
+            if ( n == null )
+            {
+                n = new Notifier(thread);
+            }
+            n.add(task);
+            return true;
+        }
+        return false;
+    }
+}

Propchange: felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/CoordinatorUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/CoordinatorUtil.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url