Reduce output from DeadlockMonitor
[controller.git] / opendaylight / config / config-manager / src / main / java / org / opendaylight / controller / config / manager / impl / ConfigRegistryImpl.java
index 93a6168ec2e9bc121118dc7274c8e9101b1ee5c0..45dac318fa06caa539b2daeb52f0e3c8bb31cfba 100644 (file)
@@ -44,11 +44,11 @@ import org.opendaylight.controller.config.manager.impl.jmx.RootRuntimeBeanRegist
 import org.opendaylight.controller.config.manager.impl.jmx.TransactionJMXRegistrator;
 import org.opendaylight.controller.config.manager.impl.osgi.BeanToOsgiServiceManager;
 import org.opendaylight.controller.config.manager.impl.osgi.BeanToOsgiServiceManager.OsgiRegistration;
+import org.opendaylight.controller.config.manager.impl.osgi.mapping.BindingContextProvider;
 import org.opendaylight.controller.config.manager.impl.util.LookupBeansUtil;
 import org.opendaylight.controller.config.manager.impl.util.ModuleQNameUtil;
 import org.opendaylight.controller.config.spi.Module;
 import org.opendaylight.controller.config.spi.ModuleFactory;
-import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
 import org.osgi.framework.BundleContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -63,7 +63,7 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
 
     private final ModuleFactoriesResolver resolver;
     private final MBeanServer configMBeanServer;
-    private final CodecRegistry codecRegistry;
+    private final BindingContextProvider bindingContextProvider;
 
     @GuardedBy("this")
     private long version = 0;
@@ -111,20 +111,20 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
 
     // constructor
     public ConfigRegistryImpl(ModuleFactoriesResolver resolver,
-                              MBeanServer configMBeanServer, CodecRegistry codecRegistry) {
+                              MBeanServer configMBeanServer, BindingContextProvider bindingContextProvider) {
         this(resolver, configMBeanServer,
-                new BaseJMXRegistrator(configMBeanServer), codecRegistry);
+                new BaseJMXRegistrator(configMBeanServer), bindingContextProvider);
     }
 
     // constructor
     public ConfigRegistryImpl(ModuleFactoriesResolver resolver,
                               MBeanServer configMBeanServer,
-                              BaseJMXRegistrator baseJMXRegistrator, CodecRegistry codecRegistry) {
+                              BaseJMXRegistrator baseJMXRegistrator, BindingContextProvider bindingContextProvider) {
         this.resolver = resolver;
         this.beanToOsgiServiceManager = new BeanToOsgiServiceManager();
         this.configMBeanServer = configMBeanServer;
         this.baseJMXRegistrator = baseJMXRegistrator;
-        this.codecRegistry = codecRegistry;
+        this.bindingContextProvider = bindingContextProvider;
         this.registryMBeanServer = MBeanServerFactory
                 .createMBeanServer("ConfigRegistry" + configMBeanServer.getDefaultDomain());
         this.transactionsMBeanServer = MBeanServerFactory
@@ -179,7 +179,7 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
                 readableSRRegistry, txLookupRegistry, allCurrentFactories);
 
         ConfigTransactionControllerInternal transactionController = new ConfigTransactionControllerImpl(
-                txLookupRegistry, version, codecRegistry,
+                txLookupRegistry, version, bindingContextProvider,
                 versionCounter, allCurrentFactories, transactionsMBeanServer,
                 configMBeanServer, blankTransaction, writableRegistry);
         try {
@@ -196,7 +196,6 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
      * {@inheritDoc}
      */
     @Override
-    @SuppressWarnings("PMD.AvoidCatchingThrowable")
     public synchronized CommitStatus commitConfig(ObjectName transactionControllerON)
             throws ConflictingVersionException, ValidationException {
         final String transactionName = ObjectNameUtil
@@ -253,28 +252,35 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
         }
 
         // set RuntimeBeanRegistrators on beans implementing
-        // RuntimeBeanRegistratorAwareModule, each module
-        // should have exactly one runtime jmx registrator.
+        // RuntimeBeanRegistratorAwareModule
         Map<ModuleIdentifier, RootRuntimeBeanRegistratorImpl> runtimeRegistrators = new HashMap<>();
         for (ModuleInternalTransactionalInfo entry : commitInfo.getCommitted()
                 .values()) {
-            RootRuntimeBeanRegistratorImpl runtimeBeanRegistrator;
-            if (entry.hasOldModule() == false) {
-                runtimeBeanRegistrator = baseJMXRegistrator
-                        .createRuntimeBeanRegistrator(entry.getIdentifier());
-            } else {
-                // reuse old JMX registrator
-                runtimeBeanRegistrator = entry.getOldInternalInfo()
-                        .getRuntimeBeanRegistrator();
-            }
             // set runtime jmx registrator if required
             Module module = entry.getProxiedModule();
+            RootRuntimeBeanRegistratorImpl runtimeBeanRegistrator = null;
+
             if (module instanceof RuntimeBeanRegistratorAwareModule) {
-                ((RuntimeBeanRegistratorAwareModule) module)
-                        .setRuntimeBeanRegistrator(runtimeBeanRegistrator);
+
+                if(entry.hasOldModule()) {
+
+                    if(module.canReuse(entry.getOldInternalInfo().getReadableModule().getModule())) {
+                        runtimeBeanRegistrator = entry.getOldInternalInfo().getRuntimeBeanRegistrator();
+                        ((RuntimeBeanRegistratorAwareModule) module).setRuntimeBeanRegistrator(runtimeBeanRegistrator);
+                    } else {
+                        runtimeBeanRegistrator = baseJMXRegistrator.createRuntimeBeanRegistrator(entry.getIdentifier());
+                        entry.getOldInternalInfo().getRuntimeBeanRegistrator().close();
+                        ((RuntimeBeanRegistratorAwareModule) module).setRuntimeBeanRegistrator(runtimeBeanRegistrator);
+                    }
+                } else {
+                    runtimeBeanRegistrator = baseJMXRegistrator.createRuntimeBeanRegistrator(entry.getIdentifier());
+                    ((RuntimeBeanRegistratorAwareModule) module).setRuntimeBeanRegistrator(runtimeBeanRegistrator);
+                }
             }
             // save it to info so it is accessible afterwards
-            runtimeRegistrators.put(entry.getIdentifier(), runtimeBeanRegistrator);
+            if(runtimeBeanRegistrator != null) {
+                runtimeRegistrators.put(entry.getIdentifier(), runtimeBeanRegistrator);
+            }
         }
 
         // can register runtime beans
@@ -339,6 +345,11 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
 
                 // close old module jmx registrator
                 oldInternalInfo.getModuleJMXRegistrator().close();
+
+                // We no longer need old internal info. Clear it out, so we do not create a serial leak evidenced
+                // by BUG-4514. The reason is that modules retain their resolver, which retains modules. If we retain
+                // the old module, we would have the complete reconfiguration history held in heap for no good reason.
+                entry.clearOldInternalInfo();
             } else {
                 // new instance:
                 // wrap in readable dynamic mbean
@@ -431,8 +442,7 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
             }
         }
 
-        // destroy all live objects one after another in order of the dependency
-        // hierarchy
+        // destroy all live objects one after another in order of the dependency hierarchy, from top to bottom
         List<DestroyedModule> destroyedModules = currentConfig
                 .getModulesToBeDestroyed();
         for (DestroyedModule destroyedModule : destroyedModules) {