You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by dj...@apache.org on 2013/07/16 01:15:37 UTC

svn commit: r1503516 - in /felix/trunk/scr/src: main/java/org/apache/felix/scr/impl/config/ main/java/org/apache/felix/scr/impl/manager/ test/java/org/apache/felix/scr/integration/ test/resources/

Author: djencks
Date: Mon Jul 15 23:15:37 2013
New Revision: 1503516

URL: http://svn.apache.org/r1503516
Log:
FELIX-4166 unregister service if it becomes unsatisfied before being created

Modified:
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ImmediateComponentHolder.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
    felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentActivationTest.java
    felix/trunk/scr/src/test/resources/integration_test_activation_components.xml

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ImmediateComponentHolder.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ImmediateComponentHolder.java?rev=1503516&r1=1503515&r2=1503516&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ImmediateComponentHolder.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ImmediateComponentHolder.java Mon Jul 15 23:15:37 2013
@@ -254,7 +254,7 @@ public class ImmediateComponentHolder<S>
         }
         else
         {
-            icm.disposeInternal( ComponentConstants.DEACTIVATION_REASON_CONFIGURATION_DELETED );
+            icm.dispose( ComponentConstants.DEACTIVATION_REASON_CONFIGURATION_DELETED );
         }
     }
 

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java?rev=1503516&r1=1503515&r2=1503516&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java Mon Jul 15 23:15:37 2013
@@ -701,7 +701,7 @@ public abstract class AbstractComponentM
         {
             log( LogService.LOG_DEBUG, "ActivateInternal: disposed",
                     null );
-            throw new IllegalStateException( "Cannot activate disposed component: " + getName() );
+            return;
         }
         if ( m_activated ) {
             log( LogService.LOG_DEBUG, "ActivateInternal: already activated",
@@ -769,7 +769,7 @@ public abstract class AbstractComponentM
     {
         if ( disposed )
         {
-            throw new IllegalStateException( "Cannot deactivate disposed component " + getName() );
+            return;
         }
         if ( m_factoryInstance )
         {
@@ -807,7 +807,7 @@ public abstract class AbstractComponentM
      * method has to actually complete before other actions like bundle stopping
      * may continue.
      */
-    public final void disposeInternal( int reason )
+    final void disposeInternal( int reason )
     {
         log( LogService.LOG_DEBUG, "Disposing component (reason: " + reason + ")", null );
         if ( m_activated )

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java?rev=1503516&r1=1503515&r2=1503516&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java Mon Jul 15 23:15:37 2013
@@ -348,29 +348,24 @@ public class DependencyManager<S, T> imp
         public void removedService( ServiceReference<T> serviceReference, RefPair<T> refPair, int trackingCount )
         {
             m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleDynamic removed {2} (enter)", new Object[] {getName(), trackingCount, serviceReference}, null );
-            if ( isActive() )
+            boolean unbind = isOptional() || !getTracker().isEmpty();
+            if ( unbind )
             {
-                boolean unbind = isOptional() || !getTracker().isEmpty();
-                if ( unbind )
+                if ( isActive() )
                 {
                     m_componentManager.invokeUnbindMethod( DependencyManager.this, refPair, trackingCount );
-                    m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleDynamic removed (unbind) {2}", new Object[] {getName(), trackingCount, serviceReference}, null );
-                    tracked( trackingCount );
-                }
-                else
-                {
-                    lastRefPair = refPair;
-                    lastRefPairTrackingCount = trackingCount;
-                    tracked( trackingCount );
-                    m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false, trackingCount );
-                    lastRefPair = null;
-                    m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleDynamic removed (deactivate) {2}", new Object[] {getName(), trackingCount, serviceReference}, null );
                 }
+                m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleDynamic removed (unbind) {2}", new Object[] {getName(), trackingCount, serviceReference}, null );
+                tracked( trackingCount );
             }
             else
             {
-                m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleDynamic removed (inactive) {2}", new Object[] {getName(), trackingCount, serviceReference}, null );
+                lastRefPair = refPair;
+                lastRefPairTrackingCount = trackingCount;
                 tracked( trackingCount );
+                m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false, trackingCount );
+                lastRefPair = null;
+                m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleDynamic removed (deactivate) {2}", new Object[] {getName(), trackingCount, serviceReference}, null );
             }
             ungetService( refPair );
         }
@@ -485,6 +480,13 @@ public class DependencyManager<S, T> imp
                 //try to reactivate after ref is no longer tracked.
                 m_componentManager.activateInternal( trackingCount );
             }
+            else if ( !isOptional() && getTracker().isEmpty() )
+            {
+                m_componentManager.log( LogService.LOG_DEBUG,
+                        "Dependency Manager: Static dependency on {0}/{1} is broken", new Object[]
+                        {getName(), m_dependencyMetadata.getInterface()}, null );
+                m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false, trackingCount );                
+            }
             //This is unlikely
             ungetService( refPair );
             m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleStaticGreedy removed {2} (exit)", new Object[] {getName(), trackingCount, serviceReference}, null );
@@ -584,6 +586,13 @@ public class DependencyManager<S, T> imp
 
                 }
             }
+            else if ( !isOptional() && getTracker().isEmpty() )
+            {
+                m_componentManager.log( LogService.LOG_DEBUG,
+                        "Dependency Manager: Static dependency on {0}/{1} is broken", new Object[]
+                        {getName(), m_dependencyMetadata.getInterface()}, null );
+                m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false, trackingCount );                
+            }
             ungetService( refPair );
             m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleStaticReluctant removed {2} (exit)", new Object[] {getName(), trackingCount, serviceReference}, null );
         }
@@ -743,27 +752,28 @@ public class DependencyManager<S, T> imp
             RefPair<T> nextRefPair = null;
             synchronized ( getTracker().tracked() )
             {
-                if ( refPair == this.refPair )
+                if ( refPair == this.refPair && isActive() )
                 {
-                    if ( isActive() )
+                    if ( !getTracker().isEmpty() )
                     {
-                        if ( !getTracker().isEmpty() )
-                        {
-                            AtomicInteger trackingCount2 = new AtomicInteger();
-                            SortedMap<ServiceReference<T>, RefPair<T>> tracked = getTracker().getTracked( true,
-                                    trackingCount2 );
-                            nextRefPair = tracked.values().iterator().next();
-                        }
-                        if ( isOptional() || nextRefPair != null )
-                        {
-                            oldRefPair = this.refPair;
-                            this.refPair = null;
-                        }
-                        else 
-                        {
-                            deactivate = true;            //required and no replacement service, deactivate
-                        }
+                        AtomicInteger trackingCount2 = new AtomicInteger();
+                        SortedMap<ServiceReference<T>, RefPair<T>> tracked = getTracker().getTracked( true,
+                                trackingCount2 );
+                        nextRefPair = tracked.values().iterator().next();
+                    }
+                    if ( isOptional() || nextRefPair != null )
+                    {
+                        oldRefPair = this.refPair;
+                        this.refPair = null;
                     }
+                    else 
+                    {
+                        deactivate = true;            //required and no replacement service, deactivate
+                    }
+                }
+                else if ( !isOptional() && this.refPair == null && getTracker().isEmpty())
+                {
+                    deactivate = true;
                 }
             }
             if ( nextRefPair != null )
@@ -947,7 +957,7 @@ public class DependencyManager<S, T> imp
             boolean reactivate;
             synchronized (getTracker().tracked())
             {
-                reactivate = isActive() && refPair == this.refPair;
+                reactivate = ( isActive() && refPair == this.refPair) || ( !isOptional() && getTracker().isEmpty());
             }
             if ( reactivate )
             {

Modified: felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentActivationTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentActivationTest.java?rev=1503516&r1=1503515&r2=1503516&view=diff
==============================================================================
--- felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentActivationTest.java (original)
+++ felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentActivationTest.java Mon Jul 15 23:15:37 2013
@@ -23,6 +23,8 @@ import junit.framework.TestCase;
 
 import org.apache.felix.scr.Component;
 import org.apache.felix.scr.integration.components.ActivatorComponent;
+import org.apache.felix.scr.integration.components.SimpleService;
+import org.apache.felix.scr.integration.components.SimpleServiceImpl;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.ops4j.pax.exam.junit.JUnit4TestRunner;
@@ -244,6 +246,7 @@ public class ComponentActivationTest ext
         delay();
         TestCase.assertEquals( Component.STATE_DISABLED, component.getState() );
     }
+    
     @Test
     public void test_activate_service_factory_register_service()
     {
@@ -272,4 +275,75 @@ public class ComponentActivationTest ext
         delay();
         TestCase.assertEquals( Component.STATE_DISABLED, component.getState() );
     }
+    
+    @Test
+    public void test_activate_register_service_single_static_dependency()
+    {
+        final String componentname = "ActivatorComponent.bind.single.static";
+
+        testRequiredDependency( componentname );
+    }
+
+    @Test
+    public void test_activate_register_service_multiple_static_dependency()
+    {
+        final String componentname = "ActivatorComponent.bind.multiple.static";
+
+        testRequiredDependency( componentname );
+    }
+
+    @Test
+    public void test_activate_register_service_single_dynamic_dependency()
+    {
+        final String componentname = "ActivatorComponent.bind.single.dynamic";
+
+        testRequiredDependency( componentname );
+    }
+
+    @Test
+    public void test_activate_register_service_multiple_dynamic_dependency()
+    {
+        final String componentname = "ActivatorComponent.bind.multiple.dynamic";
+
+        testRequiredDependency( componentname );
+    }
+
+
+    private void testRequiredDependency(final String componentname)
+    {
+        final Component component = findComponentByName( componentname );
+
+        TestCase.assertNotNull( component );
+        TestCase.assertFalse( component.isDefaultEnabled() );
+
+        TestCase.assertEquals( Component.STATE_DISABLED, component.getState() );
+
+        component.enable();
+        delay();
+
+        TestCase.assertEquals( Component.STATE_UNSATISFIED, component.getState() );
+        
+        SimpleServiceImpl ss = SimpleServiceImpl.create( bundleContext, "foo" );
+        
+        TestCase.assertEquals( Component.STATE_REGISTERED, component.getState() );
+
+        ServiceReference<ActivatorComponent> ref = bundleContext.getServiceReference( ActivatorComponent.class );
+        
+        ss.drop();
+        TestCase.assertEquals( Component.STATE_UNSATISFIED, component.getState() );
+        
+        TestCase.assertNull(bundleContext.getServiceReference( ActivatorComponent.class ));
+        ss = SimpleServiceImpl.create( bundleContext, "foo" );
+        ref = bundleContext.getServiceReference( ActivatorComponent.class );
+        ActivatorComponent ac = bundleContext.getService( ref );
+        TestCase.assertNotNull( ac.getSimpleService() );
+
+        TestCase.assertEquals( Component.STATE_ACTIVE, component.getState() );
+
+        component.disable();
+
+        delay();
+        TestCase.assertEquals( Component.STATE_DISABLED, component.getState() );
+    }
+
 }

Modified: felix/trunk/scr/src/test/resources/integration_test_activation_components.xml
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/test/resources/integration_test_activation_components.xml?rev=1503516&r1=1503515&r2=1503516&view=diff
==============================================================================
--- felix/trunk/scr/src/test/resources/integration_test_activation_components.xml (original)
+++ felix/trunk/scr/src/test/resources/integration_test_activation_components.xml Mon Jul 15 23:15:37 2013
@@ -127,4 +127,86 @@
             cardinality="0..n"
         />
     </scr:component>
+
+    <!-- 11 static dependency -->
+    <scr:component name="ActivatorComponent.bind.single.static"
+        enabled="false"
+        activate="myActivate"
+        deactivate="myDeactivate">
+        <implementation class="org.apache.felix.scr.integration.components.ActivatorComponent" />
+        <service factory="false">
+            <provide interface="org.apache.felix.scr.integration.components.ActivatorComponent"/>
+        </service>
+        <property name="registerService" value="true" />
+        <reference
+            name="service"
+            interface="org.apache.felix.scr.integration.components.SimpleService"
+            bind="bindSimpleService"
+            unbind="unbindSimpleService"
+            policy="static"
+            cardinality="1..1"
+        />
+    </scr:component>
+
+    <!-- 1n static dependency -->
+    <scr:component name="ActivatorComponent.bind.multiple.static"
+        enabled="false"
+        activate="myActivate"
+        deactivate="myDeactivate">
+        <implementation class="org.apache.felix.scr.integration.components.ActivatorComponent" />
+        <service factory="false">
+            <provide interface="org.apache.felix.scr.integration.components.ActivatorComponent"/>
+        </service>
+        <property name="registerService" value="true" />
+        <reference
+            name="service"
+            interface="org.apache.felix.scr.integration.components.SimpleService"
+            bind="bindSimpleService"
+            unbind="unbindSimpleService"
+            policy="static"
+            cardinality="1..n"
+        />
+    </scr:component>
+
+    <!-- 11 dynamic dependency -->
+    <scr:component name="ActivatorComponent.bind.single.dynamic"
+        enabled="false"
+        activate="myActivate"
+        deactivate="myDeactivate">
+        <implementation class="org.apache.felix.scr.integration.components.ActivatorComponent" />
+        <service factory="false">
+            <provide interface="org.apache.felix.scr.integration.components.ActivatorComponent"/>
+        </service>
+        <property name="registerService" value="true" />
+        <reference
+            name="service"
+            interface="org.apache.felix.scr.integration.components.SimpleService"
+            bind="bindSimpleService"
+            unbind="unbindSimpleService"
+            policy="dynamic"
+            cardinality="1..1"
+        />
+    </scr:component>
+
+    <!-- 11 static dependency -->
+    <scr:component name="ActivatorComponent.bind.multiple.dynamic"
+        enabled="false"
+        activate="myActivate"
+        deactivate="myDeactivate">
+        <implementation class="org.apache.felix.scr.integration.components.ActivatorComponent" />
+        <service factory="false">
+            <provide interface="org.apache.felix.scr.integration.components.ActivatorComponent"/>
+        </service>
+        <property name="registerService" value="true" />
+        <reference
+            name="service"
+            interface="org.apache.felix.scr.integration.components.SimpleService"
+            bind="bindSimpleService"
+            unbind="unbindSimpleService"
+            policy="dynamic"
+            cardinality="1..n"
+        />
+    </scr:component>
+
+
 </components>