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;
private final ModuleFactoriesResolver resolver;
private final MBeanServer configMBeanServer;
- private final CodecRegistry codecRegistry;
+ private final BindingContextProvider bindingContextProvider;
@GuardedBy("this")
private long version = 0;
// 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
readableSRRegistry, txLookupRegistry, allCurrentFactories);
ConfigTransactionControllerInternal transactionController = new ConfigTransactionControllerImpl(
- txLookupRegistry, version, codecRegistry,
+ txLookupRegistry, version, bindingContextProvider,
versionCounter, allCurrentFactories, transactionsMBeanServer,
configMBeanServer, blankTransaction, writableRegistry);
try {
}
// 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
// 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