Fix blueprint event handling
[controller.git] / opendaylight / blueprint / src / main / java / org / opendaylight / controller / blueprint / BlueprintContainerRestartServiceImpl.java
index 7985c5bce00e2090016986394bc17287033b866e..05a796843aeaa9f3a6f15c31011992a1c38ad930 100644 (file)
@@ -18,7 +18,6 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Deque;
-import java.util.Dictionary;
 import java.util.Hashtable;
 import java.util.LinkedHashSet;
 import java.util.List;
@@ -54,8 +53,8 @@ import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.blueprint.container.EventConstants;
-import org.osgi.service.event.EventHandler;
+import org.osgi.service.blueprint.container.BlueprintEvent;
+import org.osgi.service.blueprint.container.BlueprintListener;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
@@ -88,12 +87,13 @@ class BlueprintContainerRestartServiceImpl implements AutoCloseable, BlueprintCo
     }
 
     public void restartContainer(final Bundle bundle, final List<Object> paths) {
+        LOG.debug("restartContainer for bundle {}", bundle);
+
         if (restartExecutor.isShutdown()) {
+            LOG.debug("Already closed - returning");
             return;
         }
 
-        LOG.debug("restartContainer for bundle {}", bundle);
-
         restartExecutor.execute(() -> {
             blueprintExtenderService.destroyContainer(bundle, blueprintExtenderService.getContainer(bundle));
             blueprintExtenderService.createContainer(bundle, paths);
@@ -111,7 +111,7 @@ class BlueprintContainerRestartServiceImpl implements AutoCloseable, BlueprintCo
         restartExecutor.execute(() -> restartContainerAndDependentsInternal(bundle));
     }
 
-    private void restartContainerAndDependentsInternal(Bundle forBundle) {
+    private void restartContainerAndDependentsInternal(final Bundle forBundle) {
         Preconditions.checkNotNull(blueprintExtenderService);
         Preconditions.checkNotNull(quiesceParticipant);
 
@@ -131,10 +131,17 @@ class BlueprintContainerRestartServiceImpl implements AutoCloseable, BlueprintCo
         // restart config modules.
         final CountDownLatch containerCreationComplete = new CountDownLatch(containerBundles.size());
         ServiceRegistration<?> eventHandlerReg = registerEventHandler(forBundle.getBundleContext(), event -> {
-            final Bundle bundle = (Bundle) event.getProperty(EventConstants.BUNDLE);
-            LOG.debug("handleEvent {} for bundle {}", event.getTopic(), bundle);
-            if (containerBundles.contains(bundle)) {
+            final Bundle bundle = event.getBundle();
+            if (event.isReplay()) {
+                LOG.trace("Got replay BlueprintEvent {} for bundle {}", event.getType(), bundle);
+                return;
+            }
+
+            LOG.debug("Got BlueprintEvent {} for bundle {}", event.getType(), bundle);
+            if (containerBundles.contains(bundle)
+                    && (event.getType() == BlueprintEvent.CREATED || event.getType() == BlueprintEvent.FAILURE)) {
                 containerCreationComplete.countDown();
+                LOG.debug("containerCreationComplete is now {}", containerCreationComplete.getCount());
             }
         });
 
@@ -151,7 +158,7 @@ class BlueprintContainerRestartServiceImpl implements AutoCloseable, BlueprintCo
                         containerBundles, containerBundles.size() - containerCreationComplete.getCount());
                 return;
             }
-        } catch (InterruptedException e) {
+        } catch (final InterruptedException e) {
             LOG.debug("CountDownLatch await was interrupted - returning");
             return;
         }
@@ -160,6 +167,8 @@ class BlueprintContainerRestartServiceImpl implements AutoCloseable, BlueprintCo
 
         // Now restart any associated config system Modules.
         restartConfigModules(forBundle.getBundleContext(), configModules);
+
+        LOG.info("Finished restarting blueprint containers for bundle {} and its dependent bundles", forBundle);
     }
 
     /**
@@ -208,7 +217,7 @@ class BlueprintContainerRestartServiceImpl implements AutoCloseable, BlueprintCo
         }, Collections.singletonList(nextBundle));
     }
 
-    private void createContainers(List<Bundle> containerBundles) {
+    private void createContainers(final List<Bundle> containerBundles) {
         containerBundles.forEach(bundle -> {
             List<Object> paths = BlueprintBundleTracker.findBlueprintPaths(bundle);
 
@@ -218,7 +227,7 @@ class BlueprintContainerRestartServiceImpl implements AutoCloseable, BlueprintCo
         });
     }
 
-    private void restartConfigModules(BundleContext bundleContext, List<Entry<String,
+    private void restartConfigModules(final BundleContext bundleContext, final List<Entry<String,
             ModuleIdentifier>> configModules) {
         if (configModules.isEmpty()) {
             return;
@@ -249,8 +258,8 @@ class BlueprintContainerRestartServiceImpl implements AutoCloseable, BlueprintCo
 
     }
 
-    private void restartConfigModules(List<Entry<String, ModuleIdentifier>> configModules,
-            ConfigSubsystemFacade configFacade) throws ParserConfigurationException, DocumentedException,
+    private void restartConfigModules(final List<Entry<String, ModuleIdentifier>> configModules,
+            final ConfigSubsystemFacade configFacade) throws ParserConfigurationException, DocumentedException,
                     ValidationException, ConflictingVersionException {
 
         Document document = XmlUtil.newDocument();
@@ -274,7 +283,7 @@ class BlueprintContainerRestartServiceImpl implements AutoCloseable, BlueprintCo
                 Element moduleElement = configMapping.moduleToXml(moduleNamespace, moduleId.getFactoryName(),
                         moduleId.getInstanceName(), instanceON, document);
                 modulesElement.appendChild(moduleElement);
-            } catch (InstanceNotFoundException e) {
+            } catch (final InstanceNotFoundException e) {
                 LOG.warn("Error looking up config module: namespace {}, module name {}, instance {}",
                         moduleNamespace, moduleId.getFactoryName(), moduleId.getInstanceName(), e);
             }
@@ -300,8 +309,8 @@ class BlueprintContainerRestartServiceImpl implements AutoCloseable, BlueprintCo
      * @param containerBundles the current set of bundles containing blueprint containers
      * @param configModules the current set of bundles containing config modules
      */
-    private void findDependentContainersRecursively(Bundle bundle, Set<Bundle> containerBundles,
-            List<Entry<String, ModuleIdentifier>> configModules) {
+    private void findDependentContainersRecursively(final Bundle bundle, final Set<Bundle> containerBundles,
+            final List<Entry<String, ModuleIdentifier>> configModules) {
         if (!containerBundles.add(bundle)) {
             // Already seen this bundle...
             return;
@@ -324,8 +333,8 @@ class BlueprintContainerRestartServiceImpl implements AutoCloseable, BlueprintCo
         }
     }
 
-    private void possiblyAddConfigModuleIdentifier(ServiceReference<?> reference,
-            List<Entry<String, ModuleIdentifier>> configModules) {
+    private void possiblyAddConfigModuleIdentifier(final ServiceReference<?> reference,
+            final List<Entry<String, ModuleIdentifier>> configModules) {
         Object moduleNamespace = reference.getProperty(CONFIG_MODULE_NAMESPACE_PROP);
         if (moduleNamespace == null) {
             return;
@@ -347,8 +356,8 @@ class BlueprintContainerRestartServiceImpl implements AutoCloseable, BlueprintCo
     }
 
     @Nullable
-    private String getRequiredConfigModuleProperty(String propName, Object moduleNamespace,
-            ServiceReference<?> reference) {
+    private String getRequiredConfigModuleProperty(final String propName, final Object moduleNamespace,
+            final ServiceReference<?> reference) {
         Object value = reference.getProperty(propName);
         if (value == null) {
             LOG.warn(
@@ -360,15 +369,15 @@ class BlueprintContainerRestartServiceImpl implements AutoCloseable, BlueprintCo
         return value.toString();
     }
 
-    private ServiceRegistration<?> registerEventHandler(BundleContext bundleContext, EventHandler handler) {
-        Dictionary<String, Object> props = new Hashtable<>();
-        props.put(org.osgi.service.event.EventConstants.EVENT_TOPIC,
-                new String[]{EventConstants.TOPIC_CREATED, EventConstants.TOPIC_FAILURE});
-        return bundleContext.registerService(EventHandler.class.getName(), handler, props);
+    private ServiceRegistration<?> registerEventHandler(final BundleContext bundleContext,
+            final BlueprintListener listener) {
+        return bundleContext.registerService(BlueprintListener.class.getName(), listener, new Hashtable<>());
     }
 
     @Override
     public void close() {
+        LOG.debug("Closing");
+
         restartExecutor.shutdownNow();
     }
 }