BUG-2453 Enable nested enums in configuration 46/21146/3
authorMaros Marsalek <mmarsale@cisco.com>
Tue, 26 May 2015 15:18:30 +0000 (17:18 +0200)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 28 May 2015 14:13:02 +0000 (14:13 +0000)
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 <mmarsale@cisco.com>
opendaylight/config/yang-test/src/main/yang/config-test-impl.yang
opendaylight/config/yang-test/src/main/yang/types/test-groups.yang
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/AbstractAttributeResolvingStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ArrayAttributeResolvingStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/CompositeAttributeResolvingStrategy.java
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java
opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig.xml

index aff7c86fe4cf0b862d759d45e256aa321f57260c..06b874c9b5c9b7ef513dda95507ed9b16350c71c 100644 (file)
@@ -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==;
index 00f704bed61cbb8b01594450846ec032215b2d56..a9cac89acb147641d6389773eaf76ef559a413c7 100644 (file)
@@ -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;
 
index 2808d5dfff20a87738b07d0d29730497bc3b5ac7..5763ed8caf4349496556b34e90f2f4f201de7fd3 100644 (file)
@@ -11,7 +11,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attri
 import javax.management.openmbean.OpenType;
 
 abstract class AbstractAttributeResolvingStrategy<T, O extends OpenType<?>> implements AttributeResolvingStrategy<T, O> {
-    private final O openType;
+    private O openType;
 
     public AbstractAttributeResolvingStrategy(O openType) {
         this.openType = openType;
@@ -21,4 +21,11 @@ abstract class AbstractAttributeResolvingStrategy<T, O extends OpenType<?>> 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;
+    }
 }
index a6a521a3dda35db05ba5de02a871bc772aa0f7ed..9c17fa4892df1ef5ab4298ca1f5da8fb39dec27a 100644 (file)
@@ -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<Object>(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));
 
index 9cd2eec0260d180d10242466cee5462162468605..51eb20589899d4d0448a4ef0f6485d41e43da7e5 100644 (file)
@@ -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<String, Object> items = Maps.newHashMap();
         Map<String, OpenType<?>> 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;
     }
+
+
 }
index ec09cfa7a9c17d6a78639072041baa8b8d391add..f95e13dd01180e3ce91c78d78eab14045c1d12b7 100644 (file)
@@ -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;
     }
 
index 761225015e8e3e44c8dd340f092d5fe7cadf8bed..36efd9cc34a86e3dd57a113689919a09e26fb35e 100644 (file)
 
                     <name>instance-from-code</name>
                     <impl-netconf xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
+
+                        <from-grouping>
+                            <enum-in-grouping>version1</enum-in-grouping>
+                        </from-grouping>
                         <sleep-factor>
                             2.58
                         </sleep-factor>