Bug 6859 - Binding generator v1 refactoring
[controller.git] / opendaylight / config / config-manager / src / main / java / org / opendaylight / controller / config / manager / impl / ConfigTransactionControllerImpl.java
index eb63af89d22f66068eb943bfc8ba834304a9c7a6..ad64288ab203a0e9c00d6bbe5964dff33fedf520 100644 (file)
@@ -7,9 +7,7 @@
  */
 package org.opendaylight.controller.config.manager.impl;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-import static java.lang.String.format;
-
+import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -27,8 +25,10 @@ import javax.management.InstanceNotFoundException;
 import javax.management.MBeanServer;
 import javax.management.ObjectName;
 import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.ModuleFactoryNotFoundException;
 import org.opendaylight.controller.config.api.ModuleIdentifier;
 import org.opendaylight.controller.config.api.ValidationException;
+import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.controller.config.manager.impl.dependencyresolver.DependencyResolverManager;
 import org.opendaylight.controller.config.manager.impl.dependencyresolver.ModuleInternalTransactionalInfo;
@@ -39,12 +39,15 @@ import org.opendaylight.controller.config.manager.impl.factoriesresolver.Hierarc
 import org.opendaylight.controller.config.manager.impl.jmx.TransactionModuleJMXRegistrator;
 import org.opendaylight.controller.config.manager.impl.jmx.TransactionModuleJMXRegistrator.TransactionModuleJMXRegistration;
 import org.opendaylight.controller.config.manager.impl.osgi.mapping.BindingContextProvider;
+import org.opendaylight.controller.config.manager.impl.util.InterfacesHelper;
+import org.opendaylight.controller.config.spi.AbstractModule;
 import org.opendaylight.controller.config.spi.Module;
 import org.opendaylight.controller.config.spi.ModuleFactory;
 import org.opendaylight.yangtools.concepts.Identifiable;
 import org.osgi.framework.BundleContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+
 /**
  * This is a JMX bean representing current transaction. It contains
  * transaction identifier, unique version and parent version for
@@ -59,7 +62,8 @@ class ConfigTransactionControllerImpl implements
     private final ConfigTransactionLookupRegistry txLookupRegistry;
     private final ObjectName controllerON;
 
-    private final long parentVersion, currentVersion;
+    private final long parentVersion;
+    private final long currentVersion;
     private final HierarchicalConfigMBeanFactoriesHolder factoriesHolder;
     private final DependencyResolverManager dependencyResolverManager;
     private final TransactionStatus transactionStatus;
@@ -126,12 +130,12 @@ class ConfigTransactionControllerImpl implements
         List<ModuleFactory> toBeAdded = new ArrayList<>();
         List<ModuleFactory> toBeRemoved = new ArrayList<>();
         for (ModuleFactory moduleFactory : factoriesHolder.getModuleFactories()) {
-            if (oldSet.contains(moduleFactory) == false) {
+            if (!oldSet.contains(moduleFactory)) {
                 toBeAdded.add(moduleFactory);
             }
         }
         for (ModuleFactory moduleFactory : lastListOfFactories) {
-            if (newSet.contains(moduleFactory) == false) {
+            if (!newSet.contains(moduleFactory)) {
                 toBeRemoved.add(moduleFactory);
             }
         }
@@ -143,13 +147,24 @@ class ConfigTransactionControllerImpl implements
             for (Module module : defaultModules) {
                 // ensure default module to be registered to jmx even if its module factory does not use dependencyResolverFactory
                 DependencyResolver dependencyResolver = dependencyResolverManager.getOrCreate(module.getIdentifier());
+                final ObjectName objectName;
                 try {
                     boolean defaultBean = true;
-                    putConfigBeanToJMXAndInternalMaps(module.getIdentifier(), module, moduleFactory, null,
+                    objectName = putConfigBeanToJMXAndInternalMaps(module.getIdentifier(), module, moduleFactory, null,
                             dependencyResolver, defaultBean, bundleContext);
                 } catch (InstanceAlreadyExistsException e) {
                     throw new IllegalStateException(e);
                 }
+
+                // register default module as every possible service
+                final Set<ServiceInterfaceAnnotation> serviceInterfaceAnnotations = InterfacesHelper.getServiceInterfaceAnnotations(moduleFactory);
+                for (String qname : InterfacesHelper.getQNames(serviceInterfaceAnnotations)) {
+                    try {
+                        saveServiceReference(qname, module.getIdentifier().getInstanceName(), objectName);
+                    } catch (InstanceNotFoundException e) {
+                        throw new IllegalStateException("Unable to register default module instance " + module + " as a service of " + qname, e);
+                    }
+                }
             }
         }
 
@@ -157,13 +172,26 @@ class ConfigTransactionControllerImpl implements
         for (ModuleFactory removedFactory : toBeRemoved) {
             List<ModuleIdentifier> modulesOfRemovedFactory = dependencyResolverManager.findAllByFactory(removedFactory);
             for (ModuleIdentifier name : modulesOfRemovedFactory) {
+                // remove service refs
+                final ModuleFactory moduleFactory = dependencyResolverManager.findModuleInternalTransactionalInfo(name).getModuleFactory();
+                final Set<ServiceInterfaceAnnotation> serviceInterfaceAnnotations = InterfacesHelper.getServiceInterfaceAnnotations(moduleFactory);
+                for (String qname : InterfacesHelper.getQNames(serviceInterfaceAnnotations)) {
+                    try {
+                        removeServiceReference(qname, name.getInstanceName());
+                    } catch (InstanceNotFoundException e) {
+                        throw new IllegalStateException("Unable to UNregister default module instance " + name + " as a service of " + qname, e);
+                    }
+                }
+
+                // close module
                 destroyModule(name);
             }
         }
     }
 
 
-    private synchronized void copyExistingModule(ModuleInternalInfo oldConfigBeanInfo) throws InstanceAlreadyExistsException {
+    private synchronized void copyExistingModule(ModuleInternalInfo oldConfigBeanInfo)
+            throws InstanceAlreadyExistsException {
 
         transactionStatus.checkNotCommitStarted();
         transactionStatus.checkNotAborted();
@@ -175,7 +203,7 @@ class ConfigTransactionControllerImpl implements
         try {
             moduleFactory = factoriesHolder.findByModuleName(moduleIdentifier.getFactoryName());
             bc = getModuleFactoryBundleContext(moduleFactory.getImplementationName());
-        } catch (InstanceNotFoundException e) {
+        } catch (ModuleFactoryNotFoundException e) {
             throw new IllegalStateException(e);
         }
 
@@ -187,7 +215,7 @@ class ConfigTransactionControllerImpl implements
                     moduleIdentifier.getInstanceName(), dependencyResolver,
                     oldConfigBeanInfo.getReadableModule(), bc);
         } catch (Exception e) {
-            throw new IllegalStateException(format(
+            throw new IllegalStateException(String.format(
                     "Error while copying old configuration from %s to %s",
                     oldConfigBeanInfo, moduleFactory), e);
         }
@@ -196,8 +224,8 @@ class ConfigTransactionControllerImpl implements
     }
 
     @Override
-    public synchronized ObjectName createModule(String factoryName,
-                                                String instanceName) throws InstanceAlreadyExistsException {
+    public synchronized ObjectName createModule(String factoryName, String instanceName)
+            throws InstanceAlreadyExistsException {
 
         transactionStatus.checkNotCommitStarted();
         transactionStatus.checkNotAborted();
@@ -205,12 +233,8 @@ class ConfigTransactionControllerImpl implements
         dependencyResolverManager.assertNotExists(moduleIdentifier);
 
         // find factory
-        ModuleFactory moduleFactory;
-        try {
-            moduleFactory = factoriesHolder.findByModuleName(factoryName);
-        } catch (InstanceNotFoundException e) {
-            throw new IllegalArgumentException(e);
-        }
+        ModuleFactory moduleFactory = factoriesHolder.findByModuleName(factoryName);
+
         DependencyResolver dependencyResolver = dependencyResolverManager.getOrCreate(moduleIdentifier);
         BundleContext bundleContext = getModuleFactoryBundleContext(moduleFactory.getImplementationName());
         Module module = moduleFactory.createModule(instanceName, dependencyResolver,
@@ -220,6 +244,21 @@ class ConfigTransactionControllerImpl implements
                 moduleFactory, null, dependencyResolver, defaultBean, bundleContext);
     }
 
+    @Override
+    public synchronized void reCreateModule(ObjectName objectName) throws InstanceNotFoundException {
+        transactionStatus.checkNotCommitStarted();
+        transactionStatus.checkNotAborted();
+        checkTransactionName(objectName);
+        ObjectNameUtil.checkDomain(objectName);
+        ModuleIdentifier moduleIdentifier = ObjectNameUtil.fromON(objectName, ObjectNameUtil.TYPE_MODULE);
+
+        ModuleInternalTransactionalInfo txInfo = dependencyResolverManager.findModuleInternalTransactionalInfo(moduleIdentifier);
+        Module realModule = txInfo.getRealModule();
+        if(realModule instanceof AbstractModule) {
+            ((AbstractModule<?>)realModule).setCanReuseInstance(false);
+        }
+    }
+
     private synchronized ObjectName putConfigBeanToJMXAndInternalMaps(
             ModuleIdentifier moduleIdentifier, Module module,
             ModuleFactory moduleFactory,
@@ -228,16 +267,16 @@ class ConfigTransactionControllerImpl implements
             throws InstanceAlreadyExistsException {
 
         LOG.debug("Adding module {} to transaction {}", moduleIdentifier, this);
-        if (moduleIdentifier.equals(module.getIdentifier()) == false) {
+        if (!moduleIdentifier.equals(module.getIdentifier())) {
             throw new IllegalStateException("Incorrect name reported by module. Expected "
                     + moduleIdentifier + ", got " + module.getIdentifier());
         }
-        if (dependencyResolver.getIdentifier().equals(moduleIdentifier) == false) {
+        if (!dependencyResolver.getIdentifier().equals(moduleIdentifier)) {
             throw new IllegalStateException("Incorrect name reported by dependency resolver. Expected "
                     + moduleIdentifier + ", got " + dependencyResolver.getIdentifier());
         }
         DynamicMBean writableDynamicWrapper = new DynamicWritableWrapper(
-                module, moduleIdentifier, getTransactionIdentifier(),
+                module, moduleIdentifier, getTransactionIdentifier().getName(),
                 readOnlyAtomicBoolean, transactionsMBeanServer,
                 configMBeanServer);
 
@@ -265,7 +304,7 @@ class ConfigTransactionControllerImpl implements
     private void checkTransactionName(ObjectName objectName) {
         String foundTransactionName = ObjectNameUtil
                 .getTransactionName(objectName);
-        if (getTransactionIdentifier().getName().equals(foundTransactionName) == false) {
+        if (!getTransactionIdentifier().getName().equals(foundTransactionName)) {
             throw new IllegalArgumentException("Wrong transaction name "
                     + objectName);
         }
@@ -276,7 +315,7 @@ class ConfigTransactionControllerImpl implements
         transactionStatus.checkNotAborted();
 
         ModuleInternalTransactionalInfo found = dependencyResolverManager.findModuleInternalTransactionalInfo(moduleIdentifier);
-        if (blankTransaction == false &&
+        if (!blankTransaction &&
                 found.isDefaultBean()) {
             LOG.warn("Warning: removing default bean. This will be forbidden in next version of config-subsystem");
         }
@@ -360,7 +399,8 @@ class ConfigTransactionControllerImpl implements
             validateNoLocks();
         } catch (ValidationException e) {
             LOG.trace("Commit failed on validation");
-            configBeanModificationDisabled.set(false); // recoverable error
+            // recoverable error
+            configBeanModificationDisabled.set(false);
             throw e;
         }
         // errors in this state are not recoverable. modules are not mutable
@@ -376,7 +416,7 @@ class ConfigTransactionControllerImpl implements
     public synchronized List<ModuleIdentifier> secondPhaseCommit() {
         transactionStatus.checkNotAborted();
         transactionStatus.checkCommitStarted();
-        if (configBeanModificationDisabled.get() == false) {
+        if (!configBeanModificationDisabled.get()) {
             throw new IllegalStateException(
                     "Internal error - validateBeforeCommitAndLockTransaction should be called "
                             + "to obtain a lock");
@@ -397,13 +437,13 @@ class ConfigTransactionControllerImpl implements
                 LOG.debug("About to commit {} in transaction {}",
                         moduleIdentifier, getTransactionIdentifier());
                 AutoCloseable instance = module.getInstance();
-                checkNotNull(instance, "Instance is null:{} in transaction {}", moduleIdentifier, getTransactionIdentifier());
+                Preconditions.checkNotNull(instance, "Instance is null:{} in transaction {}", moduleIdentifier, getTransactionIdentifier());
             } catch (Exception e) {
                 LOG.error("Commit failed on {} in transaction {}", moduleIdentifier,
                         getTransactionIdentifier(), e);
                 internalAbort();
                 throw new IllegalStateException(
-                        format("Error - getInstance() failed for %s in transaction %s",
+                        String.format("Error - getInstance() failed for %s in transaction %s",
                                 moduleIdentifier, getTransactionIdentifier()), e);
             }
         }
@@ -415,7 +455,7 @@ class ConfigTransactionControllerImpl implements
     }
 
     @Override
-    public synchronized void abortConfig() {
+    public void abortConfig() {
         transactionStatus.checkNotCommitStarted();
         transactionStatus.checkNotAborted();
         internalAbort();
@@ -427,6 +467,7 @@ class ConfigTransactionControllerImpl implements
         close();
     }
 
+    @Override
     public void close() {
         dependencyResolverManager.close();
         txLookupRegistry.close();