FELIX-3327 Throw IllegalStateException on setBundleLocation, getBundleLocation, update, and delete if the Configuration Admin Service has been stopped.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1238185 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationAdapter.java b/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationAdapter.java
index b6cbade..2a3d2c3 100644
--- a/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationAdapter.java
+++ b/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationAdapter.java
@@ -75,6 +75,7 @@
final String bundleLocation = delegatee.getBundleLocation();
delegatee.getConfigurationManager().log( LogService.LOG_DEBUG, "getBundleLocation() ==> {0}", new Object[]
{ bundleLocation } );
+ checkActive();
configurationAdmin.checkPermission( ( bundleLocation == null ) ? "*" : bundleLocation );
checkDeleted();
return bundleLocation;
@@ -92,6 +93,7 @@
{ bundleLocation } );
// CM 1.4 / 104.13.2.4
+ checkActive();
final String configLocation = delegatee.getBundleLocation();
configurationAdmin.checkPermission( ( configLocation == null ) ? "*" : configLocation );
configurationAdmin.checkPermission( ( bundleLocation == null ) ? "*" : bundleLocation );
@@ -108,6 +110,7 @@
{
delegatee.getConfigurationManager().log( LogService.LOG_DEBUG, "update()", ( Throwable ) null );
+ checkActive();
checkDeleted();
delegatee.update();
}
@@ -123,6 +126,7 @@
delegatee.getConfigurationManager().log( LogService.LOG_DEBUG, "update(properties={0})", new Object[]
{ properties } );
+ checkActive();
checkDeleted();
delegatee.update( properties );
}
@@ -151,6 +155,7 @@
{
delegatee.getConfigurationManager().log( LogService.LOG_DEBUG, "delete()", ( Throwable ) null );
+ checkActive();
checkDeleted();
delegatee.delete();
}
@@ -184,6 +189,19 @@
}
/**
+ * Checks whether this configuration object is backed by an active
+ * Configuration Admin Service (ConfigurationManager here).
+ *
+ * @throws IllegalStateException If this configuration object is not
+ * backed by an active ConfigurationManager
+ */
+ private void checkActive() {
+ if (!delegatee.isActive()) {
+ throw new IllegalStateException( "Configuration " + delegatee.getPid() + " not backed by an active Configuration Admin Service" );
+ }
+ }
+
+ /**
* Checks whether this configuration object has already been deleted.
*
* @throws IllegalStateException If this configuration object has been
diff --git a/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationBase.java b/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationBase.java
index 37831db..6891060 100644
--- a/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationBase.java
+++ b/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationBase.java
@@ -77,6 +77,16 @@
}
+ /**
+ * Returns <code>true</code> if the ConfigurationManager of this
+ * configuration is still active.
+ */
+ boolean isActive()
+ {
+ return configurationManager.isActive();
+ }
+
+
abstract void store() throws IOException;
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 f441a27..18bd4b4 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
@@ -161,6 +161,9 @@
// flag indicating whether BundleChange events should be consumed (FELIX-979)
private volatile boolean handleBundleEvents;
+ // flag indicating whether the manager is considered alive
+ private volatile boolean isActive;
+
public void start( BundleContext bundleContext )
{
// track the log service using a ServiceTracker
@@ -231,6 +234,10 @@
persistenceManagerTracker = new ServiceTracker( bundleContext, PersistenceManager.class.getName(), null );
persistenceManagerTracker.open();
+ // consider alive now (before clients use Configuration Admin
+ // service registered in the next step)
+ isActive = true;
+
// create and register configuration admin - start after PM tracker ...
ConfigurationAdminFactory caf = new ConfigurationAdminFactory( this );
Hashtable props = new Hashtable();
@@ -277,6 +284,10 @@
reg.unregister();
}
+ // consider inactive after unregistering such that during
+ // unregistration the manager is still alive and can react
+ isActive = false;
+
// stop handling ManagedService[Factory] services
managedServiceFactoryTracker.close();
managedServiceTracker.close();
@@ -313,6 +324,15 @@
}
+ /**
+ * Returns <code>true</code> if this manager is considered active.
+ */
+ boolean isActive()
+ {
+ return isActive;
+ }
+
+
// ---------- Configuration caching support --------------------------------
ConfigurationImpl getCachedConfiguration( String pid )
diff --git a/configadmin/src/test/java/org/apache/felix/cm/impl/ConfigurationAdapterTest.java b/configadmin/src/test/java/org/apache/felix/cm/impl/ConfigurationAdapterTest.java
index 5d5bb99..c95ca1c 100644
--- a/configadmin/src/test/java/org/apache/felix/cm/impl/ConfigurationAdapterTest.java
+++ b/configadmin/src/test/java/org/apache/felix/cm/impl/ConfigurationAdapterTest.java
@@ -51,7 +51,13 @@
private static final String TEST_LOCATION = "test:location";
private final PersistenceManager pm = new MockPersistenceManager();
- private final MockConfigurationManager configMgr = new MockConfigurationManager();
+ private final MockConfigurationManager configMgr = new MockConfigurationManager()
+ {
+ boolean isActive()
+ {
+ return true;
+ }
+ };
{
ARRAY_VALUE = new String[]
diff --git a/configadmin/src/test/java/org/apache/felix/cm/integration/ConfigurationBaseTest.java b/configadmin/src/test/java/org/apache/felix/cm/integration/ConfigurationBaseTest.java
index fe21d0a..d8c661b 100644
--- a/configadmin/src/test/java/org/apache/felix/cm/integration/ConfigurationBaseTest.java
+++ b/configadmin/src/test/java/org/apache/felix/cm/integration/ConfigurationBaseTest.java
@@ -21,6 +21,7 @@
import java.io.IOException;
import java.util.Dictionary;
+import java.util.Hashtable;
import junit.framework.TestCase;
@@ -46,6 +47,343 @@
// paxRunnerVmOption = DEBUG_VM_OPTION;
}
+
+ @Test
+ public void test_configuration_getFacotryPid_after_config_admin_stop() throws BundleException
+ {
+ final String pid = "test_configuration_after_config_admin_stop";
+ final Configuration config = configure( pid, null, true );
+
+ final Bundle cfgAdminBundle = configAdminTracker.getServiceReference().getBundle();
+ cfgAdminBundle.stop();
+ try
+ {
+ config.getFactoryPid();
+ }
+ finally
+ {
+ try
+ {
+ cfgAdminBundle.start();
+ }
+ catch ( BundleException be )
+ {
+ // tooo bad
+ }
+ }
+ }
+
+
+ @Test
+ public void test_configuration_equals_after_config_admin_stop() throws BundleException
+ {
+ final String pid = "test_configuration_after_config_admin_stop";
+ final Configuration config = configure( pid, null, true );
+
+ final Bundle cfgAdminBundle = configAdminTracker.getServiceReference().getBundle();
+ cfgAdminBundle.stop();
+ try
+ {
+ config.equals( config );
+ }
+ finally
+ {
+ try
+ {
+ cfgAdminBundle.start();
+ }
+ catch ( BundleException be )
+ {
+ // tooo bad
+ }
+ }
+ }
+
+
+ @Test
+ public void test_configuration_hashCode_after_config_admin_stop() throws BundleException
+ {
+ final String pid = "test_configuration_after_config_admin_stop";
+ final Configuration config = configure( pid, null, true );
+
+ final Bundle cfgAdminBundle = configAdminTracker.getServiceReference().getBundle();
+ cfgAdminBundle.stop();
+ try
+ {
+ config.hashCode();
+ }
+ finally
+ {
+ try
+ {
+ cfgAdminBundle.start();
+ }
+ catch ( BundleException be )
+ {
+ // tooo bad
+ }
+ }
+ }
+
+
+ @Test
+ public void test_configuration_toString_after_config_admin_stop() throws BundleException
+ {
+ final String pid = "test_configuration_after_config_admin_stop";
+ final Configuration config = configure( pid, null, true );
+
+ final Bundle cfgAdminBundle = configAdminTracker.getServiceReference().getBundle();
+ cfgAdminBundle.stop();
+ try
+ {
+ config.toString();
+ }
+ finally
+ {
+ try
+ {
+ cfgAdminBundle.start();
+ }
+ catch ( BundleException be )
+ {
+ // tooo bad
+ }
+ }
+ }
+
+
+ public void test_configuration_getPid_after_config_admin_stop() throws BundleException
+ {
+ final String pid = "test_configuration_after_config_admin_stop";
+ final Configuration config = configure( pid, null, true );
+
+ final Bundle cfgAdminBundle = configAdminTracker.getServiceReference().getBundle();
+ cfgAdminBundle.stop();
+ try
+ {
+ config.getPid();
+ }
+ finally
+ {
+ try
+ {
+ cfgAdminBundle.start();
+ }
+ catch ( BundleException be )
+ {
+ // tooo bad
+ }
+ }
+ }
+
+
+ @Test
+ public void test_configuration_after_getProperties_config_admin_stop() throws BundleException
+ {
+ final String pid = "test_configuration_after_config_admin_stop";
+ final Configuration config = configure( pid, null, true );
+
+ final Bundle cfgAdminBundle = configAdminTracker.getServiceReference().getBundle();
+ cfgAdminBundle.stop();
+ try
+ {
+ config.getProperties();
+ }
+ finally
+ {
+ try
+ {
+ cfgAdminBundle.start();
+ }
+ catch ( BundleException be )
+ {
+ // tooo bad
+ }
+ }
+ }
+
+
+ @Test
+ public void test_configuration_delete_after_config_admin_stop() throws BundleException
+ {
+ final String pid = "test_configuration_after_config_admin_stop";
+ final Configuration config = configure( pid, null, true );
+
+ final Bundle cfgAdminBundle = configAdminTracker.getServiceReference().getBundle();
+ cfgAdminBundle.stop();
+ try
+ {
+ config.delete();
+ TestCase.fail( "Expected IllegalStateException for config.delete" );
+ }
+ catch ( IllegalStateException ise )
+ {
+ // expected
+ }
+ catch ( Exception e )
+ {
+ TestCase.fail( "Expected IllegalStateException for config.delete" );
+ }
+ finally
+ {
+ try
+ {
+ cfgAdminBundle.start();
+ }
+ catch ( BundleException be )
+ {
+ // tooo bad
+ }
+ }
+ }
+
+
+ @Test
+ public void test_configuration_after_getBundleLocation_config_admin_stop() throws BundleException
+ {
+ final String pid = "test_configuration_after_config_admin_stop";
+ final Configuration config = configure( pid, null, true );
+
+ final Bundle cfgAdminBundle = configAdminTracker.getServiceReference().getBundle();
+ cfgAdminBundle.stop();
+ try
+ {
+ config.getBundleLocation();
+ TestCase.fail( "Expected IllegalStateException for config.getBundleLocation" );
+ }
+ catch ( IllegalStateException ise )
+ {
+ // expected
+ }
+ catch ( Exception e )
+ {
+ TestCase.fail( "Expected IllegalStateException for config.getBundleLocation" );
+ }
+ finally
+ {
+ try
+ {
+ cfgAdminBundle.start();
+ }
+ catch ( BundleException be )
+ {
+ // tooo bad
+ }
+ }
+ }
+
+
+ @Test
+ public void test_configuration_setBundleLocation_after_config_admin_stop() throws BundleException
+ {
+ final String pid = "test_configuration_after_config_admin_stop";
+ final Configuration config = configure( pid, null, true );
+
+ final Bundle cfgAdminBundle = configAdminTracker.getServiceReference().getBundle();
+ cfgAdminBundle.stop();
+ try
+ {
+ config.setBundleLocation( "?*" );
+ TestCase.fail( "Expected IllegalStateException for config.setBundleLocation" );
+ }
+ catch ( IllegalStateException ise )
+ {
+ // expected
+ }
+ catch ( Exception e )
+ {
+ TestCase.fail( "Expected IllegalStateException for config.setBundleLocation" );
+ }
+ finally
+ {
+ try
+ {
+ cfgAdminBundle.start();
+ }
+ catch ( BundleException be )
+ {
+ // tooo bad
+ }
+ }
+ }
+
+
+ @Test
+ public void test_configuration_update_after_config_admin_stop() throws BundleException
+ {
+ final String pid = "test_configuration_after_config_admin_stop";
+ final Configuration config = configure( pid, null, true );
+
+ final Bundle cfgAdminBundle = configAdminTracker.getServiceReference().getBundle();
+ cfgAdminBundle.stop();
+ try
+ {
+ config.update();
+ TestCase.fail( "Expected IllegalStateException for config.update" );
+ }
+ catch ( IllegalStateException ise )
+ {
+ // expected
+ }
+ catch ( Exception e )
+ {
+ TestCase.fail( "Expected IllegalStateException for config.update" );
+ }
+ finally
+ {
+ try
+ {
+ cfgAdminBundle.start();
+ }
+ catch ( BundleException be )
+ {
+ // tooo bad
+ }
+ }
+ }
+
+
+ @SuppressWarnings("serial")
+ @Test
+ public void test_configuration_update_with_Dictionary_after_config_admin_stop() throws BundleException
+ {
+ final String pid = "test_configuration_after_config_admin_stop";
+ final Configuration config = configure( pid, null, true );
+
+ final Bundle cfgAdminBundle = configAdminTracker.getServiceReference().getBundle();
+ cfgAdminBundle.stop();
+ try
+ {
+ config.update( new Hashtable<String, Object>()
+ {
+ {
+ put( "sample", "sample" );
+ }
+ } );
+ TestCase.fail( "Expected IllegalStateException for config.update" );
+ }
+ catch ( IllegalStateException ise )
+ {
+ // expected
+ }
+ catch ( Exception e )
+ {
+ TestCase.fail( "Expected IllegalStateException for config.update" );
+ }
+ finally
+ {
+ try
+ {
+ cfgAdminBundle.start();
+ }
+ catch ( BundleException be )
+ {
+ // tooo bad
+ }
+ }
+ }
+
+
@Test
public void test_basic_configuration_configure_then_start() throws BundleException, IOException
{