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%2Fdependencyresolver%2FDependencyResolverManager.java;h=15f5d48a6f51f43decd567129ce5d0854cc9ddcb;hp=34b3093f5d3933daf456eb8a263369aedc50ef02;hb=8161319be53a57e3ac22ba72f267483526e11e0d;hpb=9fb64948564e252018f9b1e13e7cea2c92f991aa diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverManager.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverManager.java index 34b3093f5d..15f5d48a6f 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverManager.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverManager.java @@ -7,49 +7,78 @@ */ package org.opendaylight.controller.config.manager.impl.dependencyresolver; +import static com.google.common.base.Preconditions.checkState; + +import com.google.common.reflect.AbstractInvocationHandler; +import com.google.common.reflect.Reflection; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; - import javax.annotation.concurrent.GuardedBy; import javax.management.InstanceAlreadyExistsException; - +import javax.management.MBeanServer; +import org.opendaylight.controller.config.api.DependencyResolver; +import org.opendaylight.controller.config.api.DependencyResolverFactory; import org.opendaylight.controller.config.api.JmxAttribute; 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.manager.impl.CommitInfo; -import org.opendaylight.controller.config.manager.impl.ModuleInternalTransactionalInfo; +import org.opendaylight.controller.config.manager.impl.DeadlockMonitor; +import org.opendaylight.controller.config.manager.impl.ModuleInternalInfo; +import org.opendaylight.controller.config.manager.impl.TransactionIdentifier; import org.opendaylight.controller.config.manager.impl.TransactionStatus; +import org.opendaylight.controller.config.manager.impl.jmx.TransactionModuleJMXRegistrator.TransactionModuleJMXRegistration; 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; /** * Holds information about modules being created and destroyed within this * transaction. Observes usage of DependencyResolver within modules to figure * out dependency tree. */ -public class DependencyResolverManager implements TransactionHolder { +public class DependencyResolverManager implements DependencyResolverFactory, AutoCloseable { @GuardedBy("this") private final Map moduleIdentifiersToDependencyResolverMap = new HashMap<>(); + private final TransactionIdentifier transactionIdentifier; private final ModulesHolder modulesHolder; private final TransactionStatus transactionStatus; - - public DependencyResolverManager(String transactionName, - TransactionStatus transactionStatus) { - this.modulesHolder = new ModulesHolder(transactionName); + private final ServiceReferenceReadableRegistry readableRegistry; + private final CodecRegistry codecRegistry; + private final DeadlockMonitor deadlockMonitor; + private final MBeanServer mBeanServer; + + public DependencyResolverManager(TransactionIdentifier transactionIdentifier, + TransactionStatus transactionStatus, + ServiceReferenceReadableRegistry readableRegistry, CodecRegistry codecRegistry, + MBeanServer mBeanServer) { + this.transactionIdentifier = transactionIdentifier; + this.modulesHolder = new ModulesHolder(transactionIdentifier); this.transactionStatus = transactionStatus; + this.readableRegistry = readableRegistry; + this.codecRegistry = codecRegistry; + this.deadlockMonitor = new DeadlockMonitor(transactionIdentifier); + this.mBeanServer = mBeanServer; + } + + @Override + public DependencyResolver createDependencyResolver(ModuleIdentifier moduleIdentifier) { + return getOrCreate(moduleIdentifier); } public synchronized DependencyResolverImpl getOrCreate(ModuleIdentifier name) { - DependencyResolverImpl dependencyResolver = moduleIdentifiersToDependencyResolverMap - .get(name); + DependencyResolverImpl dependencyResolver = moduleIdentifiersToDependencyResolverMap.get(name); if (dependencyResolver == null) { transactionStatus.checkNotCommitted(); - dependencyResolver = new DependencyResolverImpl(name, - transactionStatus, modulesHolder); - moduleIdentifiersToDependencyResolverMap.put(name, - dependencyResolver); + dependencyResolver = new DependencyResolverImpl(name, transactionStatus, modulesHolder, readableRegistry, + codecRegistry, transactionIdentifier.getName(), mBeanServer); + moduleIdentifiersToDependencyResolverMap.put(name, dependencyResolver); } return dependencyResolver; } @@ -73,13 +102,12 @@ public class DependencyResolverManager implements TransactionHolder { List result = new ArrayList<>( moduleIdentifiersToDependencyResolverMap.size()); for (DependencyResolverImpl dri : getAllSorted()) { - ModuleIdentifier driName = dri.getName(); + ModuleIdentifier driName = dri.getIdentifier(); result.add(driName); } return result; } - @Override public ModuleInternalTransactionalInfo destroyModule( ModuleIdentifier moduleIdentifier) { transactionStatus.checkNotCommitted(); @@ -90,42 +118,102 @@ public class DependencyResolverManager implements TransactionHolder { } // protect write access - @Override + public void put( - ModuleInternalTransactionalInfo moduleInternalTransactionalInfo) { + final ModuleIdentifier moduleIdentifier, + final Module module, + ModuleFactory moduleFactory, + ModuleInternalInfo maybeOldInternalInfo, + TransactionModuleJMXRegistration transactionModuleJMXRegistration, + boolean isDefaultBean, BundleContext bundleContext) { transactionStatus.checkNotCommitted(); + + Class moduleClass = Module.class; + if (module instanceof RuntimeBeanRegistratorAwareModule) { + moduleClass = RuntimeBeanRegistratorAwareModule.class; + } + Module proxiedModule = Reflection.newProxy(moduleClass, new AbstractInvocationHandler() { + // optimization: subsequent calls to getInstance MUST return the same value during transaction, + // so it is safe to cache the response + private Object cachedInstance; + + @Override + protected Object handleInvocation(Object proxy, Method method, Object[] args) throws Throwable { + boolean isGetInstance = "getInstance".equals(method.getName()); + if (isGetInstance) { + if (cachedInstance != null) { + return cachedInstance; + } + + checkState(deadlockMonitor.isAlive(), "Deadlock monitor is not alive"); + deadlockMonitor.setCurrentlyInstantiatedModule(moduleIdentifier); + } + try { + Object response = method.invoke(module, args); + if (isGetInstance) { + cachedInstance = response; + } + return response; + } catch(InvocationTargetException e) { + throw e.getCause(); + } finally { + if (isGetInstance) { + deadlockMonitor.setCurrentlyInstantiatedModule(null); + } + } + } + }); + + + ModuleInternalTransactionalInfo moduleInternalTransactionalInfo = new ModuleInternalTransactionalInfo( + moduleIdentifier, proxiedModule, moduleFactory, + maybeOldInternalInfo, transactionModuleJMXRegistration, isDefaultBean, module, bundleContext); modulesHolder.put(moduleInternalTransactionalInfo); } // wrapped methods: - @Override public CommitInfo toCommitInfo() { return modulesHolder.toCommitInfo(); } - @Override public Module findModule(ModuleIdentifier moduleIdentifier, - JmxAttribute jmxAttributeForReporting) { + JmxAttribute jmxAttributeForReporting) { return modulesHolder.findModule(moduleIdentifier, jmxAttributeForReporting); } - @Override + public ModuleInternalTransactionalInfo findModuleInternalTransactionalInfo(ModuleIdentifier moduleIdentifier) { + return modulesHolder.findModuleInternalTransactionalInfo(moduleIdentifier); + } + public ModuleFactory findModuleFactory(ModuleIdentifier moduleIdentifier, - JmxAttribute jmxAttributeForReporting) { + JmxAttribute jmxAttributeForReporting) { return modulesHolder.findModuleFactory(moduleIdentifier, jmxAttributeForReporting); } - @Override public Map getAllModules() { return modulesHolder.getAllModules(); } - @Override public void assertNotExists(ModuleIdentifier moduleIdentifier) throws InstanceAlreadyExistsException { modulesHolder.assertNotExists(moduleIdentifier); } + + public List findAllByFactory(ModuleFactory factory) { + List result = new ArrayList<>(); + for (ModuleInternalTransactionalInfo info : modulesHolder.getAllInfos()) { + if (factory.equals(info.getModuleFactory())) { + result.add(info.getIdentifier()); + } + } + return result; + } + + public void close() { + deadlockMonitor.close(); + } + }