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%2FDependencyResolverImpl.java;h=d667f13ec601e23d6b0cb77447dba63a13c9ec56;hp=4f60a673f5f711ce17815061318f2641bbda0091;hb=6227570f6482136b72a26675d43c8bb88279503e;hpb=803d525860fbb1974b65ba5605ba5a9dfe1928a4 diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverImpl.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverImpl.java index 4f60a673f5..d667f13ec6 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverImpl.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverImpl.java @@ -7,8 +7,7 @@ */ package org.opendaylight.controller.config.manager.impl.dependencyresolver; -import static java.lang.String.format; - +import com.google.common.base.Preconditions; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Set; @@ -29,12 +28,11 @@ import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry; import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface; import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; import org.opendaylight.controller.config.manager.impl.TransactionStatus; +import org.opendaylight.controller.config.manager.impl.osgi.mapping.BindingContextProvider; import org.opendaylight.controller.config.spi.Module; import org.opendaylight.controller.config.spi.ModuleFactory; import org.opendaylight.yangtools.yang.binding.BaseIdentity; import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry; -import org.opendaylight.yangtools.yang.data.impl.codec.IdentityCodec; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,7 +43,7 @@ import org.slf4j.LoggerFactory; */ final class DependencyResolverImpl implements DependencyResolver, Comparable { - private static final Logger logger = LoggerFactory.getLogger(DependencyResolverImpl.class); + private static final Logger LOG = LoggerFactory.getLogger(DependencyResolverImpl.class); private final ModulesHolder modulesHolder; private final ModuleIdentifier name; @@ -53,15 +51,16 @@ final class DependencyResolverImpl implements DependencyResolver, @GuardedBy("this") private final Set dependencies = new HashSet<>(); private final ServiceReferenceReadableRegistry readableRegistry; - private final CodecRegistry codecRegistry; + private final BindingContextProvider bindingContextProvider; private final String transactionName; private final MBeanServer mBeanServer; + private Integer maxDependencyDepth; DependencyResolverImpl(ModuleIdentifier currentModule, TransactionStatus transactionStatus, ModulesHolder modulesHolder, - ServiceReferenceReadableRegistry readableRegistry, CodecRegistry codecRegistry, + ServiceReferenceReadableRegistry readableRegistry, BindingContextProvider bindingContextProvider, String transactionName, MBeanServer mBeanServer) { - this.codecRegistry = codecRegistry; + this.bindingContextProvider = bindingContextProvider; this.name = currentModule; this.transactionStatus = transactionStatus; this.modulesHolder = modulesHolder; @@ -100,29 +99,29 @@ final class DependencyResolverImpl implements DependencyResolver, boolean hasTransaction = ObjectNameUtil .getTransactionName(dependentReadOnlyON) != null; JmxAttributeValidationException.checkCondition( - hasTransaction == false, - format("ObjectName should not contain " + !hasTransaction, + String.format("ObjectName should not contain " + "transaction name. %s set to %s. ", jmxAttribute, dependentReadOnlyON - ), jmxAttribute + ), jmxAttribute ); - dependentReadOnlyON = translateServiceRefIfPossible(dependentReadOnlyON); + ObjectName newDependentReadOnlyON = translateServiceRefIfPossible(dependentReadOnlyON); - ModuleIdentifier moduleIdentifier = ObjectNameUtil.fromON(dependentReadOnlyON, ObjectNameUtil + ModuleIdentifier moduleIdentifier = ObjectNameUtil.fromON(newDependentReadOnlyON, ObjectNameUtil .TYPE_MODULE); ModuleFactory foundFactory = modulesHolder.findModuleFactory(moduleIdentifier, jmxAttribute); boolean implementsSI = foundFactory .isModuleImplementingServiceInterface(expectedServiceInterface); - if (implementsSI == false) { - String message = format( + if (!implementsSI) { + String message = String.format( "Found module factory does not expose expected service interface. " + "Module name is %s : %s, expected service interface %s, dependent module ON %s , " + "attribute %s", foundFactory.getImplementationName(), foundFactory, - expectedServiceInterface, dependentReadOnlyON, + expectedServiceInterface, newDependentReadOnlyON, jmxAttribute ); throw new JmxAttributeValidationException(message, jmxAttribute); @@ -134,13 +133,14 @@ final class DependencyResolverImpl implements DependencyResolver, // translate from serviceref to module ON private ObjectName translateServiceRefIfPossible(ObjectName dependentReadOnlyON) { - if (ObjectNameUtil.isServiceReference(dependentReadOnlyON)) { - String serviceQName = ObjectNameUtil.getServiceQName(dependentReadOnlyON); - String refName = ObjectNameUtil.getReferenceName(dependentReadOnlyON); - dependentReadOnlyON = ObjectNameUtil.withoutTransactionName( // strip again of transaction name + ObjectName translatedDependentReadOnlyON = dependentReadOnlyON; + if (ObjectNameUtil.isServiceReference(translatedDependentReadOnlyON)) { + String serviceQName = ObjectNameUtil.getServiceQName(translatedDependentReadOnlyON); + String refName = ObjectNameUtil.getReferenceName(translatedDependentReadOnlyON); + translatedDependentReadOnlyON = ObjectNameUtil.withoutTransactionName( // strip again of transaction name readableRegistry.lookupConfigBeanByServiceInterfaceName(serviceQName, refName)); } - return dependentReadOnlyON; + return translatedDependentReadOnlyON; } /** @@ -150,35 +150,24 @@ final class DependencyResolverImpl implements DependencyResolver, @Override public T resolveInstance(Class expectedType, ObjectName dependentReadOnlyON, JmxAttribute jmxAttribute) { - if (expectedType == null || dependentReadOnlyON == null || jmxAttribute == null) { - throw new IllegalArgumentException(format( - "Null parameters not allowed, got %s %s %s", expectedType, - dependentReadOnlyON, jmxAttribute)); - } - dependentReadOnlyON = translateServiceRefIfPossible(dependentReadOnlyON); - transactionStatus.checkCommitStarted(); - transactionStatus.checkNotCommitted(); + Module module = resolveModuleInstance(dependentReadOnlyON, jmxAttribute); - ModuleIdentifier dependentModuleIdentifier = ObjectNameUtil.fromON( - dependentReadOnlyON, ObjectNameUtil.TYPE_MODULE); - Module module = modulesHolder.findModule(dependentModuleIdentifier, - jmxAttribute); synchronized (this) { - dependencies.add(dependentModuleIdentifier); + dependencies.add(module.getIdentifier()); } AutoCloseable instance = module.getInstance(); if (instance == null) { - String message = format( + String message = String.format( "Error while %s resolving instance %s. getInstance() returned null. " + "Expected type %s , attribute %s", name, - dependentModuleIdentifier, expectedType, jmxAttribute + module.getIdentifier(), expectedType, jmxAttribute ); throw new JmxAttributeValidationException(message, jmxAttribute); } try { return expectedType.cast(instance); } catch (ClassCastException e) { - String message = format( + String message = String.format( "Instance cannot be cast to expected type. Instance class is %s , " + "expected type %s , attribute %s", instance.getClass(), expectedType, jmxAttribute @@ -187,19 +176,48 @@ final class DependencyResolverImpl implements DependencyResolver, } } + private Module resolveModuleInstance(ObjectName dependentReadOnlyON, + JmxAttribute jmxAttribute) { + Preconditions.checkArgument(dependentReadOnlyON != null ,"dependentReadOnlyON"); + Preconditions.checkArgument(jmxAttribute != null, "jmxAttribute"); + ObjectName translatedDependentReadOnlyON = translateServiceRefIfPossible(dependentReadOnlyON); + transactionStatus.checkCommitStarted(); + transactionStatus.checkNotCommitted(); + + ModuleIdentifier dependentModuleIdentifier = ObjectNameUtil.fromON( + translatedDependentReadOnlyON, ObjectNameUtil.TYPE_MODULE); + + return Preconditions.checkNotNull(modulesHolder.findModule(dependentModuleIdentifier, jmxAttribute)); + } + + @Override + public boolean canReuseDependency(ObjectName objectName, JmxAttribute jmxAttribute) { + Preconditions.checkNotNull(objectName); + Preconditions.checkNotNull(jmxAttribute); + + Module currentModule = resolveModuleInstance(objectName, jmxAttribute); + ModuleIdentifier identifier = currentModule.getIdentifier(); + ModuleInternalTransactionalInfo moduleInternalTransactionalInfo = modulesHolder.findModuleInternalTransactionalInfo(identifier); + + if(moduleInternalTransactionalInfo.hasOldModule()) { + Module oldModule = moduleInternalTransactionalInfo.getOldInternalInfo().getReadableModule().getModule(); + return currentModule.canReuse(oldModule); + } + return false; + } + @Override public Class resolveIdentity(IdentityAttributeRef identityRef, Class expectedBaseClass) { final QName qName = QName.create(identityRef.getqNameOfIdentity()); - IdentityCodec identityCodec = codecRegistry.getIdentityCodec(); - Class deserialized = identityCodec.deserialize(qName); + Class deserialized = bindingContextProvider.getBindingContext().getIdentityClass(qName); if (deserialized == null) { throw new IllegalStateException("Unable to retrieve identity class for " + qName + ", null response from " - + codecRegistry); + + bindingContextProvider.getBindingContext()); } if (expectedBaseClass.isAssignableFrom(deserialized)) { return (Class) deserialized; } else { - logger.error("Cannot resolve class of identity {} : deserialized class {} is not a subclass of {}.", + LOG.error("Cannot resolve class of identity {} : deserialized class {} is not a subclass of {}.", identityRef, deserialized, expectedBaseClass); throw new IllegalArgumentException("Deserialized identity " + deserialized + " cannot be cast to " + expectedBaseClass); } @@ -216,13 +234,11 @@ final class DependencyResolverImpl implements DependencyResolver, @Override public int compareTo(DependencyResolverImpl o) { - transactionStatus.checkCommitted(); + transactionStatus.checkCommitStarted(); return Integer.compare(getMaxDependencyDepth(), o.getMaxDependencyDepth()); } - private Integer maxDependencyDepth; - int getMaxDependencyDepth() { if (maxDependencyDepth == null) { throw new IllegalStateException("Dependency depth was not computed"); @@ -231,10 +247,14 @@ final class DependencyResolverImpl implements DependencyResolver, } void countMaxDependencyDepth(DependencyResolverManager manager) { - transactionStatus.checkCommitted(); + // We can calculate the dependency after second phase commit was started + // Second phase commit starts after validation and validation adds the dependencies into the dependency resolver, which are necessary for the calculation + // FIXME generated code for abstract module declares validate method as non-final + // Overriding the validate would cause recreate every time instead of reuse + also possibly wrong close order if there is another module depending + transactionStatus.checkCommitStarted(); if (maxDependencyDepth == null) { maxDependencyDepth = getMaxDepth(this, manager, - new LinkedHashSet()); + new LinkedHashSet<>()); } } @@ -249,7 +269,7 @@ final class DependencyResolverImpl implements DependencyResolver, DependencyResolverImpl dependentDRI = manager .getOrCreate(dependencyName); if (chainForDetectingCycles2.contains(dependencyName)) { - throw new IllegalStateException(format( + throw new IllegalStateException(String.format( "Cycle detected, %s contains %s", chainForDetectingCycles2, dependencyName)); } @@ -277,17 +297,17 @@ final class DependencyResolverImpl implements DependencyResolver, @Override public Object getAttribute(ObjectName name, String attribute) throws MBeanException, AttributeNotFoundException, InstanceNotFoundException, ReflectionException { - name = translateServiceRefIfPossible(name); + ObjectName newName = translateServiceRefIfPossible(name); // add transaction name - name = ObjectNameUtil.withTransactionName(name, transactionName); - return mBeanServer.getAttribute(name, attribute); + newName = ObjectNameUtil.withTransactionName(newName, transactionName); + return mBeanServer.getAttribute(newName, attribute); } @Override public T newMXBeanProxy(ObjectName name, Class interfaceClass) { - name = translateServiceRefIfPossible(name); + ObjectName newName = translateServiceRefIfPossible(name); // add transaction name - name = ObjectNameUtil.withTransactionName(name, transactionName); - return JMX.newMXBeanProxy(mBeanServer, name, interfaceClass); + newName = ObjectNameUtil.withTransactionName(newName, transactionName); + return JMX.newMXBeanProxy(mBeanServer, newName, interfaceClass); } }