From: Ed Warnicke Date: Sun, 26 Jan 2014 03:41:33 +0000 (+0000) Subject: Merge "Reduce verbosity/criticality of inconsistent yangstore messages" X-Git-Tag: jenkins-controller-bulk-release-prepare-only-2-10~4 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=5a33a4fe140497f02177963131a128e4852f637a;hp=28fc795bb908acd6134d6b19146ba819e311237e Merge "Reduce verbosity/criticality of inconsistent yangstore messages" --- diff --git a/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/DependencyResolver.java b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/DependencyResolver.java index 39845454ef..b020000d3d 100644 --- a/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/DependencyResolver.java +++ b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/DependencyResolver.java @@ -7,10 +7,11 @@ */ package org.opendaylight.controller.config.api; -import javax.management.ObjectName; - import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface; import org.opendaylight.yangtools.concepts.Identifiable; +import org.opendaylight.yangtools.yang.binding.BaseIdentity; + +import javax.management.ObjectName; /** * Each new {@link org.opendaylight.controller.config.spi.Module} can receive @@ -49,4 +50,15 @@ public interface DependencyResolver extends Identifiable { T resolveInstance(Class expectedType, ObjectName objectName, JmxAttribute jmxAttribute); + // TODO finish javadoc + + /** + * To be used during commit phase to resolve identity-ref config attributes. + * + * @return actual class object generated from identity + */ + Class resolveIdentity(IdentityAttributeRef identityRef, Class expectedBaseClass); + + void validateIdentity(IdentityAttributeRef identityRef, Class expectedBaseClass, JmxAttribute jmxAttribute); + } diff --git a/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/IdentityAttributeRef.java b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/IdentityAttributeRef.java new file mode 100644 index 0000000000..73737593cf --- /dev/null +++ b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/IdentityAttributeRef.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.config.api; + +import org.opendaylight.yangtools.yang.binding.BaseIdentity; + +import java.beans.ConstructorProperties; + +public final class IdentityAttributeRef { + + public static final String QNAME_ATTR_NAME = "qNameOfIdentity"; + + private final String qNameOfIdentity; + + @ConstructorProperties(QNAME_ATTR_NAME) + public IdentityAttributeRef(String qNameOfIdentity) { + if (qNameOfIdentity == null) + throw new NullPointerException("Parameter " + QNAME_ATTR_NAME + " is null"); + this.qNameOfIdentity = qNameOfIdentity; + } + + public String getqNameOfIdentity() { + return qNameOfIdentity; + } + + public Class resolveIdentity(DependencyResolver resolver, Class baseIdentity) { + return resolver.resolveIdentity(this, baseIdentity); + } + + public void validateIdentity(DependencyResolver resolver, Class baseIdentity, JmxAttribute jmxAttribute) { + resolver.validateIdentity(this, baseIdentity, jmxAttribute); + } + + @Override + public String toString() { + final StringBuffer sb = new StringBuffer("IdentityAttributeRef{"); + sb.append("qNameOfIdentity='").append(qNameOfIdentity).append('\''); + sb.append('}'); + return sb.toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof IdentityAttributeRef)) return false; + + IdentityAttributeRef that = (IdentityAttributeRef) o; + + if (!qNameOfIdentity.equals(that.qNameOfIdentity)) return false; + + return true; + } + + @Override + public int hashCode() { + return qNameOfIdentity.hashCode(); + } + +} 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 a8406b0029..39682fa6b4 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 @@ -27,6 +27,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; @@ -60,6 +61,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; @@ -107,19 +109,20 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe // 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) { + 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 @@ -161,7 +164,7 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe readableSRRegistry, txLookupRegistry, allCurrentFactories); ConfigTransactionControllerInternal transactionController = new ConfigTransactionControllerImpl( - txLookupRegistry, version, + txLookupRegistry, version, codecRegistry, versionCounter, allCurrentFactories, transactionsMBeanServer, configMBeanServer, blankTransaction, writableRegistry); try { diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImpl.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImpl.java index 90d2cb4002..0ec6969802 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImpl.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImpl.java @@ -22,6 +22,7 @@ import org.opendaylight.controller.config.manager.impl.jmx.TransactionModuleJMXR import org.opendaylight.controller.config.spi.Module; import org.opendaylight.controller.config.spi.ModuleFactory; import org.opendaylight.yangtools.concepts.Identifiable; +import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry; import org.osgi.framework.BundleContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -82,11 +83,10 @@ class ConfigTransactionControllerImpl implements private final ServiceReferenceWritableRegistry writableSRRegistry; public ConfigTransactionControllerImpl(ConfigTransactionLookupRegistry txLookupRegistry, - long parentVersion, long currentVersion, - Map> currentlyRegisteredFactories, + long parentVersion, CodecRegistry codecRegistry, long currentVersion, + Map> currentlyRegisteredFactories, MBeanServer transactionsMBeanServer, MBeanServer configMBeanServer, boolean blankTransaction, ServiceReferenceWritableRegistry writableSRRegistry) { - this.txLookupRegistry = txLookupRegistry; String transactionName = txLookupRegistry.getTransactionIdentifier().getName(); this.controllerON = ObjectNameUtil.createTransactionControllerON(transactionName); @@ -95,7 +95,7 @@ class ConfigTransactionControllerImpl implements this.currentlyRegisteredFactories = currentlyRegisteredFactories; this.factoriesHolder = new HierarchicalConfigMBeanFactoriesHolder(currentlyRegisteredFactories); this.transactionStatus = new TransactionStatus(); - this.dependencyResolverManager = new DependencyResolverManager(transactionName, transactionStatus, writableSRRegistry); + this.dependencyResolverManager = new DependencyResolverManager(transactionName, transactionStatus, writableSRRegistry, codecRegistry); this.transactionsMBeanServer = transactionsMBeanServer; this.configMBeanServer = configMBeanServer; this.blankTransaction = blankTransaction; 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 925a57b044..ec9678fd2d 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,6 +8,7 @@ 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; @@ -17,6 +18,12 @@ 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; @@ -33,17 +40,20 @@ import static java.lang.String.format; */ final class DependencyResolverImpl implements DependencyResolver, 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, - ServiceReferenceReadableRegistry readableRegistry) { - + TransactionStatus transactionStatus, ModulesHolder modulesHolder, + ServiceReferenceReadableRegistry readableRegistry, CodecRegistry codecRegistry) { + this.codecRegistry = codecRegistry; this.name = currentModule; this.transactionStatus = transactionStatus; this.modulesHolder = modulesHolder; @@ -68,7 +78,7 @@ final class DependencyResolverImpl implements DependencyResolver, throw new NullPointerException("Parameter 'jmxAttribute' is null"); JmxAttributeValidationException.checkNotNull(dependentReadOnlyON, - "is null, " + "expected dependency implementing " + "is null, expected dependency implementing " + expectedServiceInterface, jmxAttribute); @@ -128,7 +138,7 @@ final class DependencyResolverImpl implements DependencyResolver, JmxAttribute jmxAttribute) { if (expectedType == null || dependentReadOnlyON == null || jmxAttribute == null) { throw new IllegalArgumentException(format( - "Null parameters not allowed, got {} {} {}", expectedType, + "Null parameters not allowed, got %s %s %s", expectedType, dependentReadOnlyON, jmxAttribute)); } dependentReadOnlyON = translateServiceRefIfPossible(dependentReadOnlyON); @@ -162,6 +172,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 RuntimeException("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(); @@ -198,7 +235,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; 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 afd865c4fc..c115934d37 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 @@ -17,6 +17,7 @@ import org.opendaylight.controller.config.manager.impl.ModuleInternalTransaction 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.data.impl.codec.CodecRegistry; import javax.annotation.concurrent.GuardedBy; import javax.management.InstanceAlreadyExistsException; @@ -37,12 +38,14 @@ public class DependencyResolverManager implements TransactionHolder, DependencyR private final ModulesHolder modulesHolder; private final TransactionStatus transactionStatus; private final ServiceReferenceReadableRegistry readableRegistry; + private final CodecRegistry codecRegistry; public DependencyResolverManager(String transactionName, - TransactionStatus transactionStatus, ServiceReferenceReadableRegistry readableRegistry) { + TransactionStatus transactionStatus, ServiceReferenceReadableRegistry readableRegistry, CodecRegistry codecRegistry) { this.modulesHolder = new ModulesHolder(transactionName); this.transactionStatus = transactionStatus; this.readableRegistry = readableRegistry; + this.codecRegistry = codecRegistry; } @Override @@ -54,7 +57,7 @@ public class DependencyResolverManager implements TransactionHolder, DependencyR DependencyResolverImpl dependencyResolver = moduleIdentifiersToDependencyResolverMap.get(name); if (dependencyResolver == null) { transactionStatus.checkNotCommitted(); - dependencyResolver = new DependencyResolverImpl(name, transactionStatus, modulesHolder, readableRegistry); + dependencyResolver = new DependencyResolverImpl(name, transactionStatus, modulesHolder, readableRegistry, codecRegistry); moduleIdentifiersToDependencyResolverMap.put(name, dependencyResolver); } return dependencyResolver; diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ConfigManagerActivator.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ConfigManagerActivator.java index 57aa74cccc..e4e070885c 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ConfigManagerActivator.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ConfigManagerActivator.java @@ -56,7 +56,7 @@ public class ConfigManagerActivator implements BundleActivator { // TODO push codecRegistry/IdentityCodec to dependencyResolver configRegistry = new ConfigRegistryImpl( - bundleContextBackedModuleFactoriesResolver, configMBeanServer); + bundleContextBackedModuleFactoriesResolver, configMBeanServer, codecRegistry); // register config registry to OSGi configRegistryServiceRegistration = context.registerService(ConfigRegistryImpl.class, configRegistry, null); diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/ConfigRegistryImplTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/ConfigRegistryImplTest.java index e6b07bab64..9178dc40d0 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/ConfigRegistryImplTest.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/ConfigRegistryImplTest.java @@ -40,7 +40,7 @@ public class ConfigRegistryImplTest extends factory, factory); configRegistry = new ConfigRegistryImpl(resolver, - ManagementFactory.getPlatformMBeanServer()); + ManagementFactory.getPlatformMBeanServer(), null); configRegistry.beginConfig(); fail(); diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/AbstractConfigTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/AbstractConfigTest.java index 64ce14e8f1..d9bbeb4a2c 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/AbstractConfigTest.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/AbstractConfigTest.java @@ -23,6 +23,7 @@ import org.opendaylight.controller.config.manager.testingservices.threadpool.Tes import org.opendaylight.controller.config.spi.Module; import org.opendaylight.controller.config.util.ConfigRegistryJMXClient; import org.opendaylight.controller.config.util.ConfigTransactionJMXClient; +import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; import org.slf4j.Logger; @@ -97,7 +98,7 @@ public abstract class AbstractConfigTest extends baseJmxRegistrator = new BaseJMXRegistrator(internalJmxRegistrator); configRegistry = new ConfigRegistryImpl(resolver, - platformMBeanServer, baseJmxRegistrator); + platformMBeanServer, baseJmxRegistrator, getCodecRegistry()); try { configRegistryJMXRegistrator.registerToJMX(configRegistry); @@ -208,6 +209,10 @@ public abstract class AbstractConfigTest extends return new ClassBasedModuleFactory(implementationName, configBeanClass); } + protected CodecRegistry getCodecRegistry() { + return mock(CodecRegistry.class); + } + public static interface BundleContextServiceRegistrationHandler { @@ -215,10 +220,10 @@ public abstract class AbstractConfigTest extends } - private class RegisterServiceAnswer implements Answer { + private class RegisterServiceAnswer implements Answer> { @Override - public Object answer(InvocationOnMock invocation) throws Throwable { + public ServiceRegistration answer(InvocationOnMock invocation) throws Throwable { Object[] args = invocation.getArguments(); Preconditions.checkArgument(args.length == 3, "Unexpected arguments size (expected 3 was %s)", args.length); diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ConfigRegistryImplLookupTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ConfigRegistryImplLookupTest.java index a522356a27..7a4b46f9f3 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ConfigRegistryImplLookupTest.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ConfigRegistryImplLookupTest.java @@ -67,7 +67,7 @@ public class ConfigRegistryImplLookupTest extends @Before public void setUp() throws Exception { configRegistryImpl = new ConfigRegistryImpl(null, - ManagementFactory.getPlatformMBeanServer()); + ManagementFactory.getPlatformMBeanServer(), null); Field field = configRegistryImpl.getClass().getDeclaredField( "baseJMXRegistrator"); field.setAccessible(true); diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImplTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImplTest.java index 50f5742149..09aea0895f 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImplTest.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImplTest.java @@ -75,7 +75,7 @@ public class ConfigTransactionControllerImplTest extends testedTxController = new ConfigTransactionControllerImpl( - txLookupRegistry, 1, 1, + txLookupRegistry, 1, null, 1, currentlyRegisteredFactories, transactionsMBeanServer, ManagementFactory.getPlatformMBeanServer(), false, writableRegistry); TransactionModuleJMXRegistrator transactionModuleJMXRegistrator123 = testedTxController diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverManagerTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverManagerTest.java index 31e70bd84e..63a66e96eb 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverManagerTest.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverManagerTest.java @@ -42,7 +42,7 @@ public class DependencyResolverManagerTest { public void setUp() { transactionStatus = mock(TransactionStatus.class); ServiceReferenceReadableRegistry mockedRegistry = mock(ServiceReferenceReadableRegistry.class); - tested = new DependencyResolverManager("txName", transactionStatus, mockedRegistry); + tested = new DependencyResolverManager("txName", transactionStatus, mockedRegistry, null); doNothing().when(transactionStatus).checkCommitStarted(); doNothing().when(transactionStatus).checkNotCommitted(); } diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/TemplateFactory.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/TemplateFactory.java index 49a20bd462..fea9a79616 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/TemplateFactory.java +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/TemplateFactory.java @@ -12,6 +12,8 @@ import com.google.common.base.Preconditions; import com.google.common.collect.Collections2; import com.google.common.collect.Lists; import com.google.common.collect.Maps; +import org.opendaylight.controller.config.api.DependencyResolver; +import org.opendaylight.controller.config.api.IdentityAttributeRef; import org.opendaylight.controller.config.api.RuntimeBeanRegistratorAwareModule; import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface; import org.opendaylight.controller.config.api.runtime.RuntimeBean; @@ -35,6 +37,7 @@ import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Anno import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Constructor; import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Field; import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Header; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.IdentityRefModuleField; import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.MethodDeclaration; import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.MethodDefinition; import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.ModuleField; @@ -42,6 +45,7 @@ import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.FullyQual import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil; import org.opendaylight.yangtools.sal.binding.model.api.ParameterizedType; import org.opendaylight.yangtools.sal.binding.model.api.Type; +import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition; import javax.management.openmbean.SimpleType; import java.util.ArrayList; @@ -153,12 +157,12 @@ public class TemplateFactory { } // FIXME: put into Type.toString - static String serializeType(Type type) { + static String serializeType(Type type, boolean addWildcards) { if (type instanceof ParameterizedType){ ParameterizedType parameterizedType = (ParameterizedType) type; StringBuffer sb = new StringBuffer(); sb.append(parameterizedType.getRawType().getFullyQualifiedName()); - sb.append("<"); + sb.append(addWildcards ? " attrs, String packageName) { fields = Lists.newArrayList(); methods = Lists.newArrayList(); + // FIXME conflict if "dependencyResolver" field from yang + Field depRes = new Field(DependencyResolver.class.getName(), dependencyResolverVarName); + fields.add(depRes); + methods.add(new MethodDefinition("void", dependencyResolverInjectMethodName, Lists.newArrayList(depRes), + "this." + dependencyResolverVarName + " = " + dependencyResolverVarName + ";")); + for (Entry attrEntry : attrs.entrySet()) { String innerName = attrEntry.getKey(); String varName = BindingGeneratorUtil @@ -436,15 +457,23 @@ public class TemplateFactory { String fullyQualifiedName, nullableDefault = null; if (attrEntry.getValue() instanceof TypedAttribute) { Type type = ((TypedAttribute) attrEntry.getValue()).getType(); - fullyQualifiedName = serializeType(type); if(attrEntry.getValue() instanceof JavaAttribute) { nullableDefault = ((JavaAttribute)attrEntry.getValue()).getNullableDefaultWrappedForCode(); + if(((JavaAttribute)attrEntry.getValue()).isIdentityRef()) { + + String fieldType = serializeType(type, true); + String innerType = getInnerTypeFromIdentity(type); + methods.add(new MethodDefinition(fieldType, "resolve" + attrEntry.getKey(), Collections.emptyList(), + "return " + varName + ".resolveIdentity(" + dependencyResolverVarName + "," + innerType + ".class);")); + type = identityRefType; + } } + fullyQualifiedName = serializeType(type); } else { fullyQualifiedName = FullyQualifiedNameHelper .getFullyQualifiedName(packageName, attrEntry.getValue().getUpperCaseCammelCase()); } - fields.add(new Field(fullyQualifiedName, varName, nullableDefault)); + fields.add(new Field(fullyQualifiedName, varName, nullableDefault, needsDepResolver(attrEntry.getValue()))); String getterName = "get" + innerName; MethodDefinition getter = new MethodDefinition( @@ -481,6 +510,7 @@ public class TemplateFactory { } } + private static class MXBeanInterfaceAttributesProcessor { private final List methods = Lists.newArrayList(); @@ -489,9 +519,15 @@ public class TemplateFactory { String returnType; AttributeIfc attributeIfc = attrEntry.getValue(); + boolean isIdentityRef = false; if (attributeIfc instanceof TypedAttribute) { TypedAttribute typedAttribute = (TypedAttribute) attributeIfc; returnType = serializeType(typedAttribute.getType()); + + if (attributeIfc instanceof JavaAttribute && ((JavaAttribute)attrEntry.getValue()).isIdentityRef()) { + returnType = serializeType(identityRefType); + } + } else { throw new UnsupportedOperationException( "Attribute not supported: " @@ -510,6 +546,7 @@ public class TemplateFactory { MethodDeclaration setter = new MethodDeclaration("void", setterName, Lists.newArrayList(new Field(returnType, varName))); + methods.add(getter); methods.add(setter); @@ -525,10 +562,28 @@ public class TemplateFactory { } } + private static final Type identityRefType = new Type() { + public final Class IDENTITY_ATTRIBUTE_REF_CLASS = IdentityAttributeRef.class; + + @Override + public String getPackageName() { + return IDENTITY_ATTRIBUTE_REF_CLASS.getPackage().getName(); + } + + @Override + public String getName() { + return IDENTITY_ATTRIBUTE_REF_CLASS.getSimpleName(); + } + + @Override + public String getFullyQualifiedName() { + return IDENTITY_ATTRIBUTE_REF_CLASS.getName(); + } + }; + private static class AbstractFactoryAttributesProcessor { private final List fields = Lists.newArrayList(); - private static final String STRING_FULLY_QUALIFIED_NAME = "java.util.List"; void processAttributes(Map attributes, String packageName) { @@ -540,27 +595,6 @@ public class TemplateFactory { if (attributeIfc instanceof TypedAttribute) { TypedAttribute typedAttribute = (TypedAttribute) attributeIfc; type = serializeType(typedAttribute.getType()); - } else if (attributeIfc instanceof TOAttribute) { - String fullyQualifiedName = FullyQualifiedNameHelper - .getFullyQualifiedName(packageName, attributeIfc.getUpperCaseCammelCase()); - - type = fullyQualifiedName; - } else if (attributeIfc instanceof ListAttribute) { //FIXME: listAttribute might extend TypedAttribute - String fullyQualifiedName = null; - AttributeIfc innerAttr = ((ListAttribute) attributeIfc) - .getInnerAttribute(); - if (innerAttr instanceof JavaAttribute) { - fullyQualifiedName = ((JavaAttribute) innerAttr) - .getType().getFullyQualifiedName(); - nullableDefaultWrapped = ((JavaAttribute) innerAttr).getNullableDefaultWrappedForCode(); - } else if (innerAttr instanceof TOAttribute) { - fullyQualifiedName = FullyQualifiedNameHelper - .getFullyQualifiedName(packageName, innerAttr.getUpperCaseCammelCase()); - } - - type = STRING_FULLY_QUALIFIED_NAME.concat("<") - .concat(fullyQualifiedName).concat(">"); - } else { throw new UnsupportedOperationException( "Attribute not supported: " @@ -579,8 +613,6 @@ public class TemplateFactory { private static class AbstractModuleAttributesProcessor { - private static final String STRING_FULLY_QUALIFIED_NAME = "java.util.List"; - private final List moduleFields = Lists.newArrayList(); private final List methods = Lists.newArrayList(); @@ -589,34 +621,19 @@ public class TemplateFactory { for (Entry attrEntry : attributes.entrySet()) { String type, nullableDefaultWrapped = null; AttributeIfc attributeIfc = attrEntry.getValue(); + boolean isIdentity = false; + boolean needsDepResolver = needsDepResolver(attrEntry.getValue()); if (attributeIfc instanceof TypedAttribute) { TypedAttribute typedAttribute = (TypedAttribute) attributeIfc; type = serializeType(typedAttribute.getType()); if (attributeIfc instanceof JavaAttribute) { nullableDefaultWrapped = ((JavaAttribute) attributeIfc).getNullableDefaultWrappedForCode(); + if(((JavaAttribute)attrEntry.getValue()).isIdentityRef()) { + isIdentity = true; + type = serializeType(typedAttribute.getType(), true); + } } - - } else if (attributeIfc instanceof TOAttribute) { - String fullyQualifiedName = FullyQualifiedNameHelper - .getFullyQualifiedName(packageName, attributeIfc.getUpperCaseCammelCase()); - - type = fullyQualifiedName; - } else if (attributeIfc instanceof ListAttribute) { - String fullyQualifiedName = null; - AttributeIfc innerAttr = ((ListAttribute) attributeIfc) - .getInnerAttribute(); - if (innerAttr instanceof JavaAttribute) { - fullyQualifiedName = ((JavaAttribute) innerAttr) - .getType().getFullyQualifiedName(); - nullableDefaultWrapped = ((JavaAttribute) innerAttr).getNullableDefaultWrappedForCode(); - } else if (innerAttr instanceof TOAttribute) { - fullyQualifiedName = FullyQualifiedNameHelper - .getFullyQualifiedName(packageName, innerAttr.getUpperCaseCammelCase()); - } - - type = STRING_FULLY_QUALIFIED_NAME.concat("<") - .concat(fullyQualifiedName).concat(">"); } else { throw new UnsupportedOperationException( "Attribute not supported: " @@ -644,15 +661,49 @@ public class TemplateFactory { String varName = BindingGeneratorUtil .parseToValidParamName(attrEntry.getKey()); - moduleFields.add(new ModuleField(type, varName, attributeIfc - .getUpperCaseCammelCase(), nullableDefaultWrapped, isDependency, dependency, isListOfDependencies)); + + ModuleField field; + + if (isIdentity) { + String identityBaseClass = getInnerTypeFromIdentity(((TypedAttribute) attributeIfc).getType()); + IdentityRefModuleField identityField = new IdentityRefModuleField(type, varName, + attributeIfc.getUpperCaseCammelCase(), identityBaseClass); + + String getterName = "get" + + attributeIfc.getUpperCaseCammelCase() + "Identity"; + MethodDefinition additionalGetter = new MethodDefinition(type, getterName, Collections. emptyList(), + Collections. emptyList(), "return " + identityField.getIdentityClassName() + + ";"); + methods.add(additionalGetter); + + String setterName = "set" + + attributeIfc.getUpperCaseCammelCase(); + + String setterBody = "this." + identityField.getIdentityClassName() + " = " + identityField.getIdentityClassName() + ";"; + MethodDefinition additionalSetter = new MethodDefinition("void", + setterName, + Lists.newArrayList(new Field(type, identityField.getIdentityClassName())), + Collections. emptyList(), setterBody); + additionalSetter.setJavadoc(attributeIfc.getNullableDescription()); + + methods.add(additionalSetter); + + type = serializeType(identityRefType); + field = identityField; + } else { + field = new ModuleField(type, varName, attributeIfc.getUpperCaseCammelCase(), + nullableDefaultWrapped, isDependency, dependency, isListOfDependencies, needsDepResolver); + } + moduleFields.add(field); String getterName = "get" + attributeIfc.getUpperCaseCammelCase(); MethodDefinition getter = new MethodDefinition(type, getterName, Collections. emptyList(), Lists.newArrayList(overrideAnnotation), "return " - + varName + ";"); + + varName + ";"); + + methods.add(getter); String setterName = "set" + attributeIfc.getUpperCaseCammelCase(); @@ -674,7 +725,6 @@ public class TemplateFactory { annotations, setterBody); setter.setJavadoc(attributeIfc.getNullableDescription()); - methods.add(getter); methods.add(setter); } } @@ -689,4 +739,22 @@ public class TemplateFactory { } + + private static boolean needsDepResolver(AttributeIfc value) { + if(value instanceof TOAttribute) + return true; + if(value instanceof ListAttribute) { + AttributeIfc innerAttribute = ((ListAttribute) value).getInnerAttribute(); + return needsDepResolver(innerAttribute); + } + + return false; + } + + private static String getInnerTypeFromIdentity(Type type) { + Preconditions.checkArgument(type instanceof ParameterizedType); + Type[] args = ((ParameterizedType) type).getActualTypeArguments(); + Preconditions.checkArgument(args.length ==1); + return serializeType(args[0]); + } } diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/Field.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/Field.java index 0857ec6f8d..ad5cbb287c 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/Field.java +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/Field.java @@ -16,25 +16,40 @@ public class Field { private final String name; private final String definition; private final List modifiers; + private final boolean needsDepResolver; public Field(String type, String name) { - this(Lists. newArrayList(), type, name, null); + this(Lists. newArrayList(), type, name, null, false); } public Field(String type, String name, String definition) { - this(Lists. newArrayList(), type, name, definition); + this(Lists. newArrayList(), type, name, definition, false); } public Field(List modifiers, String type, String name) { - this(modifiers, type, name, null); + this(modifiers, type, name, null, false); } public Field(List modifiers, String type, String name, String definition) { + this(modifiers, type, name, definition, false); + } + + public Field(List modifiers, String type, String name, + String definition, boolean needsDepResolver) { this.modifiers = modifiers; this.type = type; this.name = name; this.definition = definition; + this.needsDepResolver = needsDepResolver; + } + + public Field(String type, String name, String definition, boolean needsDepResolver) { + this(Lists. newArrayList(), type, name, definition, needsDepResolver); + } + + public boolean isNeedsDepResolver() { + return needsDepResolver; } public String getType() { diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/IdentityRefModuleField.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/IdentityRefModuleField.java new file mode 100644 index 0000000000..f50bdb98cf --- /dev/null +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/IdentityRefModuleField.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model; + +import org.opendaylight.controller.config.api.IdentityAttributeRef; + +public class IdentityRefModuleField extends ModuleField { + + public static final String IDENTITY_CLASS_FIELD_SUFFIX = "IdentityClass"; + private final String identityBaseClass; + + public IdentityRefModuleField(String type, String name, String attributeName, String identityBaseClass) { + super(type, name, attributeName, null, false, null, false, false); + this.identityBaseClass = identityBaseClass; + } + + public String getIdentityBaseClass() { + return identityBaseClass; + } + + @Override + public boolean isIdentityRef() { + return true; + } + + public String getType() { + return IdentityAttributeRef.class.getName(); + } + + public String getIdentityClassType() { + return super.getType(); + } + + public String getIdentityClassName() { + return addIdentityClassFieldSuffix(getName()); + } + + public static String addIdentityClassFieldSuffix(String prefix) { + return prefix + IDENTITY_CLASS_FIELD_SUFFIX; + } +} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/ModuleField.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/ModuleField.java index aff7af2811..74e5bb0490 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/ModuleField.java +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/ModuleField.java @@ -20,10 +20,9 @@ public class ModuleField extends Field { private final boolean dependent, isListOfDependencies; private final Dependency dependency; - private ModuleField(List modifiers, String type, String name, - String attributeName, String nullableDefault, boolean isDependency, - Dependency dependency, boolean isListOfDependencies) { - super(modifiers, type, name); + private ModuleField(List modifiers, String type, String name, String attributeName, String nullableDefault, + boolean isDependency, Dependency dependency, boolean isListOfDependencies, boolean needsDepResolver) { + super(modifiers, type, name, null, needsDepResolver); this.dependent = isDependency; this.dependency = dependency; this.attributeName = attributeName; @@ -35,10 +34,14 @@ public class ModuleField extends Field { this.isListOfDependencies = isListOfDependencies; } - public ModuleField(String type, String name, String attributeName, - String nullableDefault, boolean isDependency, Dependency dependency, boolean isListOfDependencies) { - this(Collections. emptyList(), type, name, attributeName, - nullableDefault, isDependency, dependency, isListOfDependencies); + public ModuleField(String type, String name, String attributeName, String nullableDefault, boolean isDependency, + Dependency dependency, boolean isListOfDependencies, boolean needsDepResolve) { + this(Collections. emptyList(), type, name, attributeName, nullableDefault, isDependency, dependency, + isListOfDependencies, needsDepResolve); + } + + public boolean isIdentityRef() { + return false; } public Dependency getDependency() { diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/resources/freeMarker/module_abs_template_new.ftl b/opendaylight/config/yang-jmx-generator-plugin/src/main/resources/freeMarker/module_abs_template_new.ftl index 7192ac661f..848fcfe5fc 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/resources/freeMarker/module_abs_template_new.ftl +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/resources/freeMarker/module_abs_template_new.ftl @@ -85,6 +85,12 @@ package ${packageName}; + // caches of resolved IdentityRefs + <#list moduleFields as field> + <#if field.identityRef==true> + private ${field.identityClassType} ${field.identityClassName}; + + @Override public final ${instanceType} getInstance(){ @@ -109,6 +115,24 @@ package ${packageName}; } + + <#if field.needsDepResolver==true> + if(${field.name} != null) { + <#if field.type?starts_with("java.util.List")> + for(${field.type?substring(field.type?index_of("<") + 1, field.type?index_of(">"))} candidate : ${field.name}) { + candidate.injectDependencyResolver(dependencyResolver); + } + <#else> + ${field.name}.injectDependencyResolver(dependencyResolver); + + } + + + <#if field.identityRef==true> + if(${field.name} != null) { + set${field.attributeName}(${field.name}.resolveIdentity(dependencyResolver, ${field.identityBaseClass}.class)); + } + if(oldInstance!=null && canReuseInstance(oldModule)) { diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ModuleMXBeanEntryPluginTest.java b/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ModuleMXBeanEntryPluginTest.java index b457216480..473b245f25 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ModuleMXBeanEntryPluginTest.java +++ b/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ModuleMXBeanEntryPluginTest.java @@ -130,7 +130,7 @@ public class ModuleMXBeanEntryPluginTest extends ModuleMXBeanEntryTest { is(true)); assertThat(peerTO.getFullyQualifiedName(), is(PACKAGE_NAME + ".Peer")); - assertThat(peerTO.getMethods().size(), is(4)); + assertThat(peerTO.getMethods().size(), is(5)); Method getPort = findFirstMethodByName(peerTO.getMethods(), "getPort"); assertNotNull(getPort); diff --git a/opendaylight/config/yang-jmx-generator/pom.xml b/opendaylight/config/yang-jmx-generator/pom.xml index b5069a1661..9993c2f259 100644 --- a/opendaylight/config/yang-jmx-generator/pom.xml +++ b/opendaylight/config/yang-jmx-generator/pom.xml @@ -44,7 +44,6 @@ ${project.groupId} config-api - test org.opendaylight.yangtools diff --git a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/JavaAttribute.java b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/JavaAttribute.java index e01063ef92..5b0196cdda 100644 --- a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/JavaAttribute.java +++ b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/JavaAttribute.java @@ -8,11 +8,13 @@ package org.opendaylight.controller.config.yangjmxgenerator.attribute; import com.google.common.base.Preconditions; +import org.opendaylight.controller.config.api.IdentityAttributeRef; import org.opendaylight.controller.config.yangjmxgenerator.TypeProviderWrapper; import org.opendaylight.yangtools.sal.binding.model.api.Type; import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition; import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition; import javax.management.openmbean.ArrayType; @@ -36,6 +38,7 @@ public class JavaAttribute extends AbstractAttribute implements TypedAttribute { TypeProviderWrapper typeProviderWrapper) { super(leaf); this.type = typeProviderWrapper.getType(leaf); + this.typeDefinition = leaf.getType(); this.typeProviderWrapper = typeProviderWrapper; this.nullableDefault = leaf.getDefault(); @@ -147,11 +150,17 @@ public class JavaAttribute extends AbstractAttribute implements TypedAttribute { return getCompositeTypeForUnion(baseTypeDefinition); } else if (isDerivedType(baseType, getType())) { return getCompositeType(baseType, baseTypeDefinition); + } else if (isIdentityRef()) { + return getCompositeTypeForIdentity(); } return getSimpleType(getType()); } + public boolean isIdentityRef() { + return typeDefinition instanceof IdentityrefTypeDefinition; + } + private OpenType getCompositeTypeForUnion(TypeDefinition baseTypeDefinition) { Preconditions.checkArgument(baseTypeDefinition instanceof UnionTypeDefinition, "Expected %s instance but was %s", UnionTypeDefinition.class, baseTypeDefinition); @@ -233,6 +242,19 @@ public class JavaAttribute extends AbstractAttribute implements TypedAttribute { } } + public OpenType getCompositeTypeForIdentity() { + String[] itemNames = new String[]{IdentityAttributeRef.QNAME_ATTR_NAME}; + String description = getNullableDescription() == null ? getAttributeYangName() : getNullableDescription(); + OpenType[] itemTypes = new OpenType[]{SimpleType.STRING}; + + try { + return new CompositeType(getUpperCaseCammelCase(), description, itemNames, itemNames, itemTypes); + } catch (OpenDataException e) { + throw new RuntimeException("Unable to create " + CompositeType.class + " with inner element of type " + + itemTypes, e); + } + } + private OpenType getArrayType() { String innerTypeFullyQName = getInnerType(getType()); SimpleType innerSimpleType = SimpleTypeResolver.getSimpleType(innerTypeFullyQName); @@ -263,7 +285,7 @@ public class JavaAttribute extends AbstractAttribute implements TypedAttribute { } private boolean isDerivedType(Type baseType, Type currentType) { - return baseType.equals(currentType) == false; + return baseType.equals(currentType) == false; } private static String getInnerType(Type type) { diff --git a/opendaylight/config/yang-test/pom.xml b/opendaylight/config/yang-test/pom.xml index b9f9235269..10d62edfc1 100644 --- a/opendaylight/config/yang-test/pom.xml +++ b/opendaylight/config/yang-test/pom.xml @@ -12,6 +12,7 @@ yang-test + bundle Artifact that contains only generated code from yang files. Suitable for testing. @@ -139,6 +140,15 @@ + + + org.apache.felix + maven-bundle-plugin + + + + + diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModule.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModule.java new file mode 100644 index 0000000000..b000f11e4e --- /dev/null +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModule.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.controller.config.yang.test.impl; + +/** +* +*/ +public final class IdentityTestModule extends org.opendaylight.controller.config.yang.test.impl.AbstractIdentityTestModule + { + + public IdentityTestModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { + super(identifier, dependencyResolver); + } + + public IdentityTestModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, + IdentityTestModule oldModule, java.lang.AutoCloseable oldInstance) { + + super(identifier, dependencyResolver, oldModule, oldInstance); + } + + @Override + protected void customValidation(){ + // Add custom validation for module attributes here. + } + + @Override + public java.lang.AutoCloseable createInstance() { + System.err.println(getAfi()); + System.err.println(getAfiIdentity()); + + getAfiIdentity(); + for (Identities identities : getIdentities()) { + identities.resolveAfi(); + identities.resolveSafi(); + } + getIdentitiesContainer().resolveAfi(); + + return new AutoCloseable() { + @Override + public void close() throws Exception { + } + }; + + } +} diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModuleFactory.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModuleFactory.java new file mode 100644 index 0000000000..9de3e0bb74 --- /dev/null +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModuleFactory.java @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.controller.config.yang.test.impl; + +/** +* +*/ +public class IdentityTestModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractIdentityTestModuleFactory +{ + + +} diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModuleStub.txt b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModuleStub.txt new file mode 100644 index 0000000000..a81159ea24 --- /dev/null +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModuleStub.txt @@ -0,0 +1,15 @@ + System.err.println(getAfi()); + System.err.println(getAfiIdentity()); + + getAfiIdentity(); + for (Identities identities : getIdentities()) { + identities.resolveAfi(); + identities.resolveSafi(); + } + getIdentitiesContainer().resolveAfi(); + + return new AutoCloseable() { + @Override + public void close() throws Exception { + } + }; diff --git a/opendaylight/config/yang-test/src/main/yang/config-test-impl.yang b/opendaylight/config/yang-test/src/main/yang/config-test-impl.yang index f7cea0a52a..6ee379623b 100644 --- a/opendaylight/config/yang-test/src/main/yang/config-test-impl.yang +++ b/opendaylight/config/yang-test/src/main/yang/config-test-impl.yang @@ -35,6 +35,69 @@ module config-test-impl { config:java-name-prefix NetconfTestImpl; } + identity impl-identity-test { + base config:module-type; + config:provided-service test:testing; + config:java-name-prefix IdentityTest; + } + + identity test-identity1 { + + } + + identity test-identity2 { + base test-identity1; + } + + augment "/config:modules/config:module/config:configuration" { + case impl-identity-test { + when "/config:modules/config:module/config:type = 'impl-identity-test'"; + + leaf afi { + type identityref { + base test-identity1; + } + } + + container identities-container { + leaf afi { + type identityref { + base test-identity1; + } + } + } + + list identities { + leaf afi { + type identityref { + base test-identity1; + } + } + leaf safi { + type identityref { + base test-identity1; + } + } + + container identities-inner { + leaf afi { + type identityref { + base test-identity1; + } + } + } + } + + } + } + + augment "/config:modules/config:module/config:state" { + case impl-identity-test { + when "/config:modules/config:module/config:type = 'impl-identity-test'"; + + } + } + augment "/config:modules/config:module/config:configuration" { case impl { diff --git a/opendaylight/config/yang-test/src/test/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleTest.java b/opendaylight/config/yang-test/src/test/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleTest.java index 41ceab0e55..5a4cfc1248 100644 --- a/opendaylight/config/yang-test/src/test/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleTest.java +++ b/opendaylight/config/yang-test/src/test/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleTest.java @@ -1,17 +1,25 @@ package org.opendaylight.controller.config.yang.test.impl; import com.google.common.collect.Lists; + import junit.framework.Assert; + import org.junit.Before; import org.junit.Test; +import org.opendaylight.controller.config.api.IdentityAttributeRef; import org.opendaylight.controller.config.api.jmx.CommitStatus; import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; import org.opendaylight.controller.config.manager.impl.AbstractConfigTest; import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver; import org.opendaylight.controller.config.util.ConfigTransactionJMXClient; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.test.impl.rev130403.TestIdentity1; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.test.impl.rev130403.TestIdentity2; +import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry; +import org.opendaylight.yangtools.yang.data.impl.codec.IdentityCodec; import javax.management.InstanceAlreadyExistsException; import javax.management.ObjectName; + import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -20,6 +28,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; public class NetconfTestImplModuleTest extends AbstractConfigTest { @@ -32,7 +42,31 @@ public class NetconfTestImplModuleTest extends AbstractConfigTest { factory = new NetconfTestImplModuleFactory(); super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory, - new DepTestImplModuleFactory())); + new DepTestImplModuleFactory(), new IdentityTestModuleFactory())); + } + + @Override + protected CodecRegistry getCodecRegistry() { + final IdentityCodec codec = mock(IdentityCodec.class); + doReturn(TestIdentity1.class).when(codec).deserialize(TestIdentity1.QNAME); + doReturn(TestIdentity2.class).when(codec).deserialize(TestIdentity2.QNAME); + + final CodecRegistry ret = super.getCodecRegistry(); + doReturn(codec).when(ret).getIdentityCodec(); + return ret; + } + + @Test + public void testIdentities() throws Exception { + ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction(); + + ObjectName nameCreated = transaction.createModule(IdentityTestModuleFactory.NAME, instanceName); + IdentityTestModuleMXBean mxBean = transaction.newMXBeanProxy(nameCreated, IdentityTestModuleMXBean.class); + + final IdentitiesContainer c = new IdentitiesContainer(); + c.setAfi(new IdentityAttributeRef(TestIdentity2.QNAME.toString())); + mxBean.setIdentitiesContainer(c); + transaction.commit(); } @Test diff --git a/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowConfigMapping.xtend b/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowConfigMapping.xtend index ef806f33ef..bafdf88553 100644 --- a/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowConfigMapping.xtend +++ b/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowConfigMapping.xtend @@ -29,7 +29,6 @@ class FlowConfigMapping { } static def toFlowConfig(Flow sourceCfg) { - val flow = toFlow(sourceCfg); val it = new FlowConfig; name = String.valueOf(sourceCfg.id); node = sourceCfg.node.toADNode(); diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FlowProgrammerAdapter.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FlowProgrammerAdapter.xtend index 35c641c45a..8039156425 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FlowProgrammerAdapter.xtend +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FlowProgrammerAdapter.xtend @@ -141,7 +141,7 @@ class FlowProgrammerAdapter implements IPluginInFlowProgrammerService, SalFlowLi } override onFlowRemoved(FlowRemoved notification) { - flowProgrammerPublisher.flowRemoved(notification.node.toADNode,notification.toFlow()); + flowProgrammerPublisher.flowRemoved(notification.node.toADNode,notification.toFlow(notification.node.toADNode)); } override onFlowUpdated(FlowUpdated notification) { diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/InventoryAndReadAdapter.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/InventoryAndReadAdapter.xtend index 39d224ba16..6d209f3b17 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/InventoryAndReadAdapter.xtend +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/InventoryAndReadAdapter.xtend @@ -146,7 +146,7 @@ class InventoryAndReadAdapter implements IPluginInReadService, for(flow : table.flow){ - val adsalFlow = ToSalConversionsUtils.toFlow(flow); + val adsalFlow = ToSalConversionsUtils.toFlow(flow,node); val statsFromDataStore = flow.getAugmentation(FlowStatisticsData); if(statsFromDataStore != null){ @@ -517,14 +517,14 @@ class InventoryAndReadAdapter implements IPluginInReadService, override onFlowsStatisticsUpdate(FlowsStatisticsUpdate notification) { val adsalFlowsStatistics = new ArrayList(); + val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance; for(flowStats : notification.flowAndStatisticsMapList){ if(flowStats.tableId == 0) - adsalFlowsStatistics.add(toFlowOnNode(flowStats)); + adsalFlowsStatistics.add(toFlowOnNode(flowStats,nodeRef.toADNode)); } for (statsPublisher : statisticsPublisher){ - val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance; statsPublisher.nodeFlowStatisticsUpdated(nodeRef.toADNode,adsalFlowsStatistics); } @@ -569,9 +569,9 @@ class InventoryAndReadAdapter implements IPluginInReadService, } - private static def toFlowOnNode (FlowAndStatisticsMapList flowAndStatsMap){ + private static def toFlowOnNode (FlowAndStatisticsMapList flowAndStatsMap,Node node){ - val it = new FlowOnNode(ToSalConversionsUtils.toFlow(flowAndStatsMap)); + val it = new FlowOnNode(ToSalConversionsUtils.toFlow(flowAndStatsMap,node)); byteCount = flowAndStatsMap.byteCount.value.longValue; packetCount = flowAndStatsMap.packetCount.value.longValue; diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ToSalConversionsUtils.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ToSalConversionsUtils.java index 46fd62f3f2..baf10efc67 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ToSalConversionsUtils.java +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ToSalConversionsUtils.java @@ -43,7 +43,8 @@ import org.opendaylight.controller.sal.action.SetVlanCfi; import org.opendaylight.controller.sal.action.SetVlanId; import org.opendaylight.controller.sal.action.SetVlanPcp; import org.opendaylight.controller.sal.action.SwPath; -import org.opendaylight.controller.sal.core.Capabilities; +import org.opendaylight.controller.sal.core.ConstructionException; +import org.opendaylight.controller.sal.core.Node; import org.opendaylight.controller.sal.core.NodeConnector; import org.opendaylight.controller.sal.flowprogrammer.Flow; import org.opendaylight.controller.sal.match.Match; @@ -86,7 +87,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.acti import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.Address; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv6; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FeatureCapability; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction; import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType; @@ -116,7 +116,7 @@ public class ToSalConversionsUtils { } - public static Flow toFlow(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow source) { + public static Flow toFlow(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow source, Node node) { final Flow target = new Flow(); Integer hardTimeout = source.getHardTimeout(); @@ -138,7 +138,7 @@ public class ToSalConversionsUtils { List actions = getAction(source); if (actions != null) { - target.setActions(actionFrom(actions)); + target.setActions(actionFrom(actions, node)); } target.setId(source.getCookie().longValue()); @@ -158,7 +158,7 @@ public class ToSalConversionsUtils { return Collections.emptyList(); } - public static List actionFrom(List actions) { + public static List actionFrom(List actions, Node node) { List targetAction = new ArrayList<>(); for (Action action : actions) { org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action sourceAction = action @@ -171,7 +171,7 @@ public class ToSalConversionsUtils { Uri nodeConnector = ((OutputActionCase) sourceAction).getOutputAction().getOutputNodeConnector(); if (nodeConnector != null) { //for (Uri uri : nodeConnectors) { - targetAction.add(new Output(fromNodeConnectorRef(nodeConnector))); + targetAction.add(new Output(fromNodeConnectorRef(nodeConnector, node))); //} } } else if (sourceAction instanceof PopMplsActionCase) { @@ -339,9 +339,14 @@ public class ToSalConversionsUtils { return null; } - private static NodeConnector fromNodeConnectorRef(Uri uri) { - // TODO: Define mapping - return null; + private static NodeConnector fromNodeConnectorRef(Uri uri, Node node) { + NodeConnector nodeConnector = null; + try { + nodeConnector = new NodeConnector(NodeMapping.MD_SAL_TYPE,node.getNodeIDString()+":"+uri.getValue(),node); + } catch (ConstructionException e) { + e.printStackTrace(); + } + return nodeConnector; } public static Match toMatch(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match source) { diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/adsal/FlowServiceAdapter.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/adsal/FlowServiceAdapter.java index fd03ea4ca5..c5ea267a01 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/adsal/FlowServiceAdapter.java +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/adsal/FlowServiceAdapter.java @@ -56,7 +56,7 @@ public class FlowServiceAdapter implements SalFlowService, IFlowProgrammerListen @Override public Future> addFlow(AddFlowInput input) { - Flow flow = ToSalConversionsUtils.toFlow(input); + Flow flow = ToSalConversionsUtils.toFlow(input, null); @SuppressWarnings("unchecked") org.opendaylight.controller.sal.core.Node node = InventoryMapping.toAdNode((InstanceIdentifier) input .getNode().getValue()); @@ -70,7 +70,7 @@ public class FlowServiceAdapter implements SalFlowService, IFlowProgrammerListen @Override public Future> removeFlow(RemoveFlowInput input) { - Flow flow = ToSalConversionsUtils.toFlow(input); + Flow flow = ToSalConversionsUtils.toFlow(input, null); @SuppressWarnings("unchecked") org.opendaylight.controller.sal.core.Node node = InventoryMapping.toAdNode((InstanceIdentifier) input .getNode().getValue()); @@ -87,8 +87,8 @@ public class FlowServiceAdapter implements SalFlowService, IFlowProgrammerListen @SuppressWarnings("unchecked") org.opendaylight.controller.sal.core.Node node = InventoryMapping.toAdNode((InstanceIdentifier) input .getNode().getValue()); - Flow originalFlow = ToSalConversionsUtils.toFlow(input.getOriginalFlow()); - Flow updatedFlow = ToSalConversionsUtils.toFlow(input.getUpdatedFlow()); + Flow originalFlow = ToSalConversionsUtils.toFlow(input.getOriginalFlow(), null); + Flow updatedFlow = ToSalConversionsUtils.toFlow(input.getUpdatedFlow(), null); Status status = delegate.modifyFlowAsync(node, originalFlow, updatedFlow); UpdateFlowOutputBuilder builder = new UpdateFlowOutputBuilder(); builder.setTransactionId(new TransactionId(BigInteger.valueOf(status.getRequestId()))); diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/adsal/FlowStatisticsAdapter.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/adsal/FlowStatisticsAdapter.java index 149544b6c4..c7af60285a 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/adsal/FlowStatisticsAdapter.java +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/adsal/FlowStatisticsAdapter.java @@ -135,7 +135,7 @@ public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService, try { Node node = NodeMapping.toADNode(input.getNode()); - Flow flow = ToSalConversionsUtils.toFlow(input); + Flow flow = ToSalConversionsUtils.toFlow(input, null); FlowOnNode readFlow = readDelegate.readFlow(node, flow); List flowOnNodeToFlowStatistics = new ArrayList(); flowOnNodeToFlowStatistics.add(toOdFlowStatistics(readFlow)); diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/test/java/org/opendaylight/controller/sal/compatibility/test/TestToSalConversionsUtils.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/test/java/org/opendaylight/controller/sal/compatibility/test/TestToSalConversionsUtils.java index 793f3cc395..ca16c65f56 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/test/java/org/opendaylight/controller/sal/compatibility/test/TestToSalConversionsUtils.java +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/test/java/org/opendaylight/controller/sal/compatibility/test/TestToSalConversionsUtils.java @@ -9,6 +9,10 @@ package org.opendaylight.controller.sal.compatibility.test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.CRUDP; +import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.ETHERNET_ARP; +import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.TCP; +import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.UDP; import java.math.BigInteger; import java.net.Inet4Address; @@ -19,53 +23,95 @@ import java.util.Collections; import java.util.List; import org.junit.Test; -import org.opendaylight.controller.sal.action.*; +import org.opendaylight.controller.sal.action.Flood; +import org.opendaylight.controller.sal.action.FloodAll; +import org.opendaylight.controller.sal.action.HwPath; +import org.opendaylight.controller.sal.action.Loopback; +import org.opendaylight.controller.sal.action.Output; +import org.opendaylight.controller.sal.action.PopVlan; +import org.opendaylight.controller.sal.action.PushVlan; +import org.opendaylight.controller.sal.action.SetDlDst; +import org.opendaylight.controller.sal.action.SetDlSrc; +import org.opendaylight.controller.sal.action.SetDlType; +import org.opendaylight.controller.sal.action.SetNextHop; +import org.opendaylight.controller.sal.action.SetNwDst; +import org.opendaylight.controller.sal.action.SetNwSrc; +import org.opendaylight.controller.sal.action.SetNwTos; +import org.opendaylight.controller.sal.action.SetTpDst; +import org.opendaylight.controller.sal.action.SetTpSrc; +import org.opendaylight.controller.sal.action.SetVlanCfi; +import org.opendaylight.controller.sal.action.SetVlanId; +import org.opendaylight.controller.sal.action.SetVlanPcp; +import org.opendaylight.controller.sal.action.SwPath; import org.opendaylight.controller.sal.compatibility.ToSalConversionsUtils; +import org.opendaylight.controller.sal.core.ConstructionException; +import org.opendaylight.controller.sal.core.Node; +import org.opendaylight.controller.sal.core.Node.NodeIDType; import org.opendaylight.controller.sal.flowprogrammer.Flow; import org.opendaylight.controller.sal.match.MatchType; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.*; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Dscp; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAddedBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeFlow; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.VlanCfi; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.*; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.controller.action._case.ControllerActionBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropActionBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.flood.action._case.FloodActionBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.flood.all.action._case.FloodAllActionBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.hw.path.action._case.HwPathActionBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.loopback.action._case.LoopbackActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.ControllerActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.FloodActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.FloodAllActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.HwPathActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.LoopbackActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopMplsActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushMplsActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushPbbActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlDstActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlSrcActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlTypeActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetMplsTtlActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNextHopActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwDstActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwSrcActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwTosActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwTtlActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetQueueActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetTpDstActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetTpSrcActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanCfiActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanIdActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanPcpActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SwPathActionCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.output.action._case.OutputActionBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.mpls.action._case.PopMplsActionBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.vlan.action._case.PopVlanActionBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.mpls.action._case.PushMplsActionBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.pbb.action._case.PushPbbActionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.vlan.action._case.PushVlanActionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.dl.dst.action._case.SetDlDstActionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.dl.src.action._case.SetDlSrcActionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.dl.type.action._case.SetDlTypeActionBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.mpls.ttl.action._case.SetMplsTtlActionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.next.hop.action._case.SetNextHopActionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.dst.action._case.SetNwDstActionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.src.action._case.SetNwSrcActionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.tos.action._case.SetNwTosActionBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.ttl.action._case.SetNwTtlActionBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.queue.action._case.SetQueueActionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.tp.dst.action._case.SetTpDstActionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.tp.src.action._case.SetTpSrcActionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.vlan.cfi.action._case.SetVlanCfiActionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.vlan.id.action._case.SetVlanIdActionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.vlan.pcp.action._case.SetVlanPcpActionBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.sw.path.action._case.SwPathActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.Address; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4Builder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv6Builder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAddedBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeFlow; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType; @@ -73,8 +119,20 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId; import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanPcp; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpSourceHardwareAddressBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpTargetHardwareAddressBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.*; -import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.*; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestination; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestinationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetSource; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetSourceBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetTypeBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatch; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatch; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer3Match; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer4Match; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatch; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6MatchBuilder; @@ -82,17 +140,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder; import com.google.common.net.InetAddresses; -import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.ETHERNET_ARP; -import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.CRUDP; -import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.TCP; -import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.UDP; - public class TestToSalConversionsUtils { // prefix: // od|Od = Open Daylight @@ -101,29 +151,31 @@ public class TestToSalConversionsUtils { } @Test - public void testToSalConversion() { + public void testToSalConversion() throws ConstructionException { FlowAddedBuilder odNodeFlowBuilder = new FlowAddedBuilder(); odNodeFlowBuilder = prepareOdFlowCommon(); - - Flow salFlow = ToSalConversionsUtils.toFlow(prepareOdFlow(odNodeFlowBuilder, MtchType.other)); + + Node node = new Node(NodeIDType.OPENFLOW,(long)1); + + Flow salFlow = ToSalConversionsUtils.toFlow(prepareOdFlow(odNodeFlowBuilder, MtchType.other), node); checkSalMatch(salFlow.getMatch(), MtchType.other); - salFlow = ToSalConversionsUtils.toFlow(prepareOdFlow(odNodeFlowBuilder, MtchType.ipv4)); + salFlow = ToSalConversionsUtils.toFlow(prepareOdFlow(odNodeFlowBuilder, MtchType.ipv4), node); checkSalMatch(salFlow.getMatch(), MtchType.ipv4); - salFlow = ToSalConversionsUtils.toFlow(prepareOdFlow(odNodeFlowBuilder, MtchType.ipv6)); + salFlow = ToSalConversionsUtils.toFlow(prepareOdFlow(odNodeFlowBuilder, MtchType.ipv6), node); checkSalMatch(salFlow.getMatch(), MtchType.ipv6); - salFlow = ToSalConversionsUtils.toFlow(prepareOdFlow(odNodeFlowBuilder, MtchType.arp)); + salFlow = ToSalConversionsUtils.toFlow(prepareOdFlow(odNodeFlowBuilder, MtchType.arp), node); checkSalMatch(salFlow.getMatch(), MtchType.arp); - salFlow = ToSalConversionsUtils.toFlow(prepareOdFlow(odNodeFlowBuilder, MtchType.sctp)); + salFlow = ToSalConversionsUtils.toFlow(prepareOdFlow(odNodeFlowBuilder, MtchType.sctp), node); checkSalMatch(salFlow.getMatch(), MtchType.sctp); - salFlow = ToSalConversionsUtils.toFlow(prepareOdFlow(odNodeFlowBuilder, MtchType.tcp)); + salFlow = ToSalConversionsUtils.toFlow(prepareOdFlow(odNodeFlowBuilder, MtchType.tcp), node); checkSalMatch(salFlow.getMatch(), MtchType.tcp); - salFlow = ToSalConversionsUtils.toFlow(prepareOdFlow(odNodeFlowBuilder, MtchType.udp)); + salFlow = ToSalConversionsUtils.toFlow(prepareOdFlow(odNodeFlowBuilder, MtchType.udp), node); checkSalMatch(salFlow.getMatch(), MtchType.udp); checkSalFlow(salFlow); @@ -503,7 +555,7 @@ public class TestToSalConversionsUtils { private void prepareActionOutput(OutputActionCaseBuilder wrapper) { OutputActionBuilder outputActionBuilder = new OutputActionBuilder(); - outputActionBuilder.setOutputNodeConnector(new Uri("uri1")); + outputActionBuilder.setOutputNodeConnector(new Uri("1")); wrapper.setOutputAction(outputActionBuilder.build()); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributeIfcSwitchStatement.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributeIfcSwitchStatement.java index cf0e71e67a..502d581220 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributeIfcSwitchStatement.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributeIfcSwitchStatement.java @@ -37,6 +37,8 @@ public abstract class AttributeIfcSwitchStatement { return caseJavaBinaryAttribute(openType); } else if(((JavaAttribute)attributeIfc).isUnion()) { return caseJavaUnionAttribute(openType); + } else if(((JavaAttribute)attributeIfc).isIdentityRef()) { + return caseJavaIdentityRefAttribute(openType); } else return caseJavaAttribute(openType); } catch (UnknownOpenTypeException e) { @@ -56,6 +58,10 @@ public abstract class AttributeIfcSwitchStatement { throw getIllegalArgumentException(attributeIfc); } + protected T caseJavaIdentityRefAttribute(OpenType openType) { + return caseJavaAttribute(openType); + } + protected T caseJavaUnionAttribute(OpenType openType) { return caseJavaAttribute(openType); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectXmlReader.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectXmlReader.java index 97c0f4d834..61db74feb5 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectXmlReader.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectXmlReader.java @@ -16,20 +16,25 @@ import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribu import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributeIfcSwitchStatement; +import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig; import javax.management.openmbean.ArrayType; import javax.management.openmbean.CompositeType; import javax.management.openmbean.OpenType; import javax.management.openmbean.SimpleType; +import java.util.Date; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; public class ObjectXmlReader extends AttributeIfcSwitchStatement { private String key; + private Map> identityMap; - public Map prepareReading(Map yangToAttrConfig) { + public Map prepareReading(Map yangToAttrConfig, Map> identityMap) { Map strategies = Maps.newHashMap(); + this.identityMap = identityMap; for (Entry attributeEntry : yangToAttrConfig.entrySet()) { AttributeReadingStrategy strat = prepareReadingStrategy(attributeEntry.getKey(), attributeEntry.getValue()); @@ -72,6 +77,15 @@ public class ObjectXmlReader extends AttributeIfcSwitchStatement openType) { + Preconditions.checkState(openType instanceof CompositeType); + Set keys = ((CompositeType) openType).keySet(); + Preconditions.checkState(keys.size() == 1, "Unexpected number of elements for open type %s, should be 1", openType); + String mappingKey = keys.iterator().next(); + return new SimpleIdentityRefAttributeReadingStrategy(lastAttribute.getNullableDefault(), mappingKey, identityMap); + } + @Override protected AttributeReadingStrategy caseDependencyAttribute(SimpleType openType) { return new ObjectNameAttributeReadingStrategy(lastAttribute.getNullableDefault()); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleAttributeReadingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleAttributeReadingStrategy.java index 625e4ab3df..3765a13508 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleAttributeReadingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleAttributeReadingStrategy.java @@ -31,7 +31,7 @@ public class SimpleAttributeReadingStrategy extends AbstractAttributeReadingStra String textContent = ""; try{ - textContent = xmlElement.getTextContent(); + textContent = readElementContent(xmlElement); }catch(IllegalStateException | NullPointerException e) { // yuma sends for empty value instead of logger.warn("Ignoring exception caused by failure to read text element", e); @@ -42,6 +42,10 @@ public class SimpleAttributeReadingStrategy extends AbstractAttributeReadingStra postprocessParsedValue(textContent)); } + protected String readElementContent(XmlElement xmlElement) { + return xmlElement.getTextContent(); + } + @Override protected Object postprocessNullableDefault(String nullableDefault) { return nullableDefault; diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleBinaryAttributeReadingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleBinaryAttributeReadingStrategy.java index 2cac9029c6..266271bfce 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleBinaryAttributeReadingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleBinaryAttributeReadingStrategy.java @@ -19,6 +19,7 @@ public class SimpleBinaryAttributeReadingStrategy extends SimpleAttributeReading super(nullableDefault); } + @Override protected Object postprocessParsedValue(String textContent) { BaseEncoding en = BaseEncoding.base64(); byte[] decode = en.decode(textContent); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleCompositeAttributeReadingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleCompositeAttributeReadingStrategy.java index 22c9e015a9..ad3b9ab51b 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleCompositeAttributeReadingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleCompositeAttributeReadingStrategy.java @@ -21,6 +21,7 @@ public class SimpleCompositeAttributeReadingStrategy extends SimpleAttributeRead this.key = key; } + @Override protected Object postprocessParsedValue(String textContent) { HashMap map = Maps.newHashMap(); map.put(key, textContent); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleIdentityRefAttributeReadingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleIdentityRefAttributeReadingStrategy.java new file mode 100644 index 0000000000..1205597125 --- /dev/null +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleIdentityRefAttributeReadingStrategy.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml; + +import java.net.URI; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import com.google.common.base.Preconditions; +import com.google.common.collect.Maps; +import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig; +import org.opendaylight.controller.netconf.util.xml.XmlElement; +import org.opendaylight.yangtools.yang.common.QName; + + +public class SimpleIdentityRefAttributeReadingStrategy extends SimpleAttributeReadingStrategy { + + private final String key; + private final Map> identityMap; + + public SimpleIdentityRefAttributeReadingStrategy(String nullableDefault, String key, Map> identityMap) { + super(nullableDefault); + this.key = key; + this.identityMap = identityMap; + } + + @Override + protected String readElementContent(XmlElement xmlElement) { + // TODO test + Map.Entry namespaceOfTextContent = xmlElement.findNamespaceOfTextContent(); + String content = xmlElement.getTextContent(); + + String prefix = namespaceOfTextContent.getKey() + ":"; + Preconditions.checkArgument(content.startsWith(prefix), "Identity ref should be prefixed"); + + String localName = content.substring(prefix.length()); + String namespace = namespaceOfTextContent.getValue(); + + Date revision = null; + Map revisions = identityMap.get(namespace); + if(revisions.keySet().size() > 1) { + for (Date date : revisions.keySet()) { + if(revisions.get(date).containsIdName(localName)) { + Preconditions.checkState(revision == null, "Duplicate identity %s, in namespace %s, with revisions: %s, %s detected. Cannot map attribute", + localName, namespace, revision, date); + revision = date; + } + } + } else + revision = revisions.keySet().iterator().next(); + + + return QName.create(URI.create(namespace), revision, localName).toString(); + } + + @Override + protected Object postprocessParsedValue(String textContent) { + HashMap map = Maps.newHashMap(); + map.put(key, textContent); + return map; + } + + @Override + protected Object postprocessNullableDefault(String nullableDefault) { + return nullableDefault == null ? null : postprocessParsedValue(nullableDefault); + } +} diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleUnionAttributeReadingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleUnionAttributeReadingStrategy.java index 2e8b459b70..44cb1e7615 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleUnionAttributeReadingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleUnionAttributeReadingStrategy.java @@ -23,6 +23,7 @@ public class SimpleUnionAttributeReadingStrategy extends SimpleAttributeReadingS this.key = key; } + @Override protected Object postprocessParsedValue(String textContent) { char[] charArray = textContent.toCharArray(); List chars = Lists.newArrayListWithCapacity(charArray.length); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectXmlWriter.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectXmlWriter.java index 4e870f042d..8d63bb05d8 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectXmlWriter.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectXmlWriter.java @@ -68,6 +68,11 @@ public class ObjectXmlWriter extends AttributeIfcSwitchStatement openType) { + return new SimpleIdentityRefAttributeWritingStrategy(document, key); + } + @Override protected AttributeWritingStrategy caseJavaCompositeAttribute(CompositeType openType) { return new SimpleCompositeAttributeWritingStrategy(document, key); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleAttributeWritingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleAttributeWritingStrategy.java index 62ff682a7f..b327f8ebef 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleAttributeWritingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleAttributeWritingStrategy.java @@ -31,11 +31,15 @@ public class SimpleAttributeWritingStrategy implements AttributeWritingStrategy public void writeElement(Element parentElement, String namespace, Object value) { value = preprocess(value); Util.checkType(value, String.class); - Element innerNode = XmlUtil.createTextElement(document, key, (String) value); + Element innerNode = createElement(document, key, (String) value); XmlUtil.addNamespaceAttr(innerNode, namespace); parentElement.appendChild(innerNode); } + protected Element createElement(Document document, String key, String value) { + return XmlUtil.createTextElement(document, key, (String) value); + } + protected Object preprocess(Object value) { return value; } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleIdentityRefAttributeWritingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleIdentityRefAttributeWritingStrategy.java new file mode 100644 index 0000000000..7c90355051 --- /dev/null +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleIdentityRefAttributeWritingStrategy.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.toxml; + +import java.util.Map; + +import org.opendaylight.controller.netconf.confignetconfconnector.util.Util; +import org.opendaylight.controller.netconf.util.xml.XmlUtil; +import org.opendaylight.yangtools.yang.common.QName; +import org.w3c.dom.Document; + +import com.google.common.base.Preconditions; +import org.w3c.dom.Element; + +public class SimpleIdentityRefAttributeWritingStrategy extends SimpleAttributeWritingStrategy { + + private static final char QNAME_SEPARATOR = ':'; + private static final String PREFIX = "prefix"; + + /** + * @param document + * @param key + */ + public SimpleIdentityRefAttributeWritingStrategy(Document document, String key) { + super(document, key); + } + + protected Object preprocess(Object value) { + Util.checkType(value, Map.class); + Preconditions.checkArgument(((Map)value).size() == 1, "Unexpected number of values in %s, expected 1", value); + Object stringValue = ((Map) value).values().iterator().next(); + Util.checkType(stringValue, String.class); + + return stringValue; + } + + @Override + protected Element createElement(Document doc, String key, String value) { + QName qName = QName.create(value); + String identity = qName.getLocalName(); + Element element = XmlUtil.createPrefixedTextElement(doc, key, PREFIX, identity); + + String identityNamespace = qName.getNamespace().toString(); + XmlUtil.addPrefixedNamespaceAttr(element, PREFIX, identityNamespace); + return element; + } +} diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java index ec73cd6068..449cfbb4cd 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java @@ -15,6 +15,7 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; +import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig; import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; @@ -27,6 +28,7 @@ import org.w3c.dom.Element; import javax.management.ObjectName; import java.util.Collection; import java.util.Collections; +import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -43,13 +45,20 @@ public class Config { Map> moduleConfigs; private final Map moduleNamesToConfigs; + private final Map> identityMap; + public Config(Map> moduleConfigs) { + this(moduleConfigs, Collections.>emptyMap()); + } + + public Config(Map> moduleConfigs, Map> identityMap) { this.moduleConfigs = moduleConfigs; Map moduleNamesToConfigs = new HashMap<>(); for (Entry> entry : moduleConfigs.entrySet()) { moduleNamesToConfigs.putAll(entry.getValue()); } this.moduleNamesToConfigs = Collections.unmodifiableMap(moduleNamesToConfigs); + this.identityMap = identityMap; } public static Map>> getMappedInstances(Set instancesToMap, @@ -149,7 +158,7 @@ public class Config { @Override public ModuleElementResolved resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement, ServiceRegistryWrapper serviceTracker, String instanceName, String moduleNamespace, EditStrategyType defaultStrategy) { return moduleMapping.fromXml(moduleElement, serviceTracker, - instanceName, moduleNamespace, defaultStrategy); + instanceName, moduleNamespace, defaultStrategy, identityMap); } }; diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java index b8870e51ce..a940be7e77 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java @@ -25,6 +25,7 @@ import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attrib import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving.ObjectResolver; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.toxml.AttributeWritingStrategy; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.toxml.ObjectXmlWriter; +import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig; import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; @@ -35,6 +36,7 @@ import org.w3c.dom.Element; import javax.management.ObjectName; import javax.management.openmbean.OpenType; +import java.util.Date; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -129,10 +131,10 @@ public final class InstanceConfig { } public InstanceConfigElementResolved fromXml(XmlElement moduleElement, ServiceRegistryWrapper services, String moduleNamespace, - EditStrategyType defaultStrategy, Multimap providedServices) { + EditStrategyType defaultStrategy, Multimap providedServices, Map> identityMap) { Map retVal = Maps.newHashMap(); - Map strats = new ObjectXmlReader().prepareReading(yangToAttrConfig); + Map strats = new ObjectXmlReader().prepareReading(yangToAttrConfig, identityMap); List recognisedChildren = Lists.newArrayList(); XmlElement type = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java index 48ff835a45..bf625ea0e2 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java @@ -11,6 +11,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.confi import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; +import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig; import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; @@ -21,6 +22,8 @@ import org.w3c.dom.Element; import javax.management.ObjectName; import java.util.Collection; +import java.util.Date; +import java.util.Map; public class ModuleConfig { @@ -85,9 +88,9 @@ public class ModuleConfig { } public ModuleElementResolved fromXml(XmlElement moduleElement, ServiceRegistryWrapper depTracker, String instanceName, - String moduleNamespace, EditStrategyType defaultStrategy) { + String moduleNamespace, EditStrategyType defaultStrategy, Map> identityMap) { - InstanceConfigElementResolved ice = instanceConfig.fromXml(moduleElement, depTracker, moduleNamespace, defaultStrategy, providedServices); + InstanceConfigElementResolved ice = instanceConfig.fromXml(moduleElement, depTracker, moduleNamespace, defaultStrategy, providedServices, identityMap); return new ModuleElementResolved(instanceName, ice); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java index 7df671297c..8d2d149822 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java @@ -12,6 +12,7 @@ import com.google.common.base.Preconditions; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry; +import org.opendaylight.yangtools.yang.common.QName; import javax.management.InstanceNotFoundException; import javax.management.ObjectName; @@ -19,8 +20,6 @@ import java.util.Collection; import java.util.Collections; import java.util.Map; import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; public class ServiceRegistryWrapper { @@ -77,27 +76,15 @@ public class ServiceRegistryWrapper { ObjectName on = serviceMapping.get(serviceQName).get(refName); Services.ServiceInstance si = Services.ServiceInstance.fromObjectName(on); - // FIXME use QName's new String constructor, after it is fixed -// QName qname; -// try { -// qname = new QName(serviceQName); -// } catch (ParseException e) { -// throw new IllegalStateException("Unable to parse qname of a service " + serviceQName, e); -// } - Pattern p = Pattern.compile("\\(([^\\(\\?]+)\\?[^\\?\\)]*\\)([^\\)]+)"); - Matcher matcher = p.matcher(serviceQName); - Preconditions.checkArgument(matcher.matches()); - String namespace = matcher.group(1); - String localName = matcher.group(2); - -// String namespace = qname.getNamespace().toString(); + QName qname = QName.create(serviceQName); + String namespace = qname.getNamespace().toString(); Map> serviceToRefs = retVal.get(namespace); if(serviceToRefs==null) { serviceToRefs = Maps.newHashMap(); retVal.put(namespace, serviceToRefs); } -// String localName = qname.getLocalName(); + String localName = qname.getLocalName(); Map refsToSis = serviceToRefs.get(localName); if(refsToSis==null) { refsToSis = Maps.newHashMap(); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/InstanceRuntimeRpc.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/InstanceRuntimeRpc.java index 4b05135eaf..b7f5fc780b 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/InstanceRuntimeRpc.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/InstanceRuntimeRpc.java @@ -17,9 +17,12 @@ import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attrib import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.ObjectXmlReader; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving.AttributeResolvingStrategy; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving.ObjectResolver; +import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig; import org.opendaylight.controller.netconf.util.xml.XmlElement; import javax.management.openmbean.OpenType; +import java.util.Collections; +import java.util.Date; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -67,7 +70,9 @@ public final class InstanceRuntimeRpc { public Map fromXml(XmlElement configRootNode) { Map retVal = Maps.newHashMap(); - Map strats = new ObjectXmlReader().prepareReading(yangToAttrConfig); + // FIXME add identity map to runtime data + Map strats = new ObjectXmlReader().prepareReading(yangToAttrConfig, + Collections.> emptyMap()); for (Entry readStratEntry : strats.entrySet()) { List configNodes = configRootNode.getChildElements(readStratEntry.getKey()); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java index a61d4633a2..97535ba1e2 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java @@ -9,6 +9,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig; import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Preconditions; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; import org.opendaylight.controller.config.api.JmxAttributeValidationException; @@ -33,6 +34,8 @@ import org.opendaylight.controller.netconf.confignetconfconnector.operations.edi import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; +import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode; +import org.opendaylight.yangtools.yang.model.api.Module; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; @@ -40,9 +43,11 @@ import org.w3c.dom.Element; import javax.management.InstanceNotFoundException; import javax.management.ObjectName; +import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; public class EditConfig extends AbstractConfigNetconfOperation { @@ -207,12 +212,64 @@ public class EditConfig extends AbstractConfigNetconfOperation { } } - public static Config getConfigMapping(ConfigRegistryClient configRegistryClient, - Map> mBeanEntries) { - Map> factories = transformMbeToModuleConfigs(configRegistryClient, mBeanEntries); + public static Config getConfigMapping(ConfigRegistryClient configRegistryClient, YangStoreSnapshot yangStoreSnapshot) { + Map> factories = transformMbeToModuleConfigs(configRegistryClient, + yangStoreSnapshot.getModuleMXBeanEntryMap()); + Map> identitiesMap = transformIdentities(yangStoreSnapshot.getModules()); + return new Config(factories, identitiesMap); + } + + + public static class IdentityMapping { + private final Map identityNameToSchemaNode; + + IdentityMapping() { + this.identityNameToSchemaNode = Maps.newHashMap(); + } - return new Config(factories); + void addIdSchemaNode(IdentitySchemaNode node) { + String name = node.getQName().getLocalName(); + Preconditions.checkState(identityNameToSchemaNode.containsKey(name) == false); + identityNameToSchemaNode.put(name, node); + } + + public boolean containsIdName(String idName) { + return identityNameToSchemaNode.containsKey(idName); + } + + public IdentitySchemaNode getIdentitySchemaNode(String idName) { + Preconditions.checkState(identityNameToSchemaNode.containsKey(idName), "No identity under name %s", idName); + return identityNameToSchemaNode.get(idName); + } + } + + private static Map> transformIdentities(Set modules) { + Map> mappedIds = Maps.newHashMap(); + for (Module module : modules) { + String namespace = module.getNamespace().toString(); + Map revisionsByNamespace= mappedIds.get(namespace); + if(revisionsByNamespace == null) { + revisionsByNamespace = Maps.newHashMap(); + mappedIds.put(namespace, revisionsByNamespace); + } + + Date revision = module.getRevision(); + Preconditions.checkState(revisionsByNamespace.containsKey(revision) == false, + "Duplicate revision %s for namespace %s", revision, namespace); + + IdentityMapping identityMapping = revisionsByNamespace.get(revision); + if(identityMapping == null) { + identityMapping = new IdentityMapping(); + revisionsByNamespace.put(revision, identityMapping); + } + + for (IdentitySchemaNode identitySchemaNode : module.getIdentities()) { + identityMapping.addIdSchemaNode(identitySchemaNode); + } + + } + + return mappedIds; } public static Map idCodec = mock(IdentityCodec.class); + doReturn(TestIdentity1.class).when(idCodec).deserialize(TestIdentity1.QNAME); + doReturn(TestIdentity2.class).when(idCodec).deserialize(TestIdentity2.QNAME); + + CodecRegistry codecReg = super.getCodecRegistry(); + doReturn(idCodec).when(codecReg).getIdentityCodec(); + return codecReg; + } + @Test public void testServicePersistance() throws Exception { createModule(INSTANCE_NAME); @@ -236,7 +271,6 @@ public class NetconfMappingTest extends AbstractConfigTest { edit("netconfMessages/editConfig.xml"); Element configCandidate = getConfigCandidate(); - System.err.println(XmlUtil.toString(configCandidate)); checkBinaryLeafEdited(configCandidate); @@ -554,6 +588,21 @@ public class NetconfMappingTest extends AbstractConfigTest { return mBeanEntries; } + private Set getModules() throws Exception { + SchemaContext resolveSchemaContext = getSchemaContext(); + return resolveSchemaContext.getModules(); + } + + private SchemaContext getSchemaContext() throws Exception { + final List yangDependencies = getYangs(); + YangParserImpl parser = new YangParserImpl(); + + Set allYangModules = parser.parseYangModelsFromStreams(yangDependencies); + + return parser.resolveSchemaContext(Sets + .newHashSet(allYangModules)); + } + @Test public void testConfigNetconfRuntime() throws Exception { diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlUtil.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlUtil.java index 5e3a7ac54f..137e215a31 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlUtil.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlUtil.java @@ -111,8 +111,8 @@ public class XmlUtil { root.setAttribute(concat(XMLNS_ATTRIBUTE_KEY, prefix), namespace); } - public static Element createPrefixedTextElement(Document document, String key, String prefix, String moduleName) { - return createTextElement(document, key, concat(prefix, moduleName)); + public static Element createPrefixedTextElement(Document document, String key, String prefix, String content) { + return createTextElement(document, key, concat(prefix, content)); } private static String concat(String prefix, String value) { diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_identities.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_identities.xml new file mode 100644 index 0000000000..62c6a20997 --- /dev/null +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_identities.xml @@ -0,0 +1,37 @@ + + + + + + + set + + merge + + + + + test-impl:impl-identity-test + + id-test + + prefix:test-identity1 + prefix:test-identity2 + + + prefix:test-identity2 + prefix:test-identity1 + + + prefix:test-identity2 + + prefix:test-identity1 + + + + + + + + +