Merge "Add service reference binding to config registry."
[controller.git] / opendaylight / config / config-manager / src / main / java / org / opendaylight / controller / config / manager / impl / ConfigRegistryImpl.java
index 0fd6c5279409e3412de86a33735c3dc4daddf058..18326d91f21b8df58afd905746b2efc606ebb1ce 100644 (file)
@@ -10,6 +10,8 @@ package org.opendaylight.controller.config.manager.impl;
 import org.opendaylight.controller.config.api.ConflictingVersionException;
 import org.opendaylight.controller.config.api.ModuleIdentifier;
 import org.opendaylight.controller.config.api.RuntimeBeanRegistratorAwareModule;
+import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
+import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry;
 import org.opendaylight.controller.config.api.ValidationException;
 import org.opendaylight.controller.config.api.jmx.CommitStatus;
 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
@@ -102,6 +104,9 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
     @GuardedBy("this")
     private List<ModuleFactory> lastListOfFactories = Collections.emptyList();
 
+    @GuardedBy("this") // switched in every 2ndPC
+    private ServiceReferenceReadableRegistry readableSRRegistry = ServiceReferenceRegistryImpl.createInitialSRLookupRegistry();
+
     // constructor
     public ConfigRegistryImpl(ModuleFactoriesResolver resolver,
             BundleContext bundleContext, MBeanServer configMBeanServer) {
@@ -129,26 +134,45 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
      */
     @Override
     public synchronized ObjectName beginConfig() {
-        return beginConfigInternal().getControllerObjectName();
+        return beginConfig(false);
+    }
+
+    /**
+     * @param blankTransaction true if this transaction is created automatically by
+     *                         org.opendaylight.controller.config.manager.impl.osgi.BlankTransactionServiceTracker
+     */
+    public synchronized ObjectName beginConfig(boolean blankTransaction) {
+        return beginConfigInternal(blankTransaction).getControllerObjectName();
     }
 
-    private synchronized ConfigTransactionControllerInternal beginConfigInternal() {
+    private synchronized ConfigTransactionControllerInternal beginConfigInternal(boolean blankTransaction) {
         versionCounter++;
-        String transactionName = "ConfigTransaction-" + version + "-" + versionCounter;
-        TransactionJMXRegistrator transactionRegistrator = baseJMXRegistrator
-                .createTransactionJMXRegistrator(transactionName);
-        Map<String, Map.Entry<ModuleFactory, BundleContext>> allCurrentFactories = Collections.unmodifiableMap(resolver.getAllFactories());
+        final String transactionName = "ConfigTransaction-" + version + "-" + versionCounter;
+
+        TransactionJMXRegistratorFactory factory = new TransactionJMXRegistratorFactory() {
+            @Override
+            public TransactionJMXRegistrator create() {
+                return baseJMXRegistrator.createTransactionJMXRegistrator(transactionName);
+            }
+        };
+
+        ConfigTransactionLookupRegistry txLookupRegistry = new ConfigTransactionLookupRegistry(new TransactionIdentifier(
+                transactionName), factory);
+        Map<String, Map.Entry<ModuleFactory, BundleContext>> allCurrentFactories = Collections.unmodifiableMap(
+                resolver.getAllFactories());
+        ServiceReferenceWritableRegistry writableRegistry = ServiceReferenceRegistryImpl.createSRWritableRegistry(
+                readableSRRegistry, txLookupRegistry, allCurrentFactories);
+
         ConfigTransactionControllerInternal transactionController = new ConfigTransactionControllerImpl(
-                transactionName, transactionRegistrator, version,
-                versionCounter, allCurrentFactories, transactionsMBeanServer, configMBeanServer, bundleContext);
+                txLookupRegistry, version,
+                versionCounter, allCurrentFactories, transactionsMBeanServer,
+                configMBeanServer, blankTransaction, writableRegistry);
         try {
-            transactionRegistrator.registerMBean(transactionController, transactionController.getControllerObjectName());
+            txLookupRegistry.registerMBean(transactionController, transactionController.getControllerObjectName());
         } catch (InstanceAlreadyExistsException e) {
             throw new IllegalStateException(e);
         }
-
         transactionController.copyExistingModulesAndProcessFactoryDiff(currentConfig.getEntries(), lastListOfFactories);
-
         transactionsHolder.add(transactionName, transactionController);
         return transactionController;
     }
@@ -223,7 +247,7 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
             RootRuntimeBeanRegistratorImpl runtimeBeanRegistrator;
             if (entry.hasOldModule() == false) {
                 runtimeBeanRegistrator = baseJMXRegistrator
-                        .createRuntimeBeanRegistrator(entry.getName());
+                        .createRuntimeBeanRegistrator(entry.getIdentifier());
             } else {
                 // reuse old JMX registrator
                 runtimeBeanRegistrator = entry.getOldInternalInfo()
@@ -236,7 +260,7 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
                         .setRuntimeBeanRegistrator(runtimeBeanRegistrator);
             }
             // save it to info so it is accessible afterwards
-            runtimeRegistrators.put(entry.getName(), runtimeBeanRegistrator);
+            runtimeRegistrators.put(entry.getIdentifier(), runtimeBeanRegistrator);
         }
 
         // can register runtime beans
@@ -264,8 +288,7 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
             // determine if current instance was recreated or reused or is new
 
             // rules for closing resources:
-            // osgi registration - will be (re)created every time, so it needs
-            // to be closed here
+            // osgi registration - will be reused if possible.
             // module jmx registration - will be (re)created every time, needs
             // to be closed here
             // runtime jmx registration - should be taken care of by module
@@ -279,7 +302,7 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
                 ModuleInternalInfo oldInternalInfo = entry.getOldInternalInfo();
                 DynamicReadableWrapper oldReadableConfigBean = oldInternalInfo
                         .getReadableModule();
-                currentConfig.remove(entry.getName());
+                currentConfig.remove(entry.getIdentifier());
 
                 // test if old instance == new instance
                 if (oldReadableConfigBean.getInstance().equals(module.getInstance())) {
@@ -324,7 +347,7 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
                     BundleContext bc = configTransactionController.
                             getModuleFactoryBundleContext(moduleFactory.getImplementationName());
                     osgiRegistration = beanToOsgiServiceManager.registerToOsgi(module.getClass(),
-                            newReadableConfigBean.getInstance(), entry.getName(), bc);
+                            newReadableConfigBean.getInstance(), entry.getIdentifier(), bc);
                 } else {
                     throw new NullPointerException(entry.getIdentifier().getFactoryName() + " ModuleFactory not found.");
                 }
@@ -332,11 +355,11 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
             }
 
             RootRuntimeBeanRegistratorImpl runtimeBeanRegistrator = runtimeRegistrators
-                    .get(entry.getName());
+                    .get(entry.getIdentifier());
             ModuleInternalInfo newInfo = new ModuleInternalInfo(
-                    entry.getName(), newReadableConfigBean, osgiRegistration,
+                    entry.getIdentifier(), newReadableConfigBean, osgiRegistration,
                     runtimeBeanRegistrator, newModuleJMXRegistrator,
-                    orderingIdx);
+                    orderingIdx, entry.isDefaultBean());
 
             newConfigEntries.put(module, newInfo);
             orderingIdx++;
@@ -345,6 +368,10 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
 
         // update version
         version = configTransactionController.getVersion();
+
+        // switch readable Service Reference Registry
+        this.readableSRRegistry = ServiceReferenceRegistryImpl.createSRReadableRegistry(configTransactionController.getWritableRegistry(), this);
+
         return new CommitStatus(newInstances, reusedInstances,
                 recreatedInstances);
     }
@@ -367,7 +394,7 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
     /**
      * Abort open transactions and unregister read only modules. Since this
      * class is not responsible for registering itself under
-     * {@link ConfigRegistryMXBean#OBJECT_NAME}, it will not unregister itself
+     * {@link org.opendaylight.controller.config.api.ConfigRegistry#OBJECT_NAME}, it will not unregister itself
      * here.
      */
     @Override
@@ -486,6 +513,43 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
         return baseJMXRegistrator.queryNames(namePattern, null);
     }
 
+    @Override
+    public void checkConfigBeanExists(ObjectName objectName) throws InstanceNotFoundException {
+        ObjectNameUtil.checkDomain(objectName);
+        ObjectNameUtil.checkType(objectName, ObjectNameUtil.TYPE_MODULE);
+        String transactionName = ObjectNameUtil.getTransactionName(objectName);
+        if (transactionName != null) {
+            throw new IllegalArgumentException("Transaction attribute not supported in registry, wrong ObjectName: " + objectName);
+        }
+        // make sure exactly one match is found:
+        LookupBeansUtil.lookupConfigBean(this, ObjectNameUtil.getFactoryName(objectName), ObjectNameUtil.getInstanceName(objectName));
+    }
+
+    // service reference functionality:
+    @Override
+    public synchronized ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName) {
+        return readableSRRegistry.lookupConfigBeanByServiceInterfaceName(serviceInterfaceName, refName);
+    }
+
+    @Override
+    public synchronized Map<String, Map<String, ObjectName>> getServiceMapping() {
+        return readableSRRegistry.getServiceMapping();
+    }
+
+    @Override
+    public synchronized Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) {
+        return readableSRRegistry.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceName);
+    }
+
+    @Override
+    public synchronized Set<String> lookupServiceInterfaceNames(ObjectName objectName) throws InstanceNotFoundException {
+        return readableSRRegistry.lookupServiceInterfaceNames(objectName);
+    }
+
+    @Override
+    public synchronized String getServiceInterfaceName(String namespace, String localName) {
+        return readableSRRegistry.getServiceInterfaceName(namespace, localName);
+    }
 }
 
 /**