X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fconfig%2Fconfig-manager%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fconfig%2Fmanager%2Fimpl%2Fdependencyresolver%2FDependencyResolverImpl.java;h=c229450c30138584e615e552843c1b0f10581dca;hb=0c931b8d1fa153991b10705a4358fe39f93181cd;hp=065a0f843f501cdb7e2a4230c9cc0b72caf31f3c;hpb=d542617f3486541cf9937009fb6aa1e3f2c9f0e2;p=controller.git 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 065a0f843f..c229450c30 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 @@ -8,14 +8,22 @@ package org.opendaylight.controller.config.manager.impl.dependencyresolver; import org.opendaylight.controller.config.api.DependencyResolver; +import org.opendaylight.controller.config.api.IdentityAttributeRef; import org.opendaylight.controller.config.api.JmxAttribute; import org.opendaylight.controller.config.api.JmxAttributeValidationException; import org.opendaylight.controller.config.api.ModuleIdentifier; +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.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; import javax.annotation.concurrent.GuardedBy; import javax.management.ObjectName; @@ -31,52 +39,64 @@ import static java.lang.String.format; * during validation. Tracks dependencies for ordering purposes. */ final class DependencyResolverImpl implements DependencyResolver, - Comparable { + Comparable { + private static final Logger logger = LoggerFactory.getLogger(DependencyResolverImpl.class); + private final ModulesHolder modulesHolder; private final ModuleIdentifier name; private final TransactionStatus transactionStatus; @GuardedBy("this") private final Set dependencies = new HashSet<>(); + private final ServiceReferenceReadableRegistry readableRegistry; + private final CodecRegistry codecRegistry; DependencyResolverImpl(ModuleIdentifier currentModule, - TransactionStatus transactionStatus, ModulesHolder modulesHolder) { + TransactionStatus transactionStatus, ModulesHolder modulesHolder, + ServiceReferenceReadableRegistry readableRegistry, CodecRegistry codecRegistry) { + this.codecRegistry = codecRegistry; this.name = currentModule; this.transactionStatus = transactionStatus; this.modulesHolder = modulesHolder; + this.readableRegistry = readableRegistry; } /** * {@inheritDoc} */ + //TODO: check for cycles @Override public void validateDependency( Class expectedServiceInterface, - ObjectName dependentModuleReadOnlyON, JmxAttribute jmxAttribute) { + ObjectName dependentReadOnlyON, JmxAttribute jmxAttribute) { transactionStatus.checkNotCommitted(); if (expectedServiceInterface == null) { throw new NullPointerException( "Parameter 'expectedServiceInterface' is null"); } - if (jmxAttribute == null) + if (jmxAttribute == null) { throw new NullPointerException("Parameter 'jmxAttribute' is null"); + } - JmxAttributeValidationException.checkNotNull(dependentModuleReadOnlyON, - "is null, " + "expected dependency implementing " + JmxAttributeValidationException.checkNotNull(dependentReadOnlyON, + "is null, expected dependency implementing " + expectedServiceInterface, jmxAttribute); + // check that objectName belongs to this transaction - this should be // stripped // in DynamicWritableWrapper boolean hasTransaction = ObjectNameUtil - .getTransactionName(dependentModuleReadOnlyON) != null; + .getTransactionName(dependentReadOnlyON) != null; JmxAttributeValidationException.checkCondition( hasTransaction == false, format("ObjectName should not contain " + "transaction name. %s set to %s. ", jmxAttribute, - dependentModuleReadOnlyON), jmxAttribute); + dependentReadOnlyON), jmxAttribute); - ModuleIdentifier moduleIdentifier = ObjectNameUtil.fromON(dependentModuleReadOnlyON, ObjectNameUtil + dependentReadOnlyON = translateServiceRefIfPossible(dependentReadOnlyON); + + ModuleIdentifier moduleIdentifier = ObjectNameUtil.fromON(dependentReadOnlyON, ObjectNameUtil .TYPE_MODULE); ModuleFactory foundFactory = modulesHolder.findModuleFactory(moduleIdentifier, jmxAttribute); @@ -89,7 +109,7 @@ final class DependencyResolverImpl implements DependencyResolver, + "Module name is %s : %s, expected service interface %s, dependent module ON %s , " + "attribute %s", foundFactory.getImplementationName(), foundFactory, - expectedServiceInterface, dependentModuleReadOnlyON, + expectedServiceInterface, dependentReadOnlyON, jmxAttribute); throw new JmxAttributeValidationException(message, jmxAttribute); } @@ -98,23 +118,35 @@ 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 + readableRegistry.lookupConfigBeanByServiceInterfaceName(serviceQName, refName)); + } + return dependentReadOnlyON; + } + /** * {@inheritDoc} */ + //TODO: check for cycles @Override - public T resolveInstance(Class expectedType, ObjectName dependentON, - JmxAttribute jmxAttribute) { - if (expectedType == null || dependentON == null || jmxAttribute == null) { + 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 {} {} {}", expectedType, - dependentON, jmxAttribute)); + "Null parameters not allowed, got %s %s %s", expectedType, + dependentReadOnlyON, jmxAttribute)); } - + dependentReadOnlyON = translateServiceRefIfPossible(dependentReadOnlyON); transactionStatus.checkCommitStarted(); transactionStatus.checkNotCommitted(); ModuleIdentifier dependentModuleIdentifier = ObjectNameUtil.fromON( - dependentON, ObjectNameUtil.TYPE_MODULE); + dependentReadOnlyON, ObjectNameUtil.TYPE_MODULE); Module module = modulesHolder.findModule(dependentModuleIdentifier, jmxAttribute); synchronized (this) { @@ -129,8 +161,7 @@ final class DependencyResolverImpl implements DependencyResolver, throw new JmxAttributeValidationException(message, jmxAttribute); } try { - T result = expectedType.cast(instance); - return result; + return expectedType.cast(instance); } catch (ClassCastException e) { String message = format( "Instance cannot be cast to expected type. Instance class is %s , " @@ -140,6 +171,33 @@ final class DependencyResolverImpl implements DependencyResolver, } } + @Override + public Class resolveIdentity(IdentityAttributeRef identityRef, Class expectedBaseClass) { + final QName qName = QName.create(identityRef.getqNameOfIdentity()); + IdentityCodec identityCodec = codecRegistry.getIdentityCodec(); + Class deserialized = identityCodec.deserialize(qName); + if (deserialized == null) { + throw new IllegalStateException("Unable to retrieve identity class for " + qName + ", null response from " + + codecRegistry); + } + if (expectedBaseClass.isAssignableFrom(deserialized)) { + return (Class) deserialized; + } else { + logger.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); + } + } + + @Override + public void validateIdentity(IdentityAttributeRef identityRef, Class expectedBaseClass, JmxAttribute jmxAttribute) { + try { + resolveIdentity(identityRef, expectedBaseClass); + } catch (Exception e) { + throw JmxAttributeValidationException.wrap(e, jmxAttribute); + } + } + @Override public int compareTo(DependencyResolverImpl o) { transactionStatus.checkCommitted(); @@ -156,7 +214,7 @@ final class DependencyResolverImpl implements DependencyResolver, return maxDependencyDepth; } - public void countMaxDependencyDepth(DependencyResolverManager manager) { + void countMaxDependencyDepth(DependencyResolverManager manager) { transactionStatus.checkCommitted(); if (maxDependencyDepth == null) { maxDependencyDepth = getMaxDepth(this, manager, @@ -165,8 +223,8 @@ final class DependencyResolverImpl implements DependencyResolver, } private static int getMaxDepth(DependencyResolverImpl impl, - DependencyResolverManager manager, - LinkedHashSet chainForDetectingCycles) { + DependencyResolverManager manager, + LinkedHashSet chainForDetectingCycles) { int maxDepth = 0; LinkedHashSet chainForDetectingCycles2 = new LinkedHashSet<>( chainForDetectingCycles); @@ -176,7 +234,7 @@ final class DependencyResolverImpl implements DependencyResolver, .getOrCreate(dependencyName); if (chainForDetectingCycles2.contains(dependencyName)) { throw new IllegalStateException(format( - "Cycle detected, {} contains {}", + "Cycle detected, %s contains %s", chainForDetectingCycles2, dependencyName)); } int subDepth; @@ -199,4 +257,5 @@ final class DependencyResolverImpl implements DependencyResolver, public ModuleIdentifier getIdentifier() { return name; } + }