From: Tony Tkacik Date: Mon, 26 May 2014 19:48:32 +0000 (+0000) Subject: Merge "Bug 1036 - Allow using container in case stmt to preserve uniqueness." X-Git-Tag: autorelease-tag-v20140601202136_82eb3f9~23 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=aefe82b158bc1694fe633053d04f2364bcbe67d9;hp=3b6353dd7144251c79e9454a319675a406f0bd7f Merge "Bug 1036 - Allow using container in case stmt to preserve uniqueness." --- diff --git a/opendaylight/commons/opendaylight/pom.xml b/opendaylight/commons/opendaylight/pom.xml index e1e3164f71..7c47f3644d 100644 --- a/opendaylight/commons/opendaylight/pom.xml +++ b/opendaylight/commons/opendaylight/pom.xml @@ -928,6 +928,12 @@ ${netconf.version} test-jar + + org.opendaylight.controller + netconf-netty-util + ${netconf.version} + test-jar + org.opendaylight.controller netconf-ssh diff --git a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntry.java b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntry.java index 0cc950af65..773025c3cf 100644 --- a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntry.java +++ b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntry.java @@ -10,7 +10,6 @@ package org.opendaylight.controller.config.yangjmxgenerator; import java.util.Collection; import java.util.Collections; import java.util.Map; - import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc; import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.FullyQualifiedNameHelper; import org.opendaylight.yangtools.yang.common.QName; @@ -73,6 +72,7 @@ public class ModuleMXBeanEntry extends AbstractEntry { private final Map providedServices; private Collection runtimeBeans; + private String nullableDummyContainerName; ModuleMXBeanEntry(ModuleMXBeanEntryInitial initials, Map yangToAttributes, Map providedServices2, Collection runtimeBeans) { @@ -183,6 +183,15 @@ public class ModuleMXBeanEntry extends AbstractEntry { + '\'' + '}'; } + public String getNullableDummyContainerName() { + return nullableDummyContainerName; + } + + public void setNullableDummyContainerName(String nullableDummyContainerName) { + this.nullableDummyContainerName = nullableDummyContainerName; + } + + static final class ModuleMXBeanEntryInitial { private String localName; diff --git a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryBuilder.java b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryBuilder.java index 676c8eca6e..6da8dfc663 100644 --- a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryBuilder.java +++ b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryBuilder.java @@ -7,12 +7,27 @@ */ package org.opendaylight.controller.config.yangjmxgenerator; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import static java.lang.String.format; +import static org.opendaylight.controller.config.yangjmxgenerator.ConfigConstants.createConfigQName; + import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; import com.google.common.base.Optional; import com.google.common.collect.Collections2; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.annotation.Nullable; import org.opendaylight.controller.config.yangjmxgenerator.attribute.AbstractDependencyAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc; import org.opendaylight.controller.config.yangjmxgenerator.attribute.DependencyAttribute; @@ -35,26 +50,13 @@ import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.ModuleImport; import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath; import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.api.SchemaNode; import org.opendaylight.yangtools.yang.model.api.SchemaPath; import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; import org.opendaylight.yangtools.yang.model.api.UsesNode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.annotation.Nullable; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static com.google.common.base.Preconditions.checkState; -import static java.lang.String.format; -import static org.opendaylight.controller.config.yangjmxgenerator.ConfigConstants.createConfigQName; - final class ModuleMXBeanEntryBuilder { private Module currentModule; @@ -233,7 +235,7 @@ final class ModuleMXBeanEntryBuilder { return true; } - private void processChoiceCaseNode(Map result, + private void processChoiceCaseNode(Map result, Map uniqueGeneratedClassesNames, String configModulePrefix, Map moduleIdentities, Map unaugmentedModuleIdentities, AugmentationSchema augmentation, @@ -266,15 +268,17 @@ final class ModuleMXBeanEntryBuilder { // runtime-data Collection runtimeBeans = null; + HAS_CHILDREN_AND_QNAME dataNodeContainer = getDataNodeContainer(choiceCaseNode); + if (expectedConfigurationAugmentationSchemaPath.equals(augmentation.getTargetPath())) { logger.debug("Parsing configuration of {}", moduleLocalNameFromXPath); - yangToAttributes = fillConfiguration(choiceCaseNode, currentModule, typeProviderWrapper, qNamesToSIEs, + yangToAttributes = fillConfiguration(dataNodeContainer, currentModule, typeProviderWrapper, qNamesToSIEs, schemaContext, packageName); checkUniqueAttributesWithGeneratedClass(uniqueGeneratedClassesNames, when.getQName(), yangToAttributes); } else if (expectedStateAugmentationSchemaPath.equals(augmentation.getTargetPath())) { logger.debug("Parsing state of {}", moduleLocalNameFromXPath); try { - runtimeBeans = fillRuntimeBeans(choiceCaseNode, currentModule, typeProviderWrapper, packageName, + runtimeBeans = fillRuntimeBeans(dataNodeContainer, currentModule, typeProviderWrapper, packageName, moduleLocalNameFromXPath, javaNamePrefix); } catch (NameConflictException e) { throw new NameConflictException(e.getConflictingName(), when.getQName(), when.getQName()); @@ -289,14 +293,20 @@ final class ModuleMXBeanEntryBuilder { } else { throw new IllegalArgumentException("Cannot parse augmentation " + augmentation); } + boolean hasDummyContainer = choiceCaseNode.equals(dataNodeContainer) == false; + + String nullableDummyContainerName = hasDummyContainer ? dataNodeContainer.getQName().getLocalName() : null; if (result.containsKey(moduleLocalNameFromXPath)) { - // either fill runtimeBeans or yangToAttributes + // either fill runtimeBeans or yangToAttributes, merge ModuleMXBeanEntry moduleMXBeanEntry = result.get(moduleLocalNameFromXPath); if (yangToAttributes != null && moduleMXBeanEntry.getAttributes() == null) { moduleMXBeanEntry.setYangToAttributes(yangToAttributes); } else if (runtimeBeans != null && moduleMXBeanEntry.getRuntimeBeans() == null) { moduleMXBeanEntry.setRuntimeBeans(runtimeBeans); } + checkState(Objects.equals(nullableDummyContainerName, moduleMXBeanEntry.getNullableDummyContainerName()), + "Mismatch in module " + moduleMXBeanEntry.toString() + " - dummy container must be present/missing in" + + " both state and configuration"); } else { ModuleMXBeanEntry.ModuleMXBeanEntryInitial initial = new ModuleMXBeanEntry.ModuleMXBeanEntryInitialBuilder() .setIdSchemaNode(moduleIdentity).setPackageName(packageName).setJavaNamePrefix(javaNamePrefix) @@ -309,6 +319,7 @@ final class ModuleMXBeanEntryBuilder { moduleMXBeanEntry.setYangModuleName(currentModule.getName()); moduleMXBeanEntry.setYangModuleLocalname(moduleLocalNameFromXPath); + moduleMXBeanEntry.setNullableDummyContainerName(nullableDummyContainerName); result.put(moduleLocalNameFromXPath, moduleMXBeanEntry); } } @@ -352,29 +363,52 @@ final class ModuleMXBeanEntryBuilder { } private void checkUniqueTOAttr(Map uniqueGeneratedClassNames, QName parentQName, TOAttribute attr) { - final String upperCaseCammelCase = attr.getUpperCaseCammelCase(); - if (uniqueGeneratedClassNames.containsKey(upperCaseCammelCase)) { - QName firstDefinedQName = uniqueGeneratedClassNames.get(upperCaseCammelCase); - throw new NameConflictException(upperCaseCammelCase, firstDefinedQName, parentQName); + final String upperCaseCamelCase = attr.getUpperCaseCammelCase(); + if (uniqueGeneratedClassNames.containsKey(upperCaseCamelCase)) { + QName firstDefinedQName = uniqueGeneratedClassNames.get(upperCaseCamelCase); + throw new NameConflictException(upperCaseCamelCase, firstDefinedQName, parentQName); } else { - uniqueGeneratedClassNames.put(upperCaseCammelCase, parentQName); + uniqueGeneratedClassNames.put(upperCaseCamelCase, parentQName); } } - private Collection fillRuntimeBeans(ChoiceCaseNode choiceCaseNode, Module currentModule, + private Collection fillRuntimeBeans(DataNodeContainer dataNodeContainer, Module currentModule, TypeProviderWrapper typeProviderWrapper, String packageName, String moduleLocalNameFromXPath, String javaNamePrefix) { - return RuntimeBeanEntry.extractClassNameToRuntimeBeanMap(packageName, choiceCaseNode, moduleLocalNameFromXPath, + return RuntimeBeanEntry.extractClassNameToRuntimeBeanMap(packageName, dataNodeContainer, moduleLocalNameFromXPath, typeProviderWrapper, javaNamePrefix, currentModule).values(); } - private Map fillConfiguration(ChoiceCaseNode choiceCaseNode, Module currentModule, + /** + * Since each case statement within a module must provide unique child nodes, it is allowed to wrap + * the actual configuration with a container node with name equal to case name. + * + * @param choiceCaseNode state or configuration case statement + * @return either choiceCaseNode or its only child container + */ + private HAS_CHILDREN_AND_QNAME getDataNodeContainer(ChoiceCaseNode choiceCaseNode) { + Set childNodes = choiceCaseNode.getChildNodes(); + if (childNodes.size() == 1) { + DataSchemaNode onlyChild = childNodes.iterator().next(); + if (onlyChild instanceof ContainerSchemaNode) { + ContainerSchemaNode onlyContainer = (ContainerSchemaNode) onlyChild; + if (Objects.equals(onlyContainer.getQName().getLocalName(), choiceCaseNode.getQName().getLocalName())) { + // the actual configuration is inside dummy container + return (HAS_CHILDREN_AND_QNAME) onlyContainer; + } + } + } + return (HAS_CHILDREN_AND_QNAME) choiceCaseNode; + } + + private Map fillConfiguration(DataNodeContainer dataNodeContainer, Module currentModule, TypeProviderWrapper typeProviderWrapper, Map qNamesToSIEs, SchemaContext schemaContext, String packageName) { Map yangToAttributes = new HashMap<>(); - for (DataSchemaNode attrNode : choiceCaseNode.getChildNodes()) { + Set childNodes = dataNodeContainer.getChildNodes(); + for (DataSchemaNode attrNode : childNodes) { AttributeIfc attributeValue = getAttributeValue(attrNode, currentModule, qNamesToSIEs, typeProviderWrapper, schemaContext, packageName); yangToAttributes.put(attributeValue.getAttributeYangName(), attributeValue); @@ -483,7 +517,7 @@ final class ModuleMXBeanEntryBuilder { String prefix = m.group(1); ModuleImport moduleImport = findModuleImport(currentModule, prefix); foundModule = schemaContext.findModuleByName(moduleImport.getModuleName(), moduleImport.getRevision()); - checkState(foundModule != null, format("Module not found in SchemaContext by %s", moduleImport)); + checkNotNull(foundModule, format("Module not found in SchemaContext by %s", moduleImport)); localSIName = m.group(2); } else { foundModule = currentModule; // no prefix => SIE is in currentModule diff --git a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeBeanEntry.java b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeBeanEntry.java index cd14458b0f..c941d1504d 100644 --- a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeBeanEntry.java +++ b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeBeanEntry.java @@ -7,9 +7,24 @@ */ package org.opendaylight.controller.config.yangjmxgenerator; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkState; + import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Optional; import com.google.common.collect.Lists; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Deque; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc; import org.opendaylight.controller.config.yangjmxgenerator.attribute.JavaAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribute; @@ -18,7 +33,6 @@ import org.opendaylight.controller.config.yangjmxgenerator.attribute.VoidAttribu import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.FullyQualifiedNameHelper; import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.NameConflictException; import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode; import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; @@ -32,22 +46,6 @@ import org.opendaylight.yangtools.yang.model.api.SchemaNode; import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; import org.opendaylight.yangtools.yang.model.api.UsesNode; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.Deque; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkState; - /** * Holds information about runtime bean to be generated. There are two kinds of * RuntimeBeanEntry instances: if isRoot flag is set to true, this bean @@ -68,7 +66,7 @@ public class RuntimeBeanEntry { @VisibleForTesting RuntimeBeanEntry(String packageName, - DataSchemaNode nodeForReporting, String yangName, + DataNodeContainer nodeForReporting, String yangName, String javaNamePrefix, boolean isRoot, Optional keyYangName, List attributes, List children, Set rpcs) { @@ -112,7 +110,7 @@ public class RuntimeBeanEntry { * not contain special configuration for it. */ public static Map extractClassNameToRuntimeBeanMap( - String packageName, ChoiceCaseNode container, + String packageName, DataNodeContainer container, String moduleYangName, TypeProviderWrapper typeProviderWrapper, String javaNamePrefix, Module currentModule) { @@ -390,7 +388,7 @@ public class RuntimeBeanEntry { } private static RuntimeBeanEntry createRoot(String packageName, - DataSchemaNode nodeForReporting, String attributeYangName, + DataNodeContainer nodeForReporting, String attributeYangName, List attributes, String javaNamePrefix, List children, Set rpcs) { return new RuntimeBeanEntry(packageName, nodeForReporting, diff --git a/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/AbstractYangTest.java b/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/AbstractYangTest.java index 76d97703af..b9f2ba9cd1 100644 --- a/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/AbstractYangTest.java +++ b/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/AbstractYangTest.java @@ -7,8 +7,19 @@ */ package org.opendaylight.controller.config.yangjmxgenerator; +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.format; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + import com.google.common.base.Preconditions; import com.google.common.collect.Sets; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; import org.junit.Assert; import org.junit.Before; import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.YangModelSearchUtils; @@ -19,18 +30,6 @@ import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import static junit.framework.Assert.assertNotNull; -import static junit.framework.Assert.format; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - public abstract class AbstractYangTest { protected SchemaContext context; protected Map namesToModules; // are module names globally diff --git a/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeRegistratorTest.java b/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeRegistratorTest.java index 6dd64441df..7765b28bb5 100644 --- a/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeRegistratorTest.java +++ b/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeRegistratorTest.java @@ -11,27 +11,25 @@ import static org.apache.commons.lang3.StringUtils.capitalize; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; +import com.google.common.base.Optional; import java.net.URI; import java.util.Collections; import java.util.List; - import org.junit.Test; import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry.Rpc; import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc; import org.opendaylight.yangtools.sal.binding.model.api.Type; import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; -import com.google.common.base.Optional; - public class RuntimeRegistratorTest { // TODO add more tests protected RuntimeBeanEntry prepareRootRB(List children) { - DataSchemaNode dataSchemaNodeForReporting = mock(DataSchemaNode.class); - doReturn("DataSchemaNode").when(dataSchemaNodeForReporting).toString(); - return new RuntimeBeanEntry("pa.cka.ge", dataSchemaNodeForReporting, + DataNodeContainer nodeContainer = mock(DataNodeContainer.class); + doReturn("DataSchemaNode").when(nodeContainer).toString(); + return new RuntimeBeanEntry("pa.cka.ge", nodeContainer, "module-name", "ModuleName", true, Optional. absent(), Collections. emptyList(), children, Collections. emptySet()); @@ -39,9 +37,9 @@ public class RuntimeRegistratorTest { protected RuntimeBeanEntry prepareChildRB(List children, String prefix) { - DataSchemaNode dataSchemaNodeForReporting = mock(DataSchemaNode.class); - doReturn("DataSchemaNode").when(dataSchemaNodeForReporting).toString(); - return new RuntimeBeanEntry("pa.cka.ge", dataSchemaNodeForReporting, + DataNodeContainer nodeContainer = mock(DataNodeContainer.class); + doReturn("DataSchemaNode").when(nodeContainer).toString(); + return new RuntimeBeanEntry("pa.cka.ge", nodeContainer, prefix + "child-name", capitalize(prefix) + "ChildName", false, Optional. absent(), Collections. emptyList(), children, diff --git a/opendaylight/config/yang-jmx-generator/src/test/resources/config-bgp-listener-impl.yang b/opendaylight/config/yang-jmx-generator/src/test/resources/config-bgp-listener-impl.yang index fca83fd6be..0a011b772c 100644 --- a/opendaylight/config/yang-jmx-generator/src/test/resources/config-bgp-listener-impl.yang +++ b/opendaylight/config/yang-jmx-generator/src/test/resources/config-bgp-listener-impl.yang @@ -23,20 +23,22 @@ module config-bgp-listener-impl { augment "/config:modules/config:module/config:state" { case bgp-listener-impl { when "/config:modules/config:module/config:type = 'bgp-listener-impl'"; - list peers { - config:inner-state-bean; - leaf port { - type inet:port-number; - default 179; + container bgp-listener-impl { + list peers { + config:inner-state-bean; + leaf port { + type inet:port-number; + default 179; + } + leaf core-size { + type uint32; + } } - leaf core-size { - type uint32; - } - } - leaf as-number { - mandatory true; - type inet:as-number; + leaf as-number { + mandatory true; + type inet:as-number; + } } } } diff --git a/opendaylight/config/yang-jmx-generator/src/test/resources/test-config-threads-java.yang b/opendaylight/config/yang-jmx-generator/src/test/resources/test-config-threads-java.yang index 4af5b9569a..e189ef7d66 100644 --- a/opendaylight/config/yang-jmx-generator/src/test/resources/test-config-threads-java.yang +++ b/opendaylight/config/yang-jmx-generator/src/test/resources/test-config-threads-java.yang @@ -192,42 +192,44 @@ module config-threads-java { augment "/config:modules/config:module/config:configuration" { case threadpool-dynamic { when "/config:modules/config:module/config:type = 'threadpool-dynamic'"; - leaf core-size { - type uint32; - } + container threadpool-dynamic { + leaf core-size { + type uint32; + } - leaf keep-alive { - type uint32; - units seconds; - default 10; - } + leaf keep-alive { + type uint32; + units seconds; + default 10; + } - leaf maximum-size { - type uint32; - description "maximum-size description"; - } + leaf maximum-size { + type uint32; + description "maximum-size description"; + } - leaf binary { - type binary; - } + leaf binary { + type binary; + } - container threadfactory { - description "threadfactory description"; - uses config:service-ref { - refine type { - mandatory true; - config:required-identity th2:threadfactory; + container threadfactory { + description "threadfactory description"; + uses config:service-ref { + refine type { + mandatory true; + config:required-identity th2:threadfactory; + } } } - } - leaf-list users { - type string; - } + leaf-list users { + type string; + } - leaf-list users-numbers { - type uint32; - description "numbers of users description"; + leaf-list users-numbers { + type uint32; + description "numbers of users description"; + } } } } @@ -235,9 +237,11 @@ module config-threads-java { augment "/config:modules/config:module/config:state" { case threadpool-dynamic { when "/config:modules/config:module/config:type = 'threadpool-dynamic'"; - // root runtime bean - leaf created-sessions { - type uint32; + container threadpool-dynamic { + // root runtime bean + leaf created-sessions { + type uint32; + } } } } 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 c82da58c15..4b006bc72e 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 @@ -162,177 +162,179 @@ module config-test-impl { augment "/config:modules/config:module/config:configuration" { case impl-netconf { when "/config:modules/config:module/config:type = 'impl-netconf'"; - leaf binaryLeaf { - type binary; - default ZGVmYXVsdEJpbg==; - } - - leaf type { - type string; - default "default-string"; - } + container impl-netconf { + leaf binaryLeaf { + type binary; + default ZGVmYXVsdEJpbg==; + } - leaf extended { - type tt:extend-once; - default 1; - } + leaf type { + type string; + default "default-string"; + } - leaf extended-twice { - type tt:extend-twice; - default 2; - } + leaf extended { + type tt:extend-once; + default 1; + } - leaf extended-enum { - type tt:extend-enum; - default ONE; - } + leaf extended-twice { + type tt:extend-twice; + default 2; + } - leaf ip { - type inet:ip-address; - default 0:0:0:0:0:0:0:1; - } + leaf extended-enum { + type tt:extend-enum; + default ONE; + } - leaf union-test-attr { - type tt:unionTest; - default 456; - } + leaf ip { + type inet:ip-address; + default 0:0:0:0:0:0:0:1; + } - leaf sleep-factor { - type decimal64 { - fraction-digits 2; + leaf union-test-attr { + type tt:unionTest; + default 456; } - default 2.00; - } - container dto-c { - leaf simple-arg { - type uint32; + leaf sleep-factor { + type decimal64 { + fraction-digits 2; + } + default 2.00; } - container dto-a-inner { + container dto-c { leaf simple-arg { type uint32; } - container dto-a-inner-inner { + container dto-a-inner { leaf simple-arg { type uint32; } + + container dto-a-inner-inner { + leaf simple-arg { + type uint32; + } + } } } - } - - leaf simpleInt { - type uint32; - } - - leaf simpleBoolean { - type boolean; - default false; - } - - leaf simple-long { - type int64; - default -45; - } - - leaf simple-long-2 { - type uint32; - default 445; - } - leaf simple-BigInteger { - type uint64; - default 545454; - } + leaf simpleInt { + type uint32; + } - leaf simple-byte { - type int8; - default -4; - } + leaf simpleBoolean { + type boolean; + default false; + } - leaf simple-short { - type uint8; - default 45; - } + leaf simple-long { + type int64; + default -45; + } - leaf simple-test { - type uint16; - default 99; - } + leaf simple-long-2 { + type uint32; + default 445; + } - leaf-list simple-list { - type uint16; - } + leaf simple-BigInteger { + type uint64; + default 545454; + } - container dto_d { - leaf simple-int1 { - type uint32; + leaf simple-byte { + type int8; + default -4; } - leaf simple-int2 { - type uint32; + leaf simple-short { + type uint8; + default 45; } - leaf simple-int3 { + leaf simple-test { type uint16; + default 99; } leaf-list simple-list { type uint16; } - list complex-dto-bInner { - leaf-list simple-list { - type uint16; + container dto_d { + leaf simple-int1 { + type uint32; } + + leaf simple-int2 { + type uint32; + } + leaf simple-int3 { type uint16; } - container deep { + leaf-list simple-list { + type uint16; + } + + list complex-dto-bInner { + leaf-list simple-list { + type uint16; + } leaf simple-int3 { type uint16; - default 0; + } + + container deep { + leaf simple-int3 { + type uint16; + default 0; + } } } } - } - list complex-list { - list simple-list { - leaf simple-int3 { - type uint16; + list complex-list { + list simple-list { + leaf simple-int3 { + type uint16; + } } } - } - list peers { - leaf port { - type string; - } - leaf core-size { - type uint32; - } - leaf simple-int3 { - type uint16; - } - } + list peers { + leaf port { + type string; + } + leaf core-size { + type uint32; + } + leaf simple-int3 { + type uint16; + } + } - container testing-dep { - uses config:service-ref { - refine type { - mandatory true; - config:required-identity test:testing; + container testing-dep { + uses config:service-ref { + refine type { + mandatory true; + config:required-identity test:testing; + } } } - } - list testing-deps { - uses config:service-ref { - refine type { - mandatory true; - config:required-identity test:testing; + list testing-deps { + uses config:service-ref { + refine type { + mandatory true; + config:required-identity test:testing; + } } } } @@ -342,97 +344,99 @@ module config-test-impl { augment "/config:modules/config:module/config:state" { case impl-netconf { when "/config:modules/config:module/config:type = 'impl-netconf'"; - // rpc - rpcx:rpc-context-instance "test-rpc"; - - // root runtime bean - leaf created-sessions { - type uint32; - } - - container asdf { - leaf simpleInt { - type uint16; - } + container impl-netconf { + // rpc + rpcx:rpc-context-instance "test-rpc"; - leaf simpleString { - type string; + // root runtime bean + leaf created-sessions { + type uint32; } - } + container asdf { + leaf simpleInt { + type uint16; + } - list inner-running-data-additional { - config:inner-state-bean; + leaf simpleString { + type string; + } + } - // rpc - rpcx:rpc-context-instance "inner-test-rpc"; - key "simpleString"; + list inner-running-data-additional { + config:inner-state-bean; - leaf simple-int3 { - type uint16; - } + // rpc + rpcx:rpc-context-instance "inner-test-rpc"; - leaf simpleString { - type string; - } + key "simpleString"; - container deep4 { - leaf boool { - type boolean; + leaf simple-int3 { + type uint16; } - } - } - - list inner-running-data { - config:inner-state-bean; - key "simple-int3"; - - leaf simple-int3 { - type uint16; + leaf simpleString { + type string; } - container deep2 { - leaf boool { - type boolean; + container deep4 { + leaf boool { + type boolean; + } } - } + } - list inner-inner-running-data { + list inner-running-data { config:inner-state-bean; - rpcx:rpc-context-instance "inner-inner-test-rpc"; - rpcx:rpc-context-instance "complex-output-rpc"; - key "simple-int3"; leaf simple-int3 { - type uint16; - } + type uint16; + } - leaf-list list-of-strings { - type string; - } + container deep2 { + leaf boool { + type boolean; + } + } - list not-state-bean { - leaf element { - type string; + list inner-inner-running-data { + config:inner-state-bean; + + rpcx:rpc-context-instance "inner-inner-test-rpc"; + rpcx:rpc-context-instance "complex-output-rpc"; + + key "simple-int3"; + + leaf simple-int3 { + type uint16; } - list not-state-bean-internal { - // This should be ignored - config:inner-state-bean; + leaf-list list-of-strings { + type string; + } - leaf element2 { + list not-state-bean { + leaf element { type string; } + + list not-state-bean-internal { + // This should be ignored + config:inner-state-bean; + + leaf element2 { + type string; + } + } } - } - container deep3 { - leaf boool { - type boolean; + container deep3 { + leaf boool { + type boolean; + } } } } 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 cf9b4c1597..ff1d719c57 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 @@ -34,6 +34,7 @@ import org.opendaylight.controller.netconf.confignetconfconnector.operations.edi 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; +import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; @@ -43,11 +44,15 @@ public final class InstanceConfig { private static final Logger logger = LoggerFactory.getLogger(InstanceConfig.class); private final Map yangToAttrConfig; + private final String nullableDummyContainerName; private final Map jmxToAttrConfig; private final ConfigRegistryClient configRegistryClient; - public InstanceConfig(ConfigRegistryClient configRegistryClient, Map yangNamesToAttributes) { + public InstanceConfig(ConfigRegistryClient configRegistryClient, Map yangNamesToAttributes, + String nullableDummyContainerName) { + this.yangToAttrConfig = yangNamesToAttributes; + this.nullableDummyContainerName = nullableDummyContainerName; this.jmxToAttrConfig = reverseMap(yangNamesToAttributes); this.configRegistryClient = configRegistryClient; } @@ -83,20 +88,24 @@ public final class InstanceConfig { } public Element toXml(ObjectName on, String namespace, Document document, Element rootElement) { - Map strats = new ObjectXmlWriter().prepareWriting(yangToAttrConfig, document); - Map mappedConfig = getMappedConfiguration(on); - + Element parentElement; + if (nullableDummyContainerName != null) { + Element dummyElement = XmlUtil.createElement(document, nullableDummyContainerName, Optional.of(namespace)); + rootElement.appendChild(dummyElement); + parentElement = dummyElement; + } else { + parentElement = rootElement; + } for (Entry mappingEntry : mappedConfig.entrySet()) { try { - strats.get(mappingEntry.getKey()).writeElement(rootElement, namespace, mappingEntry.getValue()); + strats.get(mappingEntry.getKey()).writeElement(parentElement, namespace, mappingEntry.getValue()); } catch (Exception e) { throw new IllegalStateException("Unable to write value " + mappingEntry.getValue() + " for attribute " + mappingEntry.getValue(), e); } } - return rootElement; } @@ -132,22 +141,46 @@ public final class InstanceConfig { Map strats = new ObjectXmlReader().prepareReading(yangToAttrConfig, identityMap); List recognisedChildren = Lists.newArrayList(); - XmlElement type; - XmlElement name; - type = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY); - name = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.NAME_KEY); - List typeAndName = Lists.newArrayList(type, name); + XmlElement typeElement = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY); + XmlElement nameElement = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.NAME_KEY); + List typeAndNameElements = Lists.newArrayList(typeElement, nameElement); + + // if dummy container was defined in yang, set moduleElement to its content + if (nullableDummyContainerName != null) { + int size = moduleElement.getChildElements().size(); + int expectedChildNodes = 1 + typeAndNameElements.size(); + if (size > expectedChildNodes) { + throw new NetconfDocumentedException("Error reading module " + typeElement.getTextContent() + " : " + + nameElement.getTextContent() + " - Expected " + expectedChildNodes +" child nodes, " + + "one of them with name " + nullableDummyContainerName + + ", got " + size + " elements."); + } + if (size == expectedChildNodes) { + try { + moduleElement = moduleElement.getOnlyChildElement(nullableDummyContainerName, moduleNamespace); + } catch (NetconfDocumentedException e) { + throw new NetconfDocumentedException("Error reading module " + typeElement.getTextContent() + " : " + + nameElement.getTextContent() + " - Expected child node with name " + nullableDummyContainerName + + "." + e.getMessage()); + } + } // else 2 elements, no need to descend + } for (Entry readStratEntry : strats.entrySet()) { List configNodes = getConfigNodes(moduleElement, moduleNamespace, readStratEntry.getKey(), - recognisedChildren, typeAndName); + recognisedChildren, typeAndNameElements); AttributeConfigElement readElement = readStratEntry.getValue().readElement(configNodes); retVal.put(readStratEntry.getKey(), readElement); } - recognisedChildren.addAll(typeAndName); - moduleElement.checkUnrecognisedElements(recognisedChildren); - + recognisedChildren.addAll(typeAndNameElements); + try { + moduleElement.checkUnrecognisedElements(recognisedChildren); + } catch (NetconfDocumentedException e) { + throw new NetconfDocumentedException("Error reading module " + typeElement.getTextContent() + " : " + + nameElement.getTextContent() + " - " + + e.getMessage(), e.getErrorType(), e.getErrorTag(),e.getErrorSeverity(),e.getErrorInfo()); + } // TODO: add check for conflicts between global and local edit strategy String perInstanceEditStrategy = moduleElement.getAttribute(XmlNetconfConstants.OPERATION_ATTR_KEY, XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0); 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 ffc69eb8ef..319f539c25 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 @@ -273,8 +273,8 @@ public class EditConfig extends AbstractConfigNetconfOperation { String moduleName = moduleNameToMbe.getKey(); ModuleMXBeanEntry moduleMXBeanEntry = moduleNameToMbe.getValue(); - ModuleConfig moduleConfig = new ModuleConfig(moduleName, new InstanceConfig(configRegistryClient, - moduleMXBeanEntry.getAttributes())); + ModuleConfig moduleConfig = new ModuleConfig(moduleName, + new InstanceConfig(configRegistryClient,moduleMXBeanEntry.getAttributes(), moduleMXBeanEntry.getNullableDummyContainerName())); Map moduleNameToModuleConfig = namespaceToModuleNameToModuleConfig.get(namespace); if(moduleNameToModuleConfig == null) { diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java index 5e44427da3..48b4bbc2a8 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java @@ -62,7 +62,7 @@ public class Get extends AbstractConfigNetconfOperation { Map cache = Maps.newHashMap(); RuntimeBeanEntry root = null; for (RuntimeBeanEntry rbe : mbe.getRuntimeBeans()) { - cache.put(rbe, new InstanceConfig(configRegistryClient, rbe.getYangPropertiesToTypesMap())); + cache.put(rbe, new InstanceConfig(configRegistryClient, rbe.getYangPropertiesToTypesMap(), mbe.getNullableDummyContainerName())); if (rbe.isRoot()){ root = rbe; } diff --git a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java index 54b15a85b2..41301543a3 100644 --- a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java +++ b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java @@ -24,6 +24,7 @@ import static org.opendaylight.controller.netconf.util.xml.XmlUtil.readXmlToElem import com.google.common.base.Optional; import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; @@ -39,6 +40,7 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import javax.management.InstanceAlreadyExistsException; import javax.management.InstanceNotFoundException; @@ -75,6 +77,7 @@ import org.opendaylight.controller.config.yang.test.impl.IdentityTestModuleFacto import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleFactory; import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleMXBean; import org.opendaylight.controller.config.yang.test.impl.Peers; +import org.opendaylight.controller.config.yang.test.impl.TestImplModuleFactory; import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.operations.Commit; @@ -93,7 +96,6 @@ import org.opendaylight.controller.netconf.mapping.api.HandlingPriority; import org.opendaylight.controller.netconf.mapping.api.NetconfOperation; import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution; import org.opendaylight.controller.netconf.util.test.XmlFileLoader; -import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.test.types.rev131127.TestIdentity1; @@ -124,6 +126,7 @@ public class NetconfMappingTest extends AbstractConfigTest { private NetconfTestImplModuleFactory factory; private DepTestImplModuleFactory factory2; private IdentityTestModuleFactory factory3; + private TestImplModuleFactory factory4; @Mock YangStoreSnapshot yangStoreSnapshot; @@ -144,8 +147,9 @@ public class NetconfMappingTest extends AbstractConfigTest { this.factory = new NetconfTestImplModuleFactory(); this.factory2 = new DepTestImplModuleFactory(); this.factory3 = new IdentityTestModuleFactory(); + factory4 = new TestImplModuleFactory(); super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, this.factory, this.factory2, - this.factory3)); + this.factory3, factory4)); transactionProvider = new TransactionProvider(this.configRegistryClient, NETCONF_SESSION_ID); } @@ -423,42 +427,42 @@ public class NetconfMappingTest extends AbstractConfigTest { assertEquals(2, afterReplace); } - @Test(expected = NetconfDocumentedException.class) + @Test public void testSameAttrDifferentNamespaces() throws Exception { try { edit("netconfMessages/namespaces/editConfig_sameAttrDifferentNamespaces.xml"); + fail(); } catch (NetconfDocumentedException e) { String message = e.getMessage(); - assertContainsString(message, "Element simple-long-2 present multiple times with different namespaces"); + assertContainsString(message, "Element simpleInt present multiple times with different namespaces"); assertContainsString(message, TEST_NAMESPACE); assertContainsString(message, XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); - throw e; } } - @Test(expected = NetconfDocumentedException.class) + @Test public void testDifferentNamespaceInTO() throws Exception { try { edit("netconfMessages/namespaces/editConfig_differentNamespaceTO.xml"); + fail(); } catch (NetconfDocumentedException e) { String message = e.getMessage(); assertContainsString(message, "Unrecognised elements"); assertContainsString(message, "simple-int2"); assertContainsString(message, "dto_d"); - throw e; } } - @Test(expected = NetconfDocumentedException.class) + @Test public void testSameAttrDifferentNamespacesList() throws Exception { try { edit("netconfMessages/namespaces/editConfig_sameAttrDifferentNamespacesList.xml"); + fail(); } catch (NetconfDocumentedException e) { String message = e.getMessage(); - assertContainsString(message, "Element binaryLeaf present multiple times with different namespaces"); + assertContainsString(message, "Element allow-user present multiple times with different namespaces"); assertContainsString(message, TEST_NAMESPACE); assertContainsString(message, XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); - throw e; } } @@ -491,6 +495,7 @@ public class NetconfMappingTest extends AbstractConfigTest { for (int i = 0; i < TESTS_COUNT; i++) { String file = String.format(format, i + 1); + logger.info("Reading {}", file); try { edit(file); } catch (NetconfDocumentedException e) { @@ -564,23 +569,13 @@ public class NetconfMappingTest extends AbstractConfigTest { assertThat(string, JUnitMatchers.containsString(substring)); } - private void checkEnum(final Document response) throws NetconfDocumentedException { - XmlElement modulesElement = XmlElement.fromDomElement(response.getDocumentElement()).getOnlyChildElement("data") - .getOnlyChildElement("modules"); + private void checkEnum(final Document response) throws Exception { - String enumName = "extended-enum"; - String enumContent = "TWO"; + String expectedEnumContent = "TWO"; - for (XmlElement moduleElement : modulesElement.getChildElements("module")) { - String name = moduleElement.getOnlyChildElement("name").getTextContent(); - if(name.equals(INSTANCE_NAME)) { - XmlElement enumAttr = moduleElement.getOnlyChildElement(enumName); - assertEquals(enumContent, enumAttr.getTextContent()); - return; - } - } - - fail("Enum attribute " + enumName + ":" + enumContent + " not present in " + XmlUtil.toString(response)); + XMLAssert.assertXpathEvaluatesTo(expectedEnumContent, + getXpathForNetconfImplSubnode(INSTANCE_NAME,"extended-enum"), + response); } private void checkTestingDeps(Document response) { @@ -588,24 +583,23 @@ public class NetconfMappingTest extends AbstractConfigTest { assertEquals(2, testingDepsSize); } - private void checkTypeConfigAttribute(Document response) throws NetconfDocumentedException { - - XmlElement modulesElement = XmlElement.fromDomElement(response.getDocumentElement()).getOnlyChildElement("data") - .getOnlyChildElement("modules"); - - List expectedValues = Lists.newArrayList("default-string", "configAttributeType"); - Set configAttributeType = Sets.newHashSet(); + private String getXpathForNetconfImplSubnode(String instanceName, String subnode) { + return "/urn:ietf:params:xml:ns:netconf:base:1.0:rpc-reply" + + "/urn:ietf:params:xml:ns:netconf:base:1.0:data" + + "/urn:opendaylight:params:xml:ns:yang:controller:config:modules" + + "/module[name='"+instanceName+"']" + + "/urn:opendaylight:params:xml:ns:yang:controller:test:impl:impl-netconf" + + "/urn:opendaylight:params:xml:ns:yang:controller:test:impl:"+subnode; + } - for (XmlElement moduleElement : modulesElement.getChildElements("module")) { - for (XmlElement type : moduleElement.getChildElements("type")) { - if (type.getNamespaceOptionally().isPresent()) { - configAttributeType.add(type.getTextContent()); - } - } - } + private void checkTypeConfigAttribute(Document response) throws Exception { - for (String expectedValue : expectedValues) { - assertTrue(configAttributeType.contains(expectedValue)); + Map namesToTypeValues = ImmutableMap.of("instance-from-code", "configAttributeType", + "test2", "default-string"); + for (Entry nameToExpectedValue : namesToTypeValues.entrySet()) { + XMLAssert.assertXpathEvaluatesTo(nameToExpectedValue.getValue(), + getXpathForNetconfImplSubnode(nameToExpectedValue.getKey(),"type"), + response); } } diff --git a/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/NetconfDocumentedException.java b/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/NetconfDocumentedException.java index 57bd3dd620..1ecbc55b2a 100644 --- a/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/NetconfDocumentedException.java +++ b/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/NetconfDocumentedException.java @@ -62,6 +62,14 @@ public class NetconfDocumentedException extends Exception { private final ErrorSeverity errorSeverity; private final Map errorInfo; + public NetconfDocumentedException(String message) { + this(message, + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.invalid_value, + NetconfDocumentedException.ErrorSeverity.error + ); + } + public NetconfDocumentedException(final String message, final ErrorType errorType, final ErrorTag errorTag, final ErrorSeverity errorSeverity) { this(message, errorType, errorTag, errorSeverity, Collections. emptyMap()); diff --git a/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/test/XmlUnitUtil.java b/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/test/XmlUnitUtil.java index e8a453e5d3..e0d432f27c 100644 --- a/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/test/XmlUnitUtil.java +++ b/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/test/XmlUnitUtil.java @@ -16,6 +16,7 @@ import org.custommonkey.xmlunit.AbstractNodeTester; import org.custommonkey.xmlunit.NodeTest; import org.custommonkey.xmlunit.NodeTestException; import org.custommonkey.xmlunit.NodeTester; +import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -88,7 +89,7 @@ public class XmlUnitUtil { @Override public void noMoreNodes(NodeTest forTest) throws NodeTestException { - assertTrue(elementFound); + assertTrue(XmlUtil.toString(doc), elementFound); } }; assertNodeTestPasses(nt, tester, new short[]{Node.ELEMENT_NODE}, true); diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig.xml index 35cf2c6a14..5dd5a90f7d 100644 --- a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig.xml +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig.xml @@ -30,78 +30,79 @@ instance-from-code + + + 2.58 + - - 2.58 - + + 10 + - - 10 - + + 20 + - - 20 - + + TWO + - - TWO - + 44 + YmluYXJ5 - 44 - YmluYXJ5 - - configAttributeType - - 444 - 4444 - 454 - - 44 - - 4 - + configAttributeType + + 444 + 4444 + 454 + + 44 + + 4 + + 4 + 4 - - 4 - - 44 - 545 - 454545 - false - - - - 456 - - 44 - - - 4 - 999 - 4 - - port1 - 456 - 44 - - - port23 - 456 - 44 - - - prefix:testing - ref_dep_user - + + 44 + 545 + 454545 + false + + + + 456 + + 44 + + + 4 + 999 + 4 + + port1 + 456 + 44 + + + port23 + 456 + 44 + + + prefix:testing + ref_dep_user + - - prefix:testing - ref_dep_user - - - prefix:testing - ref_dep_user_two - + + prefix:testing + ref_dep_user + + + prefix:testing + ref_dep_user_two + + @@ -109,12 +110,13 @@ test-impl:impl-netconf test2 - 4 - - - prefix:testing - ref_dep_user_two - + + 4 + + prefix:testing + ref_dep_user_two + + diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_none.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_none.xml index ade40f6a49..be3155222a 100644 --- a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_none.xml +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_none.xml @@ -26,46 +26,48 @@ test-impl:impl-netconf instance-from-code - 44 - 8ad1 - - 444 - 4444 - 454 - - 44 - - 4 - + + 44 + 8ad1 + + 444 + 4444 + 454 + + 44 + + 4 + + 4 + 4 - - 4 - - 44 - 545 - 454545 - false - - - - 456 - - 44 - - - 4 - 999 - 4 - - port1 - 456 - 44 - - - port23 - 456 - 44 - + + 44 + 545 + 454545 + false + + + + 456 + + 44 + + + 4 + 999 + 4 + + port1 + 456 + 44 + + + port23 + 456 + 44 + + diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_setUnions.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_setUnions.xml index 21db4b8e42..3f088e48c9 100644 --- a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_setUnions.xml +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_setUnions.xml @@ -15,10 +15,10 @@ instance-from-code - - 127.1.2.3 - randomStringForUnion - + + 127.1.2.3 + randomStringForUnion + diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_differentNamespaceTO.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_differentNamespaceTO.xml index df2a5e8452..16947f9ec7 100644 --- a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_differentNamespaceTO.xml +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_differentNamespaceTO.xml @@ -30,52 +30,53 @@ test1 - - 44 - 8545649856 - configAttributeType - - 444 - 4444 - 454 - - 44 - - 4 - + + 44 + 8545649856 + configAttributeType + + 444 + 4444 + 454 + + 44 + + 4 + + 4 + 4 - - 4 - - 44 - 545 - 454545 - false - - - - 456 - - 44 - - - 4 - 999 - 4 - - port1 - 456 - 44 - - - port23 - 456 - 44 - - - prefix:testing - ref_dep - + + 44 + 545 + 454545 + false + + + + 456 + + 44 + + + 4 + 999 + 4 + + port1 + 456 + 44 + + + port23 + 456 + 44 + + + prefix:testing + ref_dep + + @@ -83,10 +84,12 @@ test-impl:impl-netconf test2 - - prefix:testing - ref_dep - + + + prefix:testing + ref_dep + + diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_sameAttrDifferentNamespaces.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_sameAttrDifferentNamespaces.xml index c399c196d3..3dbaef4042 100644 --- a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_sameAttrDifferentNamespaces.xml +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_sameAttrDifferentNamespaces.xml @@ -24,61 +24,70 @@ + + + test-impl:impl + + + testimpl + 1 + 2 + + test-impl:impl-netconf test1 - - 44 - 44 - 8 - 1 - 0 - configAttributeType - - 444 - 4444 - 454 - - 44 - - 4 - + + 44 + 44 + + configAttributeType + + 444 + 4444 + 454 + + 44 + + 4 + + 4 + 4 - - 4 - - 44 - 545 - 454545 - false - - - - 456 - - 44 - - - 4 - 999 - 4 - - port1 - 456 - 44 - - - port23 - 456 - 44 - - - prefix:testing - ref_dep - + + 44 + 545 + 454545 + false + + + + 456 + + 44 + + + 4 + 999 + 4 + + port1 + 456 + 44 + + + port23 + 456 + 44 + + + prefix:testing + ref_dep + + @@ -86,10 +95,12 @@ test-impl:impl-netconf test2 - - prefix:testing - ref_dep - + + + prefix:testing + ref_dep + + diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_sameAttrDifferentNamespacesList.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_sameAttrDifferentNamespacesList.xml index 47b82c6114..6ee97ee09c 100644 --- a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_sameAttrDifferentNamespacesList.xml +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_sameAttrDifferentNamespacesList.xml @@ -26,58 +26,12 @@ - test-impl:impl-netconf + test-impl:impl test1 - - 44 - 8 - 1 - 0 - configAttributeType - - 444 - 4444 - 454 - - 44 - - 4 - - 4 - - 4 - - 44 - 545 - 454545 - false - - - - 456 - - 44 - - - 4 - 999 - 4 - - port1 - 456 - 44 - - - port23 - 456 - 44 - - - prefix:testing - ref_dep - + 1 + 2 @@ -85,33 +39,17 @@ test-impl:impl-netconf test2 - - prefix:testing - ref_dep - + + + prefix:testing + ref_dep + + - - prefix:testing - - ref_dep - /modules/module[type='impl-dep'][name='dep'] - - - - ref_dep_2 - /modules/module[type='impl-dep'][name='dep2'] - - - - ref_test1 - - /modules/module[type='impl-netconf'][name='test1'] - - - + diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_typeNameConfigAttributeMatching.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_typeNameConfigAttributeMatching.xml index 02aca8d787..1e5c6da79c 100644 --- a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_typeNameConfigAttributeMatching.xml +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_typeNameConfigAttributeMatching.xml @@ -30,51 +30,52 @@ test1 - - 44 - 8545649856 - - 444 - 4444 - 454 - - 44 - - 4 - + + 44 + 8545649856 + + 444 + 4444 + 454 + + 44 + + 4 + + 4 + 4 - - 4 - - 44 - 545 - 454545 - false - - - - 456 - - 44 - - - 4 - 999 - 4 - - port1 - 456 - 44 - - - port23 - 456 - 44 - - - prefix:testing - ref_dep - + + 44 + 545 + 454545 + false + + + + 456 + + 44 + + + 4 + 999 + 4 + + port1 + 456 + 44 + + + port23 + 456 + 44 + + + prefix:testing + ref_dep + + @@ -82,10 +83,12 @@ test-impl:impl-netconf test2 - - prefix:testing - ref_dep - + + + prefix:testing + ref_dep + + diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/unrecognised/editConfig_unrecognised7.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/unrecognised/editConfig_unrecognised7.xml index 825be6d19f..156c111408 100644 --- a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/unrecognised/editConfig_unrecognised7.xml +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/unrecognised/editConfig_unrecognised7.xml @@ -30,52 +30,53 @@ test1 - - 44 - 8545649856 - - error - 444 - 4444 - 454 - - 44 - - 4 - + + 44 + 8545649856 + + error + 444 + 4444 + 454 + + 44 + + 4 + + 4 + 4 - - 4 - - 44 - 545 - 454545 - false - - - - 456 - - 44 - - - 4 - 999 - 4 - - port1 - 456 - 44 - - - port23 - 456 - 44 - - - prefix:testing - ref_dep - + + 44 + 545 + 454545 + false + + + + 456 + + 44 + + + 4 + 999 + 4 + + port1 + 456 + 44 + + + port23 + 456 + 44 + + + prefix:testing + ref_dep + + @@ -83,10 +84,12 @@ test-impl:impl-netconf test2 - - prefix:testing - ref_dep - + + + prefix:testing + ref_dep + + diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/unrecognised/editConfig_unrecognised8.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/unrecognised/editConfig_unrecognised8.xml index 9ef2bed7d7..9b9157e65a 100644 --- a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/unrecognised/editConfig_unrecognised8.xml +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/unrecognised/editConfig_unrecognised8.xml @@ -30,52 +30,53 @@ test1 - - 44 - 8545649856 - - 444 - 4444 - 454 - - 44 - - 4 - + + 44 + 8545649856 + + 444 + 4444 + 454 + + 44 + + 4 + + 4 + 4 - - 4 - - 44 - 545 - 454545 - false - - - - 456 - - 44 - - - 4 - 999 - 4 - - port1 - 456 - 44 - - - port23 - 456 - 44 - error - - - prefix:testing - ref_dep - + + 44 + 545 + 454545 + false + + + + 456 + + 44 + + + 4 + 999 + 4 + + port1 + 456 + 44 + + + port23 + 456 + 44 + error + + + prefix:testing + ref_dep + + @@ -83,10 +84,12 @@ test-impl:impl-netconf test2 - - prefix:testing - ref_dep - + + + prefix:testing + ref_dep + +