X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fconfig%2Fconfig-manager%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fconfig%2Fmanager%2Fimpl%2FConfigRegistryImpl.java;h=fbf18f7134ac274f4f963359054a7f9c70371379;hp=e3311c747f872f601b0448e01d7e864163a15a75;hb=0c931b8d1fa153991b10705a4358fe39f93181cd;hpb=713279a4aa4984b57e1a5c0f6645aed9e78a65c9 diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigRegistryImpl.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigRegistryImpl.java index e3311c747f..fbf18f7134 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigRegistryImpl.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigRegistryImpl.java @@ -7,14 +7,16 @@ */ package org.opendaylight.controller.config.manager.impl; +import com.google.common.collect.Maps; 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.annotations.ServiceInterfaceAnnotation; import org.opendaylight.controller.config.api.jmx.CommitStatus; import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; +import org.opendaylight.controller.config.manager.impl.dependencyresolver.DestroyedModule; +import org.opendaylight.controller.config.manager.impl.dependencyresolver.ModuleInternalTransactionalInfo; import org.opendaylight.controller.config.manager.impl.dynamicmbean.DynamicReadableWrapper; import org.opendaylight.controller.config.manager.impl.factoriesresolver.HierarchicalConfigMBeanFactoriesHolder; import org.opendaylight.controller.config.manager.impl.factoriesresolver.ModuleFactoriesResolver; @@ -28,6 +30,7 @@ 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; @@ -61,6 +64,7 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe private final ModuleFactoriesResolver resolver; private final MBeanServer configMBeanServer; + private final CodecRegistry codecRegistry; @GuardedBy("this") private long version = 0; @@ -104,23 +108,24 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe private List lastListOfFactories = Collections.emptyList(); @GuardedBy("this") // switched in every 2ndPC - private ServiceReferenceReadableRegistry readableSRRegistry = ServiceReferenceRegistryImpl.createInitialSRLookupRegistry(); + private CloseableServiceReferenceReadableRegistry readableSRRegistry = ServiceReferenceRegistryImpl.createInitialSRLookupRegistry(); // constructor public ConfigRegistryImpl(ModuleFactoriesResolver resolver, - MBeanServer configMBeanServer) { + MBeanServer configMBeanServer, CodecRegistry codecRegistry) { this(resolver, configMBeanServer, - new BaseJMXRegistrator(configMBeanServer)); + new BaseJMXRegistrator(configMBeanServer), codecRegistry); } // constructor public ConfigRegistryImpl(ModuleFactoriesResolver resolver, - MBeanServer configMBeanServer, - BaseJMXRegistrator baseJMXRegistrator) { + MBeanServer configMBeanServer, + BaseJMXRegistrator baseJMXRegistrator, CodecRegistry codecRegistry) { this.resolver = resolver; this.beanToOsgiServiceManager = new BeanToOsgiServiceManager(); this.configMBeanServer = configMBeanServer; this.baseJMXRegistrator = baseJMXRegistrator; + this.codecRegistry = codecRegistry; this.registryMBeanServer = MBeanServerFactory .createMBeanServer("ConfigRegistry" + configMBeanServer.getDefaultDomain()); this.transactionsMBeanServer = MBeanServerFactory @@ -156,13 +161,15 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe Map> allCurrentFactories = Collections.unmodifiableMap( resolver.getAllFactories()); + + // closed by transaction controller ConfigTransactionLookupRegistry txLookupRegistry = new ConfigTransactionLookupRegistry(new TransactionIdentifier( transactionName), factory, allCurrentFactories); - ServiceReferenceWritableRegistry writableRegistry = ServiceReferenceRegistryImpl.createSRWritableRegistry( + SearchableServiceReferenceWritableRegistry writableRegistry = ServiceReferenceRegistryImpl.createSRWritableRegistry( readableSRRegistry, txLookupRegistry, allCurrentFactories); ConfigTransactionControllerInternal transactionController = new ConfigTransactionControllerImpl( - txLookupRegistry, version, + txLookupRegistry, version, codecRegistry, versionCounter, allCurrentFactories, transactionsMBeanServer, configMBeanServer, blankTransaction, writableRegistry); try { @@ -171,7 +178,7 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe throw new IllegalStateException(e); } transactionController.copyExistingModulesAndProcessFactoryDiff(currentConfig.getEntries(), lastListOfFactories); - transactionsHolder.add(transactionName, transactionController); + transactionsHolder.add(transactionName, transactionController, txLookupRegistry); return transactionController; } @@ -179,19 +186,21 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe * {@inheritDoc} */ @Override + @SuppressWarnings("PMD.AvoidCatchingThrowable") public synchronized CommitStatus commitConfig(ObjectName transactionControllerON) throws ConflictingVersionException, ValidationException { final String transactionName = ObjectNameUtil .getTransactionName(transactionControllerON); - logger.info("About to commit {}. Current parentVersion: {}, versionCounter {}", transactionName, version, versionCounter); + logger.trace("About to commit {}. Current parentVersion: {}, versionCounter {}", transactionName, version, versionCounter); // find ConfigTransactionController - Map transactions = transactionsHolder.getCurrentTransactions(); - ConfigTransactionControllerInternal configTransactionController = transactions.get(transactionName); - if (configTransactionController == null) { + Map> transactions = transactionsHolder.getCurrentTransactions(); + Entry configTransactionControllerEntry = transactions.get(transactionName); + if (configTransactionControllerEntry == null) { throw new IllegalArgumentException(String.format( "Transaction with name '%s' not found", transactionName)); } + ConfigTransactionControllerInternal configTransactionController = configTransactionControllerEntry.getKey(); // check optimistic lock if (version != configTransactionController.getParentVersion()) { throw new ConflictingVersionException( @@ -206,10 +215,9 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe lastListOfFactories = Collections.unmodifiableList(configTransactionController.getCurrentlyRegisteredFactories()); // non recoverable from here: try { - return secondPhaseCommit( - configTransactionController, commitInfo); + return secondPhaseCommit(configTransactionController, commitInfo, configTransactionControllerEntry.getValue()); } catch (Throwable t) { // some libs throw Errors: e.g. - // javax.xml.ws.spi.FactoryFinder$ConfigurationError + // javax.xml.ws.spi.FactoryFinder$ConfigurationError isHealthy = false; logger.error("Configuration Transaction failed on 2PC, server is unhealthy", t); if (t instanceof RuntimeException) { @@ -223,14 +231,14 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe } private CommitStatus secondPhaseCommit(ConfigTransactionControllerInternal configTransactionController, - CommitInfo commitInfo) { + CommitInfo commitInfo, ConfigTransactionLookupRegistry txLookupRegistry) { // close instances which were destroyed by the user, including // (hopefully) runtime beans for (DestroyedModule toBeDestroyed : commitInfo .getDestroyedFromPreviousTransactions()) { toBeDestroyed.close(); // closes instance (which should close - // runtime jmx registrator), + // runtime jmx registrator), // also closes osgi registration and ModuleJMXRegistrator // registration currentConfig.remove(toBeDestroyed.getIdentifier()); @@ -252,7 +260,7 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe .getRuntimeBeanRegistrator(); } // set runtime jmx registrator if required - Module module = entry.getModule(); + Module module = entry.getProxiedModule(); if (module instanceof RuntimeBeanRegistratorAwareModule) { ((RuntimeBeanRegistratorAwareModule) module) .setRuntimeBeanRegistrator(runtimeBeanRegistrator); @@ -262,8 +270,9 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe } // can register runtime beans - List orderedModuleIdentifiers = configTransactionController - .secondPhaseCommit(); + List orderedModuleIdentifiers = configTransactionController.secondPhaseCommit(); + txLookupRegistry.close(); + configTransactionController.close(); // copy configuration to read only mode List newInstances = new LinkedList<>(); @@ -274,12 +283,14 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe int orderingIdx = 0; for (ModuleIdentifier moduleIdentifier : orderedModuleIdentifiers) { + logger.trace("Registering {}", moduleIdentifier); ModuleInternalTransactionalInfo entry = commitInfo.getCommitted() .get(moduleIdentifier); - if (entry == null) + if (entry == null) { throw new NullPointerException("Module not found " + moduleIdentifier); - Module module = entry.getModule(); + } + ObjectName primaryReadOnlyON = ObjectNameUtil .createReadOnlyModuleON(moduleIdentifier); @@ -296,14 +307,14 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe .createModuleJMXRegistrator(); OsgiRegistration osgiRegistration = null; + AutoCloseable instance = entry.getProxiedModule().getInstance(); if (entry.hasOldModule()) { ModuleInternalInfo oldInternalInfo = entry.getOldInternalInfo(); - DynamicReadableWrapper oldReadableConfigBean = oldInternalInfo - .getReadableModule(); + DynamicReadableWrapper oldReadableConfigBean = oldInternalInfo.getReadableModule(); currentConfig.remove(entry.getIdentifier()); // test if old instance == new instance - if (oldReadableConfigBean.getInstance().equals(module.getInstance())) { + if (oldReadableConfigBean.getInstance().equals(instance)) { // reused old instance: // wrap in readable dynamic mbean reusedInstances.add(primaryReadOnlyON); @@ -325,31 +336,28 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe // wrap in readable dynamic mbean newInstances.add(primaryReadOnlyON); } + Module realModule = entry.getRealModule(); DynamicReadableWrapper newReadableConfigBean = new DynamicReadableWrapper( - module, module.getInstance(), moduleIdentifier, + realModule, instance, moduleIdentifier, registryMBeanServer, configMBeanServer); // register to JMX try { - newModuleJMXRegistrator.registerMBean(newReadableConfigBean, - primaryReadOnlyON); + newModuleJMXRegistrator.registerMBean(newReadableConfigBean, primaryReadOnlyON); } catch (InstanceAlreadyExistsException e) { - throw new IllegalStateException(e); + throw new IllegalStateException("Possible code error, already registered:" + primaryReadOnlyON,e); } - // register to OSGi + // register services to OSGi + Map annotationMapping = configTransactionController.getWritableRegistry().findServiceInterfaces(moduleIdentifier); + BundleContext bc = configTransactionController.getModuleFactoryBundleContext( + entry.getModuleFactory().getImplementationName()); if (osgiRegistration == null) { - ModuleFactory moduleFactory = entry.getModuleFactory(); - if(moduleFactory != null) { - BundleContext bc = configTransactionController. - getModuleFactoryBundleContext(moduleFactory.getImplementationName()); - osgiRegistration = beanToOsgiServiceManager.registerToOsgi(module.getClass(), - newReadableConfigBean.getInstance(), entry.getIdentifier(), bc); - } else { - throw new NullPointerException(entry.getIdentifier().getFactoryName() + " ModuleFactory not found."); - } - + osgiRegistration = beanToOsgiServiceManager.registerToOsgi( + newReadableConfigBean.getInstance(), moduleIdentifier, bc, annotationMapping); + } else { + osgiRegistration.updateRegistrations(annotationMapping, bc, instance); } RootRuntimeBeanRegistratorImpl runtimeBeanRegistrator = runtimeRegistrators @@ -359,7 +367,7 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe runtimeBeanRegistrator, newModuleJMXRegistrator, orderingIdx, entry.isDefaultBean()); - newConfigEntries.put(module, newInfo); + newConfigEntries.put(realModule, newInfo); orderingIdx++; } currentConfig.addAll(newConfigEntries.values()); @@ -368,7 +376,9 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe version = configTransactionController.getVersion(); // switch readable Service Reference Registry - this.readableSRRegistry = ServiceReferenceRegistryImpl.createSRReadableRegistry(configTransactionController.getWritableRegistry(), this); + this.readableSRRegistry.close(); + this.readableSRRegistry = ServiceReferenceRegistryImpl.createSRReadableRegistry( + configTransactionController.getWritableRegistry(), this, baseJMXRegistrator); return new CommitStatus(newInstances, reusedInstances, recreatedInstances); @@ -379,12 +389,12 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe */ @Override public synchronized List getOpenConfigs() { - Map transactions = transactionsHolder + Map> transactions = transactionsHolder .getCurrentTransactions(); List result = new ArrayList<>(transactions.size()); - for (ConfigTransactionControllerInternal configTransactionController : transactions + for (Entry configTransactionControllerEntry : transactions .values()) { - result.add(configTransactionController.getControllerObjectName()); + result.add(configTransactionControllerEntry.getKey().getControllerObjectName()); } return result; } @@ -398,11 +408,14 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe @Override public synchronized void close() { // abort transactions - Map transactions = transactionsHolder + Map> transactions = transactionsHolder .getCurrentTransactions(); - for (ConfigTransactionControllerInternal configTransactionController : transactions + for (Entry configTransactionControllerEntry : transactions .values()) { + + ConfigTransactionControllerInternal configTransactionController = configTransactionControllerEntry.getKey(); try { + configTransactionControllerEntry.getValue().close(); configTransactionController.abortConfig(); } catch (RuntimeException e) { logger.warn("Ignoring exception while aborting {}", @@ -482,7 +495,7 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe */ @Override public Set lookupConfigBeans(String moduleName, - String instanceName) { + String instanceName) { ObjectName namePattern = ObjectNameUtil.createModulePattern(moduleName, instanceName); return baseJMXRegistrator.queryNames(namePattern, null); @@ -501,11 +514,13 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe */ @Override public Set lookupRuntimeBeans(String moduleName, - String instanceName) { - if (moduleName == null) + String instanceName) { + if (moduleName == null) { moduleName = "*"; - if (instanceName == null) + } + if (instanceName == null) { instanceName = "*"; + } ObjectName namePattern = ObjectNameUtil.createRuntimeBeanPattern( moduleName, instanceName); return baseJMXRegistrator.queryNames(namePattern, null); @@ -525,8 +540,8 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe // service reference functionality: @Override - public synchronized ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName) { - return readableSRRegistry.lookupConfigBeanByServiceInterfaceName(serviceInterfaceName, refName); + public synchronized ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceQName, String refName) { + return readableSRRegistry.lookupConfigBeanByServiceInterfaceName(serviceInterfaceQName, refName); } @Override @@ -535,8 +550,8 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe } @Override - public synchronized Map lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) { - return readableSRRegistry.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceName); + public synchronized Map lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceQName) { + return readableSRRegistry.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceQName); } @Override @@ -549,11 +564,28 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe return readableSRRegistry.getServiceInterfaceName(namespace, localName); } + @Override + public void checkServiceReferenceExists(ObjectName objectName) throws InstanceNotFoundException { + readableSRRegistry.checkServiceReferenceExists(objectName); + } + + @Override + public ObjectName getServiceReference(String serviceInterfaceQName, String refName) throws InstanceNotFoundException { + return readableSRRegistry.getServiceReference(serviceInterfaceQName, refName); + } + @Override public Set getAvailableModuleFactoryQNames() { return ModuleQNameUtil.getQNames(resolver.getAllFactories()); } + @Override + public String toString() { + return "ConfigRegistryImpl{" + + "versionCounter=" + versionCounter + + ", version=" + version + + '}'; + } } /** @@ -579,12 +611,12 @@ class ConfigHolder { } private void add(ModuleInternalInfo configInfo) { - ModuleInternalInfo oldValue = currentConfig.put(configInfo.getName(), + ModuleInternalInfo oldValue = currentConfig.put(configInfo.getIdentifier(), configInfo); if (oldValue != null) { throw new IllegalStateException( "Cannot overwrite module with same name:" - + configInfo.getName() + ":" + configInfo); + + configInfo.getIdentifier() + ":" + configInfo); } } @@ -626,18 +658,18 @@ class TransactionsHolder { * {@link ConfigTransactionControllerInternal} instances, because platform * MBeanServer transforms mbeans into another representation. Map is cleaned * every time current transactions are requested. - * */ @GuardedBy("ConfigRegistryImpl.this") - private final Map transactions = new HashMap<>(); + private final Map> transactions = new HashMap<>(); /** * Can only be called from within synchronized method. */ public void add(String transactionName, - ConfigTransactionControllerInternal transactionController) { + ConfigTransactionControllerInternal transactionController, ConfigTransactionLookupRegistry txLookupRegistry) { Object oldValue = transactions.put(transactionName, - transactionController); + Maps.immutableEntry(transactionController, txLookupRegistry)); if (oldValue != null) { throw new IllegalStateException( "Error: two transactions with same name"); @@ -651,13 +683,13 @@ class TransactionsHolder { * * @return current view on transactions map. */ - public Map getCurrentTransactions() { + public Map> getCurrentTransactions() { // first, remove closed transaction - for (Iterator> it = transactions - .entrySet().iterator(); it.hasNext();) { - Entry entry = it + for (Iterator>> it = transactions + .entrySet().iterator(); it.hasNext(); ) { + Entry> entry = it .next(); - if (entry.getValue().isClosed()) { + if (entry.getValue().getKey().isClosed()) { it.remove(); } }