Fix namespace handling
[controller.git] / opendaylight / blueprint / src / main / java / org / opendaylight / controller / blueprint / BlueprintBundleTracker.java
index 4d7780147caab1dbdf68cf37131dbc9dbc7f2981..657d6451e882b72d730bc01ae4977ef777a58812 100644 (file)
@@ -11,21 +11,22 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Dictionary;
 import java.util.Enumeration;
 import java.util.HashSet;
-import java.util.Hashtable;
 import java.util.List;
-import javax.annotation.Nullable;
+import java.util.Map;
 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.opendaylight.controller.blueprint.ext.OpendaylightNamespaceHandler;
+import org.opendaylight.yangtools.util.xml.UntrustedXML;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleEvent;
+import org.osgi.framework.FrameworkUtil;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.framework.SynchronousBundleListener;
@@ -50,7 +51,8 @@ import org.slf4j.LoggerFactory;
 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;
 
@@ -73,6 +75,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;
@@ -83,7 +88,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(
@@ -103,7 +108,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(
@@ -145,21 +150,20 @@ 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<>();
-        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(),
+            FrameworkUtil.asDictionary(Map.of(
+                "osgi.service.blueprint.namespace", OpendaylightNamespaceHandler.NAMESPACE_2_0_0)));
     }
 
     private void registerBlueprintEventHandler(final BundleContext context) {
-        eventHandlerReg = context.registerService(BlueprintListener.class.getName(), this, new Hashtable<>());
+        eventHandlerReg = context.registerService(BlueprintListener.class, this, null);
     }
 
     /**
@@ -207,7 +211,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,7 +235,7 @@ public class BlueprintBundleTracker implements BundleActivator, BundleTrackerCus
      * @param event the event to handle
      */
     @Override
-    public void blueprintEvent(BlueprintEvent event) {
+    public void blueprintEvent(final BlueprintEvent event) {
         if (event.getType() == BlueprintEvent.CREATED) {
             LOG.info("Blueprint container for bundle {} was successfully created", event.getBundle());
             return;
@@ -254,13 +258,17 @@ public class BlueprintBundleTracker implements BundleActivator, BundleTrackerCus
         }
     }
 
-    @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);
+    }
+
+    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();
+            return List.of();
         } else {
-            return Collections.list((Enumeration)rntries);
+            return List.copyOf(Collections.list(rntries));
         }
     }
 
@@ -287,7 +295,7 @@ public class BlueprintBundleTracker implements BundleActivator, BundleTrackerCus
         LOG.info("Shutdown of blueprint containers complete");
     }
 
-    private List<Bundle> getBundlesToDestroy(final Collection<Bundle> containerBundles) {
+    private static List<Bundle> getBundlesToDestroy(final Collection<Bundle> containerBundles) {
         List<Bundle> bundlesToDestroy = new ArrayList<>();
 
         // Find all container bundles that either have no registered services or whose services are no
@@ -308,7 +316,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 {
@@ -332,8 +340,7 @@ public class BlueprintBundleTracker implements BundleActivator, BundleTrackerCus
         return bundlesToDestroy;
     }
 
-    @Nullable
-    private Bundle findBundleWithHighestUsedServiceId(final Collection<Bundle> containerBundles) {
+    private static @Nullable Bundle findBundleWithHighestUsedServiceId(final Collection<Bundle> containerBundles) {
         ServiceReference<?> highestServiceRef = null;
         for (Bundle bundle : containerBundles) {
             ServiceReference<?>[] references = bundle.getRegisteredServices();