Bump upstream SNAPSHOTS
[controller.git] / opendaylight / blueprint / src / main / java / org / opendaylight / controller / blueprint / ext / AbstractDependentComponentFactoryMetadata.java
index 8001c3e4d63461d47e10a5f5619c6e57f6b004fd..07bfd8fae862f97002281470aafa85a4ef2bb6b2 100644 (file)
@@ -7,18 +7,21 @@
  */
 package org.opendaylight.controller.blueprint.ext;
 
-import com.google.common.base.Preconditions;
+import static java.util.Objects.requireNonNull;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.function.Consumer;
-import javax.annotation.Nullable;
 import org.apache.aries.blueprint.di.AbstractRecipe;
 import org.apache.aries.blueprint.di.ExecutionContext;
 import org.apache.aries.blueprint.di.Recipe;
 import org.apache.aries.blueprint.ext.DependentComponentFactoryMetadata;
 import org.apache.aries.blueprint.services.ExtendedBlueprintContainer;
+import org.checkerframework.checker.lock.qual.GuardedBy;
+import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.controller.blueprint.BlueprintContainerRestartService;
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.blueprint.container.ComponentDefinitionException;
@@ -26,23 +29,29 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
+ * Abstract base class for a DependentComponentFactoryMetadata implementation.
+ *
  * @author Thomas Pantelis
  */
 abstract class AbstractDependentComponentFactoryMetadata implements DependentComponentFactoryMetadata {
-    private final Logger log = LoggerFactory.getLogger(getClass());
+    @SuppressFBWarnings("SLF4J_LOGGER_SHOULD_BE_PRIVATE")
+    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) {
-        this.id = Preconditions.checkNotNull(id);
+    protected AbstractDependentComponentFactoryMetadata(final String id) {
+        this.id = requireNonNull(id);
     }
 
     @Override
@@ -62,7 +71,7 @@ abstract class AbstractDependentComponentFactoryMetadata implements DependentCom
 
     @Override
     public String getDependencyDescriptor() {
-        return dependendencyDesc;
+        return dependencyDesc;
     }
 
     @Override
@@ -70,19 +79,18 @@ abstract class AbstractDependentComponentFactoryMetadata implements DependentCom
         return satisfied.get();
     }
 
-    protected abstract void startTracking();
-
-    protected void setFailureMessage(String failureMessage) {
+    protected void setFailureMessage(final String failureMessage) {
         setFailure(failureMessage, null);
     }
 
-    protected void setFailure(String failureMessage, Throwable failureCause) {
+    @SuppressWarnings("checkstyle:hiddenField")
+    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() {
@@ -90,38 +98,45 @@ abstract class AbstractDependentComponentFactoryMetadata implements DependentCom
     }
 
     protected void setSatisfied() {
-        if(satisfied.compareAndSet(false, true)) {
+        if (satisfied.compareAndSet(false, true)) {
             satisfactionCallback.notifyChanged();
         }
     }
 
-    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() {
-        return (container != null ? container.getBundleContext().getBundle().getSymbolicName() : "") +
-                " (" + id + ")";
+        return (container != null ? container.getBundleContext().getBundle().getSymbolicName() : "") + " (" + id + ")";
     }
 
     @Override
-    public void init(ExtendedBlueprintContainer container) {
-        this.container = container;
+    public void init(final ExtendedBlueprintContainer newContainer) {
+        this.container = newContainer;
 
         log.debug("{}: In init", logName());
     }
 
     protected void onCreate() throws ComponentDefinitionException {
-        if(failureMessage != null) {
+        if (failureMessage != null) {
             throw new ComponentDefinitionException(failureMessage, failureCause);
         }
 
@@ -152,7 +167,7 @@ abstract class AbstractDependentComponentFactoryMetadata implements DependentCom
         executionContext.removePartialObject(id);
 
         Recipe myRecipe = executionContext.getRecipe(id);
-        if(myRecipe instanceof AbstractRecipe) {
+        if (myRecipe instanceof AbstractRecipe) {
             log.debug("{}: setPrototype to false", logName());
             ((AbstractRecipe)myRecipe).setPrototype(false);
         } else {
@@ -160,15 +175,17 @@ abstract class AbstractDependentComponentFactoryMetadata implements DependentCom
         }
     }
 
+    protected abstract void startTracking();
+
     @Override
-    public final void startTracking(final SatisfactionCallback satisfactionCallback) {
-        if(!started.compareAndSet(false, true)) {
+    public final void startTracking(final SatisfactionCallback newSatisfactionCallback) {
+        if (!started.compareAndSet(false, true)) {
             return;
         }
 
         log.debug("{}: In startTracking", logName());
 
-        this.satisfactionCallback = satisfactionCallback;
+        this.satisfactionCallback = newSatisfactionCallback;
 
         startTracking();
     }
@@ -181,24 +198,27 @@ 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() {
-        if(restarting.compareAndSet(false, true)) {
+        if (restarting.compareAndSet(false, true)) {
             BlueprintContainerRestartService restartService = getOSGiService(BlueprintContainerRestartService.class);
-            if(restartService != null) {
+            if (restartService != null) {
                 log.debug("{}: Restarting container", logName());
                 restartService.restartContainerAndDependents(container().getBundleContext().getBundle());
             }
@@ -206,24 +226,23 @@ abstract class AbstractDependentComponentFactoryMetadata implements DependentCom
     }
 
     @SuppressWarnings("unchecked")
-    @Nullable
-    protected <T> T getOSGiService(Class<T> serviceInterface) {
+    protected <T> @Nullable T getOSGiService(final Class<T> serviceInterface) {
         try {
             ServiceReference<T> serviceReference =
                     container().getBundleContext().getServiceReference(serviceInterface);
-            if(serviceReference == null) {
+            if (serviceReference == null) {
                 log.warn("{}: {} reference not found", logName(), serviceInterface.getSimpleName());
                 return null;
             }
 
             T service = (T)container().getService(serviceReference);
-            if(service == null) {
+            if (service == null) {
                 // This could happen on shutdown if the service was already unregistered so we log as debug.
                 log.debug("{}: {} was not found", logName(), serviceInterface.getSimpleName());
             }
 
             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);