From d65a9c7d39f52b589e0f02abdde0afd6ac98ba35 Mon Sep 17 00:00:00 2001 From: Maros Marsalek Date: Thu, 5 Dec 2013 13:39:22 +0100 Subject: [PATCH] Added support for union yang types to netconf. Change-Id: I3f936850fdf9a2c96e0ccda50a5178da6d90a92d Signed-off-by: Maros Marsalek --- .../config/yang-jmx-generator/pom.xml | 4 + .../yangjmxgenerator/TypeProviderWrapper.java | 4 + .../attribute/JavaAttribute.java | 79 ++++++++++++++++++- .../attribute/SimpleTypeResolver.java | 2 + .../types/rev131127/UnionTestBuilder.java | 24 ++++++ .../src/main/yang/config-test-impl.yang | 14 +++- .../src/main/yang/types/test-types.yang | 8 ++ .../AttributeIfcSwitchStatement.java | 16 +++- .../attributes/fromxml/ObjectXmlReader.java | 7 ++ .../SimpleUnionAttributeReadingStrategy.java | 43 ++++++++++ .../CompositeAttributeMappingStrategy.java | 20 +++-- .../attributes/mapping/ObjectMapper.java | 16 ++++ ...nionCompositeAttributeMappingStrategy.java | 34 ++++++++ .../CompositeAttributeResolvingStrategy.java | 7 +- .../attributes/resolving/ObjectResolver.java | 21 ++++- ...onCompositeAttributeResolvingStrategy.java | 44 +++++++++++ .../attributes/toxml/ObjectXmlWriter.java | 5 ++ .../SimpleUnionAttributeWritingStrategy.java | 43 ++++++++++ .../confignetconfconnector/util/Util.java | 2 +- .../NetconfMappingTest.java | 25 +++++- .../impl/PropertiesProviderAdapterImpl.java | 11 ++- .../state/schemas/LocationBuilder.java | 23 ++++++ .../netconfMessages/editConfig_setUnions.xml | 30 +++++++ 23 files changed, 451 insertions(+), 31 deletions(-) create mode 100644 opendaylight/config/yang-test/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/controller/config/test/types/rev131127/UnionTestBuilder.java create mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleUnionAttributeReadingStrategy.java create mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/UnionCompositeAttributeMappingStrategy.java create mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/UnionCompositeAttributeResolvingStrategy.java create mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleUnionAttributeWritingStrategy.java create mode 100644 opendaylight/netconf/ietf-netconf-monitoring/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/monitoring/rev101004/netconf/state/schemas/LocationBuilder.java create mode 100644 opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_setUnions.xml diff --git a/opendaylight/config/yang-jmx-generator/pom.xml b/opendaylight/config/yang-jmx-generator/pom.xml index c312cc8493..c66b112566 100644 --- a/opendaylight/config/yang-jmx-generator/pom.xml +++ b/opendaylight/config/yang-jmx-generator/pom.xml @@ -57,6 +57,10 @@ commons-lang3 test + + org.opendaylight.yangtools + binding-type-provider + diff --git a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/TypeProviderWrapper.java b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/TypeProviderWrapper.java index 764ecd3886..c43fead0fc 100644 --- a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/TypeProviderWrapper.java +++ b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/TypeProviderWrapper.java @@ -64,4 +64,8 @@ public class TypeProviderWrapper { public String getJMXParamForBaseType(TypeDefinition baseType) { return typeProvider.getConstructorPropertyName(baseType); } + + public String getJMXParamForUnionInnerType(TypeDefinition unionInnerType) { + return typeProvider.getParamNameFromType(unionInnerType); + } } diff --git a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/JavaAttribute.java b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/JavaAttribute.java index 3e20e4a55a..e01063ef92 100644 --- a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/JavaAttribute.java +++ b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/JavaAttribute.java @@ -7,20 +7,26 @@ */ package org.opendaylight.controller.config.yangjmxgenerator.attribute; +import com.google.common.base.Preconditions; import org.opendaylight.controller.config.yangjmxgenerator.TypeProviderWrapper; 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.UnionTypeDefinition; import javax.management.openmbean.ArrayType; import javax.management.openmbean.CompositeType; import javax.management.openmbean.OpenDataException; import javax.management.openmbean.OpenType; import javax.management.openmbean.SimpleType; +import java.util.Arrays; +import java.util.List; public class JavaAttribute extends AbstractAttribute implements TypedAttribute { + public static final String DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION = "valueOfArtificialUnionProperty"; + private final Type type; private final String nullableDescription, nullableDefault, nullableDefaultWrappedForCode; private final TypeProviderWrapper typeProviderWrapper; @@ -47,6 +53,11 @@ public class JavaAttribute extends AbstractAttribute implements TypedAttribute { this.nullableDescription = leaf.getDescription(); } + public boolean isUnion() { + TypeDefinition base = getBaseType(typeProviderWrapper, typeDefinition); + return base instanceof UnionTypeDefinition; + } + public TypeDefinition getTypeDefinition() { return typeDefinition; } @@ -132,13 +143,70 @@ public class JavaAttribute extends AbstractAttribute implements TypedAttribute { return getArrayType(); } else if (isEnum(baseType)) { return getSimpleType(baseType); - } else if (isDerivedType(baseType)) { + } else if (isUnion()) { + return getCompositeTypeForUnion(baseTypeDefinition); + } else if (isDerivedType(baseType, getType())) { return getCompositeType(baseType, baseTypeDefinition); } return getSimpleType(getType()); } + private OpenType getCompositeTypeForUnion(TypeDefinition baseTypeDefinition) { + Preconditions.checkArgument(baseTypeDefinition instanceof UnionTypeDefinition, + "Expected %s instance but was %s", UnionTypeDefinition.class, baseTypeDefinition); + + List> types = ((UnionTypeDefinition) baseTypeDefinition).getTypes(); + + String[] itemNames = new String[types.size()+1]; + OpenType[] itemTypes = new OpenType[itemNames.length]; + + addArtificialPropertyToUnionCompositeType(baseTypeDefinition, itemNames, itemTypes); + + String description = getNullableDescription() == null ? getAttributeYangName() : getNullableDescription(); + + int i = 1; + for (TypeDefinition innerTypeDefinition : types) { + + Type innerType = typeProviderWrapper.getType(innerTypeDefinition, innerTypeDefinition); + + TypeDefinition baseInnerTypeDefinition = getBaseType(typeProviderWrapper, innerTypeDefinition); + Type innerTypeBaseType = typeProviderWrapper.getType(baseInnerTypeDefinition, baseInnerTypeDefinition); + + OpenType innerCompositeType; + + if(isDerivedType(innerTypeBaseType, innerType)) { + innerCompositeType = getCompositeType(innerTypeBaseType, baseInnerTypeDefinition); + } else { + innerCompositeType = SimpleTypeResolver.getSimpleType(innerType); + } + + itemNames[i] = typeProviderWrapper.getJMXParamForUnionInnerType(innerTypeDefinition); + itemTypes[i++] = innerCompositeType; + } + + String[] descriptions = Arrays.copyOf(itemNames, itemNames.length); + descriptions[0] = DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION; + + try { + return new CompositeType(getUpperCaseCammelCase(), description, itemNames, descriptions, itemTypes); + } catch (OpenDataException e) { + throw new RuntimeException("Unable to create " + CompositeType.class + " with inner elements " + + Arrays.toString(itemTypes), e); + } + } + + public static final Class TYPE_OF_ARTIFICIAL_UNION_PROPERTY = char.class; + + private void addArtificialPropertyToUnionCompositeType(TypeDefinition baseTypeDefinition, String[] itemNames, OpenType[] itemTypes) { + String artificialPropertyName = typeProviderWrapper.getJMXParamForBaseType(baseTypeDefinition); + itemNames[0] = artificialPropertyName; + + OpenType artificialPropertyType = getArrayOpenTypeForSimpleType(TYPE_OF_ARTIFICIAL_UNION_PROPERTY.getName(), + SimpleTypeResolver.getSimpleType(TYPE_OF_ARTIFICIAL_UNION_PROPERTY.getName())); + itemTypes[0] = artificialPropertyType; + } + private boolean isEnum(Type baseType) { return baseType.getFullyQualifiedName().equals(Enum.class.getName()); } @@ -163,12 +231,15 @@ public class JavaAttribute extends AbstractAttribute implements TypedAttribute { throw new RuntimeException("Unable to create " + CompositeType.class + " with inner element of type " + itemTypes, e); } - } private OpenType getArrayType() { String innerTypeFullyQName = getInnerType(getType()); SimpleType innerSimpleType = SimpleTypeResolver.getSimpleType(innerTypeFullyQName); + return getArrayOpenTypeForSimpleType(innerTypeFullyQName, innerSimpleType); + } + + private OpenType getArrayOpenTypeForSimpleType(String innerTypeFullyQName, SimpleType innerSimpleType) { try { ArrayType arrayType = isPrimitive(innerTypeFullyQName) ? new ArrayType<>(innerSimpleType, true) : new ArrayType<>(1, innerSimpleType); @@ -191,8 +262,8 @@ public class JavaAttribute extends AbstractAttribute implements TypedAttribute { return type.getName().endsWith("[]"); } - private boolean isDerivedType(Type baseType) { - return baseType.equals(getType()) == false; + private boolean isDerivedType(Type baseType, Type currentType) { + return baseType.equals(currentType) == false; } private static String getInnerType(Type type) { diff --git a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/SimpleTypeResolver.java b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/SimpleTypeResolver.java index 87b55f3756..f4bd979fac 100644 --- a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/SimpleTypeResolver.java +++ b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/SimpleTypeResolver.java @@ -59,6 +59,8 @@ 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); } } diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/controller/config/test/types/rev131127/UnionTestBuilder.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/controller/config/test/types/rev131127/UnionTestBuilder.java new file mode 100644 index 0000000000..c49319be9f --- /dev/null +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/controller/config/test/types/rev131127/UnionTestBuilder.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2013 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.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.test.types.rev131127; + + +/** +**/ +public class UnionTestBuilder { + + public static UnionTest getDefaultInstance(String defaultValue) { + try { + int i = Integer.valueOf(defaultValue); + return new UnionTest(new ExtendTwice(i)); + } catch (NumberFormatException e) { + return new UnionTest(defaultValue); + } + } + +} 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 9ad7a44915..f7cea0a52a 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 @@ -61,10 +61,6 @@ module config-test-impl { default 127.0.0.1; } - leaf ip { - type inet:ip-address; - // TODO defaults for union default 0:0:0:0:0:0:0:1; - } } leaf as-number { @@ -136,6 +132,16 @@ module config-test-impl { default ONE; } + leaf ip { + type inet:ip-address; + default 0:0:0:0:0:0:0:1; + } + + leaf union-test-attr { + type tt:unionTest; + default 456; + } + leaf sleep-factor { type decimal64 { fraction-digits 2; diff --git a/opendaylight/config/yang-test/src/main/yang/types/test-types.yang b/opendaylight/config/yang-test/src/main/yang/types/test-types.yang index 84fbcb089d..8c086d8ace 100644 --- a/opendaylight/config/yang-test/src/main/yang/types/test-types.yang +++ b/opendaylight/config/yang-test/src/main/yang/types/test-types.yang @@ -23,4 +23,12 @@ module test-types { } } + typedef unionTest { + type union { + type string; + type uint32; + type extend-twice; + } + } + } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributeIfcSwitchStatement.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributeIfcSwitchStatement.java index 697b811d51..cf0e71e67a 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributeIfcSwitchStatement.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributeIfcSwitchStatement.java @@ -29,12 +29,16 @@ public abstract class AttributeIfcSwitchStatement { this.lastAttribute = attributeIfc; + OpenType openType = attributeIfc.getOpenType(); + if (attributeIfc instanceof JavaAttribute) { try { if(((JavaAttribute)attributeIfc).getTypeDefinition() instanceof BinaryTypeDefinition) { - return caseJavaBinaryAttribute(attributeIfc.getOpenType()); + return caseJavaBinaryAttribute(openType); + } else if(((JavaAttribute)attributeIfc).isUnion()) { + return caseJavaUnionAttribute(openType); } else - return caseJavaAttribute(attributeIfc.getOpenType()); + return caseJavaAttribute(openType); } catch (UnknownOpenTypeException e) { throw getIllegalArgumentException(attributeIfc); } @@ -42,9 +46,9 @@ public abstract class AttributeIfcSwitchStatement { } else if (attributeIfc instanceof DependencyAttribute) { return caseDependencyAttribute(((DependencyAttribute) attributeIfc).getOpenType()); } else if (attributeIfc instanceof ListAttribute) { - return caseListAttribute((ArrayType) attributeIfc.getOpenType()); + return caseListAttribute((ArrayType) openType); } else if (attributeIfc instanceof ListDependenciesAttribute) { - return caseListDependeciesAttribute((ArrayType) attributeIfc.getOpenType()); + return caseListDependeciesAttribute((ArrayType) openType); } else if (attributeIfc instanceof TOAttribute) { return caseTOAttribute(((TOAttribute) attributeIfc).getOpenType()); } @@ -52,6 +56,10 @@ public abstract class AttributeIfcSwitchStatement { throw getIllegalArgumentException(attributeIfc); } + protected T caseJavaUnionAttribute(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/fromxml/ObjectXmlReader.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectXmlReader.java index a2691f241c..97c0f4d834 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectXmlReader.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectXmlReader.java @@ -11,6 +11,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attri import com.google.common.base.Preconditions; import com.google.common.collect.Maps; import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc; +import org.opendaylight.controller.config.yangjmxgenerator.attribute.JavaAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute; @@ -47,6 +48,12 @@ public class ObjectXmlReader extends AttributeIfcSwitchStatement openType) { + String mappingKey = JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION; + return new SimpleUnionAttributeReadingStrategy(lastAttribute.getNullableDefault(), mappingKey); + } + @Override public AttributeReadingStrategy caseJavaSimpleAttribute(SimpleType openType) { return new SimpleAttributeReadingStrategy(lastAttribute.getNullableDefault()); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleUnionAttributeReadingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleUnionAttributeReadingStrategy.java new file mode 100644 index 0000000000..2e8b459b70 --- /dev/null +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleUnionAttributeReadingStrategy.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2013 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.fromxml; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; + +import java.util.List; +import java.util.Map; + +public class SimpleUnionAttributeReadingStrategy extends SimpleAttributeReadingStrategy { + + private final String key; + + public SimpleUnionAttributeReadingStrategy(String nullableDefault, String key) { + super(nullableDefault); + this.key = key; + } + + protected Object postprocessParsedValue(String textContent) { + char[] charArray = textContent.toCharArray(); + List chars = Lists.newArrayListWithCapacity(charArray.length); + + for (char c : charArray) { + chars.add(Character.toString(c)); + } + + Map map = Maps.newHashMap(); + map.put(key, chars); + return map; + } + + @Override + protected Object postprocessNullableDefault(String nullableDefault) { + return nullableDefault == null ? null : postprocessParsedValue(nullableDefault); + } +} diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/CompositeAttributeMappingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/CompositeAttributeMappingStrategy.java index 252b13bf68..368e1f12a6 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/CompositeAttributeMappingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/CompositeAttributeMappingStrategy.java @@ -53,17 +53,21 @@ public class CompositeAttributeMappingStrategy extends Map retVal = Maps.newHashMap(); for (String jmxName : jmxToJavaNameMapping.keySet()) { - String innerAttrJmxName = jmxName; - Object innerValue = compositeData.get(innerAttrJmxName); - - AttributeMappingStrategy> attributeMappingStrategy = innerStrategies - .get(innerAttrJmxName); - Optional mapAttribute = attributeMappingStrategy.mapAttribute(innerValue); - if (mapAttribute.isPresent()) - retVal.put(jmxToJavaNameMapping.get(innerAttrJmxName), mapAttribute.get()); + Optional mapped = mapInnerAttribute(compositeData, jmxName, expectedType.getDescription(jmxName)); + if(mapped.isPresent()) + retVal.put(jmxToJavaNameMapping.get(jmxName), mapped.get()); } return Optional.of(retVal); } + protected Optional mapInnerAttribute(CompositeDataSupport compositeData, String jmxName, String description) { + Object innerValue = compositeData.get(jmxName); + + AttributeMappingStrategy> attributeMappingStrategy = innerStrategies + .get(jmxName); + Optional mapAttribute = attributeMappingStrategy.mapAttribute(innerValue); + return mapAttribute; + } + } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java index 6e5bd0d3fe..fb385221c8 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java @@ -90,6 +90,22 @@ public class ObjectMapper extends AttributeIfcSwitchStatement> caseJavaUnionAttribute(OpenType openType) { + Map>> innerStrategies = Maps.newHashMap(); + + Map attributeMapping = Maps.newHashMap(); + + CompositeType compositeType = (CompositeType) openType; + for (String innerAttributeKey : compositeType.keySet()) { + + innerStrategies.put(innerAttributeKey, caseJavaAttribute(compositeType.getType(innerAttributeKey))); + attributeMapping.put(innerAttributeKey, innerAttributeKey); + } + + return new UnionCompositeAttributeMappingStrategy(compositeType, innerStrategies, attributeMapping); + } + private String serviceNameOfDepAttr; private String namespaceOfDepAttr; diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/UnionCompositeAttributeMappingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/UnionCompositeAttributeMappingStrategy.java new file mode 100644 index 0000000000..81a1e53598 --- /dev/null +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/UnionCompositeAttributeMappingStrategy.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2013 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 org.opendaylight.controller.config.yangjmxgenerator.attribute.JavaAttribute; + +import javax.management.openmbean.CompositeDataSupport; +import javax.management.openmbean.CompositeType; +import javax.management.openmbean.OpenType; +import java.util.Map; + +public class UnionCompositeAttributeMappingStrategy extends + CompositeAttributeMappingStrategy { + + + public UnionCompositeAttributeMappingStrategy(CompositeType compositeType, Map>> innerStrategies, Map jmxToJavaNameMapping) { + super(compositeType, innerStrategies, jmxToJavaNameMapping); + } + + @Override + protected Optional mapInnerAttribute(CompositeDataSupport compositeData, String jmxName, String description) { + if(description.equals(JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION) == false) + return Optional.absent(); + + return super.mapInnerAttribute(compositeData, jmxName, description); + } +} 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 c477821051..e8e97f990f 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 @@ -21,7 +21,7 @@ import javax.management.openmbean.OpenDataException; import javax.management.openmbean.OpenType; import java.util.Map; -final class CompositeAttributeResolvingStrategy extends +class CompositeAttributeResolvingStrategy extends AbstractAttributeResolvingStrategy { private final Map>> innerTypes; private final Map yangToJavaAttrMapping; @@ -49,6 +49,7 @@ final class CompositeAttributeResolvingStrategy extends Util.checkType(value, Map.class); Map valueMap = (Map) value; + valueMap = preprocessValueMap(valueMap); Map items = Maps.newHashMap(); Map> openTypes = Maps.newHashMap(); @@ -82,4 +83,8 @@ final class CompositeAttributeResolvingStrategy extends return Optional.of(parsedValue); } + + protected Map preprocessValueMap(Map valueMap) { + return valueMap; + } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java index f5a2511260..a3e2813fa0 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java @@ -72,13 +72,30 @@ public class ObjectResolver extends AttributeIfcSwitchStatement> caseJavaCompositeAttribute(CompositeType openType) { Map>> innerMap = Maps.newHashMap(); - Map yangToJmxMapping = Maps.newHashMap(); + + fillMappingForComposite(openType, innerMap, yangToJmxMapping); + return new CompositeAttributeResolvingStrategy(innerMap, openType, yangToJmxMapping); + } + + private void fillMappingForComposite(CompositeType openType, Map>> innerMap, Map yangToJmxMapping) { for (String innerAttributeKey : openType.keySet()) { innerMap.put(innerAttributeKey, caseJavaAttribute(openType.getType(innerAttributeKey))); yangToJmxMapping.put(innerAttributeKey, innerAttributeKey); } - return new CompositeAttributeResolvingStrategy(innerMap, openType, yangToJmxMapping); + } + + @Override + protected AttributeResolvingStrategy> caseJavaUnionAttribute(OpenType openType) { + + Preconditions.checkState(openType instanceof CompositeType, "Unexpected open type, expected %s but was %s"); + CompositeType compositeType = (CompositeType) openType; + + Map>> innerMap = Maps.newHashMap(); + Map yangToJmxMapping = Maps.newHashMap(); + fillMappingForComposite(compositeType, innerMap, yangToJmxMapping); + + return new UnionCompositeAttributeResolvingStrategy(innerMap, compositeType, yangToJmxMapping); } @Override diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/UnionCompositeAttributeResolvingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/UnionCompositeAttributeResolvingStrategy.java new file mode 100644 index 0000000000..bc99ecf09a --- /dev/null +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/UnionCompositeAttributeResolvingStrategy.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2013 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.Preconditions; +import com.google.common.collect.Maps; +import org.opendaylight.controller.config.yangjmxgenerator.attribute.JavaAttribute; + +import javax.management.openmbean.CompositeType; +import javax.management.openmbean.OpenType; +import java.util.Map; + +final class UnionCompositeAttributeResolvingStrategy extends CompositeAttributeResolvingStrategy { + + UnionCompositeAttributeResolvingStrategy(Map>> innerTypes, + CompositeType openType, Map yangToJavaAttrMapping) { + super(innerTypes, openType, yangToJavaAttrMapping); + } + + protected Map preprocessValueMap(Map valueMap) { + CompositeType openType = getOpenType(); + + Preconditions.checkArgument( + valueMap.size() == 1 && valueMap.containsKey(JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION), + "Unexpected structure of incoming map, expecting one element under %s, but was %s", + JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION, valueMap); + + Map newMap = Maps.newHashMap(); + + for (String key : openType.keySet()) { + if (openType.getDescription(key).equals(JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION)) + newMap.put(key, valueMap.get(JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION)); + else + newMap.put(key, null); + } + return newMap; + } +} diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectXmlWriter.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectXmlWriter.java index a174e9a251..4e870f042d 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectXmlWriter.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectXmlWriter.java @@ -73,6 +73,11 @@ public class ObjectXmlWriter extends AttributeIfcSwitchStatement openType) { + return new SimpleUnionAttributeWritingStrategy(document, key); + } + @Override protected AttributeWritingStrategy caseDependencyAttribute(SimpleType openType) { return new ObjectNameAttributeWritingStrategy(document, key); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleUnionAttributeWritingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleUnionAttributeWritingStrategy.java new file mode 100644 index 0000000000..d75feb273e --- /dev/null +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleUnionAttributeWritingStrategy.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2013 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.toxml; + +import com.google.common.base.Preconditions; +import org.opendaylight.controller.netconf.confignetconfconnector.util.Util; +import org.w3c.dom.Document; + +import java.util.List; +import java.util.Map; + +public class SimpleUnionAttributeWritingStrategy extends SimpleAttributeWritingStrategy { + + /** + * @param document + * @param key + */ + public SimpleUnionAttributeWritingStrategy(Document document, String key) { + super(document, key); + } + + protected Object preprocess(Object value) { + Util.checkType(value, Map.class); + Preconditions.checkArgument(((Map)value).size() == 1, "Unexpected number of values in %s, expected 1", value); + Object listOfStrings = ((Map) value).values().iterator().next(); + Util.checkType(listOfStrings, List.class); + + StringBuilder b = new StringBuilder(); + for (Object character: (List)listOfStrings) { + Util.checkType(character, String.class); + b.append(character); + } + + return b.toString(); + } + +} diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/util/Util.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/util/Util.java index 26719592bb..1c806742e9 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/util/Util.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/util/Util.java @@ -38,7 +38,7 @@ public final class Util { public static void checkType(final Object value, final Class clazz) { Preconditions.checkArgument(clazz.isAssignableFrom(value.getClass()), "Unexpected type " + value.getClass() - + " should be " + clazz); + + " should be " + clazz + " of " + value); } // TODO: add message and proper error types 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 b248342a0a..11cf1aae6a 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 @@ -144,7 +144,7 @@ public class NetconfMappingTest extends AbstractConfigTest { "ref_from_code_to_instance-from-code_1"); edit("netconfMessages/editConfig_addServiceName.xml"); - config = getConfigCandidate(); + config = getConfigCandidate(); assertCorrectServiceNames(config, 7, "ref_test2", "user_to_instance_from_code", "ref_dep_user", "ref_dep_user_two", "ref_from_code_to_instance-from-code_dep_1", "ref_from_code_to_instance-from-code_1", "ref_dep_user_another"); @@ -199,6 +199,29 @@ public class NetconfMappingTest extends AbstractConfigTest { } } + @Test + public void testConfigNetconfUnionTypes() throws Exception { + + createModule(INSTANCE_NAME); + + edit("netconfMessages/editConfig.xml"); + commit(); + Element response = getConfigRunning(); + String trimmedResponse = XmlUtil.toString(response).replaceAll("\\s", ""); + assertContainsString(trimmedResponse, "0:0:0:0:0:0:0:1"); + assertContainsString(trimmedResponse, "456"); + + + edit("netconfMessages/editConfig_setUnions.xml"); + commit(); + response = getConfigRunning(); + + trimmedResponse = XmlUtil.toString(response).replaceAll("\\s", ""); + assertContainsString(trimmedResponse, "127.1.2.3"); + assertContainsString(trimmedResponse, "randomStringForUnion"); + + } + @Test public void testConfigNetconf() throws Exception { diff --git a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PropertiesProviderAdapterImpl.java b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PropertiesProviderAdapterImpl.java index 981be827b7..d9466ff00b 100644 --- a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PropertiesProviderAdapterImpl.java +++ b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PropertiesProviderAdapterImpl.java @@ -1,10 +1,9 @@ -/** - * @author Tomas Olvecky +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. * - * 11 2013 - * - * Copyright (c) 2013 by Cisco Systems, Inc. - * 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.persist.impl; diff --git a/opendaylight/netconf/ietf-netconf-monitoring/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/monitoring/rev101004/netconf/state/schemas/LocationBuilder.java b/opendaylight/netconf/ietf-netconf-monitoring/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/monitoring/rev101004/netconf/state/schemas/LocationBuilder.java new file mode 100644 index 0000000000..0a084b0ff6 --- /dev/null +++ b/opendaylight/netconf/ietf-netconf-monitoring/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/monitoring/rev101004/netconf/state/schemas/LocationBuilder.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2013 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.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.Schema.Location; + + +/** +**/ +public class LocationBuilder { + + public static Location getDefaultInstance(String defaultValue) { + return defaultValue.equals("NETCONF") ? new Location(Location.Enumeration.NETCONF) : new Location(new Uri( + defaultValue)); + } + +} diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_setUnions.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_setUnions.xml new file mode 100644 index 0000000000..21db4b8e42 --- /dev/null +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_setUnions.xml @@ -0,0 +1,30 @@ + + + + + + + set + + merge + + + + + test-impl:impl-netconf + + + instance-from-code + + 127.1.2.3 + randomStringForUnion + + + + + + + + + + -- 2.36.6