Bug 8879: Migrate controller to the new XML parser
[controller.git] / opendaylight / blueprint / src / main / java / org / opendaylight / controller / blueprint / ext / AbstractDependentComponentFactoryMetadata.java
index c55fa0ce913147b8d554a40693ededf97359aa10..81b374d9fa43420af3a4f2fa670e702d0280d314 100644 (file)
@@ -14,6 +14,7 @@ import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.function.Consumer;
 import javax.annotation.Nullable;
+import javax.annotation.concurrent.GuardedBy;
 import org.apache.aries.blueprint.di.AbstractRecipe;
 import org.apache.aries.blueprint.di.ExecutionContext;
 import org.apache.aries.blueprint.di.Recipe;
@@ -31,19 +32,22 @@ import org.slf4j.LoggerFactory;
  * @author Thomas Pantelis
  */
 abstract class AbstractDependentComponentFactoryMetadata implements DependentComponentFactoryMetadata {
-    private final Logger log = LoggerFactory.getLogger(getClass());
+    final Logger log = LoggerFactory.getLogger(getClass());
     private final String id;
     private final AtomicBoolean started = new AtomicBoolean();
     private final AtomicBoolean satisfied = new AtomicBoolean();
     private final AtomicBoolean restarting = new AtomicBoolean();
+    @GuardedBy("serviceRecipes")
     private final List<StaticServiceReferenceRecipe> serviceRecipes = new ArrayList<>();
     private volatile ExtendedBlueprintContainer container;
     private volatile SatisfactionCallback satisfactionCallback;
     private volatile String failureMessage;
     private volatile Throwable failureCause;
-    private volatile String dependendencyDesc;
+    private volatile String dependencyDesc;
+    @GuardedBy("serviceRecipes")
+    private boolean stoppedServiceRecipes;
 
-    protected AbstractDependentComponentFactoryMetadata(String id) {
+    protected AbstractDependentComponentFactoryMetadata(final String id) {
         this.id = Preconditions.checkNotNull(id);
     }
 
@@ -64,7 +68,7 @@ abstract class AbstractDependentComponentFactoryMetadata implements DependentCom
 
     @Override
     public String getDependencyDescriptor() {
-        return dependendencyDesc;
+        return dependencyDesc;
     }
 
     @Override
@@ -72,17 +76,17 @@ abstract class AbstractDependentComponentFactoryMetadata implements DependentCom
         return satisfied.get();
     }
 
-    protected void setFailureMessage(String failureMessage) {
+    protected void setFailureMessage(final String failureMessage) {
         setFailure(failureMessage, null);
     }
 
-    protected void setFailure(String failureMessage, Throwable failureCause) {
+    protected void setFailure(final String failureMessage, final Throwable failureCause) {
         this.failureMessage = failureMessage;
         this.failureCause = failureCause;
     }
 
-    protected void setDependendencyDesc(String dependendencyDesc) {
-        this.dependendencyDesc = dependendencyDesc;
+    protected void setDependencyDesc(final String dependencyDesc) {
+        this.dependencyDesc = dependencyDesc;
     }
 
     protected final ExtendedBlueprintContainer container() {
@@ -95,17 +99,25 @@ abstract class AbstractDependentComponentFactoryMetadata implements DependentCom
         }
     }
 
-    protected void retrieveService(String name, Class<?> interfaceClass, Consumer<Object> onServiceRetrieved) {
+    protected void retrieveService(final String name, final Class<?> interfaceClass,
+            final Consumer<Object> onServiceRetrieved) {
         retrieveService(name, interfaceClass.getName(), onServiceRetrieved);
     }
 
-    protected void retrieveService(String name, String interfaceName, Consumer<Object> onServiceRetrieved) {
-        StaticServiceReferenceRecipe recipe = new StaticServiceReferenceRecipe(getId() + "-" + name,
-                container, interfaceName);
-        setDependendencyDesc(recipe.getOsgiFilter());
-        serviceRecipes.add(recipe);
+    protected void retrieveService(final String name, final String interfaceName,
+            final Consumer<Object> onServiceRetrieved) {
+        synchronized (serviceRecipes) {
+            if (stoppedServiceRecipes) {
+                return;
+            }
+
+            StaticServiceReferenceRecipe recipe = new StaticServiceReferenceRecipe(getId() + "-" + name,
+                    container, interfaceName);
+            setDependencyDesc(recipe.getOsgiFilter());
+            serviceRecipes.add(recipe);
 
-        recipe.startTracking(onServiceRetrieved);
+            recipe.startTracking(onServiceRetrieved);
+        }
     }
 
     protected final String logName() {
@@ -113,7 +125,7 @@ abstract class AbstractDependentComponentFactoryMetadata implements DependentCom
     }
 
     @Override
-    public void init(ExtendedBlueprintContainer newContainer) {
+    public void init(final ExtendedBlueprintContainer newContainer) {
         this.container = newContainer;
 
         log.debug("{}: In init", logName());
@@ -182,18 +194,21 @@ abstract class AbstractDependentComponentFactoryMetadata implements DependentCom
     }
 
     @Override
-    public void destroy(Object instance) {
+    public void destroy(final Object instance) {
         log.debug("{}: In destroy", logName());
 
         stopServiceRecipes();
     }
 
     private void stopServiceRecipes() {
-        for (StaticServiceReferenceRecipe recipe: serviceRecipes) {
-            recipe.stop();
-        }
+        synchronized (serviceRecipes) {
+            stoppedServiceRecipes = true;
+            for (StaticServiceReferenceRecipe recipe: serviceRecipes) {
+                recipe.stop();
+            }
 
-        serviceRecipes.clear();
+            serviceRecipes.clear();
+        }
     }
 
     protected void restartContainer() {
@@ -208,7 +223,7 @@ abstract class AbstractDependentComponentFactoryMetadata implements DependentCom
 
     @SuppressWarnings("unchecked")
     @Nullable
-    protected <T> T getOSGiService(Class<T> serviceInterface) {
+    protected <T> T getOSGiService(final Class<T> serviceInterface) {
         try {
             ServiceReference<T> serviceReference =
                     container().getBundleContext().getServiceReference(serviceInterface);
@@ -224,7 +239,7 @@ abstract class AbstractDependentComponentFactoryMetadata implements DependentCom
             }
 
             return service;
-        } catch (IllegalStateException e) {
+        } catch (final IllegalStateException e) {
             // This is thrown if the BundleContext is no longer valid which is possible on shutdown so we
             // log as debug.
             log.debug("{}: Error obtaining {}", logName(), serviceInterface.getSimpleName(), e);