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);
}
} 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());
}
throw getIllegalArgumentException(attributeIfc);
}
+ protected T caseJavaUnionAttribute(OpenType<?> openType) {
+ return caseJavaAttribute(openType);
+ }
+
protected T caseJavaBinaryAttribute(OpenType<?> openType) {
return caseJavaAttribute(openType);
}
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;
return new SimpleBinaryAttributeReadingStrategy(lastAttribute.getNullableDefault());
}
+ @Override
+ protected AttributeReadingStrategy caseJavaUnionAttribute(OpenType<?> 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());
--- /dev/null
+/*
+ * 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<String> chars = Lists.newArrayListWithCapacity(charArray.length);
+
+ for (char c : charArray) {
+ chars.add(Character.toString(c));
+ }
+
+ Map<String, Object> map = Maps.newHashMap();
+ map.put(key, chars);
+ return map;
+ }
+
+ @Override
+ protected Object postprocessNullableDefault(String nullableDefault) {
+ return nullableDefault == null ? null : postprocessParsedValue(nullableDefault);
+ }
+}
Map<String, Object> retVal = Maps.newHashMap();
for (String jmxName : jmxToJavaNameMapping.keySet()) {
- String innerAttrJmxName = jmxName;
- Object innerValue = compositeData.get(innerAttrJmxName);
-
- AttributeMappingStrategy<?, ? extends OpenType<?>> 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<?, ? extends OpenType<?>> attributeMappingStrategy = innerStrategies
+ .get(jmxName);
+ Optional<?> mapAttribute = attributeMappingStrategy.mapAttribute(innerValue);
+ return mapAttribute;
+ }
+
}
return new CompositeAttributeMappingStrategy(openType, innerStrategies, attributeMapping);
}
+ @Override
+ protected AttributeMappingStrategy<?, ? extends OpenType<?>> caseJavaUnionAttribute(OpenType<?> openType) {
+ Map<String, AttributeMappingStrategy<?, ? extends OpenType<?>>> innerStrategies = Maps.newHashMap();
+
+ Map<String, String> 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;
--- /dev/null
+/*
+ * 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<String, AttributeMappingStrategy<?, ? extends OpenType<?>>> innerStrategies, Map<String, String> 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);
+ }
+}
import javax.management.openmbean.OpenType;
import java.util.Map;
-final class CompositeAttributeResolvingStrategy extends
+class CompositeAttributeResolvingStrategy extends
AbstractAttributeResolvingStrategy<CompositeDataSupport, CompositeType> {
private final Map<String, AttributeResolvingStrategy<?, ? extends OpenType<?>>> innerTypes;
private final Map<String, String> yangToJavaAttrMapping;
Util.checkType(value, Map.class);
Map<?, ?> valueMap = (Map<?, ?>) value;
+ valueMap = preprocessValueMap(valueMap);
Map<String, Object> items = Maps.newHashMap();
Map<String, OpenType<?>> openTypes = Maps.newHashMap();
return Optional.of(parsedValue);
}
+
+ protected Map<?, ?> preprocessValueMap(Map<?, ?> valueMap) {
+ return valueMap;
+ }
}
@Override
protected AttributeResolvingStrategy<?, ? extends OpenType<?>> caseJavaCompositeAttribute(CompositeType openType) {
Map<String, AttributeResolvingStrategy<?, ? extends OpenType<?>>> innerMap = Maps.newHashMap();
-
Map<String, String> yangToJmxMapping = Maps.newHashMap();
+
+ fillMappingForComposite(openType, innerMap, yangToJmxMapping);
+ return new CompositeAttributeResolvingStrategy(innerMap, openType, yangToJmxMapping);
+ }
+
+ private void fillMappingForComposite(CompositeType openType, Map<String, AttributeResolvingStrategy<?, ? extends OpenType<?>>> innerMap, Map<String, String> 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<?, ? extends OpenType<?>> caseJavaUnionAttribute(OpenType<?> openType) {
+
+ Preconditions.checkState(openType instanceof CompositeType, "Unexpected open type, expected %s but was %s");
+ CompositeType compositeType = (CompositeType) openType;
+
+ Map<String, AttributeResolvingStrategy<?, ? extends OpenType<?>>> innerMap = Maps.newHashMap();
+ Map<String, String> yangToJmxMapping = Maps.newHashMap();
+ fillMappingForComposite(compositeType, innerMap, yangToJmxMapping);
+
+ return new UnionCompositeAttributeResolvingStrategy(innerMap, compositeType, yangToJmxMapping);
}
@Override
--- /dev/null
+/*
+ * 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<String, AttributeResolvingStrategy<?, ? extends OpenType<?>>> innerTypes,
+ CompositeType openType, Map<String, String> yangToJavaAttrMapping) {
+ super(innerTypes, openType, yangToJavaAttrMapping);
+ }
+
+ protected Map<String, Object> 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<String, Object> 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;
+ }
+}
return new SimpleCompositeAttributeWritingStrategy(document, key);
}
+ @Override
+ protected AttributeWritingStrategy caseJavaUnionAttribute(OpenType<?> openType) {
+ return new SimpleUnionAttributeWritingStrategy(document, key);
+ }
+
@Override
protected AttributeWritingStrategy caseDependencyAttribute(SimpleType<?> openType) {
return new ObjectNameAttributeWritingStrategy(document, key);
--- /dev/null
+/*
+ * 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();
+ }
+
+}
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
"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");
}
}
+ @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, "<ipxmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">0:0:0:0:0:0:0:1</ip>");
+ assertContainsString(trimmedResponse, "<union-test-attrxmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">456</union-test-attr>");
+
+
+ edit("netconfMessages/editConfig_setUnions.xml");
+ commit();
+ response = getConfigRunning();
+
+ trimmedResponse = XmlUtil.toString(response).replaceAll("\\s", "");
+ assertContainsString(trimmedResponse, "<ipxmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">127.1.2.3</ip>");
+ assertContainsString(trimmedResponse, "<union-test-attrxmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">randomStringForUnion</union-test-attr>");
+
+ }
+
@Test
public void testConfigNetconf() throws Exception {
-/**
- * @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;
--- /dev/null
+/*
+ * 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));
+ }
+
+}
--- /dev/null
+<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+ <edit-config>
+ <target>
+ <candidate/>
+ </target>
+ <test-option>
+ set
+ </test-option>
+ <default-operation>merge</default-operation>
+ <config>
+ <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <module>
+ <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
+ test-impl:impl-netconf
+ </type>
+
+ <name>instance-from-code</name>
+
+ <ip xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">127.1.2.3</ip>
+ <union-test-attr xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">randomStringForUnion</union-test-attr>
+
+ </module>
+ </modules>
+
+ <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+
+ </services>
+ </config>
+ </edit-config>
+</rpc>