FELIX-1545 Added guards to ManagedService[Factory]Update to prevent multiple
updates and a guard to ManagedServiceUpdate to prevent setting the last update
field if no properties were provided to the ManagedService
Plus added some more DEBUG logging
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@809608 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java b/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java
index 57cbe77..78354c8 100644
--- a/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java
+++ b/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java
@@ -563,12 +563,14 @@
// remove the configuration from the cache
removeConfiguration( config );
updateThread.schedule( new DeleteConfiguration( config, true ) );
+ log( LogService.LOG_DEBUG, "DeleteConfiguration(" + config.getPid() + ") scheduled", null );
}
void updated( ConfigurationImpl config, boolean fireEvent )
{
updateThread.schedule( new UpdateConfiguration( config, fireEvent ) );
+ log( LogService.LOG_DEBUG, "UpdateConfiguration(" + config.getPid() + ") scheduled", null );
}
@@ -694,6 +696,7 @@
{
ManagedServiceUpdate update = new ManagedServiceUpdate( pids[i], sr, service );
updateThread.schedule( update );
+ log( LogService.LOG_DEBUG, "ManagedServiceUpdate(" + pids[i] + ") scheduled", null );
}
}
}
@@ -708,6 +711,7 @@
{
ManagedServiceFactoryUpdate update = new ManagedServiceFactoryUpdate( pids[i], sr, service );
updateThread.schedule( update );
+ log( LogService.LOG_DEBUG, "ManagedServiceFactoryUpdate(" + pids[i] + ") scheduled", null );
}
}
}
@@ -1029,6 +1033,8 @@
private final Dictionary rawProperties;
+ private final long lastModificationTime;
+
ManagedServiceUpdate( String pid, ServiceReference sr, ManagedService service )
{
this.pid = pid;
@@ -1038,11 +1044,17 @@
// get or load configuration for the pid
ConfigurationImpl config = null;
Dictionary rawProperties = null;
+ long lastModificationTime = -1;
try
{
config = getExistingConfiguration( pid );
- if (config != null) {
- rawProperties = config.getProperties( true );
+ if ( config != null )
+ {
+ synchronized ( config )
+ {
+ rawProperties = config.getProperties( true );
+ lastModificationTime = config.getLastModificationTime();
+ }
}
}
catch ( IOException ioe )
@@ -1052,15 +1064,30 @@
this.config = config;
this.rawProperties = rawProperties;
+ this.lastModificationTime = lastModificationTime;
}
public void run()
{
- // check configuration and call plugins if existing
+ // only update configuration if lastModificationTime is less than
+ // lastUpdateTime
Dictionary properties = rawProperties;
+ if ( properties != null && config != null && lastModificationTime <= config.getLastUpdatedTime()
+ && sr.equals( config.getServiceReference() ) )
+ {
+ log( LogService.LOG_DEBUG, "Configuration " + config.getPid() + " at modification #"
+ + config.getLastModificationTime() + " has already been updated to update #"
+ + config.getLastUpdatedTime() + ", nothing to be done anymore.", null );
+ return;
+ }
+
+ // check configuration and call plugins if existing
if ( config != null )
{
+ log( LogService.LOG_DEBUG, "Updating configuration " + config.getPid() + " to modification #"
+ + config.getLastModificationTime(), null );
+
Bundle serviceBundle = sr.getBundle();
if ( serviceBundle == null )
{
@@ -1117,9 +1144,11 @@
}
// update the lastUpdatedTime if there is configuration
- if ( config != null )
+ if ( config != null && properties != null )
{
config.setLastUpdatedTime();
+ log( LogService.LOG_DEBUG, "Updated configuration " + config.getPid() + " to update #"
+ + config.getLastUpdatedTime(), null );
}
}
@@ -1141,6 +1170,8 @@
private final Map configs;
+ private final Map stamps;
+
ManagedServiceFactoryUpdate( String factoryPid, ServiceReference sr, ManagedServiceFactory service )
{
this.factoryPid = factoryPid;
@@ -1149,11 +1180,13 @@
Factory factory = null;
Map configs = null;
+ Map stamps = null;
try
{
factory = getFactory( factoryPid );
if (factory != null) {
configs = new HashMap();
+ stamps = new HashMap();
for ( Iterator pi = factory.getPIDs().iterator(); pi.hasNext(); )
{
final String pid = ( String ) pi.next();
@@ -1198,7 +1231,11 @@
}
// get the configuration properties for later
- configs.put(cfg, cfg.getProperties( true ));
+ synchronized ( cfg )
+ {
+ configs.put( cfg, cfg.getProperties( true ) );
+ stamps.put( cfg, new Long( cfg.getLastModificationTime() ) );
+ }
}
}
}
@@ -1209,6 +1246,7 @@
this.factory = factory;
this.configs = configs;
+ this.stamps = stamps;
}
@@ -1238,6 +1276,18 @@
final Map.Entry entry = (Map.Entry) ci.next();
final ConfigurationImpl cfg = (ConfigurationImpl) entry.getKey();
final Dictionary properties = (Dictionary) entry.getValue();
+ final long lastModificationTime = ( ( Long ) stamps.get( cfg ) ).longValue();
+
+ if ( lastModificationTime <= cfg.getLastUpdatedTime() && sr.equals( cfg.getServiceReference() ) )
+ {
+ log( LogService.LOG_DEBUG, "Configuration " + cfg.getPid() + " at modification #"
+ + cfg.getLastModificationTime() + " has already been updated to update #"
+ + cfg.getLastUpdatedTime() + ", nothing to be done anymore.", null );
+ return;
+ }
+
+ log( LogService.LOG_DEBUG, "Updating configuration " + cfg.getPid() + " to modification #"
+ + cfg.getLastModificationTime(), null );
// check bundle location of configuration
if ( !cfg.tryBindLocation( serviceBundleLocation ) )
@@ -1285,6 +1335,8 @@
// update the lastUpdatedTime
cfg.setLastUpdatedTime();
+ log( LogService.LOG_DEBUG, "Updated configuration " + cfg.getPid() + " to update #"
+ + cfg.getLastUpdatedTime(), null );
}
}
}
@@ -1326,13 +1378,17 @@
// (this must be inside the try-catch-finally to ensure
// the event is sent regardless of ManagedService[Factory]
// update)
- if ( lastModificationTime < config.getLastUpdatedTime() )
+ if ( lastModificationTime <= config.getLastUpdatedTime() )
{
- log( LogService.LOG_DEBUG, "Configuration " + config.getPid()
- + " has already been updated, nothing to be done anymore.", null );
+ log( LogService.LOG_DEBUG, "Configuration " + config.getPid() + " at modification #"
+ + config.getLastModificationTime() + " has already been updated to update #"
+ + config.getLastUpdatedTime() + ", nothing to be done anymore.", null );
return;
}
+ log( LogService.LOG_DEBUG, "Updating configuration " + config.getPid() + " to modification #"
+ + config.getLastModificationTime(), null );
+
if ( config.getFactoryPid() == null )
{
final ServiceReference[] srList = bundleContext.getServiceReferences( ManagedService.class
@@ -1400,6 +1456,8 @@
// update the lastUpdatedTime
config.setLastUpdatedTime();
+ log( LogService.LOG_DEBUG, "Updated configuration " + config.getPid() + " to update #"
+ + config.getLastUpdatedTime(), null );
}
}
}
@@ -1471,6 +1529,8 @@
// update the lastUpdatedTime
config.setLastUpdatedTime();
+ log( LogService.LOG_DEBUG, "Updated configuration " + config.getPid() + " to update #"
+ + config.getLastUpdatedTime(), null );
}
}
}