FELIX-2557 Refactor ConfigurationEvent dispatching:
* Schedule event dispatching before scheduling updating the ManagedService[Factory]
* Create list of listeners before scheduling
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@989277 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 99853ff..860dbc5 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
@@ -562,38 +562,40 @@
{
// remove the configuration from the cache
removeConfiguration( config );
- updateThread.schedule( new DeleteConfiguration( config, true ) );
- log( LogService.LOG_DEBUG, "DeleteConfiguration(" + config.getPid() + ") scheduled", null );
+ fireConfigurationEvent( ConfigurationEvent.CM_DELETED, config.getPid(), config.getFactoryPid() );
+ updateThread.schedule( new DeleteConfiguration( config ) );
+ if ( isLogEnabled( LogService.LOG_DEBUG ) )
+ {
+ 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 );
- }
-
-
- void revokeConfiguration( ConfigurationImpl config )
- {
- updateThread.schedule( new DeleteConfiguration( config, false ) );
-
- // immediately unbind the configuration
- config.setDynamicBundleLocation( null );
- config.setServiceReference( null );
- }
-
-
- void reassignConfiguration( ConfigurationImpl config )
- {
- updateThread.schedule( new UpdateConfiguration( config, false ) );
+ if ( fireEvent )
+ {
+ fireConfigurationEvent( ConfigurationEvent.CM_UPDATED, config.getPid(), config.getFactoryPid() );
+ }
+ updateThread.schedule( new UpdateConfiguration( config ) );
+ if ( isLogEnabled( LogService.LOG_DEBUG ) )
+ {
+ log( LogService.LOG_DEBUG, "UpdateConfiguration(" + config.getPid() + ") scheduled", null );
+ }
}
void fireConfigurationEvent( int type, String pid, String factoryPid )
{
-
- updateThread.schedule( new FireConfigurationEvent( type, pid, factoryPid) );
+ FireConfigurationEvent event = new FireConfigurationEvent( type, pid, factoryPid );
+ if ( event.hasConfigurationEventListeners() )
+ {
+ updateThread.schedule( event );
+ }
+ else if ( isLogEnabled( LogService.LOG_DEBUG ) )
+ {
+ log( LogService.LOG_DEBUG, "No ConfigurationListeners to send " + event.getTypeName() + " event to.", null );
+ }
}
@@ -696,7 +698,10 @@
{
ManagedServiceUpdate update = new ManagedServiceUpdate( pids[i], sr, service );
updateThread.schedule( update );
- log( LogService.LOG_DEBUG, "ManagedServiceUpdate(" + pids[i] + ") scheduled", null );
+ if ( isLogEnabled( LogService.LOG_DEBUG ) )
+ {
+ log( LogService.LOG_DEBUG, "ManagedServiceUpdate(" + pids[i] + ") scheduled", null );
+ }
}
}
}
@@ -711,7 +716,10 @@
{
ManagedServiceFactoryUpdate update = new ManagedServiceFactoryUpdate( pids[i], sr, service );
updateThread.schedule( update );
- log( LogService.LOG_DEBUG, "ManagedServiceFactoryUpdate(" + pids[i] + ") scheduled", null );
+ if ( isLogEnabled( LogService.LOG_DEBUG ) )
+ {
+ log( LogService.LOG_DEBUG, "ManagedServiceFactoryUpdate(" + pids[i] + ") scheduled", null );
+ }
}
}
}
@@ -893,6 +901,12 @@
}
+ boolean isLogEnabled( int level )
+ {
+ return level <= logLevel;
+ }
+
+
void log( int level, String message, Throwable t )
{
// log using the LogService if available
@@ -904,7 +918,7 @@
}
// Otherwise only log if more serious than the configured level
- if ( level <= logLevel )
+ if ( isLogEnabled( level ) )
{
String code;
switch ( level )
@@ -1007,7 +1021,6 @@
{
log( LogService.LOG_ERROR, toString( target ) + ": Updating configuration caused a problem: "
+ ce.getReason(), ce );
-
}
}
else
@@ -1076,23 +1089,32 @@
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 );
+ if ( isLogEnabled( LogService.LOG_DEBUG ) )
+ {
+ 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 );
+ if ( isLogEnabled( LogService.LOG_DEBUG ) )
+ {
+ log( LogService.LOG_DEBUG, "Updating configuration " + config.getPid() + " to modification #"
+ + config.getLastModificationTime(), null );
+ }
Bundle serviceBundle = sr.getBundle();
if ( serviceBundle == null )
{
- log( LogService.LOG_INFO, "Service for PID " + pid
- + " seems to already have been unregistered, not updating with configuration", null );
+ if ( isLogEnabled( LogService.LOG_INFO ) )
+ {
+ log( LogService.LOG_INFO, "Service for PID " + pid
+ + " seems to already have been unregistered, not updating with configuration", null );
+ }
return;
}
@@ -1147,8 +1169,11 @@
if ( config != null && properties != null )
{
config.setLastUpdatedTime( lastModificationTime );
- log( LogService.LOG_DEBUG, "Updated configuration " + config.getPid() + " to update #"
- + config.getLastUpdatedTime(), null );
+ if ( isLogEnabled( LogService.LOG_DEBUG ) )
+ {
+ log( LogService.LOG_DEBUG, "Updated configuration " + config.getPid() + " to update #"
+ + config.getLastUpdatedTime(), null );
+ }
}
}
@@ -1255,8 +1280,11 @@
Bundle serviceBundle = sr.getBundle();
if ( serviceBundle == null )
{
- log( LogService.LOG_INFO, "ManagedServiceFactory for factory PID " + factoryPid
- + " seems to already have been unregistered, not updating with factory", null );
+ if ( isLogEnabled( LogService.LOG_INFO ) )
+ {
+ log( LogService.LOG_INFO, "ManagedServiceFactory for factory PID " + factoryPid
+ + " seems to already have been unregistered, not updating with factory", null );
+ }
return;
}
@@ -1280,14 +1308,20 @@
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 );
+ if ( isLogEnabled( LogService.LOG_DEBUG ) )
+ {
+ 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 );
+ if ( isLogEnabled( LogService.LOG_DEBUG ) )
+ {
+ log( LogService.LOG_DEBUG, "Updating configuration " + cfg.getPid() + " to modification #"
+ + cfg.getLastModificationTime(), null );
+ }
// check bundle location of configuration
if ( !cfg.tryBindLocation( serviceBundleLocation ) )
@@ -1323,7 +1357,11 @@
// update the service with the configuration (if non-null)
if ( properties != null )
{
- log( LogService.LOG_DEBUG, sr + ": Updating configuration pid=" + cfg.getPid(), null );
+ if ( isLogEnabled( LogService.LOG_DEBUG ) )
+ {
+ log( LogService.LOG_DEBUG, sr + ": Updating configuration pid=" + cfg.getPid(), null );
+ }
+
try
{
service.updated( cfg.getPid(), properties );
@@ -1335,8 +1373,12 @@
// update the lastUpdatedTime
cfg.setLastUpdatedTime( lastModificationTime );
- log( LogService.LOG_DEBUG, "Updated configuration " + cfg.getPid() + " to update #"
- + cfg.getLastUpdatedTime(), null );
+
+ if ( isLogEnabled( LogService.LOG_DEBUG ) )
+ {
+ log( LogService.LOG_DEBUG, "Updated configuration " + cfg.getPid() + " to update #"
+ + cfg.getLastUpdatedTime(), null );
+ }
}
}
}
@@ -1354,10 +1396,9 @@
private final ConfigurationImpl config;
private final Dictionary properties;
private final long lastModificationTime;
- private final boolean fireEvent;
- UpdateConfiguration( final ConfigurationImpl config, boolean fireEvent )
+ UpdateConfiguration( final ConfigurationImpl config )
{
this.config = config;
synchronized ( config )
@@ -1365,7 +1406,6 @@
this.properties = config.getProperties( true );
this.lastModificationTime = config.getLastModificationTime();
}
- this.fireEvent = fireEvent;
}
@@ -1380,14 +1420,20 @@
// update)
if ( lastModificationTime <= config.getLastUpdatedTime() )
{
- 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 );
+ if ( isLogEnabled( LogService.LOG_DEBUG ) )
+ {
+ 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 ( isLogEnabled( LogService.LOG_DEBUG ) )
+ {
+ log( LogService.LOG_DEBUG, "Updating configuration " + config.getPid() + " to modification #"
+ + config.getLastModificationTime(), null );
+ }
if ( config.getFactoryPid() == null )
{
@@ -1456,8 +1502,12 @@
// update the lastUpdatedTime
config.setLastUpdatedTime( lastModificationTime );
- log( LogService.LOG_DEBUG, "Updated configuration " + config.getPid() + " to update #"
- + config.getLastUpdatedTime(), null );
+
+ if ( isLogEnabled( LogService.LOG_DEBUG ) )
+ {
+ log( LogService.LOG_DEBUG, "Updated configuration " + config.getPid() + " to update #"
+ + config.getLastUpdatedTime(), null );
+ }
}
}
}
@@ -1529,8 +1579,12 @@
// update the lastUpdatedTime
config.setLastUpdatedTime( lastModificationTime );
- log( LogService.LOG_DEBUG, "Updated configuration " + config.getPid() + " to update #"
- + config.getLastUpdatedTime(), null );
+
+ if ( isLogEnabled( LogService.LOG_DEBUG ) )
+ {
+ log( LogService.LOG_DEBUG, "Updated configuration " + config.getPid() + " to update #"
+ + config.getLastUpdatedTime(), null );
+ }
}
}
}
@@ -1539,15 +1593,6 @@
{
log( LogService.LOG_ERROR, "Service selection filter is invalid to update " + config, ise );
}
- finally
- {
- // the update event has to be sent regardless of whether the
- // configuration was updated in a managed service or not
- if ( fireEvent )
- {
- fireConfigurationEvent( ConfigurationEvent.CM_UPDATED, config.getPid(), config.getFactoryPid() );
- }
- }
}
@@ -1601,10 +1646,9 @@
private final ConfigurationImpl config;
private final String configLocation;
- private final boolean fireEvent;
- DeleteConfiguration( ConfigurationImpl config, boolean fireEvent )
+ DeleteConfiguration( ConfigurationImpl config )
{
/*
* NOTE: We keep the configuration because it might be cleared just
@@ -1613,7 +1657,6 @@
*/
this.config = config;
this.configLocation = config.getBoundBundleLocation();
- this.fireEvent = fireEvent;
}
@@ -1700,15 +1743,6 @@
{
log( LogService.LOG_ERROR, "Service selection filter is invalid to update " + config, ise );
}
- finally
- {
- // the delete event has to be sent regardless of whether the
- // configuration was updated in a managed service or not
- if ( fireEvent )
- {
- fireConfigurationEvent( ConfigurationEvent.CM_DELETED, pid, factoryPid );
- }
- }
}
public String toString()
@@ -1719,43 +1753,90 @@
private class FireConfigurationEvent implements Runnable
{
- private int type;
+ private final int type;
- private String pid;
+ private final String pid;
- private String factoryPid;
+ private final String factoryPid;
+
+ private final ServiceReference[] listenerReferences;
+
+ private final ConfigurationListener[] listeners;
+
+ private final Bundle[] listenerProvider;
- FireConfigurationEvent( int type, String pid, String factoryPid )
+ private FireConfigurationEvent( final int type, final String pid, final String factoryPid)
{
this.type = type;
this.pid = pid;
this.factoryPid = factoryPid;
+
+ final ServiceReference[] srs = configurationListenerTracker.getServiceReferences();
+ if ( srs == null || srs.length == 0 )
+ {
+ this.listenerReferences = null;
+ this.listeners = null;
+ this.listenerProvider = null;
+ }
+ else
+ {
+ this.listenerReferences = srs;
+ this.listeners = new ConfigurationListener[srs.length];
+ this.listenerProvider = new Bundle[srs.length];
+ for ( int i = 0; i < srs.length; i++ )
+ {
+ this.listeners[i] = ( ConfigurationListener ) configurationListenerTracker.getService( srs[i] );
+ this.listenerProvider[i] = srs[i].getBundle();
+ }
+ }
+ }
+
+
+ boolean hasConfigurationEventListeners()
+ {
+ return this.listenerReferences != null;
+ }
+
+
+ String getTypeName()
+ {
+ switch ( type )
+ {
+ case ConfigurationEvent.CM_DELETED:
+ return "CM_DELETED";
+ case ConfigurationEvent.CM_UPDATED:
+ return "CM_UPDATED";
+ default:
+ return "<UNKNOWN(" + type + ")>";
+ }
}
public void run()
{
- // get the listeners
- ServiceReference[] srs = configurationListenerTracker.getServiceReferences();
- if ( srs == null || srs.length == 0 )
- {
- return;
- }
+ final String typeName = getTypeName();
+ final ConfigurationEvent event = new ConfigurationEvent( getServiceReference(), type, factoryPid, pid );
- ConfigurationEvent event = new ConfigurationEvent( getServiceReference(), type, factoryPid, pid );
-
- for ( int i = 0; i < srs.length; i++ )
+ for ( int i = 0; i < listeners.length; i++ )
{
- ConfigurationListener cl = ( ConfigurationListener ) configurationListenerTracker.getService( srs[i] );
- try
+ if ( listenerProvider[i].getState() == Bundle.ACTIVE )
{
- cl.configurationEvent( event );
- }
- catch ( Throwable t )
- {
- log( LogService.LOG_ERROR, "Unexpected problem delivery configuration event to "
- + ConfigurationManager.toString( srs[i] ), t );
+ if ( isLogEnabled( LogService.LOG_DEBUG ) )
+ {
+ log( LogService.LOG_DEBUG, "Sending " + typeName + " event for " + pid + " to "
+ + ConfigurationManager.toString( listenerReferences[i] ), null );
+ }
+
+ try
+ {
+ listeners[i].configurationEvent( event );
+ }
+ catch ( Throwable t )
+ {
+ log( LogService.LOG_ERROR, "Unexpected problem delivery configuration event to "
+ + ConfigurationManager.toString( listenerReferences[i] ), t );
+ }
}
}
}