BUG-2453 (De)Serialize enum values as defined in yang 25/20025/10
authorMaros Marsalek <mmarsale@cisco.com>
Mon, 11 May 2015 14:53:19 +0000 (16:53 +0200)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 28 May 2015 14:38:39 +0000 (14:38 +0000)
Netconf endpoint for config subsystem did not (de)serialize enum values properly
It assumed the enum constants are identical in yang and in generated binding

Change-Id: If46c770a49653348201cd5d5c9303b5207048252
Signed-off-by: Maros Marsalek <mmarsale@cisco.com>
33 files changed:
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/RefreshingSCPModuleInfoRegistry.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/osgi/RefreshingSCPModuleInfoRegistryTest.java
opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/JavaAttribute.java
opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/SimpleTypeResolver.java
opendaylight/config/yang-test/src/main/yang/config-test-impl.yang
opendaylight/config/yang-test/src/main/yang/types/test-types.yang
opendaylight/netconf/config-netconf-connector/pom.xml
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributeIfcSwitchStatement.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/EnumAttributeMappingStrategy.java [new file with mode: 0644]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/EnumAttributeResolvingStrategy.java [new file with mode: 0644]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectXmlWriter.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/InstanceRuntimeRpc.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/ModuleRpcs.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/InstanceRuntime.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/Activator.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/EnumResolver.java [new file with mode: 0644]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/YangStoreContext.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/YangStoreService.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/YangStoreSnapshot.java
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/AbstractNetconfConfigTest.java
opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig.xml

index d4add50..90b3357 100644 (file)
@@ -12,6 +12,7 @@ import java.util.Hashtable;
 import org.opendaylight.yangtools.concepts.ObjectRegistration;
 import org.opendaylight.yangtools.sal.binding.generator.api.ClassLoadingStrategy;
 import org.opendaylight.yangtools.sal.binding.generator.api.ModuleInfoRegistry;
+import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
 import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
 import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
 import org.osgi.framework.BundleContext;
@@ -40,7 +41,10 @@ public class RefreshingSCPModuleInfoRegistry implements ModuleInfoRegistry, Auto
 
     private void updateService() {
         bindingContextProvider.update(classLoadingStrat, schemaContextProvider);
-        osgiReg.setProperties(null); // send modifiedService event
+        osgiReg.setProperties(new Hashtable<String, Object>() {{
+                put(BindingRuntimeContext.class.getName(), bindingContextProvider.getBindingContext());
+            }
+        }); // send modifiedService event
     }
 
     @Override
index bb2d9c7..850b45c 100644 (file)
@@ -1,5 +1,6 @@
 package org.opendaylight.controller.config.manager.impl.osgi;
 
+import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
@@ -13,6 +14,7 @@ import org.opendaylight.controller.config.manager.impl.osgi.mapping.RefreshingSC
 import org.opendaylight.yangtools.concepts.ObjectRegistration;
 import org.opendaylight.yangtools.sal.binding.generator.api.ClassLoadingStrategy;
 import org.opendaylight.yangtools.sal.binding.generator.api.ModuleInfoRegistry;
+import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
 import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
 import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
 import org.osgi.framework.BundleContext;
@@ -26,16 +28,19 @@ public class RefreshingSCPModuleInfoRegistryTest {
         doReturn("string").when(prov).toString();
         BundleContext ctxt = mock(BundleContext.class);
         ServiceRegistration<?> servReg = mock(ServiceRegistration.class);
-        doReturn(servReg).when(ctxt).registerService(Mockito.any(Class.class), Mockito.any(SchemaContextProvider.class), Mockito.any(Dictionary.class));
-        doReturn(servReg).when(ctxt).registerService(Mockito.anyString(), Mockito.any(Object.class), Mockito.any(Dictionary.class));
+        doReturn(servReg).when(ctxt).registerService(any(Class.class), any(SchemaContextProvider.class), any(Dictionary.class));
+        doReturn(servReg).when(ctxt).registerService(Mockito.anyString(), any(Object.class), any(Dictionary.class));
+        doNothing().when(servReg).setProperties(any(Dictionary.class));
 
         final ClassLoadingStrategy classLoadingStrat = mock(ClassLoadingStrategy.class);
         final BindingContextProvider codecRegistryProvider = mock(BindingContextProvider.class);
         doNothing().when(codecRegistryProvider).update(classLoadingStrat, prov);
+        final BindingRuntimeContext bindingRuntimeContext = mock(BindingRuntimeContext.class);
+        doReturn("B-runtime-context").when(bindingRuntimeContext).toString();
+        doReturn(bindingRuntimeContext).when(codecRegistryProvider).getBindingContext();
 
         RefreshingSCPModuleInfoRegistry scpreg = new RefreshingSCPModuleInfoRegistry(reg, prov, classLoadingStrat, codecRegistryProvider, ctxt);
 
-        doNothing().when(servReg).setProperties(null);
         doNothing().when(servReg).unregister();
 
         YangModuleInfo modInfo = mock(YangModuleInfo.class);
@@ -49,7 +54,7 @@ public class RefreshingSCPModuleInfoRegistryTest {
 
         scpreg.close();
 
-        Mockito.verify(servReg, Mockito.times(1)).setProperties(null);
+        Mockito.verify(servReg, Mockito.times(1)).setProperties(any(Dictionary.class));
         Mockito.verify(servReg, Mockito.times(1)).unregister();
     }
 }
index 6a90439..d830e97 100644 (file)
@@ -21,6 +21,7 @@ import org.opendaylight.yangtools.sal.binding.model.api.Type;
 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
 
@@ -60,6 +61,11 @@ public class JavaAttribute extends AbstractAttribute implements TypedAttribute {
         return base instanceof UnionTypeDefinition;
     }
 
+    public boolean isEnum() {
+        TypeDefinition<?> base = getBaseType(typeProviderWrapper, typeDefinition);
+        return base instanceof EnumTypeDefinition;
+    }
+
     public TypeDefinition<?> getTypeDefinition() {
         return typeDefinition;
     }
@@ -149,8 +155,8 @@ public class JavaAttribute extends AbstractAttribute implements TypedAttribute {
 
         if (isArray()) {
             return getArrayType();
-        } else if (isEnum(baseType)) {
-            return getSimpleType(baseType);
+        } else if (isEnum()) {
+            return getEnumType(baseTypeDefinition);
         } else if (isUnion()) {
             return getCompositeTypeForUnion(baseTypeDefinition);
         } else if (isDerivedType(baseType, getType())) {
@@ -162,6 +168,18 @@ public class JavaAttribute extends AbstractAttribute implements TypedAttribute {
         return getSimpleType(getType());
     }
 
+    private OpenType<?> getEnumType(final TypeDefinition<?> baseType) {
+        final String fullyQualifiedName = typeProviderWrapper.getType(node, getTypeDefinition()).getFullyQualifiedName();
+        final String[] items = {"instance"};
+        String description = getNullableDescription() == null ? getAttributeYangName() : getNullableDescription();
+
+        try {
+            return new CompositeType(fullyQualifiedName, description, items, items, new OpenType[]{SimpleType.STRING});
+        } catch (OpenDataException e) {
+            throw new RuntimeException("Unable to create enum type" + fullyQualifiedName + " as open type", e);
+        }
+    }
+
     public boolean isIdentityRef() {
         return typeDefinition instanceof IdentityrefTypeDefinition;
     }
@@ -223,10 +241,6 @@ public class JavaAttribute extends AbstractAttribute implements TypedAttribute {
         itemTypes[0] = artificialPropertyType;
     }
 
-    private boolean isEnum(Type baseType) {
-        return baseType.getFullyQualifiedName().equals(Enum.class.getName());
-    }
-
     private OpenType<?> getSimpleType(Type type) {
         SimpleType<?> simpleType = SimpleTypeResolver.getSimpleType(type);
         return simpleType;
index 8454a6b..08aff12 100644 (file)
@@ -51,7 +51,6 @@ public class SimpleTypeResolver {
         JAVA_TYPE_TO_SIMPLE_TYPE.put(Long.class.getName(), SimpleType.LONG);
         JAVA_TYPE_TO_SIMPLE_TYPE.put(long.class.getName(), SimpleType.LONG);
         JAVA_TYPE_TO_SIMPLE_TYPE.put(String.class.getName(), SimpleType.STRING);
-        JAVA_TYPE_TO_SIMPLE_TYPE.put(Enum.class.getName(), SimpleType.STRING);
         JAVA_TYPE_TO_SIMPLE_TYPE.put(Boolean.class.getName(), SimpleType.BOOLEAN);
         JAVA_TYPE_TO_SIMPLE_TYPE.put(boolean.class.getName(), SimpleType.BOOLEAN);
         JAVA_TYPE_TO_SIMPLE_TYPE.put(BigInteger.class.getName(), SimpleType.BIGINTEGER);
@@ -61,7 +60,6 @@ public class SimpleTypeResolver {
         JAVA_TYPE_TO_SIMPLE_TYPE.put(Date.class.getName(), SimpleType.DATE);
         JAVA_TYPE_TO_SIMPLE_TYPE.put(Double.class.getName(), SimpleType.DOUBLE);
         JAVA_TYPE_TO_SIMPLE_TYPE.put(double.class.getName(), SimpleType.DOUBLE);
-
         JAVA_TYPE_TO_SIMPLE_TYPE.put(char.class.getName(), SimpleType.CHARACTER);
     }
 
index f772a26..aff7c86 100644 (file)
@@ -192,7 +192,7 @@ module config-test-impl {
 
                 leaf extended-enum {
                     type tt:extend-enum;
-                    default ONE;
+                    default one;
                 }
 
                 leaf ip {
index ee466b4..df8cf94 100644 (file)
@@ -20,8 +20,8 @@ module test-types {
 
     typedef extend-enum {
         type enumeration {
-            enum "ONE";
-            enum "TWO";
+            enum "one";
+            enum "two";
         }
     }
 
index 2093ace..d8b2ea1 100644 (file)
       <groupId>org.opendaylight.yangtools</groupId>
       <artifactId>mockito-configuration</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>binding-generator-impl</artifactId>
+    </dependency>
     <dependency>
       <groupId>org.osgi</groupId>
       <artifactId>org.osgi.core</artifactId>
index 4d55119..38c0b06 100644 (file)
@@ -38,6 +38,8 @@ public abstract class AttributeIfcSwitchStatement<T> {
                     return caseJavaUnionAttribute(openType);
                 } else if(((JavaAttribute)attributeIfc).isIdentityRef()) {
                     return caseJavaIdentityRefAttribute(openType);
+                } else if(((JavaAttribute)attributeIfc).isEnum()) {
+                    return caseJavaEnumAttribute(openType);
                 } else {
                     return caseJavaAttribute(openType);
                 }
@@ -70,6 +72,10 @@ public abstract class AttributeIfcSwitchStatement<T> {
         return caseJavaAttribute(openType);
     }
 
+    protected T caseJavaEnumAttribute(OpenType<?> openType) {
+        return caseJavaAttribute(openType);
+    }
+
     protected T caseJavaBinaryAttribute(OpenType<?> openType) {
         return caseJavaAttribute(openType);
     }
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/EnumAttributeMappingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/EnumAttributeMappingStrategy.java
new file mode 100644 (file)
index 0000000..052438b
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.mapping;
+
+import com.google.common.base.Optional;
+import javax.management.openmbean.CompositeType;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.EnumResolver;
+
+public class EnumAttributeMappingStrategy extends AbstractAttributeMappingStrategy<String, CompositeType> {
+
+    private final EnumResolver enumResolver;
+
+    public EnumAttributeMappingStrategy(CompositeType openType, final EnumResolver enumResolver) {
+        super(openType);
+        this.enumResolver = enumResolver;
+    }
+
+    @Override
+    public Optional<String> mapAttribute(Object value) {
+        if (value == null){
+            return Optional.absent();
+        }
+
+        String expectedClass = getOpenType().getTypeName();
+        return Optional.of(enumResolver.toYang(expectedClass, value.toString()));
+    }
+
+}
index b50a035..463e981 100644 (file)
@@ -22,12 +22,15 @@ import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribu
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributeIfcSwitchStatement;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.EnumResolver;
 
 public class ObjectMapper extends AttributeIfcSwitchStatement<AttributeMappingStrategy<?, ? extends OpenType<?>>> {
 
+    private EnumResolver enumResolver;
 
     public Map<String, AttributeMappingStrategy<?, ? extends OpenType<?>>> prepareMapping(
-            Map<String, AttributeIfc> configDefinition) {
+            Map<String, AttributeIfc> configDefinition, EnumResolver enumResolver) {
+        this.enumResolver = Preconditions.checkNotNull(enumResolver);
         Map<String, AttributeMappingStrategy<?, ? extends OpenType<?>>> strategies = Maps.newHashMap();
 
         for (Entry<String, AttributeIfc> attrEntry : configDefinition.entrySet()) {
@@ -63,6 +66,11 @@ public class ObjectMapper extends AttributeIfcSwitchStatement<AttributeMappingSt
         return new SimpleAttributeMappingStrategy(openType);
     }
 
+    @Override
+    protected AttributeMappingStrategy<?, ? extends OpenType<?>> caseJavaEnumAttribute(final OpenType<?> openType) {
+        return new EnumAttributeMappingStrategy(((CompositeType) openType), enumResolver);
+    }
+
     @Override
     protected AttributeMappingStrategy<?, ? extends OpenType<?>> caseJavaArrayAttribute(ArrayType<?> openType) {
 
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/EnumAttributeResolvingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/EnumAttributeResolvingStrategy.java
new file mode 100644 (file)
index 0000000..25c4da1
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import java.util.Map;
+import javax.management.openmbean.CompositeType;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.EnumResolver;
+import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+final class EnumAttributeResolvingStrategy extends AbstractAttributeResolvingStrategy<Object, CompositeType> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(EnumAttributeResolvingStrategy.class);
+    private final EnumResolver enumResolver;
+
+    EnumAttributeResolvingStrategy(CompositeType simpleType, final EnumResolver enumResolver) {
+        super(simpleType);
+        this.enumResolver = enumResolver;
+    }
+
+    @Override
+    public String toString() {
+        return "ResolvedEnumAttribute [" + getOpenType().getClassName() + "]";
+    }
+
+    @Override
+    public Optional<Object> parseAttribute(String attrName, Object value) throws NetconfDocumentedException {
+        if (value == null) {
+            return Optional.absent();
+        }
+
+        Util.checkType(value, Map.class);
+        Map<?, ?> valueMap = (Map<?, ?>) value;
+        Preconditions.checkArgument(valueMap.size() == 1, "Unexpected value size " + value + " should be just 1 foe enum");
+        final Object innerValue = valueMap.values().iterator().next();
+        Util.checkType(innerValue, String.class);
+
+        final String className = getOpenType().getTypeName();
+        final Object parsedValue = enumResolver.fromYang(className, ((String) innerValue));
+
+        LOG.debug("Attribute {} : {} parsed to enum type {} with value {}", attrName, innerValue, getOpenType(), parsedValue);
+        return Optional.of(parsedValue);
+    }
+
+}
index b231cf8..93c83eb 100644 (file)
@@ -22,17 +22,21 @@ import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDepende
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributeIfcSwitchStatement;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.EnumResolver;
 
 public class ObjectResolver extends AttributeIfcSwitchStatement<AttributeResolvingStrategy<?, ? extends OpenType<?>>> {
 
     private final ServiceRegistryWrapper serviceTracker;
+    private EnumResolver enumResolver;
 
     public ObjectResolver(ServiceRegistryWrapper serviceTracker) {
         this.serviceTracker = serviceTracker;
     }
 
     public Map<String, AttributeResolvingStrategy<?, ? extends OpenType<?>>> prepareResolving(
-            Map<String, AttributeIfc> configDefinition) {
+            Map<String, AttributeIfc> configDefinition, final EnumResolver enumResolver) {
+        this.enumResolver = enumResolver;
+
         Map<String, AttributeResolvingStrategy<?, ? extends OpenType<?>>> strategies = Maps.newHashMap();
 
         for (Entry<String, AttributeIfc> attrEntry : configDefinition.entrySet()) {
@@ -44,7 +48,6 @@ public class ObjectResolver extends AttributeIfcSwitchStatement<AttributeResolvi
     }
 
     private AttributeResolvingStrategy<?, ? extends OpenType<?>> prepareStrategy(AttributeIfc attributeIfc) {
-
         return switchAttribute(attributeIfc);
     }
 
@@ -56,6 +59,11 @@ public class ObjectResolver extends AttributeIfcSwitchStatement<AttributeResolvi
         return retVal;
     }
 
+    @Override
+    protected AttributeResolvingStrategy<?, ? extends OpenType<?>> caseJavaEnumAttribute(final OpenType<?> openType) {
+        return new EnumAttributeResolvingStrategy((CompositeType) openType, enumResolver);
+    }
+
     @Override
     protected AttributeResolvingStrategy<?, ? extends OpenType<?>>  caseJavaSimpleAttribute(SimpleType<?> openType) {
         return new SimpleAttributeResolvingStrategy(openType);
@@ -63,6 +71,7 @@ public class ObjectResolver extends AttributeIfcSwitchStatement<AttributeResolvi
 
     @Override
     protected AttributeResolvingStrategy<?, ? extends OpenType<?>>  caseJavaArrayAttribute(ArrayType<?> openType) {
+
         SimpleType<?> innerType = (SimpleType<?>) openType.getElementOpenType();
         AttributeResolvingStrategy<?, ? extends OpenType<?>> strat = new SimpleAttributeResolvingStrategy(innerType);
         return new ArrayAttributeResolvingStrategy(strat, openType);
index fcbb3a5..022e370 100644 (file)
@@ -56,6 +56,11 @@ public class ObjectXmlWriter extends AttributeIfcSwitchStatement<AttributeWritin
         return new SimpleBinaryAttributeWritingStrategy(document, key);
     }
 
+    @Override
+    protected AttributeWritingStrategy caseJavaEnumAttribute(final OpenType<?> openType) {
+        return new SimpleAttributeWritingStrategy(document, key);
+    }
+
     @Override
     protected AttributeWritingStrategy caseJavaSimpleAttribute(SimpleType<?> openType) {
         return new SimpleAttributeWritingStrategy(document, key);
index 6931893..c26b4cf 100644 (file)
@@ -29,6 +29,7 @@ import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.EnumResolver;
 import org.opendaylight.controller.netconf.util.xml.XmlElement;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.w3c.dom.Document;
@@ -42,13 +43,16 @@ public class Config {
 
     private final Map<String, Map<Date, EditConfig.IdentityMapping>> identityMap;
 
-    public Config(Map<String, Map<String, ModuleConfig>> moduleConfigs) {
-        this(moduleConfigs, Collections.<String, Map<Date, EditConfig.IdentityMapping>>emptyMap());
+    private final EnumResolver enumResolver;
+
+    public Config(Map<String, Map<String, ModuleConfig>> moduleConfigs, final EnumResolver enumResolver) {
+        this(moduleConfigs, Collections.<String, Map<Date, EditConfig.IdentityMapping>>emptyMap(), enumResolver);
     }
 
-    public Config(Map<String, Map<String, ModuleConfig>> moduleConfigs, Map<String, Map<Date,EditConfig.IdentityMapping>> identityMap) {
+    public Config(Map<String, Map<String, ModuleConfig>> moduleConfigs, Map<String, Map<Date, EditConfig.IdentityMapping>> identityMap, final EnumResolver enumResolver) {
         this.moduleConfigs = moduleConfigs;
         this.identityMap = identityMap;
+        this.enumResolver = enumResolver;
     }
 
     public static Map<String, Map<String, Collection<ObjectName>>> getMappedInstances(Set<ObjectName> instancesToMap,
@@ -115,7 +119,7 @@ public class Config {
                 }
 
                 for (ObjectName objectName : moduleMappingEntry.getValue()) {
-                    modulesElement.appendChild(mapping.toXml(objectName, document, moduleToInstanceEntry.getKey()));
+                    modulesElement.appendChild(mapping.toXml(objectName, document, moduleToInstanceEntry.getKey(), enumResolver));
                 }
 
             }
@@ -141,7 +145,7 @@ public class Config {
                 @Override
                 public ModuleElementResolved resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement, ServiceRegistryWrapper serviceTracker, String instanceName, String moduleNamespace, EditStrategyType defaultStrategy) throws NetconfDocumentedException {
                     return moduleMapping.fromXml(moduleElement, serviceTracker,
-                            instanceName, moduleNamespace, defaultStrategy, identityMap);
+                            instanceName, moduleNamespace, defaultStrategy, identityMap, enumResolver);
                 }
             };
 
index ba7b2f2..7cfeb45 100644 (file)
@@ -33,6 +33,7 @@ import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attrib
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.toxml.ObjectXmlWriter;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.EnumResolver;
 import org.opendaylight.controller.netconf.util.xml.XmlElement;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.slf4j.Logger;
@@ -57,11 +58,11 @@ public final class InstanceConfig {
         this.configRegistryClient = configRegistryClient;
     }
 
-    private Map<String, Object> getMappedConfiguration(ObjectName on) {
+    private Map<String, Object> getMappedConfiguration(ObjectName on, final EnumResolver enumResolver) {
 
         // TODO make field, mappingStrategies can be instantiated only once
         Map<String, AttributeMappingStrategy<?, ? extends OpenType<?>>> mappingStrategies = new ObjectMapper()
-                .prepareMapping(jmxToAttrConfig);
+                .prepareMapping(jmxToAttrConfig, enumResolver);
 
         Map<String, Object> toXml = Maps.newHashMap();
 
@@ -87,9 +88,9 @@ public final class InstanceConfig {
         return toXml;
     }
 
-    public Element toXml(ObjectName on, String namespace, Document document, Element rootElement) {
+    public Element toXml(ObjectName on, String namespace, Document document, Element rootElement, final EnumResolver enumResolver) {
         Map<String, AttributeWritingStrategy> strats = new ObjectXmlWriter().prepareWriting(yangToAttrConfig, document);
-        Map<String, Object> mappedConfig = getMappedConfiguration(on);
+        Map<String, Object> mappedConfig = getMappedConfiguration(on, enumResolver);
         Element parentElement;
         if (nullableDummyContainerName != null) {
             Element dummyElement = XmlUtil.createElement(document, nullableDummyContainerName, Optional.of(namespace));
@@ -109,11 +110,11 @@ public final class InstanceConfig {
         return rootElement;
     }
 
-    private void resolveConfiguration(InstanceConfigElementResolved mappedConfig, ServiceRegistryWrapper depTracker) {
+    private void resolveConfiguration(InstanceConfigElementResolved mappedConfig, ServiceRegistryWrapper depTracker, final EnumResolver enumResolver) {
 
         // TODO make field, resolvingStrategies can be instantiated only once
         Map<String, AttributeResolvingStrategy<?, ? extends OpenType<?>>> resolvingStrategies = new ObjectResolver(
-                depTracker).prepareResolving(yangToAttrConfig);
+                depTracker).prepareResolving(yangToAttrConfig, enumResolver);
 
         for (Entry<String, AttributeConfigElement> configDefEntry : mappedConfig.getConfiguration().entrySet()) {
             AttributeConfigElement value = configDefEntry.getValue();
@@ -135,7 +136,7 @@ public final class InstanceConfig {
 
     public InstanceConfigElementResolved fromXml(XmlElement moduleElement, ServiceRegistryWrapper services, String moduleNamespace,
                                                  EditStrategyType defaultStrategy,
-                                                 Map<String, Map<Date,EditConfig.IdentityMapping>> identityMap) throws NetconfDocumentedException {
+                                                 Map<String, Map<Date, EditConfig.IdentityMapping>> identityMap, final EnumResolver enumResolver) throws NetconfDocumentedException {
         Map<String, AttributeConfigElement> retVal = Maps.newHashMap();
 
         Map<String, AttributeReadingStrategy> strats = new ObjectXmlReader().prepareReading(yangToAttrConfig, identityMap);
@@ -188,7 +189,7 @@ public final class InstanceConfig {
         InstanceConfigElementResolved instanceConfigElementResolved = perInstanceEditStrategy.equals("") ? new InstanceConfigElementResolved(
                 retVal, defaultStrategy) : new InstanceConfigElementResolved(perInstanceEditStrategy, retVal, defaultStrategy);
 
-        resolveConfiguration(instanceConfigElementResolved, services);
+        resolveConfiguration(instanceConfigElementResolved, services, enumResolver);
         return instanceConfigElementResolved;
     }
 
index 7dfe0cd..5cadc08 100644 (file)
@@ -17,6 +17,7 @@ import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.EnumResolver;
 import org.opendaylight.controller.netconf.util.xml.XmlElement;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.w3c.dom.Document;
@@ -32,7 +33,7 @@ public class ModuleConfig {
         this.instanceConfig = mbeanMapping;
     }
 
-    public Element toXml(ObjectName instanceON, Document document, String namespace) {
+    public Element toXml(ObjectName instanceON, Document document, String namespace, final EnumResolver enumResolver) {
         Element root = XmlUtil.createElement(document, XmlNetconfConstants.MODULE_KEY, Optional.<String>absent());
 
         // type belongs to config.yang namespace, but needs to be <type prefix:moduleNS>prefix:moduleName</type>
@@ -47,15 +48,15 @@ public class ModuleConfig {
 
         root.appendChild(nameElement);
 
-        root = instanceConfig.toXml(instanceON, namespace, document, root);
+        root = instanceConfig.toXml(instanceON, namespace, document, root, enumResolver);
 
         return root;
     }
 
     public ModuleElementResolved fromXml(XmlElement moduleElement, ServiceRegistryWrapper depTracker, String instanceName,
-                                         String moduleNamespace, EditStrategyType defaultStrategy, Map<String, Map<Date,EditConfig.IdentityMapping>> identityMap) throws NetconfDocumentedException {
+                                         String moduleNamespace, EditStrategyType defaultStrategy, Map<String, Map<Date, EditConfig.IdentityMapping>> identityMap, final EnumResolver enumResolver) throws NetconfDocumentedException {
 
-        InstanceConfigElementResolved ice = instanceConfig.fromXml(moduleElement, depTracker, moduleNamespace, defaultStrategy, identityMap);
+        InstanceConfigElementResolved ice = instanceConfig.fromXml(moduleElement, depTracker, moduleNamespace, defaultStrategy, identityMap, enumResolver);
         return new ModuleElementResolved(instanceName, ice);
     }
 
index e870731..f7108f4 100644 (file)
@@ -25,14 +25,17 @@ import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attrib
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving.AttributeResolvingStrategy;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving.ObjectResolver;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.EnumResolver;
 import org.opendaylight.controller.netconf.util.xml.XmlElement;
 
 public final class InstanceRuntimeRpc {
 
     private final Map<String, AttributeIfc> yangToAttrConfig;
     private final Rpc rpc;
+    private final EnumResolver enumResolver;
 
-    public InstanceRuntimeRpc(Rpc rpc) {
+    public InstanceRuntimeRpc(Rpc rpc, final EnumResolver enumResolver) {
+        this.enumResolver = enumResolver;
         this.yangToAttrConfig = map(rpc.getParameters());
         this.rpc = rpc;
     }
@@ -49,7 +52,7 @@ public final class InstanceRuntimeRpc {
 
         // TODO make field, resolvingStrategies can be instantiated only once
         Map<String, AttributeResolvingStrategy<?, ? extends OpenType<?>>> resolvingStrategies = new ObjectResolver(null)
-                .prepareResolving(yangToAttrConfig);
+                .prepareResolving(yangToAttrConfig, enumResolver);
         // TODO make constructor for object resolver without service tracker
         for (Entry<String, AttributeConfigElement> configDefEntry : mappedConfig.entrySet()) {
             try {
index 0722555..7316dbc 100644 (file)
@@ -13,11 +13,17 @@ import com.google.common.collect.Maps;
 import java.util.Map;
 import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry;
 import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry.Rpc;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.EnumResolver;
 
 public final class ModuleRpcs {
 
     private final Map<String, String> yangToJavaNames = Maps.newHashMap();
     private final Map<String, Map<String, InstanceRuntimeRpc>> rpcMapping = Maps.newHashMap();
+    private final EnumResolver enumResolver;
+
+    public ModuleRpcs(final EnumResolver enumResolver) {
+        this.enumResolver = enumResolver;
+    }
 
     public void addNameMapping(RuntimeBeanEntry runtimeEntry) {
         String yangName = runtimeEntry.getYangName();
@@ -36,7 +42,7 @@ public final class ModuleRpcs {
 
         Preconditions.checkState(!map.containsKey(rpc.getYangName()), "Rpc %s for runtime bean %s added twice",
                 rpc.getYangName(), yangName);
-        map.put(rpc.getYangName(), new InstanceRuntimeRpc(rpc));
+        map.put(rpc.getYangName(), new InstanceRuntimeRpc(rpc, enumResolver));
     }
 
     public String getRbeJavaName(String yangName) {
index e6102cf..ce30dc4 100644 (file)
@@ -17,6 +17,7 @@ import java.util.Map.Entry;
 import java.util.Set;
 import javax.management.ObjectName;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.EnumResolver;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -84,13 +85,13 @@ public class InstanceRuntime {
         }));
     }
 
-    public Element toXml(ObjectName rootOn, Set<ObjectName> childRbeOns, Document document, Element parentElement, String namespace) {
-        return toXml(rootOn, childRbeOns, document, null, parentElement, namespace);
+    public Element toXml(ObjectName rootOn, Set<ObjectName> childRbeOns, Document document, Element parentElement, String namespace, final EnumResolver enumResolver) {
+        return toXml(rootOn, childRbeOns, document, null, parentElement, namespace, enumResolver);
     }
 
     public Element toXml(ObjectName rootOn, Set<ObjectName> childRbeOns, Document document, String instanceIndex,
-                         Element parentElement, String namespace) {
-        Element xml = instanceMapping.toXml(rootOn, namespace, document, parentElement);
+                         Element parentElement, String namespace, final EnumResolver enumResolver) {
+        Element xml = instanceMapping.toXml(rootOn, namespace, document, parentElement, enumResolver);
 
         if (instanceIndex != null) {
             xml.setAttribute(KEY_ATTRIBUTE_KEY, instanceIndex);
@@ -108,7 +109,7 @@ public class InstanceRuntime {
 
                 Element innerXml = XmlUtil.createElement(document, elementName, Optional.of(namespace));
                 childMappingEntry.getValue().toXml(objectName, innerChildRbeOns, document,
-                        runtimeInstanceIndex, innerXml, namespace);
+                        runtimeInstanceIndex, innerXml, namespace, enumResolver);
                 xml.appendChild(innerXml);
             }
         }
index 4d67c75..ca2c019 100644 (file)
@@ -13,6 +13,7 @@ import java.util.Collection;
 import java.util.Set;
 import javax.management.ObjectName;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.EnumResolver;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
@@ -34,9 +35,9 @@ public class ModuleRuntime {
     }
 
     public Element toXml(String namespace, Collection<ObjectName> runtimeBeanOns,
-                         Document document, ModuleConfig moduleConfig, ObjectName configBeanON) {
+                         Document document, ModuleConfig moduleConfig, ObjectName configBeanON, final EnumResolver enumResolver) {
 
-        Element moduleElement = moduleConfig.toXml(configBeanON, document, namespace);
+        Element moduleElement = moduleConfig.toXml(configBeanON, document, namespace, enumResolver);
 
         ObjectName rootName = findRoot(runtimeBeanOns);
 
@@ -44,7 +45,7 @@ public class ModuleRuntime {
         childrenRuntimeBeans.remove(rootName);
 
         // FIXME: why is this called and not used?
-        instanceRuntime.toXml(rootName, childrenRuntimeBeans, document, moduleElement, namespace);
+        instanceRuntime.toXml(rootName, childrenRuntimeBeans, document, moduleElement, namespace, enumResolver);
 
         return moduleElement;
     }
index 4a6c0eb..ddbc99d 100644 (file)
@@ -20,6 +20,7 @@ import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Config;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.EnumResolver;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -59,7 +60,7 @@ public class Runtime {
         return retVal;
     }
 
-    public Element toXml(Set<ObjectName> instancesToMap, Set<ObjectName> configBeans, Document document) {
+    public Element toXml(Set<ObjectName> instancesToMap, Set<ObjectName> configBeans, Document document, final EnumResolver enumResolver) {
         Element root = XmlUtil.createElement(document, XmlNetconfConstants.DATA_KEY, Optional.<String>absent());
 
         Element modulesElement = XmlUtil.createElement(document, XmlNetconfConstants.MODULES_KEY, Optional.of(XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG));
@@ -82,11 +83,11 @@ public class Runtime {
                     Element runtimeXml;
                     ModuleConfig moduleConfig = moduleConfigs.get(localNamespace).get(moduleName);
                     if(instanceToRbe==null || !instanceToRbe.containsKey(instanceName)) {
-                        runtimeXml = moduleConfig.toXml(instanceON, document, localNamespace);
+                        runtimeXml = moduleConfig.toXml(instanceON, document, localNamespace, enumResolver);
                     } else {
                         ModuleRuntime moduleRuntime = moduleRuntimes.get(localNamespace).get(moduleName);
                         runtimeXml = moduleRuntime.toXml(localNamespace, instanceToRbe.get(instanceName), document,
-                                moduleConfig, instanceON);
+                                moduleConfig, instanceON, enumResolver);
                     }
                     modulesElement.appendChild(runtimeXml);
                 }
index 8b31a59..7948bb6 100644 (file)
@@ -209,7 +209,7 @@ public class EditConfig extends AbstractConfigNetconfOperation {
         Map<String, Map<String, ModuleConfig>> factories = transformMbeToModuleConfigs(configRegistryClient,
                 yangStoreSnapshot.getModuleMXBeanEntryMap());
         Map<String, Map<Date, IdentityMapping>> identitiesMap = transformIdentities(yangStoreSnapshot.getModules());
-        return new Config(factories, identitiesMap);
+        return new Config(factories, identitiesMap, yangStoreSnapshot.getEnumResolver());
     }
 
 
index fe7f277..40592ea 100644 (file)
@@ -136,7 +136,7 @@ public class Get extends AbstractConfigNetconfOperation {
 
             final Runtime runtime = new Runtime(moduleRuntimes, moduleConfigs);
 
-            final Element element = runtime.toXml(runtimeBeans, configBeans, document);
+            final Element element = runtime.toXml(runtimeBeans, configBeans, document, yangStoreSnapshot.getEnumResolver());
 
             LOG.trace("{} operation successful", XmlNetconfConstants.GET);
 
index 2c4bde0..401124e 100644 (file)
@@ -89,7 +89,7 @@ public class GetConfig extends AbstractConfigNetconfOperation {
                     .queryInstances(configRegistryClient);
 
             final Config configMapping = new Config(EditConfig.transformMbeToModuleConfigs(registryClient,
-                    yangStoreSnapshot.getModuleMXBeanEntryMap()));
+                    yangStoreSnapshot.getModuleMXBeanEntryMap()), yangStoreSnapshot.getEnumResolver());
 
             ServiceRegistryWrapper serviceTracker = new ServiceRegistryWrapper(registryClient);
             dataElement = configMapping.toXml(instances, this.maybeNamespace, document, dataElement, serviceTracker);
index ebbc0e5..f7d28b7 100644 (file)
@@ -30,6 +30,7 @@ import org.opendaylight.controller.netconf.confignetconfconnector.mapping.rpc.In
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.rpc.ModuleRpcs;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.rpc.Rpcs;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.EnumResolver;
 import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreContext;
 import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
 import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException;
@@ -103,7 +104,7 @@ public class RuntimeRpc extends AbstractConfigNetconfOperation {
         final RuntimeRpcElementResolved id = RuntimeRpcElementResolved.fromXpath(
                 contextInstanceElement.getTextContent(), operationName, namespace);
 
-        final Rpcs rpcs = mapRpcs(yangStoreSnapshot.getModuleMXBeanEntryMap());
+        final Rpcs rpcs = mapRpcs(yangStoreSnapshot.getModuleMXBeanEntryMap(), yangStoreSnapshot.getEnumResolver());
 
         final ModuleRpcs rpcMapping = rpcs.getRpcMapping(id);
         final InstanceRuntimeRpc instanceRuntimeRpc = rpcMapping.getRpc(id.getRuntimeBeanName(), operationName);
@@ -144,7 +145,7 @@ public class RuntimeRpc extends AbstractConfigNetconfOperation {
                 .getTextContent(), netconfOperationName, netconfOperationNamespace);
 
         // TODO reuse rpcs instance in fromXml method
-        final Rpcs rpcs = mapRpcs(yangStoreSnapshot.getModuleMXBeanEntryMap());
+        final Rpcs rpcs = mapRpcs(yangStoreSnapshot.getModuleMXBeanEntryMap(), yangStoreSnapshot.getEnumResolver());
 
         try {
 
@@ -239,7 +240,7 @@ public class RuntimeRpc extends AbstractConfigNetconfOperation {
         return sorted;
     }
 
-    private static Rpcs mapRpcs(final Map<String, Map<String, ModuleMXBeanEntry>> mBeanEntries) {
+    private static Rpcs mapRpcs(final Map<String, Map<String, ModuleMXBeanEntry>> mBeanEntries, final EnumResolver enumResolver) {
 
         final Map<String, Map<String, ModuleRpcs>> map = Maps.newHashMap();
 
@@ -255,7 +256,7 @@ public class RuntimeRpc extends AbstractConfigNetconfOperation {
 
                 ModuleRpcs rpcMapping = namespaceToModules.get(moduleEntry.getKey());
                 if (rpcMapping == null) {
-                    rpcMapping = new ModuleRpcs();
+                    rpcMapping = new ModuleRpcs(enumResolver);
                     namespaceToModules.put(moduleEntry.getKey(), rpcMapping);
                 }
 
index f39a21d..6f082b7 100644 (file)
@@ -14,6 +14,7 @@ import java.util.Dictionary;
 import java.util.Hashtable;
 import org.opendaylight.controller.netconf.api.util.NetconfConstants;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
+import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
@@ -53,7 +54,9 @@ public class Activator implements BundleActivator {
             @Override
             public void modifiedService(ServiceReference<SchemaContextProvider> reference, ConfigRegistryLookupThread configRegistryLookup) {
                 LOG.debug("Got modifiedService(SchemaContextProvider) event");
-                configRegistryLookup.yangStoreService.refresh();
+                final BindingRuntimeContext runtimeContext = (BindingRuntimeContext) reference.getProperty(BindingRuntimeContext.class.getName());
+                LOG.debug("BindingRuntimeContext retrieved as {}", runtimeContext);
+                configRegistryLookup.yangStoreService.refresh(runtimeContext);
 
             }
 
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/EnumResolver.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/EnumResolver.java
new file mode 100644 (file)
index 0000000..7efdf5f
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.netconf.confignetconfconnector.osgi;
+
+public interface EnumResolver {
+
+    String fromYang(String enumType, String enumYangValue);
+
+    String toYang(String enumType, String enumJavaValue);
+}
index ac3873e..ad771f9 100644 (file)
@@ -33,6 +33,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.not
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChangeBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.changed.by.parms.ChangedByBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.changed.by.parms.changed.by.server.or.user.ServerBuilder;
+import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
@@ -58,7 +59,7 @@ public class YangStoreService implements YangStoreContext {
      *
      * We synchronize with GC as usual, using a SoftReference.
      *
-     * The atomic reference is used to synchronize with {@link #refresh()}, e.g. when
+     * The atomic reference is used to synchronize with {@link #refresh(org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext)}, e.g. when
      * refresh happens, it will push a SoftReference(null), e.g. simulate the GC. Now
      * that may happen while the getter is already busy acting on the old schema context,
      * so it needs to understand that a refresh has happened and retry. To do that, it
@@ -71,6 +72,9 @@ public class YangStoreService implements YangStoreContext {
     private final AtomicReference<SoftReference<YangStoreSnapshot>> ref =
             new AtomicReference<>(new SoftReference<YangStoreSnapshot>(null));
 
+    private final AtomicReference<SoftReference<BindingRuntimeContext>> refBindingContext =
+            new AtomicReference<>(new SoftReference<BindingRuntimeContext>(null));
+
     private final SchemaContextProvider schemaContextProvider;
     private final BaseNetconfNotificationListener notificationPublisher;
 
@@ -98,7 +102,7 @@ public class YangStoreService implements YangStoreContext {
 
         while (ret == null) {
             // We need to be compute a new value
-            ret = new YangStoreSnapshot(schemaContextProvider.getSchemaContext());
+            ret = new YangStoreSnapshot(schemaContextProvider.getSchemaContext(), refBindingContext.get().get());
 
             if (!ref.compareAndSet(r, new SoftReference<>(ret))) {
                 LOG.debug("Concurrent refresh detected, recomputing snapshot");
@@ -130,9 +134,15 @@ public class YangStoreService implements YangStoreContext {
         return getYangStoreSnapshot().getModuleSource(moduleIdentifier);
     }
 
-    public void refresh() {
+    @Override
+    public EnumResolver getEnumResolver() {
+        return getYangStoreSnapshot().getEnumResolver();
+    }
+
+    public void refresh(final BindingRuntimeContext runtimeContext) {
         final YangStoreSnapshot previous = ref.get().get();
         ref.set(new SoftReference<YangStoreSnapshot>(null));
+        refBindingContext.set(new SoftReference<>(runtimeContext));
         notificationExecutor.submit(new CapabilityChangeNotifier(previous));
     }
 
index 5da5322..c798da7 100644 (file)
@@ -9,7 +9,9 @@
 package org.opendaylight.controller.netconf.confignetconfconnector.osgi;
 
 import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
 import com.google.common.base.Predicate;
+import com.google.common.collect.BiMap;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
@@ -23,6 +25,7 @@ import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
 import org.opendaylight.controller.config.yangjmxgenerator.PackageTranslator;
 import org.opendaylight.controller.config.yangjmxgenerator.ServiceInterfaceEntry;
 import org.opendaylight.controller.config.yangjmxgenerator.TypeProviderWrapper;
+import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
 import org.opendaylight.yangtools.sal.binding.yang.types.TypeProviderImpl;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
@@ -32,7 +35,7 @@ import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleIdentifierImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-final class YangStoreSnapshot implements YangStoreContext {
+final class YangStoreSnapshot implements YangStoreContext, EnumResolver {
     private static final Logger LOG = LoggerFactory.getLogger(YangStoreSnapshot.class);
 
 
@@ -43,8 +46,10 @@ final class YangStoreSnapshot implements YangStoreContext {
     private final Map<QName, Map<String, ModuleMXBeanEntry>> qNamesToIdentitiesToModuleMXBeanEntries;
 
     private final SchemaContext schemaContext;
+    private final BindingRuntimeContext bindingContextProvider;
 
-    public YangStoreSnapshot(final SchemaContext resolveSchemaContext) {
+    public YangStoreSnapshot(final SchemaContext resolveSchemaContext, final BindingRuntimeContext bindingContextProvider) {
+        this.bindingContextProvider = bindingContextProvider;
         LOG.trace("Resolved modules:{}", resolveSchemaContext.getModules());
         this.schemaContext = resolveSchemaContext;
         // JMX generator
@@ -132,6 +137,11 @@ final class YangStoreSnapshot implements YangStoreContext {
         }
     }
 
+    @Override
+    public EnumResolver getEnumResolver() {
+        return this;
+    }
+
     @Override
     public boolean equals(final Object o) {
         if (this == o) return true;
@@ -149,4 +159,21 @@ final class YangStoreSnapshot implements YangStoreContext {
     public int hashCode() {
         return schemaContext != null ? schemaContext.hashCode() : 0;
     }
+
+    @Override
+    public String fromYang(final String enumClass, final String enumYangValue) {
+        Preconditions.checkState(bindingContextProvider != null, "Binding context provider was not set yet");
+        final BiMap<String, String> enumMapping = bindingContextProvider.getEnumMapping(enumClass);
+        final String javaName = enumMapping.get(enumYangValue);
+        return Preconditions.checkNotNull(javaName, "Unable to resolve enum value %s for enum class %s with assumed enum mapping: %s", enumYangValue, enumClass, enumMapping);
+    }
+
+    @Override
+    public String toYang(final String enumClass, final String enumJavaValue) {
+        Preconditions.checkState(bindingContextProvider != null, "Binding context provider was not set yet");
+        final BiMap<String, String> enumMapping = bindingContextProvider.getEnumMapping(enumClass);
+        final String javaName = enumMapping.inverse().get(enumJavaValue);
+        return Preconditions.checkNotNull(javaName, "Unable to map enumcd .." +
+                "cd  value %s for enum class %s with assumed enum mapping: %s", enumJavaValue, enumClass, enumMapping.inverse());
+    }
 }
index 47bdcd8..ec09cfa 100644 (file)
@@ -26,6 +26,8 @@ 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.BiMap;
+import com.google.common.collect.HashBiMap;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
@@ -92,6 +94,7 @@ import org.opendaylight.controller.netconf.confignetconfconnector.operations.edi
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.get.Get;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.getconfig.GetConfig;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.runtimerpc.RuntimeRpc;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.EnumResolver;
 import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreContext;
 import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreService;
 import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
@@ -162,6 +165,19 @@ public class NetconfMappingTest extends AbstractConfigTest {
 
         doReturn(getMbes()).when(this.yangStoreSnapshot).getModuleMXBeanEntryMap();
         doReturn(getModules()).when(this.yangStoreSnapshot).getModules();
+        doReturn(new EnumResolver() {
+            @Override
+            public String fromYang(final String enumType, final String enumYangValue) {
+                return Preconditions.checkNotNull(getEnumMapping().get(enumYangValue),
+                        "Unable to resolve enum value %s, for enum %s with mappings %s", enumYangValue, enumType, getEnumMapping());
+            }
+
+            @Override
+            public String toYang(final String enumType, final String enumYangValue) {
+                return Preconditions.checkNotNull(getEnumMapping().inverse().get(enumYangValue),
+                        "Unable to resolve enum value %s, for enum %s with mappings %s", enumYangValue, enumType, getEnumMapping().inverse());
+            }
+        }).when(this.yangStoreSnapshot).getEnumResolver();
 
         this.factory = new NetconfTestImplModuleFactory();
         this.factory2 = new DepTestImplModuleFactory();
@@ -601,9 +617,9 @@ public class NetconfMappingTest extends AbstractConfigTest {
         // Default
         assertContainsElement(response, readXmlToElement("<extended-twice xmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">2</extended-twice>"));
 
-        assertContainsElement(response, readXmlToElement("<extended-enum xmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">TWO</extended-enum>"));
+        assertContainsElement(response, readXmlToElement("<extended-enum xmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">two</extended-enum>"));
         // Default
-        assertContainsElement(response, readXmlToElement("<extended-enum xmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">ONE</extended-enum>"));
+        assertContainsElement(response, readXmlToElement("<extended-enum xmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">one</extended-enum>"));
     }
 
     private void assertContainsString(String string, String substring) {
@@ -612,7 +628,7 @@ public class NetconfMappingTest extends AbstractConfigTest {
 
     private void checkEnum(final Document response) throws Exception {
 
-        String expectedEnumContent = "TWO";
+        String expectedEnumContent = "two";
 
         XMLAssert.assertXpathEvaluatesTo(expectedEnumContent,
                 getXpathForNetconfImplSubnode(INSTANCE_NAME,"extended-enum"),
@@ -657,11 +673,22 @@ public class NetconfMappingTest extends AbstractConfigTest {
                 return schemaContext ;
             }
         }, mockedContext);
+        final BindingRuntimeContext bindingRuntimeContext = mock(BindingRuntimeContext.class);
+        doReturn(getEnumMapping()).when(bindingRuntimeContext).getEnumMapping(any(Class.class));
+        yangStoreService.refresh(bindingRuntimeContext);
         mBeanEntries.putAll(yangStoreService.getModuleMXBeanEntryMap());
 
         return mBeanEntries;
     }
 
+    private BiMap<String, String> getEnumMapping() {
+        final HashBiMap<String, String> enumBiMap = HashBiMap.create();
+        // Enum constants mapping from yang -> Java and back
+        enumBiMap.put("one", "One");
+        enumBiMap.put("two", "Two");
+        return enumBiMap;
+    }
+
     private Set<org.opendaylight.yangtools.yang.model.api.Module> getModules() throws Exception {
         SchemaContext resolveSchemaContext = getSchemaContext();
         return resolveSchemaContext.getModules();
index 7cdcb1b..1e31782 100644 (file)
@@ -50,6 +50,7 @@ import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
 import org.opendaylight.controller.netconf.client.SimpleNetconfClientSessionListener;
 import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
 import org.opendaylight.controller.netconf.client.conf.NetconfClientConfigurationBuilder;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.EnumResolver;
 import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl;
 import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreService;
 import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer;
@@ -65,6 +66,7 @@ import org.opendaylight.controller.netconf.notifications.BaseNetconfNotification
 import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
 import org.opendaylight.protocol.framework.NeverReconnectStrategy;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChange;
+import org.opendaylight.yangtools.yang.binding.BindingMapping;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
@@ -280,5 +282,20 @@ public abstract class AbstractNetconfConfigTest extends AbstractConfigTest {
             final YangParserImpl yangParser = new YangParserImpl();
             return yangParser.resolveSchemaContext(new HashSet<>(yangParser.parseYangModelsFromStreamsMapped(byteArrayInputStreams).values()));
         }
+
+        @Override
+        public EnumResolver getEnumResolver() {
+            return new EnumResolver() {
+                @Override
+                public String fromYang(final String enumType, final String enumYangValue) {
+                    return BindingMapping.getClassName(enumYangValue);
+                }
+
+                @Override
+                public String toYang(final String enumType, final String enumJavaValue) {
+                    return enumJavaValue.toLowerCase();
+                }
+            };
+        }
     }
 }
index a0458c4..7612250 100644 (file)
@@ -44,7 +44,7 @@
                         </extended-twice>
 
                         <extended-enum>
-                            TWO
+                            two
                         </extended-enum>
 
                         <simple-long-2>44</simple-long-2>

©2013 OpenDaylight, A Linux Foundation Collaborative Project. All Rights Reserved.
OpenDaylight is a registered trademark of The OpenDaylight Project, Inc.
Linux Foundation and OpenDaylight are registered trademarks of the Linux Foundation.
Linux is a registered trademark of Linus Torvalds.