Return-Path: X-Original-To: apmail-felix-commits-archive@www.apache.org Delivered-To: apmail-felix-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id E5505109E3 for ; Mon, 15 Jul 2013 23:16:00 +0000 (UTC) Received: (qmail 96261 invoked by uid 500); 15 Jul 2013 23:16:00 -0000 Delivered-To: apmail-felix-commits-archive@felix.apache.org Received: (qmail 96222 invoked by uid 500); 15 Jul 2013 23:16:00 -0000 Mailing-List: contact commits-help@felix.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@felix.apache.org Delivered-To: mailing list commits@felix.apache.org Received: (qmail 96215 invoked by uid 99); 15 Jul 2013 23:16:00 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 15 Jul 2013 23:16:00 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 15 Jul 2013 23:15:58 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 1940D238889B; Mon, 15 Jul 2013 23:15:38 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: 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/ Date: Mon, 15 Jul 2013 23:15:37 -0000 To: commits@felix.apache.org From: djencks@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20130715231538.1940D238889B@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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 } 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 imp public void removedService( ServiceReference serviceReference, RefPair 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 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 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 imp RefPair 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, RefPair> 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, RefPair> 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 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 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" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +