X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fblueprint%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fblueprint%2Fext%2FAbstractDependentComponentFactoryMetadata.java;h=07bfd8fae862f97002281470aafa85a4ef2bb6b2;hb=e84f63ee098fff5b02cbce1281ca0d1208f966fa;hp=8001c3e4d63461d47e10a5f5619c6e57f6b004fd;hpb=354e9b9cf8686a42add3f81a979a26a963f5be64;p=controller.git diff --git a/opendaylight/blueprint/src/main/java/org/opendaylight/controller/blueprint/ext/AbstractDependentComponentFactoryMetadata.java b/opendaylight/blueprint/src/main/java/org/opendaylight/controller/blueprint/ext/AbstractDependentComponentFactoryMetadata.java index 8001c3e4d6..07bfd8fae8 100644 --- a/opendaylight/blueprint/src/main/java/org/opendaylight/controller/blueprint/ext/AbstractDependentComponentFactoryMetadata.java +++ b/opendaylight/blueprint/src/main/java/org/opendaylight/controller/blueprint/ext/AbstractDependentComponentFactoryMetadata.java @@ -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 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 onServiceRetrieved) { + protected void retrieveService(final String name, final Class interfaceClass, + final Consumer onServiceRetrieved) { retrieveService(name, interfaceClass.getName(), onServiceRetrieved); } - protected void retrieveService(String name, String interfaceName, Consumer 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 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 getOSGiService(Class serviceInterface) { + protected @Nullable T getOSGiService(final Class serviceInterface) { try { ServiceReference 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);