From 7d402c78624fbd9968ad6e1f6295527dbc387821 Mon Sep 17 00:00:00 2001 From: Milos Fabian Date: Mon, 9 Dec 2013 15:27:45 +0100 Subject: [PATCH] Added conflict handling between configuration and state choice nodes. -unique node naming required Change-Id: I7db0a094d8abbd4c1616b6a01a22ac201e91ad64 Signed-off-by: Milos Fabian --- .../yangjmxgenerator/ModuleMXBeanEntry.java | 121 +++++++++++------- .../ModuleMXBeanEntryNameConflictTest.java | 3 + ...icate-attribute-in-runtime-and-mxbean.yang | 57 +++++++++ 3 files changed, 136 insertions(+), 45 deletions(-) create mode 100644 opendaylight/config/yang-jmx-generator/src/test/resources/duplicates/config-test-duplicate-attribute-in-runtime-and-mxbean.yang 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 a7110b874c..4eba739b46 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 @@ -7,9 +7,21 @@ */ package org.opendaylight.controller.config.yangjmxgenerator; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Optional; -import com.google.common.collect.Sets; +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 java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + import org.opendaylight.controller.config.yangjmxgenerator.attribute.AbstractDependencyAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc; import org.opendaylight.controller.config.yangjmxgenerator.attribute.DependencyAttribute; @@ -41,20 +53,9 @@ import org.opendaylight.yangtools.yang.model.api.UsesNode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -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.Optional; +import com.google.common.collect.Sets; /** * Represents part of yang model that describes a module. @@ -184,8 +185,9 @@ public class ModuleMXBeanEntry extends AbstractEntry { } /** - * @return services implemented by this module. Keys are fully qualified java names of generated - * ServiceInterface classes, values are identity local names. + * @return services implemented by this module. Keys are fully qualified + * java names of generated ServiceInterface classes, values are + * identity local names. */ public Map getProvidedServices() { return providedServices; @@ -360,7 +362,6 @@ public class ModuleMXBeanEntry extends AbstractEntry { e.getConflictingName(), when.getQName(), when.getQName()); } - checkUniqueRuntimeBeansGeneratedClasses( uniqueGeneratedClassesNames, when, runtimeBeans); Set runtimeBeanEntryValues = Sets @@ -415,6 +416,11 @@ public class ModuleMXBeanEntry extends AbstractEntry { . emptyList()); } } + // check attributes name uniqueness + for (Entry entry : result.entrySet()) { + checkUniqueRuntimeBeanAttributesName(entry.getValue(), + uniqueGeneratedClassesNames); + } if (unaugmentedModuleIdentities.size() > 0) { logger.warn("Augmentation not found for all module identities: {}", unaugmentedModuleIdentities.keySet()); @@ -443,6 +449,25 @@ public class ModuleMXBeanEntry extends AbstractEntry { } } + private static void checkUniqueRuntimeBeanAttributesName( + ModuleMXBeanEntry mxBeanEntry, + Map uniqueGeneratedClassesNames) { + for (RuntimeBeanEntry runtimeBeanEntry : mxBeanEntry.getRuntimeBeans()) { + for (String runtimeAttName : runtimeBeanEntry + .getYangPropertiesToTypesMap().keySet()) { + if (mxBeanEntry.getAttributes().keySet() + .contains(runtimeAttName)) { + QName qName1 = uniqueGeneratedClassesNames + .get(runtimeBeanEntry.getJavaNameOfRuntimeMXBean()); + QName qName2 = uniqueGeneratedClassesNames.get(mxBeanEntry + .getGloballyUniqueName()); + throw new NameConflictException(runtimeAttName, qName1, + qName2); + } + } + } + } + private static void checkUniqueAttributesWithGeneratedClass( Map uniqueGeneratedClassNames, QName parentQName, Map yangToAttributes) { @@ -566,7 +591,8 @@ public class ModuleMXBeanEntry extends AbstractEntry { private static AttributeIfc getAttributeValue(DataSchemaNode attrNode, Module currentModule, Map qNamesToSIEs, - TypeProviderWrapper typeProviderWrapper, SchemaContext schemaContext, String packageName) { + TypeProviderWrapper typeProviderWrapper, + SchemaContext schemaContext, String packageName) { if (attrNode instanceof LeafSchemaNode) { // simple type @@ -575,12 +601,14 @@ public class ModuleMXBeanEntry extends AbstractEntry { } else if (attrNode instanceof ContainerSchemaNode) { // reference or TO ContainerSchemaNode containerSchemaNode = (ContainerSchemaNode) attrNode; - Optional dependencyAttributeOptional = extractDependency(containerSchemaNode, - attrNode, currentModule, qNamesToSIEs, schemaContext); + Optional dependencyAttributeOptional = extractDependency( + containerSchemaNode, attrNode, currentModule, qNamesToSIEs, + schemaContext); if (dependencyAttributeOptional.isPresent()) { return dependencyAttributeOptional.get(); } else { - return TOAttribute.create(containerSchemaNode, typeProviderWrapper, packageName); + return TOAttribute.create(containerSchemaNode, + typeProviderWrapper, packageName); } } else if (attrNode instanceof LeafListSchemaNode) { @@ -588,12 +616,14 @@ public class ModuleMXBeanEntry extends AbstractEntry { typeProviderWrapper); } else if (attrNode instanceof ListSchemaNode) { ListSchemaNode listSchemaNode = (ListSchemaNode) attrNode; - Optional dependencyAttributeOptional = extractDependency(listSchemaNode, - attrNode, currentModule, qNamesToSIEs, schemaContext); + Optional dependencyAttributeOptional = extractDependency( + listSchemaNode, attrNode, currentModule, qNamesToSIEs, + schemaContext); if (dependencyAttributeOptional.isPresent()) { return dependencyAttributeOptional.get(); } else { - return ListAttribute.create(listSchemaNode, typeProviderWrapper, packageName); + return ListAttribute.create(listSchemaNode, + typeProviderWrapper, packageName); } } else { throw new UnsupportedOperationException( @@ -601,16 +631,15 @@ public class ModuleMXBeanEntry extends AbstractEntry { } } - private static Optional extractDependency(DataNodeContainer dataNodeContainer, - DataSchemaNode attrNode, - Module currentModule, - Map qNamesToSIEs, - SchemaContext schemaContext) { + private static Optional extractDependency( + DataNodeContainer dataNodeContainer, DataSchemaNode attrNode, + Module currentModule, + Map qNamesToSIEs, + SchemaContext schemaContext) { if (dataNodeContainer.getUses().size() == 1 && getChildNodeSizeWithoutUses(dataNodeContainer) == 0) { // reference - UsesNode usesNode = dataNodeContainer.getUses().iterator() - .next(); + UsesNode usesNode = dataNodeContainer.getUses().iterator().next(); checkState(usesNode.getRefines().size() == 1, "Unexpected 'refine' child node size of " + dataNodeContainer); @@ -618,26 +647,28 @@ public class ModuleMXBeanEntry extends AbstractEntry { .values().iterator().next(); checkState(refine.getUnknownSchemaNodes().size() == 1, "Unexpected unknown schema node size of " + refine); - UnknownSchemaNode requiredIdentity = refine - .getUnknownSchemaNodes().iterator().next(); + UnknownSchemaNode requiredIdentity = refine.getUnknownSchemaNodes() + .iterator().next(); checkState( ConfigConstants.REQUIRED_IDENTITY_EXTENSION_QNAME.equals(requiredIdentity - .getNodeType()), - "Unexpected language extension " + requiredIdentity); + .getNodeType()), "Unexpected language extension " + + requiredIdentity); String prefixAndIdentityLocalName = requiredIdentity .getNodeParameter(); // import should point to a module ServiceInterfaceEntry serviceInterfaceEntry = findSIE( - prefixAndIdentityLocalName, currentModule, - qNamesToSIEs, schemaContext); + prefixAndIdentityLocalName, currentModule, qNamesToSIEs, + schemaContext); boolean mandatory = refine.getConstraints().isMandatory(); AbstractDependencyAttribute reference; - if (dataNodeContainer instanceof ContainerSchemaNode ){ - reference = new DependencyAttribute(attrNode, serviceInterfaceEntry, - mandatory, attrNode.getDescription()); + if (dataNodeContainer instanceof ContainerSchemaNode) { + reference = new DependencyAttribute(attrNode, + serviceInterfaceEntry, mandatory, + attrNode.getDescription()); } else { - reference = new ListDependenciesAttribute(attrNode, serviceInterfaceEntry, - mandatory, attrNode.getDescription()); + reference = new ListDependenciesAttribute(attrNode, + serviceInterfaceEntry, mandatory, + attrNode.getDescription()); } return Optional.of(reference); } diff --git a/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryNameConflictTest.java b/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryNameConflictTest.java index deef08a292..9032a2c930 100644 --- a/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryNameConflictTest.java +++ b/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryNameConflictTest.java @@ -100,6 +100,9 @@ public class ModuleMXBeanEntryNameConflictTest extends AbstractYangTest { testedYangModulesToExpectedConflictingName.put( "config-test-runtime-bean-name-conflict2", "StateARuntimeMXBean"); + testedYangModulesToExpectedConflictingName.put( + "config-test-duplicate-attribute-in-runtime-and-mxbean", + "port"); } private String getYangModuleName(String name) { diff --git a/opendaylight/config/yang-jmx-generator/src/test/resources/duplicates/config-test-duplicate-attribute-in-runtime-and-mxbean.yang b/opendaylight/config/yang-jmx-generator/src/test/resources/duplicates/config-test-duplicate-attribute-in-runtime-and-mxbean.yang new file mode 100644 index 0000000000..58c3af262c --- /dev/null +++ b/opendaylight/config/yang-jmx-generator/src/test/resources/duplicates/config-test-duplicate-attribute-in-runtime-and-mxbean.yang @@ -0,0 +1,57 @@ +// vi: set smarttab et sw=4 tabstop=4: +module config-test-duplicate-attribute-in-runtime-and-mxbean { + yang-version 1; + namespace "urn:opendaylight:params:xml:ns:yang:controller:jmx:duplicate:runtime"; + prefix "th-java"; + + import config { prefix config; revision-date 2013-04-05; } + import rpc-context { prefix rpcx; revision-date 2013-06-17; } + import ietf-inet-types { prefix inet; revision-date 2010-09-24;} + + + description + "This module contains the base YANG definitions for NS-OS + thread services pure Java implementation."; + + revision "2013-04-05" { + description + "Updated to work with new anchors."; + } + + revision "2013-04-03" { + description + "Initial revision."; + } + + identity async-eventbus { + base config:module-type; + config:java-name-prefix AsyncEventBus; + } + + augment "/config:modules/config:module/config:configuration" { + case async-eventbus { + when "/config:modules/config:module/config:type = 'async-eventbus'"; + leaf port { + type string; + } + leaf core-size { + type uint32; + } + leaf simple-int3 { + type uint16; + } + } + } + + augment "/config:modules/config:module/config:state" { + case async-eventbus { + when "/config:modules/config:module/config:type = 'async-eventbus'"; + leaf simple-arg { + type uint32; + } + leaf port { + type inet:port-number; + } + } + } +} \ No newline at end of file -- 2.36.6