From 7d4251f30d145d8b402e206a11fb4a2ff90ac351 Mon Sep 17 00:00:00 2001 From: Maros Marsalek Date: Tue, 26 May 2015 17:18:30 +0200 Subject: [PATCH] BUG-2453 Enable nested enums in configuration Nested enums could not be pushed due to an open type issue. Enums had a composite open type, where the class name of the enum was stored. JMX was not happy with this open type and expected a SimpleType.STRING. After the enum is resolved, the open type is changed to SimpleType. Change-Id: Ifce5bec70c8c3973f560260e93fadba2bd1119fa Signed-off-by: Maros Marsalek --- .../src/main/yang/config-test-impl.yang | 4 +++ .../src/main/yang/types/test-groups.yang | 27 +++++++++++++++++++ .../AbstractAttributeResolvingStrategy.java | 9 ++++++- .../ArrayAttributeResolvingStrategy.java | 12 +++++++++ .../CompositeAttributeResolvingStrategy.java | 27 +++++++++++++++++-- .../NetconfMappingTest.java | 2 ++ .../resources/netconfMessages/editConfig.xml | 4 +++ 7 files changed, 82 insertions(+), 3 deletions(-) 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 aff7c86fe4..06b874c9b5 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 @@ -169,7 +169,11 @@ module config-test-impl { augment "/config:modules/config:module/config:configuration" { case impl-netconf { when "/config:modules/config:module/config:type = 'impl-netconf'"; + container impl-netconf { + + uses tg:config-grouping; + leaf binaryLeaf { type binary; default ZGVmYXVsdEJpbg==; diff --git a/opendaylight/config/yang-test/src/main/yang/types/test-groups.yang b/opendaylight/config/yang-test/src/main/yang/types/test-groups.yang index 00f704bed6..a9cac89acb 100644 --- a/opendaylight/config/yang-test/src/main/yang/types/test-groups.yang +++ b/opendaylight/config/yang-test/src/main/yang/types/test-groups.yang @@ -15,6 +15,33 @@ module test-groups { rpcx:rpc-context-instance common-rpc-ctx-two; } + typedef version { + type enumeration { + enum version1 { + value 1; + } + enum version2 { + value 2; + } + enum version3 { + value 3; + } + enum version4 { + value 4; + } + } + } + + grouping config-grouping { + + container from-grouping { + leaf enum-in-grouping { + type version; + } + } + } + + identity common-rpc-ctx; identity common-rpc-ctx-two; diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/AbstractAttributeResolvingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/AbstractAttributeResolvingStrategy.java index 2808d5dfff..5763ed8caf 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/AbstractAttributeResolvingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/AbstractAttributeResolvingStrategy.java @@ -11,7 +11,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attri import javax.management.openmbean.OpenType; abstract class AbstractAttributeResolvingStrategy> implements AttributeResolvingStrategy { - private final O openType; + private O openType; public AbstractAttributeResolvingStrategy(O openType) { this.openType = openType; @@ -21,4 +21,11 @@ abstract class AbstractAttributeResolvingStrategy> impl public O getOpenType() { return openType; } + + /** + * Composite types might change during resolution. Use this setter to update open type + */ + public void setOpenType(final O openType) { + this.openType = openType; + } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ArrayAttributeResolvingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ArrayAttributeResolvingStrategy.java index a6a521a3dd..9c17fa4892 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ArrayAttributeResolvingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ArrayAttributeResolvingStrategy.java @@ -14,6 +14,7 @@ import java.util.List; import javax.management.openmbean.ArrayType; import javax.management.openmbean.CompositeDataSupport; import javax.management.openmbean.CompositeType; +import javax.management.openmbean.OpenDataException; import javax.management.openmbean.OpenType; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.util.Util; @@ -73,6 +74,17 @@ final class ArrayAttributeResolvingStrategy extends AbstractAttributeResolvingSt i++; } + // Rebuild open type. Underlying composite types might have changed + if (innerTypeResolvingStrategy.getOpenType() instanceof CompositeType) { + try { + final ArrayType openType = new ArrayType(getOpenType().getDimension(), innerTypeResolvingStrategy.getOpenType()); + setOpenType(openType); + } catch (OpenDataException e) { + throw new IllegalStateException("An error occurred during restoration of array type " + this + + " for attribute " + attrName + " from value " + value, e); + } + } + LOG.debug("Attribute {} : {} parsed to type {} as {}", attrName, value, getOpenType(), toStringArray(parsedArray)); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/CompositeAttributeResolvingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/CompositeAttributeResolvingStrategy.java index 9cd2eec026..51eb205898 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/CompositeAttributeResolvingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/CompositeAttributeResolvingStrategy.java @@ -16,6 +16,7 @@ import javax.management.openmbean.CompositeDataSupport; import javax.management.openmbean.CompositeType; import javax.management.openmbean.OpenDataException; import javax.management.openmbean.OpenType; +import javax.management.openmbean.SimpleType; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.util.Util; import org.slf4j.Logger; @@ -54,6 +55,10 @@ class CompositeAttributeResolvingStrategy extends Map items = Maps.newHashMap(); Map> openTypes = Maps.newHashMap(); + final String[] names = new String[getOpenType().keySet().size()]; + OpenType[] itemTypes = new OpenType[names.length]; + int i = 0; + for (Object innerAttrName : innerTypes.keySet()) { Preconditions.checkState(innerAttrName instanceof String, "Attribute name must be string"); String innerAttrNameStr = (String) innerAttrName; @@ -65,17 +70,32 @@ class CompositeAttributeResolvingStrategy extends Optional parsedInnerValue = attributeResolvingStrategy.parseAttribute(innerAttrNameStr, valueToParse); - openTypes.put(innerAttrNameStr, attributeResolvingStrategy.getOpenType()); + if(attributeResolvingStrategy instanceof EnumAttributeResolvingStrategy) { + // Open type for enum contain the class name necessary for its resolution, however in a DTO + // the open type need to be just SimpleType.STRING so that JMX is happy + // After the enum attribute is resolved, change its open type back to STRING + openTypes.put(innerAttrNameStr, SimpleType.STRING); + } else { + openTypes.put(innerAttrNameStr, attributeResolvingStrategy.getOpenType()); + } items.put(yangToJavaAttrMapping.get(innerAttrNameStr), parsedInnerValue.isPresent() ? parsedInnerValue.get() : null); + + // fill names + item types in order to reconstruct the open type for current attribute + names[i] = yangToJavaAttrMapping.get(innerAttrNameStr); + itemTypes[i] = openTypes.get(innerAttrNameStr); + i++; } CompositeDataSupport parsedValue; try { + LOG.trace("Attribute {} with open type {}. Reconstructing open type.", attrName, getOpenType()); + setOpenType(new CompositeType(getOpenType().getTypeName(), getOpenType().getDescription(), names, names, itemTypes)); + LOG.debug("Attribute {} with open type {}. Open type reconstructed to {}", attrName, getOpenType(), getOpenType()); parsedValue = new CompositeDataSupport(getOpenType(), items); } catch (OpenDataException e) { - throw new IllegalStateException("An error occured during restoration of composite type " + this + throw new IllegalStateException("An error occurred during restoration of composite type " + this + " for attribute " + attrName + " from value " + value, e); } @@ -84,7 +104,10 @@ class CompositeAttributeResolvingStrategy extends return Optional.of(parsedValue); } + protected Map preprocessValueMap(Map valueMap) { return valueMap; } + + } 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 ec09cfa7a9..f95e13dd01 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 @@ -686,6 +686,8 @@ public class NetconfMappingTest extends AbstractConfigTest { // Enum constants mapping from yang -> Java and back enumBiMap.put("one", "One"); enumBiMap.put("two", "Two"); + enumBiMap.put("version1", "Version1"); + enumBiMap.put("version2", "Version2"); return enumBiMap; } 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 761225015e..36efd9cc34 100644 --- a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig.xml +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig.xml @@ -31,6 +31,10 @@ instance-from-code + + + version1 + 2.58 -- 2.36.6