FELIX-3651 TargetedPID tests
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1515661 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/config/ComponentHolder.java b/scr/src/main/java/org/apache/felix/scr/impl/config/ComponentHolder.java
index 0c0a240..598db65 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/config/ComponentHolder.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/config/ComponentHolder.java
@@ -71,8 +71,10 @@
* @param props the property dictionary from the configuration.
* @param changeCount change count of the configuration, or R4 imitation.
* @param targetedPid TODO
+ * @return true if a new component is created for a factory PID, false if an existing factory pid configuration is updated or
+ * we have no factory pid
*/
- void configurationUpdated( String pid, Dictionary<String, Object> props, long changeCount, TargetedPID targetedPid );
+ boolean configurationUpdated( String pid, Dictionary<String, Object> props, long changeCount, TargetedPID targetedPid );
/**
* Change count (or fake R4 imitation)
@@ -82,9 +84,10 @@
/**
* Returns the targeted PID used to configure this component
+ * @param pid TODO
* @return
*/
- TargetedPID getConfigurationTargetedPID();
+ TargetedPID getConfigurationTargetedPID(TargetedPID pid);
/**
* Returns all <code>Component</code> instances held by this holder.
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurationSupport.java b/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurationSupport.java
index a6af683..93725c7 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurationSupport.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurationSupport.java
@@ -102,7 +102,7 @@
// ---------- BaseConfigurationSupport overwrites
- public void configureComponentHolder(final ComponentHolder holder)
+ public boolean configureComponentHolder(final ComponentHolder holder)
{
// 112.7 configure unless configuration not required
@@ -111,11 +111,11 @@
final BundleContext bundleContext = holder.getActivator().getBundleContext();
if ( bundleContext == null )
{
- return;// bundle was stopped concurrently with configuration deletion
+ return false;// bundle was stopped concurrently with configuration deletion
}
final String confPid = holder.getComponentMetadata().getConfigurationPid();
- final ServiceReference caRef = bundleContext.getServiceReference(ComponentRegistry.CONFIGURATION_ADMIN);
+ final ServiceReference<?> caRef = bundleContext.getServiceReference(ComponentRegistry.CONFIGURATION_ADMIN);
if (caRef != null)
{
final Object cao = bundleContext.getService(caRef);
@@ -129,15 +129,17 @@
final Collection<Configuration> factory = findFactoryConfigurations(ca, confPid, bundleContext.getBundle());
if (!factory.isEmpty())
{
+ boolean created = false;
for (Configuration config: factory)
{
config = getConfiguration( ca, config.getPid() );
if ( checkBundleLocation( config, bundleContext.getBundle() ))
{
long changeCount = changeCounter.getChangeCount( config, false, -1 );
- holder.configurationUpdated(config.getPid(), config.getProperties(), changeCount, new TargetedPID(config.getFactoryPid()));
+ created |= holder.configurationUpdated(config.getPid(), config.getProperties(), changeCount, new TargetedPID(config.getFactoryPid()));
}
}
+ return created;
}
else
{
@@ -148,8 +150,9 @@
singleton = getConfiguration( ca, singleton.getPid() );
if ( singleton != null && checkBundleLocation( singleton, bundleContext.getBundle() ))
{
- long changeCount = changeCounter.getChangeCount( singleton, false, -1 );
- holder.configurationUpdated(confPid, singleton.getProperties(), changeCount, new TargetedPID(singleton.getPid()));
+ long changeCount = changeCounter.getChangeCount( singleton, false, -1 );
+ holder.configurationUpdated(confPid, singleton.getProperties(), changeCount, new TargetedPID(singleton.getPid()));
+ return true;
}
}
}
@@ -162,6 +165,7 @@
"Component Bundle's Configuration Admin is not compatible with "
+ "ours. This happens if multiple Configuration Admin API versions "
+ "are deployed and different bundles wire to different versions", null );
+ return false;
}
}
@@ -179,6 +183,7 @@
}
}
}
+ return false;
}
// ---------- ServiceListener
@@ -246,9 +251,10 @@
{
switch (event.getType()) {
case ConfigurationEvent.CM_DELETED:
- componentHolder.configurationDeleted(pid.getServicePid());
- //fall back to less-strong pid match
- configureComponentHolder( componentHolder );
+ if ( !configureComponentHolder( componentHolder ) )
+ {
+ componentHolder.configurationDeleted( pid.getServicePid() );
+ }
break;
case ConfigurationEvent.CM_UPDATED:
@@ -266,7 +272,7 @@
}
TargetedPID targetedPid = factoryPid == null? pid: factoryPid;
- TargetedPID oldTargetedPID = componentHolder.getConfigurationTargetedPID();
+ TargetedPID oldTargetedPID = componentHolder.getConfigurationTargetedPID(pid);
if ( targetedPid.equals(oldTargetedPID) || targetedPid.bindsStronger( oldTargetedPID ))
{
final ConfigurationInfo configInfo = getConfiguration( pid, componentHolder, bundleContext );
@@ -316,7 +322,7 @@
}
TargetedPID targetedPid = factoryPid == null? pid: factoryPid;
- TargetedPID oldTargetedPID = componentHolder.getConfigurationTargetedPID();
+ TargetedPID oldTargetedPID = componentHolder.getConfigurationTargetedPID(pid);
if ( targetedPid.equals(oldTargetedPID))
{
//this sets the location to this component's bundle if not already set. OK here
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/config/ImmediateComponentHolder.java b/scr/src/main/java/org/apache/felix/scr/impl/config/ImmediateComponentHolder.java
index 3d2edc0..89dc367 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/config/ImmediateComponentHolder.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/config/ImmediateComponentHolder.java
@@ -106,10 +106,7 @@
* enabled. Otherwise they are not enabled immediately.
*/
private volatile boolean m_enabled;
- private final ComponentMethods m_componentMethods;
-
- private TargetedPID m_targetedPID;
-
+ private final ComponentMethods m_componentMethods;
public ImmediateComponentHolder( final BundleComponentActivator activator, final ComponentMetadata metadata )
{
@@ -192,7 +189,6 @@
log( LogService.LOG_DEBUG, "ImmediateComponentHolder configuration deleted for pid {0}",
new Object[] {pid}, null);
- m_targetedPID = null;
// component to deconfigure or dispose of
final ImmediateComponentManager icm;
boolean deconfigure = false;
@@ -251,7 +247,7 @@
// is not the "last" and has to be disposed off
if ( deconfigure )
{
- icm.reconfigure( null, -1 );
+ icm.reconfigure( null, -1, null );
}
else
{
@@ -273,30 +269,24 @@
* this case a new component is created, configured and stored in the map</li>
* </ul>
*/
- public void configurationUpdated( final String pid, final Dictionary<String, Object> props, long changeCount, TargetedPID targetedPid )
+ public boolean configurationUpdated( final String pid, final Dictionary<String, Object> props, long changeCount, TargetedPID targetedPid )
{
log( LogService.LOG_DEBUG, "ImmediateComponentHolder configuration updated for pid {0} with properties {1}",
new Object[] {pid, props}, null);
- if ( m_targetedPID != null && !m_targetedPID.equals( targetedPid ))
- {
- log( LogService.LOG_ERROR, "ImmediateComponentHolder unexpected change in targetedPID from {0} to {1}",
- new Object[] {m_targetedPID, targetedPid}, null);
- throw new IllegalStateException("Unexpected targetedPID change");
- }
- m_targetedPID = targetedPid;
// component to update or create
final ImmediateComponentManager icm;
final String message;
final boolean enable;
Object[] notEnabledArguments = null;
+ boolean created = false;
synchronized ( m_components )
{
// FELIX-2231: nothing to do any more, all components have been disposed off
if (m_singleComponent == null)
{
- return;
+ return false;
}
if ( pid.equals( getComponentMetadata().getConfigurationPid() ) )
@@ -319,6 +309,7 @@
else
{
// factory configuration created
+ created = true;
if ( !m_singleComponent.hasConfiguration() )
{
// configure the single instance if this is not configured
@@ -351,7 +342,7 @@
log( LogService.LOG_DEBUG, message, new Object[] {pid}, null);
// configure the component
- icm.reconfigure( props, changeCount );
+ icm.reconfigure( props, changeCount, targetedPid );
log( LogService.LOG_DEBUG, "ImmediateComponentHolder Finished configuring the dependency managers for component for pid {0} ",
new Object[] {pid}, null );
@@ -366,6 +357,7 @@
log( LogService.LOG_DEBUG, "ImmediateComponentHolder Will not enable component for pid {0}: holder enabled state: {1}, metadata enabled: {2} ",
notEnabledArguments, null );
}
+ return created;
}
public synchronized long getChangeCount( String pid)
@@ -566,9 +558,25 @@
}
}
- public TargetedPID getConfigurationTargetedPID()
+ public TargetedPID getConfigurationTargetedPID(TargetedPID pid)
{
- return m_targetedPID;
+ ImmediateComponentManager icm = null;
+ synchronized (m_components)
+ {
+ if ( pid.getServicePid().equals( m_componentMetadata.getConfigurationPid() )) {
+ //singleton
+ icm = m_singleComponent;
+ }
+ else
+ {
+ icm = m_components.get( pid.getServicePid() );
+ }
+ }
+ if ( icm != null)
+ {
+ return icm.getConfigurationTargetedPID();
+ }
+ return null;
}
}
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
index 0996aa3..75e27b9 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
@@ -91,7 +91,7 @@
*/
protected volatile long m_changeCount = -1;
- private TargetedPID m_targetedPID;
+ protected TargetedPID m_targetedPID;
public ComponentFactoryImpl( BundleComponentActivator activator, ComponentMetadata metadata )
{
@@ -119,7 +119,7 @@
ComponentInstance instance;
cm.setFactoryProperties( ( Dictionary<String, Object> ) dictionary );
//configure the properties
- cm.reconfigure( m_configuration, m_changeCount );
+ cm.reconfigure( m_configuration, m_changeCount, m_targetedPID );
// enable
cm.enableInternal();
//activate immediately
@@ -330,7 +330,7 @@
}
- public void configurationUpdated( String pid, Dictionary<String, Object> configuration, long changeCount, TargetedPID targetedPid )
+ public boolean configurationUpdated( String pid, Dictionary<String, Object> configuration, long changeCount, TargetedPID targetedPid )
{
if ( m_targetedPID != null && !m_targetedPID.equals( targetedPid ))
{
@@ -346,7 +346,7 @@
log( LogService.LOG_DEBUG,
"ImmediateComponentHolder out of order configuration updated for pid {0} with existing count {1}, new count {2}",
new Object[] { getConfigurationPid(), m_changeCount, changeCount }, null );
- return;
+ return false;
}
m_changeCount = changeCount;
}
@@ -361,7 +361,7 @@
// Ignore the configuration is our policy is 'ignore'
if ( getComponentMetadata().isConfigurationIgnored() )
{
- return;
+ return false;
}
// Store the config admin configuration
@@ -388,7 +388,7 @@
log( LogService.LOG_DEBUG,
"Component Factory target filters not satisfied anymore: deactivating", null );
deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false, getTrackingCount().get() );
- return;
+ return false;
}
}
@@ -406,6 +406,7 @@
// 112.7 Factory Configuration not allowed for factory component
log( LogService.LOG_ERROR, "Component Factory cannot be configured by factory configuration", null );
}
+ return false;
}
@@ -520,7 +521,7 @@
}
- public TargetedPID getConfigurationTargetedPID()
+ public TargetedPID getConfigurationTargetedPID(TargetedPID pid)
{
return m_targetedPID;
}
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ConfigurationComponentFactoryImpl.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ConfigurationComponentFactoryImpl.java
index 28dc231..54f05b2 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ConfigurationComponentFactoryImpl.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ConfigurationComponentFactoryImpl.java
@@ -130,11 +130,11 @@
}
- public void configurationUpdated( String pid, Dictionary<String, Object> configuration, long changeCount, TargetedPID targetedPid )
+ public boolean configurationUpdated( String pid, Dictionary<String, Object> configuration, long changeCount, TargetedPID targetedPid )
{
if ( pid.equals( getComponentMetadata().getConfigurationPid() ) )
{
- super.configurationUpdated( pid, configuration, changeCount, targetedPid );
+ return super.configurationUpdated( pid, configuration, changeCount, targetedPid );
}
else //non-spec backwards compatible
{
@@ -151,7 +151,7 @@
// this should not call component reactivation because it is
// not active yet
- cm.reconfigure( configuration, changeCount );
+ cm.reconfigure( configuration, changeCount, m_targetedPID );
// enable asynchronously if components are already enabled
if ( getState() == STATE_FACTORY )
@@ -164,12 +164,14 @@
// keep a reference for future updates
m_configuredServices.put( pid, cm );
}
+ return true;
}
else
{
// update the configuration as if called as ManagedService
- cm.reconfigure( configuration, changeCount );
+ cm.reconfigure( configuration, changeCount, m_targetedPID );
+ return false;
}
}
}
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
index ff31830..0eea200 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
@@ -24,6 +24,7 @@
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.felix.scr.impl.BundleComponentActivator;
+import org.apache.felix.scr.impl.TargetedPID;
import org.apache.felix.scr.impl.config.ComponentHolder;
import org.apache.felix.scr.impl.helper.ActivateMethod.ActivatorParameter;
import org.apache.felix.scr.impl.helper.ComponentMethods;
@@ -71,6 +72,8 @@
private Dictionary<String, Object> m_configurationProperties;
private volatile long m_changeCount = -1;
+ private TargetedPID m_targetedPID;
+
private final ThreadLocal<Boolean> m_circularReferences = new ThreadLocal<Boolean>();
@@ -521,9 +524,15 @@
* the Configuration Admin Service or <code>null</code> if there is
* no configuration or if the configuration has just been deleted.
* @param changeCount TODO
+ * @param targetedPID TODO
*/
- public void reconfigure( Dictionary<String, Object> configuration, long changeCount )
+ public void reconfigure( Dictionary<String, Object> configuration, long changeCount, TargetedPID targetedPID )
{
+ if ( targetedPID == null || !targetedPID.equals( m_targetedPID ) )
+ {
+ m_targetedPID = targetedPID;
+ m_changeCount = -1;
+ }
if ( configuration != null )
{
if ( changeCount <= m_changeCount )
@@ -874,4 +883,9 @@
{
return m_changeCount;
}
+
+ public TargetedPID getConfigurationTargetedPID()
+ {
+ return m_targetedPID;
+ }
}
diff --git a/scr/src/test/java/org/apache/felix/scr/impl/config/ConfiguredComponentHolderTest.java b/scr/src/test/java/org/apache/felix/scr/impl/config/ConfiguredComponentHolderTest.java
index 8992782..5d3cc72 100644
--- a/scr/src/test/java/org/apache/felix/scr/impl/config/ConfiguredComponentHolderTest.java
+++ b/scr/src/test/java/org/apache/felix/scr/impl/config/ConfiguredComponentHolderTest.java
@@ -251,7 +251,7 @@
}
- public void reconfigure( Dictionary configuration, long changeCount )
+ public void reconfigure( Dictionary configuration, long changeCount, TargetedPID targetedPID )
{
this.m_configuration = configuration;
}
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java b/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java
index abbc7c5..8e86855 100644
--- a/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java
+++ b/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java
@@ -19,6 +19,7 @@
package org.apache.felix.scr.integration;
+import static org.ops4j.pax.exam.CoreOptions.frameworkProperty;
import static org.ops4j.pax.exam.CoreOptions.junitBundles;
import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
import static org.ops4j.pax.exam.CoreOptions.options;
@@ -109,6 +110,8 @@
protected static String DS_LOGLEVEL = "debug";
+ protected static String bsnVersionUniqueness = "single";
+
// the descriptor file to use for the installed test bundle
protected static String descriptorFile = "/integration_test_simple_components.xml";
protected static String COMPONENT_PACKAGE = "org.apache.felix.scr.integration.components";
@@ -160,6 +163,7 @@
mavenBundle( "org.apache.felix", "org.apache.felix.configadmin", felixCaVersion )
),
junitBundles(),
+ frameworkProperty( "org.osgi.framework.bsnversion" ).value( bsnVersionUniqueness ),
systemProperty( "ds.factory.enabled" ).value( Boolean.toString( NONSTANDARD_COMPONENT_FACTORY_BEHAVIOR ) ),
systemProperty( "ds.loglevel" ).value( DS_LOGLEVEL )
@@ -414,10 +418,10 @@
protected Bundle installBundle( final String descriptorFile, String componentPackage ) throws BundleException
{
- return installBundle(descriptorFile, componentPackage, "simplecomponent", "0.0.11");
+ return installBundle(descriptorFile, componentPackage, "simplecomponent", "0.0.11", null);
}
- protected Bundle installBundle( final String descriptorFile, String componentPackage, String symbolicName, String version ) throws BundleException
+ protected Bundle installBundle( final String descriptorFile, String componentPackage, String symbolicName, String version, String location ) throws BundleException
{
final InputStream bundleStream = bundle()
.add("OSGI-INF/components.xml", getClass().getResource(descriptorFile))
@@ -430,7 +434,10 @@
try
{
- final String location = "test:SimpleComponent/" + System.currentTimeMillis();
+ if ( location == null )
+ {
+ location = "test:SimpleComponent/" + System.currentTimeMillis();
+ }
return bundleContext.installBundle( location, bundleStream );
}
finally
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/LocationTest.java b/scr/src/test/java/org/apache/felix/scr/integration/LocationTest.java
index 63e24f1..4e10d1e 100644
--- a/scr/src/test/java/org/apache/felix/scr/integration/LocationTest.java
+++ b/scr/src/test/java/org/apache/felix/scr/integration/LocationTest.java
@@ -77,7 +77,7 @@
TestCase.assertEquals( PROP_NAME, SimpleComponent.INSTANCE.getProperty( PROP_NAME ) );
- Bundle b2 = installBundle( descriptorFile, COMPONENT_PACKAGE, "simplecomponent2", "0.0.11" );
+ Bundle b2 = installBundle( descriptorFile, COMPONENT_PACKAGE, "simplecomponent2", "0.0.11", null );
b2.start();
Component[] components = findComponentsByName( pid );
TestCase.assertEquals( 2, components.length );
@@ -146,7 +146,7 @@
TestCase.assertEquals( PROP_NAME, SimpleComponent.INSTANCE.getProperty( PROP_NAME ) );
- Bundle b2 = installBundle( descriptorFile, COMPONENT_PACKAGE, "simplecomponent2", "0.0.11" );
+ Bundle b2 = installBundle( descriptorFile, COMPONENT_PACKAGE, "simplecomponent2", "0.0.11", null );
b2.start();
Component[] components = findComponentsByName( pid );
TestCase.assertEquals( 2, components.length );
@@ -224,7 +224,7 @@
TestCase.assertEquals( PROP_NAME, SimpleComponent.INSTANCE.getProperty( PROP_NAME ) );
- Bundle b2 = installBundle( descriptorFile, COMPONENT_PACKAGE, "simplecomponent2", "0.0.11" );
+ Bundle b2 = installBundle( descriptorFile, COMPONENT_PACKAGE, "simplecomponent2", "0.0.11", null );
b2.start();
Component[] components = findComponentsByName( pid );
TestCase.assertEquals( 2, components.length );
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/TargetedPIDTest.java b/scr/src/test/java/org/apache/felix/scr/integration/TargetedPIDTest.java
new file mode 100644
index 0000000..25589fb
--- /dev/null
+++ b/scr/src/test/java/org/apache/felix/scr/integration/TargetedPIDTest.java
@@ -0,0 +1,178 @@
+/*
+ * 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.scr.integration;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+import org.apache.felix.scr.Component;
+import org.apache.felix.scr.integration.components.SimpleComponent;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationEvent;
+import org.osgi.service.cm.ConfigurationListener;
+import org.osgi.service.cm.ConfigurationPermission;
+
+@RunWith(JUnit4TestRunner.class)
+public class TargetedPIDTest extends ComponentTestBase
+{
+
+ private static final String TARGETED_PID = "targetedPID";
+ private static final String COMPONENT_NAME = "SimpleComponent.configuration.require";
+ private static final String REGION = "?foo";
+ private boolean eventReceived;
+
+ static
+ {
+ bsnVersionUniqueness = "multiple";
+ descriptorFile = "/integration_test_simple_components_location.xml";
+ // uncomment to enable debugging of this test class
+// paxRunnerVmOption = DEBUG_VM_OPTION;
+ }
+
+
+ @Test
+ public void testTargetedPID() throws Exception
+ {
+ try
+ {
+ new ConfigurationPermission(REGION, ConfigurationPermission.TARGET);
+ }
+ catch (IllegalArgumentException e)
+ {
+ return;//not an R5 CA
+ }
+ String pid = COMPONENT_NAME;
+ theConfig.put(TARGETED_PID, pid);
+ Configuration config = configure( pid );
+ config.setBundleLocation( REGION );
+
+ String pidSN = pid + "|simplecomponent2";
+ theConfig.put(TARGETED_PID, pidSN);
+ Configuration configSN = configure( pidSN );
+ configSN.setBundleLocation( REGION );
+
+ String pidSNV = pidSN + "|0.0.12";
+ theConfig.put(TARGETED_PID, pidSNV);
+ Configuration configSNV = configure( pidSNV );
+ configSNV.setBundleLocation( REGION );
+
+ String pidSNVL = pidSNV + "|bundleLocation";
+ theConfig.put(TARGETED_PID, pidSNVL);
+ Configuration configSNVL = configure( pidSNVL );
+ configSNVL.setBundleLocation( REGION );
+
+ //Add more and more specific components to check that they pick up the appropriate configuration
+ Set<Component> known = new HashSet<Component>();
+
+ final Component component = findComponentByName( COMPONENT_NAME );
+ known.add( component );
+ component.enable();
+ delay();
+
+ TestCase.assertEquals( Component.STATE_ACTIVE, component.getState() );
+ TestCase.assertNotNull( SimpleComponent.INSTANCE );
+ SimpleComponent sc = SimpleComponent.INSTANCE;
+ TestCase.assertEquals( pid, sc.getProperty( TARGETED_PID ) );
+
+
+ Bundle bSN = installBundle( descriptorFile, COMPONENT_PACKAGE, "simplecomponent2", "0.0.11", null );
+ bSN.start();
+ Component[] components = findComponentsByName( pid );
+ TestCase.assertEquals( 2, components.length );
+ Component cSN = getNewComponent( known, components );
+
+
+ cSN.enable();
+ delay();
+ TestCase.assertEquals( Component.STATE_ACTIVE, cSN.getState() );
+ SimpleComponent scSN = SimpleComponent.INSTANCE;
+ TestCase.assertEquals( pidSN, scSN.getProperty( TARGETED_PID ) );
+
+ Bundle bSNV = installBundle( descriptorFile, COMPONENT_PACKAGE, "simplecomponent2", "0.0.12", null );
+ bSNV.start();
+ components = findComponentsByName( pid );
+ TestCase.assertEquals( 3, components.length );
+ Component cSNV = getNewComponent( known, components );
+
+ cSNV.enable();
+ delay();
+ TestCase.assertEquals( Component.STATE_ACTIVE, cSNV.getState() );
+ SimpleComponent scSNV = SimpleComponent.INSTANCE;
+ TestCase.assertEquals( pidSNV, scSNV.getProperty( TARGETED_PID ) );
+
+ Bundle bSNVL = installBundle( descriptorFile, COMPONENT_PACKAGE, "simplecomponent2", "0.0.12", "bundleLocation" );
+ bSNVL.start();
+ components = findComponentsByName( pid );
+ TestCase.assertEquals( 4, components.length );
+ Component cSNVL = getNewComponent( known, components );
+
+ cSNVL.enable();
+ delay();
+ TestCase.assertEquals( Component.STATE_ACTIVE, cSNVL.getState() );
+ SimpleComponent scSNVL = SimpleComponent.INSTANCE;
+ TestCase.assertEquals( pidSNVL, scSNVL.getProperty( TARGETED_PID ) );
+
+ //remove configurations to check that the components now use the less specific configurations.
+
+ configSNVL.delete();
+ delay();
+ TestCase.assertEquals( Component.STATE_ACTIVE, cSNVL.getState() );
+ TestCase.assertEquals( pidSNV, scSNVL.getProperty( TARGETED_PID ) );
+
+ configSNV.delete();
+ delay();
+ TestCase.assertEquals( Component.STATE_ACTIVE, cSNVL.getState() );
+ TestCase.assertEquals( pidSN, scSNVL.getProperty( TARGETED_PID ) );
+ TestCase.assertEquals( Component.STATE_ACTIVE, cSNV.getState() );
+ TestCase.assertEquals( pidSN, scSNV.getProperty( TARGETED_PID ) );
+
+ configSN.delete();
+ delay();
+ TestCase.assertEquals( Component.STATE_ACTIVE, cSNVL.getState() );
+ TestCase.assertEquals( pid, scSNVL.getProperty( TARGETED_PID ) );
+ TestCase.assertEquals( Component.STATE_ACTIVE, cSNV.getState() );
+ TestCase.assertEquals( pid, scSNV.getProperty( TARGETED_PID ) );
+ TestCase.assertEquals( Component.STATE_ACTIVE, cSN.getState() );
+ TestCase.assertEquals( pid, scSN.getProperty( TARGETED_PID ) );
+
+
+ }
+
+
+ private Component getNewComponent(Set<Component> known, Component[] components)
+ {
+ List<Component> cs = new ArrayList(Arrays.asList( components ));
+ cs.removeAll( known );
+ Component c = cs.get( 0 );
+ known.add(c);
+ return c;
+ }
+
+
+}
diff --git a/scr/src/test/resources/integration_test_simple_components_location.xml b/scr/src/test/resources/integration_test_simple_components_location.xml
index 746497d..072c8a6 100644
--- a/scr/src/test/resources/integration_test_simple_components_location.xml
+++ b/scr/src/test/resources/integration_test_simple_components_location.xml
@@ -22,7 +22,8 @@
<!-- component requires configuration -->
<scr:component name="SimpleComponent.configuration.require"
enabled="false"
- configuration-policy="require" >
+ configuration-policy="require"
+ modified="modified" >
<implementation class="org.apache.felix.scr.integration.components.SimpleComponent" />
<property name="service.pid" value="SimpleComponent.configuration.require" />
</scr:component>