Bump odlparent to 6.0.0
[controller.git] / opendaylight / blueprint / src / main / java / org / opendaylight / controller / blueprint / BlueprintBundleTracker.java
index 5119c90363794b2b71334e3fc4ac17d1e2d8ae29..8812650aa681474e881c9ea39f7476671b85a1e3 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.controller.blueprint;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -16,13 +17,14 @@ import java.util.Enumeration;
 import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.List;
-import javax.annotation.Nullable;
 import org.apache.aries.blueprint.NamespaceHandler;
 import org.apache.aries.blueprint.services.BlueprintExtenderService;
 import org.apache.aries.quiesce.participant.QuiesceParticipant;
 import org.apache.aries.util.AriesFrameworkUtil;
+import org.eclipse.jdt.annotation.Nullable;
+import org.gaul.modernizer_maven_annotations.SuppressModernizer;
 import org.opendaylight.controller.blueprint.ext.OpendaylightNamespaceHandler;
-import org.opendaylight.controller.config.api.ConfigSystemService;
+import org.opendaylight.yangtools.util.xml.UntrustedXML;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
@@ -31,9 +33,8 @@ import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.framework.SynchronousBundleListener;
 import org.osgi.service.blueprint.container.BlueprintContainer;
-import org.osgi.service.blueprint.container.EventConstants;
-import org.osgi.service.event.Event;
-import org.osgi.service.event.EventHandler;
+import org.osgi.service.blueprint.container.BlueprintEvent;
+import org.osgi.service.blueprint.container.BlueprintListener;
 import org.osgi.util.tracker.BundleTracker;
 import org.osgi.util.tracker.BundleTrackerCustomizer;
 import org.osgi.util.tracker.ServiceTracker;
@@ -49,10 +50,11 @@ import org.slf4j.LoggerFactory;
  *
  * @author Thomas Pantelis
  */
-public class BlueprintBundleTracker implements BundleActivator, BundleTrackerCustomizer<Bundle>, EventHandler,
+public class BlueprintBundleTracker implements BundleActivator, BundleTrackerCustomizer<Bundle>, BlueprintListener,
         SynchronousBundleListener {
     private static final Logger LOG = LoggerFactory.getLogger(BlueprintBundleTracker.class);
-    private static final String BLUEPRINT_FILE_PATH = "org/opendaylight/blueprint/";
+    private static final String ODL_CUSTOM_BLUEPRINT_FILE_PATH = "org/opendaylight/blueprint/";
+    private static final String STANDARD_BLUEPRINT_FILE_PATH = "OSGI-INF/blueprint/";
     private static final String BLUEPRINT_FLE_PATTERN = "*.xml";
     private static final long SYSTEM_BUNDLE_ID = 0;
 
@@ -75,6 +77,9 @@ public class BlueprintBundleTracker implements BundleActivator, BundleTrackerCus
     public void start(final BundleContext context) {
         LOG.info("Starting {}", getClass().getSimpleName());
 
+        // CONTROLLER-1867: force UntrustedXML initialization, so that it uses our TCCL to initialize
+        UntrustedXML.newDocumentBuilder();
+
         restartService = new BlueprintContainerRestartServiceImpl();
 
         bundleContext = context;
@@ -85,7 +90,7 @@ public class BlueprintBundleTracker implements BundleActivator, BundleTrackerCus
 
         bundleTracker = new BundleTracker<>(context, Bundle.ACTIVE, this);
 
-        blueprintExtenderServiceTracker = new ServiceTracker<>(context, BlueprintExtenderService.class.getName(),
+        blueprintExtenderServiceTracker = new ServiceTracker<>(context, BlueprintExtenderService.class,
                 new ServiceTrackerCustomizer<BlueprintExtenderService, BlueprintExtenderService>() {
                     @Override
                     public BlueprintExtenderService addingService(
@@ -105,7 +110,7 @@ public class BlueprintBundleTracker implements BundleActivator, BundleTrackerCus
                 });
         blueprintExtenderServiceTracker.open();
 
-        quiesceParticipantTracker = new ServiceTracker<>(context, QuiesceParticipant.class.getName(),
+        quiesceParticipantTracker = new ServiceTracker<>(context, QuiesceParticipant.class,
                 new ServiceTrackerCustomizer<QuiesceParticipant, QuiesceParticipant>() {
                     @Override
                     public QuiesceParticipant addingService(
@@ -126,6 +131,8 @@ public class BlueprintBundleTracker implements BundleActivator, BundleTrackerCus
         quiesceParticipantTracker.open();
     }
 
+    @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
+            justification = "https://github.com/spotbugs/spotbugs/issues/811")
     private QuiesceParticipant onQuiesceParticipantAdded(final ServiceReference<QuiesceParticipant> reference) {
         quiesceParticipant = reference.getBundle().getBundleContext().getService(reference);
 
@@ -136,6 +143,8 @@ public class BlueprintBundleTracker implements BundleActivator, BundleTrackerCus
         return quiesceParticipant;
     }
 
+    @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
+            justification = "https://github.com/spotbugs/spotbugs/issues/811")
     private BlueprintExtenderService onBlueprintExtenderServiceAdded(
             final ServiceReference<BlueprintExtenderService> reference) {
         blueprintExtenderService = reference.getBundle().getBundleContext().getService(reference);
@@ -147,24 +156,25 @@ public class BlueprintBundleTracker implements BundleActivator, BundleTrackerCus
 
         restartService.setBlueprintExtenderService(blueprintExtenderService);
 
-        blueprintContainerRestartReg = bundleContext.registerService(
-                BlueprintContainerRestartService.class.getName(), restartService, new Hashtable<>());
+        blueprintContainerRestartReg = bundleContext.registerService(BlueprintContainerRestartService.class,
+            restartService, null);
 
         return blueprintExtenderService;
     }
 
     private void registerNamespaceHandler(final BundleContext context) {
-        Dictionary<String, Object> props = new Hashtable<>();
+        Dictionary<String, Object> props = emptyDict();
         props.put("osgi.service.blueprint.namespace", OpendaylightNamespaceHandler.NAMESPACE_1_0_0);
-        namespaceReg = context.registerService(NamespaceHandler.class.getName(),
-                new OpendaylightNamespaceHandler(), props);
+        namespaceReg = context.registerService(NamespaceHandler.class, new OpendaylightNamespaceHandler(), props);
     }
 
     private void registerBlueprintEventHandler(final BundleContext context) {
-        Dictionary<String, Object> props = new Hashtable<>();
-        props.put(org.osgi.service.event.EventConstants.EVENT_TOPIC,
-                new String[]{EventConstants.TOPIC_CREATED, EventConstants.TOPIC_FAILURE});
-        eventHandlerReg = context.registerService(EventHandler.class.getName(), this, props);
+        eventHandlerReg = context.registerService(BlueprintListener.class, this, null);
+    }
+
+    @SuppressModernizer
+    private static Dictionary<String, Object> emptyDict() {
+        return new Hashtable<>();
     }
 
     /**
@@ -212,7 +222,7 @@ public class BlueprintBundleTracker implements BundleActivator, BundleTrackerCus
         }
 
         if (bundle.getState() == Bundle.ACTIVE) {
-            List<Object> paths = findBlueprintPaths(bundle);
+            List<Object> paths = findBlueprintPaths(bundle, ODL_CUSTOM_BLUEPRINT_FILE_PATH);
 
             if (!paths.isEmpty()) {
                 LOG.info("Creating blueprint container for bundle {} with paths {}", bundle, paths);
@@ -231,15 +241,14 @@ public class BlueprintBundleTracker implements BundleActivator, BundleTrackerCus
     }
 
     /**
-     * Implemented from EventHandler to listen for blueprint events.
+     * Implemented from BlueprintListener to listen for blueprint events.
      *
      * @param event the event to handle
      */
     @Override
-    public void handleEvent(final Event event) {
-        if (EventConstants.TOPIC_CREATED.equals(event.getTopic())) {
-            LOG.info("Blueprint container for bundle {} was successfully created",
-                    event.getProperty(EventConstants.BUNDLE));
+    public void blueprintEvent(final BlueprintEvent event) {
+        if (event.getType() == BlueprintEvent.CREATED) {
+            LOG.info("Blueprint container for bundle {} was successfully created", event.getBundle());
             return;
         }
 
@@ -247,23 +256,27 @@ public class BlueprintBundleTracker implements BundleActivator, BundleTrackerCus
         // is indicated via a non-null DEPENDENCIES property containing the missing dependencies. The
         // default timeout is 5 min and ideally we would set this to infinite but the timeout can only
         // be set at the bundle level in the manifest - there's no way to set it globally.
-        if (EventConstants.TOPIC_FAILURE.equals(event.getTopic())
-                && event.getProperty(EventConstants.DEPENDENCIES) != null) {
-            Bundle bundle = (Bundle) event.getProperty(EventConstants.BUNDLE);
+        if (event.getType() == BlueprintEvent.FAILURE && event.getDependencies() != null) {
+            Bundle bundle = event.getBundle();
 
             List<Object> paths = findBlueprintPaths(bundle);
             if (!paths.isEmpty()) {
                 LOG.warn("Blueprint container for bundle {} timed out waiting for dependencies - restarting it",
-                        event.getProperty(EventConstants.BUNDLE));
+                        bundle);
 
                 restartService.restartContainer(bundle, paths);
             }
         }
     }
 
-    @SuppressWarnings({ "rawtypes", "unchecked" })
     static List<Object> findBlueprintPaths(final Bundle bundle) {
-        Enumeration<?> rntries = bundle.findEntries(BLUEPRINT_FILE_PATH, BLUEPRINT_FLE_PATTERN, false);
+        List<Object> paths = findBlueprintPaths(bundle, STANDARD_BLUEPRINT_FILE_PATH);
+        return !paths.isEmpty() ? paths : findBlueprintPaths(bundle, ODL_CUSTOM_BLUEPRINT_FILE_PATH);
+    }
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    private static List<Object> findBlueprintPaths(final Bundle bundle, final String path) {
+        Enumeration<?> rntries = bundle.findEntries(path, BLUEPRINT_FLE_PATTERN, false);
         if (rntries == null) {
             return Collections.emptyList();
         } else {
@@ -276,12 +289,6 @@ public class BlueprintBundleTracker implements BundleActivator, BundleTrackerCus
 
         restartService.close();
 
-        // Close all CSS modules first.
-        ConfigSystemService configSystem = getOSGiService(ConfigSystemService.class);
-        if (configSystem != null) {
-            configSystem.closeAllConfigModules();
-        }
-
         LOG.info("Shutting down all blueprint containers...");
 
         Collection<Bundle> containerBundles = new HashSet<>(Arrays.asList(bundleContext.getBundles()));
@@ -321,7 +328,7 @@ public class BlueprintBundleTracker implements BundleActivator, BundleTrackerCus
         }
 
         if (!bundlesToDestroy.isEmpty()) {
-            Collections.sort(bundlesToDestroy, (b1, b2) -> (int) (b2.getLastModified() - b1.getLastModified()));
+            bundlesToDestroy.sort((b1, b2) -> (int) (b2.getLastModified() - b1.getLastModified()));
 
             LOG.debug("Selected bundles {} for destroy (no services in use)", bundlesToDestroy);
         } else {
@@ -345,8 +352,7 @@ public class BlueprintBundleTracker implements BundleActivator, BundleTrackerCus
         return bundlesToDestroy;
     }
 
-    @Nullable
-    private Bundle findBundleWithHighestUsedServiceId(final Collection<Bundle> containerBundles) {
+    private @Nullable Bundle findBundleWithHighestUsedServiceId(final Collection<Bundle> containerBundles) {
         ServiceReference<?> highestServiceRef = null;
         for (Bundle bundle : containerBundles) {
             ServiceReference<?>[] references = bundle.getRegisteredServices();
@@ -377,28 +383,4 @@ public class BlueprintBundleTracker implements BundleActivator, BundleTrackerCus
         Bundle[] usingBundles = ref.getUsingBundles();
         return usingBundles != null ? usingBundles.length : 0;
     }
-
-    private <T> T getOSGiService(final Class<T> serviceInterface) {
-        try {
-            ServiceReference<T> serviceReference = bundleContext.getServiceReference(serviceInterface);
-            if (serviceReference == null) {
-                LOG.warn("{} service reference not found", serviceInterface.getSimpleName());
-                return null;
-            }
-
-            T service = bundleContext.getService(serviceReference);
-            if (service == null) {
-                // This could happen on shutdown if the service was already unregistered so we log as debug.
-                LOG.debug("{} service instance was not found", serviceInterface.getSimpleName());
-            }
-
-            return service;
-        } 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 OSGi service {}", serviceInterface.getSimpleName(), e);
-        }
-
-        return null;
-    }
 }