config-manager: final parameters
[controller.git] / opendaylight / config / config-manager / src / main / java / org / opendaylight / controller / config / manager / impl / osgi / BeanToOsgiServiceManager.java
index 01afe223bbc82c681be967f8e4a2add32ba676a4..ff504dafdcac22176d798569836bfe6e5ce460c7 100644 (file)
@@ -7,22 +7,20 @@
  */
 package org.opendaylight.controller.config.manager.impl.osgi;
 
-import org.opendaylight.controller.config.api.ModuleIdentifier;
-import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.annotation.concurrent.GuardedBy;
+import com.google.common.base.Preconditions;
 import java.util.Dictionary;
 import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
-
-import static com.google.common.base.Preconditions.checkState;
+import javax.annotation.concurrent.GuardedBy;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Registers instantiated beans as OSGi services and unregisters these services
@@ -36,21 +34,14 @@ public class BeanToOsgiServiceManager {
      * It is expected that before using this method OSGi service registry will
      * be cleaned from previous registrations.
      */
-    public OsgiRegistration registerToOsgi(AutoCloseable instance, ModuleIdentifier moduleIdentifier,
-                                           BundleContext bundleContext,
-                                           Map<String, ServiceInterfaceAnnotation> serviceNamesToAnnotations) {
+    public OsgiRegistration registerToOsgi(final AutoCloseable instance, final ModuleIdentifier moduleIdentifier,
+                                           final BundleContext bundleContext,
+                                           final Map<ServiceInterfaceAnnotation, String /* service ref name */> serviceNamesToAnnotations) {
         return new OsgiRegistration(instance, moduleIdentifier, bundleContext, serviceNamesToAnnotations);
     }
 
-    private static Dictionary<String, String> createProps(String serviceName) {
-        Hashtable<String, String> result = new Hashtable<>();
-        result.put(SERVICE_NAME_OSGI_PROP, serviceName);
-        return result;
-    }
-
-
     public static class OsgiRegistration implements AutoCloseable {
-        private static final Logger logger = LoggerFactory.getLogger(OsgiRegistration.class);
+        private static final Logger LOG = LoggerFactory.getLogger(OsgiRegistration.class);
 
         @GuardedBy("this")
         private AutoCloseable instance;
@@ -58,25 +49,32 @@ public class BeanToOsgiServiceManager {
         @GuardedBy("this")
         private final Set<ServiceRegistration<?>> serviceRegistrations;
         @GuardedBy("this")
-        private final Map<String, ServiceInterfaceAnnotation> serviceNamesToAnnotations;
+        private final Map<ServiceInterfaceAnnotation, String /* service ref name */> serviceNamesToAnnotations;
 
-        public OsgiRegistration(AutoCloseable instance, ModuleIdentifier moduleIdentifier,
-                                BundleContext bundleContext,
-                                Map<String, ServiceInterfaceAnnotation> serviceNamesToAnnotations) {
+        public OsgiRegistration(final AutoCloseable instance, final ModuleIdentifier moduleIdentifier,
+                                final BundleContext bundleContext,
+                                final Map<ServiceInterfaceAnnotation, String /* service ref name */> serviceNamesToAnnotations) {
             this.instance = instance;
             this.moduleIdentifier = moduleIdentifier;
             this.serviceNamesToAnnotations = serviceNamesToAnnotations;
             this.serviceRegistrations = registerToSR(instance, bundleContext, serviceNamesToAnnotations);
         }
 
-        private static Set<ServiceRegistration<?>> registerToSR(AutoCloseable instance, BundleContext bundleContext,
-                                                                Map<String, ServiceInterfaceAnnotation> serviceNamesToAnnotations) {
+        private static Set<ServiceRegistration<?>> registerToSR(final AutoCloseable instance, final BundleContext bundleContext,
+                                                                final Map<ServiceInterfaceAnnotation, String /* service ref name */> serviceNamesToAnnotations) {
             Set<ServiceRegistration<?>> serviceRegistrations = new HashSet<>();
-            for (Entry<String, ServiceInterfaceAnnotation> entry : serviceNamesToAnnotations.entrySet()) {
-                Class<?> requiredInterface = entry.getValue().osgiRegistrationType();
-                checkState(requiredInterface.isInstance(instance), instance.getClass().getName() +
+            for (Entry<ServiceInterfaceAnnotation, String /* service ref name */> entry : serviceNamesToAnnotations.entrySet()) {
+                ServiceInterfaceAnnotation annotation = entry.getKey();
+                Class<?> requiredInterface = annotation.osgiRegistrationType();
+
+                if(!annotation.registerToOsgi()) {
+                    LOG.debug("registerToOsgi for service interface {} is false - not registering", requiredInterface);
+                    continue;
+                }
+
+                Preconditions.checkState(requiredInterface.isInstance(instance), instance.getClass().getName() +
                         " instance should implement " + requiredInterface.getName());
-                Dictionary<String, String> propertiesForOsgi = createProps(entry.getKey());
+                Dictionary<String, String> propertiesForOsgi = createProps(entry.getValue());
                 ServiceRegistration<?> serviceRegistration = bundleContext
                         .registerService(requiredInterface.getName(), instance, propertiesForOsgi);
                 serviceRegistrations.add(serviceRegistration);
@@ -87,18 +85,22 @@ public class BeanToOsgiServiceManager {
         @Override
         public synchronized void close() {
             for (ServiceRegistration<?> serviceRegistration : serviceRegistrations) {
-                serviceRegistration.unregister();
+                try {
+                    serviceRegistration.unregister();
+                } catch(final IllegalStateException e) {
+                    LOG.trace("Cannot unregister {}", serviceRegistration, e);
+                }
             }
             serviceRegistrations.clear();
         }
 
-        public synchronized void updateRegistrations(Map<String, ServiceInterfaceAnnotation> newAnnotationMapping,
-                                                     BundleContext bundleContext, AutoCloseable newInstance) {
-            boolean notEquals = this.instance != newInstance;
-            notEquals |= newAnnotationMapping.equals(serviceNamesToAnnotations) == false;
+        public synchronized void updateRegistrations(final Map<ServiceInterfaceAnnotation, String /* service ref name */> newAnnotationMapping,
+                                                     final BundleContext bundleContext, final AutoCloseable newInstance) {
+            boolean notEquals = !this.instance.equals(newInstance);
+            notEquals |= !newAnnotationMapping.equals(serviceNamesToAnnotations);
             if (notEquals) {
                 // FIXME: changing from old state to new state can be improved by computing the diff
-                logger.debug("Detected change in service registrations for {}: old: {}, new: {}", moduleIdentifier,
+                LOG.debug("Detected change in service registrations for {}: old: {}, new: {}", moduleIdentifier,
                         serviceNamesToAnnotations, newAnnotationMapping);
                 close();
                 this.instance = newInstance;
@@ -107,5 +109,11 @@ public class BeanToOsgiServiceManager {
                 serviceRegistrations.addAll(newRegs);
             }
         }
+
+        private static Dictionary<String, String> createProps(final String serviceName) {
+            Hashtable<String, String> result = new Hashtable<>();
+            result.put(SERVICE_NAME_OSGI_PROP, serviceName);
+            return result;
+        }
     }
 }