Fixed RESTConf support for identity-ref build-in datatype 01/3701/3
authorTony Tkacik <ttkacik@cisco.com>
Tue, 17 Dec 2013 16:26:05 +0000 (17:26 +0100)
committerTony Tkacik <ttkacik@cisco.com>
Tue, 17 Dec 2013 16:26:05 +0000 (17:26 +0100)
- Created implementation of codec for identityref
- Identityref is supported in XML and JSON
- Tests

Change-Id: I813f1f52e990317b6adf30f1d0d8a164c60a4901
Signed-off-by: Martin Sunal <msunal@cisco.com>
Signed-off-by: Tony Tkacik <ttkacik@cisco.com>
56 files changed:
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonReader.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfProvider.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlMapper.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlReader.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/IdentityValuesDTO.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/SimpleNodeWrapper.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/CnSnToXmlTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/JsonToCnSnTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/TestUtils.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ToJsonBasicDataTypesTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ToJsonIdentityrefTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlToCnSnTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/identityref/identity-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/identityref/identityref-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/instance_identifier/aug-referenced-elements-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/instance_identifier/eferenced-elements-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/instance_identifier/rinstance-identifier-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/array-with-null.json [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/empty-data.json [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/empty-data1.json [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/identityref/identity-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/identityref/identityref-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/identityref/json/data.json [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/multiple-items-in-list.json [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/multiple-leaflist-items.json [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-container-yang/simple-container.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-container.json [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/simple-list1.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/simple-list2.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list.json [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/wrong-top-level1.json [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/wrong-top-level2.json [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/wrong-top-level3.json [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-container-yang/data-container.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-container.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-list-yang/data-container.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-list-yang/data-list.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-list.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-nmspc-in-attributes.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/empty-data.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/identity-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/identityref-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-default-nmspc-in-element.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-default-nmspc-in-parrent-element.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-nmspc-in-element.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-nmspc-in-parrent-element.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-no-nmspc-value-with-prefix.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-no-nmspc-value-without-prefix.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/yang-augments/general-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/yang-augments/identity-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/yang-augments/identityref-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/simple-data-types/xml/data.xml

index a42c468..ea793e9 100644 (file)
@@ -3,15 +3,42 @@ package org.opendaylight.controller.sal.rest.impl;
 import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.io.IOException;
-import java.util.*;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
 
 import javax.activation.UnsupportedDataTypeException;
 
 import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
+import org.opendaylight.controller.sal.restconf.impl.RestCodec;
+import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO;
+import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO.IdentityValue;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.*;
-import org.opendaylight.yangtools.yang.model.api.*;
-import org.opendaylight.yangtools.yang.model.api.type.*;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.api.SimpleNode;
+import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
+import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Preconditions;
 import com.google.gson.stream.JsonWriter;
@@ -20,6 +47,7 @@ class JsonMapper {
 
     private final Set<LeafListSchemaNode> foundLeafLists = new HashSet<>();
     private final Set<ListSchemaNode> foundLists = new HashSet<>();
+    private final Logger logger = LoggerFactory.getLogger(JsonMapper.class); 
 
     public void write(JsonWriter writer, CompositeNode data, DataNodeContainer schema) throws IOException {
         Preconditions.checkNotNull(writer);
@@ -162,17 +190,17 @@ class JsonMapper {
         TypeDefinition<?> baseType = resolveBaseTypeFrom(type);
 
         // TODO check InstanceIdentifierTypeDefinition,
-        // IdentityrefTypeDefinition
         if (baseType instanceof IdentityrefTypeDefinition) {
             if (node.getValue() instanceof QName) {
-                QName qName = (QName) node.getValue();
-
-                ControllerContext contContext = ControllerContext.getInstance();
-                String moduleName = contContext.findModuleByNamespace(qName.getNamespace());
-
-                writer.value(moduleName + ":" + qName.getLocalName());
+                IdentityValuesDTO valueDTO = (IdentityValuesDTO) RestCodec.from(type).serialize(node.getValue());
+                IdentityValue valueFromDTO = valueDTO.getValuesWithNamespaces().get(0);
+                String moduleName = ControllerContext.getInstance().findModuleByNamespace(URI.create(valueFromDTO.getNamespace()));
+                writer.value(moduleName + ":" + valueFromDTO.getValue());
+            } else {
+                logger.debug("Value of " + baseType.getQName().getNamespace() + ":"
+                        + baseType.getQName().getLocalName() + " is not instance of " + QName.class + " but is " + node.getValue().getClass());
+                writer.value(String.valueOf(node.getValue()));
             }
-
         } else if (baseType instanceof LeafrefTypeDefinition) {
             ControllerContext contContext = ControllerContext.getInstance();
             LeafSchemaNode lfSchemaNode = contContext.resolveTypeFromLeafref((LeafrefTypeDefinition) baseType, schema);
index 83e2d20..f4c5034 100644 (file)
@@ -9,6 +9,7 @@ import java.util.Set;
 import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
 import org.opendaylight.controller.sal.restconf.impl.EmptyNodeWrapper;
 import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO;
 
 import com.google.common.collect.Lists;
 import com.google.gson.JsonElement;
@@ -52,8 +53,8 @@ class JsonReader {
     }
 
     private CompositeNodeWrapper createStructureWithRoot(String rootObjectName, JsonObject rootObject) {
-        CompositeNodeWrapper firstNode = new CompositeNodeWrapper(getNamespaceFrom(rootObjectName),
-                getLocalNameFrom(rootObjectName));
+        CompositeNodeWrapper firstNode = new CompositeNodeWrapper(getNamespaceFor(rootObjectName),
+                getLocalNameFor(rootObjectName));
         for (Entry<String, JsonElement> childOfFirstNode : rootObject.entrySet()) {
             addChildToParent(childOfFirstNode.getKey(), childOfFirstNode.getValue(), firstNode);
         }
@@ -62,15 +63,15 @@ class JsonReader {
 
     private void addChildToParent(String childName, JsonElement childType, CompositeNodeWrapper parent) {
         if (childType.isJsonObject()) {
-            CompositeNodeWrapper child = new CompositeNodeWrapper(getNamespaceFrom(childName),
-                    getLocalNameFrom(childName));
+            CompositeNodeWrapper child = new CompositeNodeWrapper(getNamespaceFor(childName),
+                    getLocalNameFor(childName));
             parent.addValue(child);
             for (Entry<String, JsonElement> childOfChild : childType.getAsJsonObject().entrySet()) {
                 addChildToParent(childOfChild.getKey(), childOfChild.getValue(), child);
             }
         } else if (childType.isJsonArray()) {
             if (childType.getAsJsonArray().size() == 1 && childType.getAsJsonArray().get(0).isJsonNull()) {
-                parent.addValue(new EmptyNodeWrapper(getNamespaceFrom(childName), getLocalNameFrom(childName)));
+                parent.addValue(new EmptyNodeWrapper(getNamespaceFor(childName), getLocalNameFor(childName)));
 
             } else {
                 for (JsonElement childOfChildType : childType.getAsJsonArray()) {
@@ -80,24 +81,36 @@ class JsonReader {
         } else if (childType.isJsonPrimitive()) {
             JsonPrimitive childPrimitive = childType.getAsJsonPrimitive();
             String value = childPrimitive.getAsString();
-            parent.addValue(new SimpleNodeWrapper(getNamespaceFrom(childName), getLocalNameFrom(childName), value));
+            parent.addValue(new SimpleNodeWrapper(getNamespaceFor(childName), getLocalNameFor(childName),
+                    resolveValueOfElement(value)));
         }
     }
 
-    private URI getNamespaceFrom(String jsonElementName) {
-        int indexOfDelimeter = jsonElementName.lastIndexOf(':');
-        if (indexOfDelimeter == -1) {
+    private URI getNamespaceFor(String jsonElementName) {
+        String[] moduleNameAndLocalName = jsonElementName.split(":");
+        if (moduleNameAndLocalName.length != 2) { // it is not "moduleName:localName"
             return null;
         }
-        return URI.create(jsonElementName.substring(0, indexOfDelimeter));
+        return URI.create(moduleNameAndLocalName[0]);
     }
 
-    private String getLocalNameFrom(String jsonElementName) {
-        int indexOfDelimeter = jsonElementName.lastIndexOf(':');
-        if (indexOfDelimeter == -1) {
+    private String getLocalNameFor(String jsonElementName) {
+        String[] moduleNameAndLocalName = jsonElementName.split(":");
+        if (moduleNameAndLocalName.length != 2) { // it is not "moduleName:localName"
             return jsonElementName;
         }
-        return jsonElementName.substring(indexOfDelimeter + 1, jsonElementName.length());
+        return moduleNameAndLocalName[1];
+    }
+
+    /**
+     * @param value
+     *            value of json element
+     * @return if value is "moduleName:localName" then {@link IdentityValuesDTO} else
+     *         the same string as parameter "value"
+     */
+    private Object resolveValueOfElement(String value) {
+        URI namespace = getNamespaceFor(value);
+        return namespace == null ? value : new IdentityValuesDTO(namespace.toString(), getLocalNameFor(value), null);
     }
 
 }
index 53b401e..242f18d 100644 (file)
@@ -20,7 +20,7 @@ import org.osgi.util.tracker.ServiceTrackerCustomizer;
 
 public class RestconfProvider implements BundleActivator, Provider, ServiceTrackerCustomizer<Broker, Broker> {
 
-    public final static String NOT_INITALIZED_MSG = "Restcof is not initialized yet. Please try again later";
+    public final static String NOT_INITALIZED_MSG = "Restconf is not initialized yet. Please try again later";
     
     private ListenerRegistration<SchemaServiceListener> listenerRegistration;
     private ServiceTracker<Broker, Broker> brokerServiceTrancker;
index 4a077e6..f580b32 100644 (file)
@@ -7,6 +7,9 @@ import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 
+import org.opendaylight.controller.sal.restconf.impl.RestCodec;
+import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO;
+import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO.IdentityValue;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.Node;
@@ -92,10 +95,21 @@ public class XmlMapper {
 
         TypeDefinition<?> baseType = resolveBaseTypeFrom(type);
 
-        if (baseType instanceof IdentityrefTypeDefinition && node.getValue() instanceof QName) {
-            QName value = (QName) node.getValue();
-            element.setAttribute("xmlns:x", value.getNamespace().toString());
-            element.setTextContent("x:" + value.getLocalName());
+        if (baseType instanceof IdentityrefTypeDefinition) {
+            if (node.getValue() instanceof QName) {
+                IdentityValuesDTO valueDTO = (IdentityValuesDTO) RestCodec.from(type).serialize(node.getValue());
+                IdentityValue value = valueDTO.getValuesWithNamespaces().get(0);
+                String prefix = "x";
+                if (value.getPrefix() != null && !value.getPrefix().isEmpty()) {
+                    prefix = value.getPrefix();
+                }
+                element.setAttribute("xmlns:" + prefix, value.getNamespace());
+                element.setTextContent(prefix + ":" + value.getValue());
+            } else {
+                logger.debug("Value of " + baseType.getQName().getNamespace() + ":"
+                        + baseType.getQName().getLocalName() + " is not instance of " + QName.class + " but is " + node.getValue().getClass());
+                element.setTextContent(String.valueOf(node.getValue()));
+            }
         } else {
             Object value = node.getValue();
             if (value != null) {
index a532814..014e839 100644 (file)
@@ -14,6 +14,7 @@ import javax.xml.stream.events.StartElement;
 import javax.xml.stream.events.XMLEvent;
 
 import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO;
 import org.opendaylight.controller.sal.restconf.impl.EmptyNodeWrapper;
 import org.opendaylight.controller.sal.restconf.impl.NodeWrapper;
 import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
@@ -123,11 +124,24 @@ public class XmlReader {
         return false;
     }
 
+    private CompositeNodeWrapper resolveCompositeNodeFromStartElement(final StartElement startElement) {
+        checkArgument(startElement != null, "Start Element cannot be NULL!");
+        return new CompositeNodeWrapper(getNamespaceFor(startElement), getLocalNameFor(startElement));
+    }
+
     private NodeWrapper<? extends Node<?>> resolveSimpleNodeFromStartElement(final StartElement startElement)
             throws XMLStreamException {
         checkArgument(startElement != null, "Start Element cannot be NULL!");
-        String data = null;
+        String data = getValueOf(startElement);
+        if (data == null) {
+            return new EmptyNodeWrapper(getNamespaceFor(startElement), getLocalNameFor(startElement));
+        }
+        return new SimpleNodeWrapper(getNamespaceFor(startElement), getLocalNameFor(startElement),
+                resolveValueOfElement(data, startElement));
+    }
 
+    private String getValueOf(StartElement startElement) throws XMLStreamException {
+        String data = null;
         if (eventReader.hasNext()) {
             final XMLEvent innerEvent = eventReader.peek();
             if (innerEvent.isCharacters()) {
@@ -143,24 +157,36 @@ public class XmlReader {
                 }
             }
         }
-        if(data == null) {
-            return new EmptyNodeWrapper(getNamespaceFrom(startElement), getLocalNameFrom(startElement));
-        }
-        return new SimpleNodeWrapper(getNamespaceFrom(startElement), getLocalNameFrom(startElement), data);
+        return data;
     }
 
-    private CompositeNodeWrapper resolveCompositeNodeFromStartElement(final StartElement startElement) {
-        checkArgument(startElement != null, "Start Element cannot be NULL!");
-        return new CompositeNodeWrapper(getNamespaceFrom(startElement), getLocalNameFrom(startElement));
-    }
-
-    private String getLocalNameFrom(StartElement startElement) {
+    private String getLocalNameFor(StartElement startElement) {
         return startElement.getName().getLocalPart();
     }
 
-    private URI getNamespaceFrom(StartElement startElement) {
+    private URI getNamespaceFor(StartElement startElement) {
         String namespaceURI = startElement.getName().getNamespaceURI();
         return namespaceURI.isEmpty() ? null : URI.create(namespaceURI);
     }
 
+    /**
+     * @param value
+     *            value of startElement
+     * @param startElement
+     *            element containing value
+     * @return if value is "prefix:value" then {@link IdentityValuesDTO} else the same
+     *         string as parameter "value"
+     */
+    private Object resolveValueOfElement(String value, StartElement startElement) {
+        String[] namespaceAndValue = value.split(":");
+        if (namespaceAndValue.length != 2) { // it is not "prefix:value"
+            return value;
+        }
+        String namespace = startElement.getNamespaceContext().getNamespaceURI(namespaceAndValue[0]);
+        if (namespace != null && !namespace.isEmpty()) {
+            return new IdentityValuesDTO(namespace, namespaceAndValue[1], namespaceAndValue[0]);
+        }
+        return value;
+    }
+
 }
index 930aa66..406480d 100644 (file)
@@ -1,6 +1,7 @@
 package org.opendaylight.controller.sal.restconf.impl
 
 import com.google.common.collect.BiMap
+import com.google.common.collect.FluentIterable
 import com.google.common.collect.HashBiMap
 import java.net.URI
 import java.net.URLDecoder
@@ -18,6 +19,7 @@ import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.InstanceIdent
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument
+import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec
 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode
 import org.opendaylight.yangtools.yang.model.api.ChoiceNode
 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
@@ -28,14 +30,12 @@ import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
 import org.opendaylight.yangtools.yang.model.api.RpcDefinition
 import org.opendaylight.yangtools.yang.model.api.SchemaContext
 import org.opendaylight.yangtools.yang.model.api.SchemaNode
+import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition
 import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition
 import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil
+import org.slf4j.LoggerFactory
 
 import static com.google.common.base.Preconditions.*
-import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec
-import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition
-import org.slf4j.LoggerFactory
-import com.google.common.collect.FluentIterable
 
 class ControllerContext implements SchemaServiceListener {
     val static LOG = LoggerFactory.getLogger(ControllerContext)
@@ -96,7 +96,7 @@ class ControllerContext implements SchemaServiceListener {
         return getLatestModule(startModule)
     }
 
-    private def getLatestModule(String moduleName) {
+    def getLatestModule(String moduleName) {
         checkPreconditions
         checkArgument(moduleName !== null && !moduleName.empty)
         val modules = schemas.modules.filter[m|m.name == moduleName]
@@ -142,20 +142,37 @@ class ControllerContext implements SchemaServiceListener {
         var module = uriToModuleName.get(namespace)
         if (module === null) {
             val moduleSchemas = schemas.findModuleByNamespace(namespace);
-            if(moduleSchemas === null) throw new IllegalArgumentException()
+            if(moduleSchemas === null) return null
             var latestModule = moduleSchemas.head
             for (m : moduleSchemas) {
                 if (m.revision.after(latestModule.revision)) {
                     latestModule = m
                 }
             }
-            if(latestModule === null) throw new IllegalArgumentException()
+            if(latestModule === null) return null
             uriToModuleName.put(namespace, latestModule.name)
             module = latestModule.name;
         }
         return module
     }
 
+    def findNamespaceByModule(String module) {
+        var namespace = moduleNameToUri.get(module)
+        if (namespace === null) {
+            val moduleSchemas = schemas.modules.filter[it|it.name.equals(module)]
+            var latestModule = moduleSchemas.head
+            for (m : moduleSchemas) {
+                if (m.revision.after(latestModule.revision)) {
+                    latestModule = m
+                }
+            }
+            if(latestModule === null) return null
+            namespace = latestModule.namespace
+            uriToModuleName.put(namespace, latestModule.name)
+        }
+        return namespace
+    }
+
     def CharSequence toRestconfIdentifier(QName qname) {
         checkPreconditions
         var module = uriToModuleName.get(qname.namespace)
@@ -295,9 +312,9 @@ class ControllerContext implements SchemaServiceListener {
         val typedef = (node as LeafSchemaNode).type;
         
         var decoded = TypeDefinitionAwareCodec.from(typedef)?.deserialize(urlDecoded)
-        if(decoded == null) {
+        if(decoded === null) {
             var baseType = typedef
-            while (baseType.baseType != null) {
+            while (baseType.baseType !== null) {
                 baseType = baseType.baseType;
             }
             if(baseType instanceof IdentityrefTypeDefinition) {
diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/IdentityValuesDTO.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/IdentityValuesDTO.java
new file mode 100644 (file)
index 0000000..6924fb6
--- /dev/null
@@ -0,0 +1,60 @@
+package org.opendaylight.controller.sal.restconf.impl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public final class IdentityValuesDTO {
+
+    private final List<IdentityValue> elementData = new ArrayList<>();
+
+    public IdentityValuesDTO(String namespace, String value, String prefix) {
+        elementData.add(new IdentityValue(namespace, value, prefix));
+    }
+
+    public void add(String namespace, String value, String prefix) {
+        elementData.add(new IdentityValue(namespace, value, prefix));
+    }
+
+    public List<IdentityValue> getValuesWithNamespaces() {
+        return Collections.unmodifiableList(elementData);
+    }
+
+    public static final class IdentityValue {
+
+        private String namespace;
+        private String value;
+        private String prefix;
+
+        public IdentityValue(String namespace, String value, String prefix) {
+            this.namespace = namespace;
+            this.value = value;
+            this.prefix = prefix;
+        }
+
+        public String getNamespace() {
+            return namespace;
+        }
+
+        public void setNamespace(String namespace) {
+            this.namespace = namespace;
+        }
+
+        public String getValue() {
+            return value;
+        }
+
+        public void setValue(String value) {
+            this.value = value;
+        }
+
+        public String getPrefix() {
+            return prefix;
+        }
+
+        public void setPrefix(String prefix) {
+            this.prefix = prefix;
+        }
+
+    }
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java
new file mode 100644 (file)
index 0000000..6452b72
--- /dev/null
@@ -0,0 +1,75 @@
+package org.opendaylight.controller.sal.restconf.impl;
+
+import java.net.URI;
+
+import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO.IdentityValue;
+import org.opendaylight.yangtools.concepts.Codec;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.codec.IdentityrefCodec;
+import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
+
+public class RestCodec {
+    
+    @SuppressWarnings("rawtypes")
+    public static final Codec IDENTITYREF_DEFAULT_CODEC = new IdentityrefCodecImpl();
+    
+    private RestCodec() {
+    }
+    
+    public static final Codec<Object, Object> from(TypeDefinition<?> typeDefinition) {
+        return new ObjectCodec(typeDefinition);
+    }
+    
+    public static final class ObjectCodec implements Codec<Object, Object> {
+
+        private TypeDefinition<?> type;
+        
+        private ObjectCodec(TypeDefinition<?> typeDefinition) {
+            type = typeDefinition;
+        }
+        
+        @SuppressWarnings("unchecked")
+        @Override
+        public Object deserialize(Object input) {
+            if (type instanceof IdentityrefTypeDefinition) {
+                return IDENTITYREF_DEFAULT_CODEC.deserialize(input);
+            } else {
+                return TypeDefinitionAwareCodec.from(type).deserialize(String.valueOf(input));
+            }
+        }
+
+        @SuppressWarnings("unchecked")
+        @Override
+        public Object serialize(Object input) {
+            if (type instanceof IdentityrefTypeDefinition) {
+                return IDENTITYREF_DEFAULT_CODEC.serialize(input);
+            } else {
+                return TypeDefinitionAwareCodec.from(type).serialize(input);
+            }
+        }
+        
+    }
+    
+    public static class IdentityrefCodecImpl implements IdentityrefCodec<IdentityValuesDTO> {
+
+        @Override
+        public IdentityValuesDTO serialize(QName data) {
+            return new IdentityValuesDTO(data.getNamespace().toString(), data.getLocalName(), data.getPrefix());
+        }
+
+        @Override
+        public QName deserialize(IdentityValuesDTO data) {
+            IdentityValue valueWithNamespace = data.getValuesWithNamespaces().get(0);
+            String namespace = valueWithNamespace.getNamespace();
+            URI validNamespace = ControllerContext.getInstance().findNamespaceByModule(namespace);
+            if (validNamespace == null) {
+                validNamespace = URI.create(namespace);
+            }
+            return QName.create(validNamespace, null, valueWithNamespace.getValue());
+        }
+
+    }
+    
+}
index 02a4b18..4645a41 100644 (file)
@@ -10,7 +10,6 @@ import org.opendaylight.yangtools.yang.common.QName
 import org.opendaylight.yangtools.yang.data.api.CompositeNode
 import org.opendaylight.yangtools.yang.data.api.Node
 import org.opendaylight.yangtools.yang.data.impl.NodeFactory
-import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec
 import org.opendaylight.yangtools.yang.model.api.ChoiceNode
 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
@@ -19,6 +18,7 @@ import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode
 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition
+import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition
 
 import static javax.ws.rs.core.Response.Status.*
 
@@ -150,7 +150,7 @@ class RestconfImpl implements RestconfService {
         }
         val moduleName = controllerContext.findModuleByNamespace(validQName.namespace);
         if (nodeBuilder.namespace === null || nodeBuilder.namespace == validQName.namespace ||
-            nodeBuilder.namespace.path == moduleName) {
+            nodeBuilder.namespace.toString == moduleName) {
             nodeBuilder.qname = validQName
         } else {
             throw new ResponseException(BAD_REQUEST,
@@ -183,10 +183,17 @@ class RestconfImpl implements RestconfService {
             }
         } else if (nodeBuilder instanceof SimpleNodeWrapper) {
             val simpleNode = (nodeBuilder as SimpleNodeWrapper)
-            val stringValue = simpleNode.value as String;
-
-            val objectValue = TypeDefinitionAwareCodec.from(schema.typeDefinition)?.deserialize(stringValue);
-            simpleNode.setValue(objectValue)
+            val value = simpleNode.value
+            var inputValue = value;
+            
+            if (schema.typeDefinition instanceof IdentityrefTypeDefinition) {
+                if (value instanceof String) {
+                    inputValue = new IdentityValuesDTO(validQName.namespace.toString, value as String, null)
+                } // else value is instance of ValuesDTO
+            }
+            
+            val outputValue = RestCodec.from(schema.typeDefinition)?.deserialize(inputValue);
+            simpleNode.setValue(outputValue)
         } else if (nodeBuilder instanceof EmptyNodeWrapper) {
             val emptyNodeBuilder = nodeBuilder as EmptyNodeWrapper
             if (schema instanceof LeafSchemaNode) {
@@ -200,11 +207,19 @@ class RestconfImpl implements RestconfService {
     }
 
     private def dispatch TypeDefinition<?> typeDefinition(LeafSchemaNode node) {
-        node.type
+        var baseType = node.type
+        while (baseType.baseType !== null) {
+            baseType = baseType.baseType;
+        }
+        baseType
     }
 
     private def dispatch TypeDefinition<?> typeDefinition(LeafListSchemaNode node) {
-        node.type
+        var TypeDefinition<?> baseType = node.type
+        while (baseType.baseType !== null) {
+            baseType = baseType.baseType;
+        }
+        baseType
     }
 
     private def DataSchemaNode findFirstSchemaByLocalName(String localName, Set<DataSchemaNode> schemas) {
index 9f3c6e5..97f8102 100644 (file)
@@ -13,7 +13,7 @@ import com.google.common.base.Preconditions;
 
 public final class SimpleNodeWrapper implements NodeWrapper<SimpleNode<?>>, SimpleNode<Object> {
     
-    private SimpleNode<?> simpleNode;
+    private SimpleNode<Object> simpleNode;
     
     private String localName;
     private Object value;
@@ -25,7 +25,7 @@ public final class SimpleNodeWrapper implements NodeWrapper<SimpleNode<?>>, Simp
         this.value = value;
     }
     
-    public SimpleNodeWrapper(URI namespace, String localName, String value) {
+    public SimpleNodeWrapper(URI namespace, String localName, Object value) {
         this(localName, value);
         this.namespace = namespace;
     }
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/CnSnToXmlTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/CnSnToXmlTest.java
new file mode 100644 (file)
index 0000000..d8261a6
--- /dev/null
@@ -0,0 +1,89 @@
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.StringWriter;
+import java.util.Set;
+
+import javax.activation.UnsupportedDataTypeException;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.XmlMapper;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.ModifyAction;
+import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.api.MutableSimpleNode;
+import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.w3c.dom.Document;
+
+public class CnSnToXmlTest {
+
+    private static Set<Module> modules;
+    private static DataSchemaNode dataSchemaNode;
+
+    @BeforeClass
+    public static void initialization() {
+        modules = TestUtils.resolveModules("/cnsn-to-xml/identityref");
+        assertEquals(2, modules.size());
+        Module module = TestUtils.resolveModule("identityref-module", modules);
+        assertNotNull(module);
+        dataSchemaNode = TestUtils.resolveDataSchemaNode(module, "cont");
+        assertNotNull(dataSchemaNode);
+
+    }
+
+    @Test
+    public void compositeNodeToXMLTest() {
+        XmlMapper xmlMapper = new XmlMapper();
+        String xmlString = null;
+        if (dataSchemaNode instanceof DataNodeContainer) {
+            try {
+                Document doc = xmlMapper.write(prepareData(), (DataNodeContainer) dataSchemaNode);
+                DOMSource domSource = new DOMSource(doc);
+                StringWriter writer = new StringWriter();
+                StreamResult result = new StreamResult(writer);
+                TransformerFactory tf = TransformerFactory.newInstance();
+                Transformer transformer = tf.newTransformer();
+                transformer.transform(domSource, result);
+                xmlString = writer.toString();
+
+            } catch (UnsupportedDataTypeException | TransformerException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+        }
+        assertNotNull(xmlString);
+        assertTrue(xmlString.contains("<lf1 xmlns:x=\"identity:module\">x:iden</lf1>"));
+
+    }
+
+    private CompositeNode prepareData() {
+        MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(
+                TestUtils.buildQName("cont", "identityref:module", "2013-12-2"), null, null, ModifyAction.CREATE, null);
+        MutableCompositeNode cont1 = NodeFactory
+                .createMutableCompositeNode(TestUtils.buildQName("cont1", "identityref:module", "2013-12-2"), cont,
+                        null, ModifyAction.CREATE, null);
+        cont.getChildren().add(cont1);
+
+        MutableSimpleNode<Object> lf11 = NodeFactory.createMutableSimpleNode(
+                TestUtils.buildQName("lf1", "identityref:module", "2013-12-2"), cont1,
+                TestUtils.buildQName("iden", "identity:module", "2013-12-2"), ModifyAction.CREATE, null);
+        cont1.getChildren().add(lf11);
+        cont1.init();
+        cont.init();
+
+        return cont;
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/JsonToCnSnTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/JsonToCnSnTest.java
new file mode 100644 (file)
index 0000000..546becb
--- /dev/null
@@ -0,0 +1,407 @@
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import static org.junit.Assert.*;
+
+import java.io.*;
+import java.net.URISyntaxException;
+import java.util.List;
+import java.util.Set;
+
+import javax.ws.rs.WebApplicationException;
+
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
+import org.opendaylight.controller.sal.restconf.impl.*;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.*;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.gson.JsonSyntaxException;
+
+public class JsonToCnSnTest {
+
+    private static final Logger LOG = LoggerFactory.getLogger(JsonToCnSnTest.class);
+
+    @Test
+    public void simpleListTest() {
+        simpleTest("/json-to-cnsn/simple-list.json", "/json-to-cnsn/simple-list-yang", "lst", "simple:list:yang1",
+                "simple-list-yang1");
+    }
+
+    @Test
+    public void simpleContainerTest() {
+        simpleTest("/json-to-cnsn/simple-container.json", "/json-to-cnsn/simple-container-yang", "cont",
+                "simple:container:yang", "simple-container-yang");
+    }
+
+    /**
+     * test if for every leaf list item is simple node instance created
+     */
+    @Test
+    public void multipleItemsInLeafList() {
+        CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/multiple-leaflist-items.json", true);
+        assertNotNull(compositeNode);
+        assertEquals(3, compositeNode.getChildren().size());
+
+        boolean lflst1_1 = false;
+        boolean lflst1_2 = false;
+        boolean lflst1_3 = false;
+
+        for (Node<?> node : compositeNode.getChildren()) {
+            assertEquals("lflst1", node.getNodeType().getLocalName());
+            assertTrue(node instanceof SimpleNode<?>);
+            SimpleNode<?> simpleNode = (SimpleNode<?>) node;
+            if (simpleNode.getValue().equals("45")) {
+                lflst1_1 = true;
+            } else if (simpleNode.getValue().equals("55")) {
+                lflst1_2 = true;
+            } else if (simpleNode.getValue().equals("66")) {
+                lflst1_3 = true;
+            }
+        }
+
+        assertTrue(lflst1_1);
+        assertTrue(lflst1_2);
+        assertTrue(lflst1_3);
+
+    }
+
+    /**
+     * List contains 4 items and in every item are other elements. It is
+     * supposed that there should be: lf11, lflst11, cont11, lst11
+     */
+    @Test
+    public void multipleItemsInListTest() {
+        CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/multiple-items-in-list.json", true);
+        assertNotNull(compositeNode);
+
+        assertEquals("lst", compositeNode.getNodeType().getLocalName());
+
+        verityMultipleItemsInList(compositeNode);
+    }
+
+    @Test
+    public void nullArrayToSimpleNodeWithNullValueTest() {
+        CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/array-with-null.json", true);
+        assertNotNull(compositeNode);
+        assertEquals("cont", compositeNode.getNodeType().getLocalName());
+
+        assertNotNull(compositeNode.getChildren());
+        assertEquals(1, compositeNode.getChildren().size());
+        Node<?> lfNode = compositeNode.getChildren().iterator().next();
+
+        assertTrue(lfNode instanceof SimpleNode<?>);
+        assertEquals(null, ((SimpleNode<?>) lfNode).getValue());
+
+    }
+
+    @Test
+    public void incorrectTopLevelElementsTest() {
+        Throwable cause1 = null;
+        try {
+            compositeContainerFromJson("/json-to-cnsn/wrong-top-level1.json", true);
+        } catch (WebApplicationException e) {
+            cause1 = e;
+        }
+
+        assertNotNull(cause1);
+        assertTrue(cause1
+                .getCause()
+                .getMessage()
+                .contains(
+                        "First element in Json Object has to be \"Object\" or \"Array with one Object element\". Other scenarios are not supported yet."));
+
+        Throwable cause2 = null;
+        try {
+            compositeContainerFromJson("/json-to-cnsn/wrong-top-level2.json", true);
+        } catch (WebApplicationException e) {
+            cause2 = e;
+        }
+        assertNotNull(cause2);
+        assertTrue(cause2.getCause().getMessage().contains("Json Object should contain one element"));
+
+        Throwable cause3 = null;
+        try {
+            compositeContainerFromJson("/json-to-cnsn/wrong-top-level3.json", true);
+        } catch (WebApplicationException e) {
+            cause3 = e;
+        }
+        assertNotNull(cause3);
+        assertTrue(cause3
+                .getCause()
+                .getMessage()
+                .contains(
+                        "First element in Json Object has to be \"Object\" or \"Array with one Object element\". Other scenarios are not supported yet."));
+
+    }
+
+    /**
+     * if leaf list with no data is in json then no corresponding data is
+     * created in composite node. if leaf with no data then exception is raised
+     */
+    @Test
+    public void emptyDataReadTest() {
+        CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/empty-data.json", true);
+
+        assertNotNull(compositeNode);
+
+        assertEquals("cont", compositeNode.getNodeType().getLocalName());
+        assertTrue(compositeNode instanceof CompositeNode);
+        List<Node<?>> children = ((CompositeNode) compositeNode).getChildren();
+        assertEquals(1, children.size());
+        assertEquals("lflst2", children.get(0).getNodeType().getLocalName());
+        assertEquals("45", children.get(0).getValue());
+
+        String reason = null;
+        try {
+            compositeContainerFromJson("/json-to-cnsn/empty-data1.json", true);
+        } catch (JsonSyntaxException e) {
+            reason = e.getMessage();
+        }
+
+        assertTrue(reason.contains("Expected value at line"));
+
+    }
+
+    /**
+     * Tests whether namespace <b>stay unchanged</b> if concrete values are
+     * present in composite or simple node and if the method for update is
+     * called.
+     * 
+     */
+    @Test
+    public void notSupplyNamespaceIfAlreadySupplied() {
+
+        CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/simple-list.json");
+        assertNotNull(compositeNode);
+
+        DataSchemaNode dataSchemaNode1 = null;
+        DataSchemaNode dataSchemaNode2 = null;
+        try {
+            dataSchemaNode1 = TestUtils.obtainSchemaFromYang("/json-to-cnsn/simple-list-yang", "simple-list-yang1");
+            dataSchemaNode2 = TestUtils.obtainSchemaFromYang("/json-to-cnsn/simple-list-yang", "simple-list-yang2");
+        } catch (FileNotFoundException e) {
+            LOG.error(e.getMessage());
+            assertTrue(false);
+        }
+        assertNotNull(dataSchemaNode1);
+        assertNotNull(dataSchemaNode2);
+
+        // supplement namespaces according to first data schema -
+        // "simple:data:types1"
+        TestUtils.supplementNamespace(dataSchemaNode1, compositeNode);
+
+        assertTrue(compositeNode instanceof CompositeNodeWrapper);
+        CompositeNode compNode = ((CompositeNodeWrapper) compositeNode).unwrap();
+
+        assertEquals("lst", compNode.getNodeType().getLocalName());
+        verifyCompositeNode(compNode, "simple:list:yang1");
+
+        // dataSchemaNode2 should't be taken into account, because compNode
+        // isn't CompositeNodeWrapper
+        TestUtils.supplementNamespace(dataSchemaNode2, compNode);
+        verifyCompositeNode(compNode, "simple:list:yang1");
+
+    }
+
+    @Test
+    public void jsonIdentityrefToCompositeNode() {
+        CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/identityref/json/data.json");
+        assertNotNull(compositeNode);
+
+        Set<Module> modules = TestUtils.resolveModules("/json-to-cnsn/identityref");
+        assertEquals(2, modules.size());
+        Module module = TestUtils.resolveModule("identityref-module", modules);
+        assertNotNull(module);
+        DataSchemaNode dataSchemaNode = TestUtils.resolveDataSchemaNode(module, null);
+        assertNotNull(dataSchemaNode);
+
+        RestconfImpl restconf = RestconfImpl.getInstance();
+        ControllerContext.getInstance().setSchemas(TestUtils.loadSchemaContext(modules));
+
+        TestUtils.prepareMockForRestconfBeforeNormalization(modules, dataSchemaNode, restconf);
+
+        restconf.createConfigurationData("identityref-module:cont", compositeNode);
+
+        assertEquals("cont", compositeNode.getNodeType().getLocalName());
+
+        List<Node<?>> childs = compositeNode.getChildren();
+        assertEquals(1, childs.size());
+        Node<?> nd = childs.iterator().next();
+        assertTrue(nd instanceof CompositeNode);
+        assertEquals("cont1", nd.getNodeType().getLocalName());
+
+        childs = ((CompositeNode) nd).getChildren();
+        assertEquals(4, childs.size());
+        SimpleNode<?> lf11 = null;
+        SimpleNode<?> lf12 = null;
+        SimpleNode<?> lf13 = null;
+        SimpleNode<?> lf14 = null;
+        for (Node<?> child : childs) {
+            assertTrue(child instanceof SimpleNode);
+            if (child.getNodeType().getLocalName().equals("lf11")) {
+                lf11 = (SimpleNode<?>) child;
+            } else if (child.getNodeType().getLocalName().equals("lf12")) {
+                lf12 = (SimpleNode<?>) child;
+            } else if (child.getNodeType().getLocalName().equals("lf13")) {
+                lf13 = (SimpleNode<?>) child;
+            } else if (child.getNodeType().getLocalName().equals("lf14")) {
+                lf14 = (SimpleNode<?>) child;
+            }
+        }
+
+        assertTrue(lf11.getValue() instanceof QName);
+        assertEquals("iden", ((QName) lf11.getValue()).getLocalName());
+        assertEquals("identity:module", ((QName) lf11.getValue()).getNamespace().toString());
+
+        assertTrue(lf12.getValue() instanceof QName);
+        assertEquals("iden_local", ((QName) lf12.getValue()).getLocalName());
+        assertEquals("identityref:module", ((QName) lf12.getValue()).getNamespace().toString());
+
+        assertTrue(lf13.getValue() instanceof QName);
+        assertEquals("iden_local", ((QName) lf13.getValue()).getLocalName());
+        assertEquals("identityref:module", ((QName) lf13.getValue()).getNamespace().toString());
+
+        assertTrue(lf14.getValue() instanceof QName);
+        assertEquals("iden_local", ((QName) lf14.getValue()).getLocalName());
+        assertEquals("identity:module", ((QName) lf14.getValue()).getNamespace().toString());
+    }
+
+    private void simpleTest(String jsonPath, String yangPath, String topLevelElementName, String namespace,
+            String moduleName) {
+        CompositeNode compositeNode = compositeContainerFromJson(jsonPath);
+        assertNotNull(compositeNode);
+
+        DataSchemaNode dataSchemaNode = null;
+        try {
+            dataSchemaNode = TestUtils.obtainSchemaFromYang(yangPath, moduleName);
+        } catch (FileNotFoundException e) {
+            LOG.error(e.getMessage());
+            assertTrue(false);
+        }
+        assertNotNull(dataSchemaNode);
+
+        TestUtils.supplementNamespace(dataSchemaNode, compositeNode);
+
+        assertTrue(compositeNode instanceof CompositeNodeWrapper);
+        CompositeNode compNode = ((CompositeNodeWrapper) compositeNode).unwrap();
+
+        assertEquals(topLevelElementName, compNode.getNodeType().getLocalName());
+        verifyCompositeNode(compNode, namespace);
+    }
+
+    private void verityMultipleItemsInList(CompositeNode compositeNode) {
+        List<Node<?>> childrenNodes = compositeNode.getChildren();
+        assertEquals(4, childrenNodes.size());
+        boolean lf11Found = false;
+        boolean cont11Found = false;
+        boolean lst11Found = false;
+        for (Node<?> lst1Item : childrenNodes) {
+            assertEquals("lst1", lst1Item.getNodeType().getLocalName());
+            assertTrue(lst1Item instanceof CompositeNode);
+
+            List<Node<?>> childrenLst1 = ((CompositeNode) lst1Item).getChildren();
+            assertEquals(1, childrenLst1.size());
+            String localName = childrenLst1.get(0).getNodeType().getLocalName();
+            if (localName.equals("lf11")) {
+                assertTrue(childrenLst1.get(0) instanceof SimpleNode);
+                lf11Found = true;
+            } else if (localName.equals("lflst11")) {
+                assertTrue(childrenLst1.get(0) instanceof SimpleNode);
+                assertEquals("45", ((SimpleNode<?>) childrenLst1.get(0)).getValue());
+                lf11Found = true;
+            } else if (localName.equals("cont11")) {
+                assertTrue(childrenLst1.get(0) instanceof CompositeNode);
+                cont11Found = true;
+            } else if (localName.equals("lst11")) {
+                lst11Found = true;
+                assertTrue(childrenLst1.get(0) instanceof CompositeNode);
+                assertEquals(0, ((CompositeNode) childrenLst1.get(0)).getChildren().size());
+            }
+
+        }
+        assertTrue(lf11Found);
+        assertTrue(cont11Found);
+        assertTrue(lst11Found);
+    }
+
+    private void verifyCompositeNode(CompositeNode compositeNode, String namespace) {
+        boolean cont1Found = false;
+        boolean lst1Found = false;
+        boolean lflst1_1Found = false;
+        boolean lflst1_2Found = false;
+        boolean lf1Found = false;
+
+        assertEquals(namespace, compositeNode.getNodeType().getNamespace().toString());
+
+        for (Node<?> node : compositeNode.getChildren()) {
+            if (node.getNodeType().getLocalName().equals("cont1")) {
+                if (node instanceof CompositeNode) {
+                    cont1Found = true;
+                    assertEquals(0, ((CompositeNode) node).getChildren().size());
+                }
+            } else if (node.getNodeType().getLocalName().equals("lst1")) {
+                if (node instanceof CompositeNode) {
+                    lst1Found = true;
+                    assertEquals(0, ((CompositeNode) node).getChildren().size());
+                }
+            } else if (node.getNodeType().getLocalName().equals("lflst1")) {
+                if (node instanceof SimpleNode) {
+                    if (((SimpleNode<?>) node).getValue().equals("lflst1_1")) {
+                        lflst1_1Found = true;
+                    } else if (((SimpleNode<?>) node).getValue().equals("lflst1_2")) {
+                        lflst1_2Found = true;
+                    }
+                }
+
+            } else if (node.getNodeType().getLocalName().equals("lf1")) {
+                if (node instanceof SimpleNode) {
+                    if (((SimpleNode<?>) node).getValue().equals("lf1")) {
+                        lf1Found = true;
+                    }
+                }
+            }
+            assertEquals(namespace, node.getNodeType().getNamespace().toString());
+        }
+        assertTrue(cont1Found);
+        assertTrue(lst1Found);
+        assertTrue(lflst1_1Found);
+        assertTrue(lflst1_2Found);
+        assertTrue(lf1Found);
+    }
+
+    private CompositeNode compositeContainerFromJson(String jsonPath) {
+        return compositeContainerFromJson(jsonPath, false);
+    }
+
+    private CompositeNode compositeContainerFromJson(String jsonPath, boolean dummyNamespaces)
+            throws WebApplicationException {
+
+        JsonToCompositeNodeProvider jsonToCompositeNodeProvider = JsonToCompositeNodeProvider.INSTANCE;
+        InputStream jsonStream = JsonToCnSnTest.class.getResourceAsStream(jsonPath);
+        try {
+            CompositeNode compositeNode = jsonToCompositeNodeProvider
+                    .readFrom(null, null, null, null, null, jsonStream);
+            assertTrue(compositeNode instanceof CompositeNodeWrapper);
+            if (dummyNamespaces) {
+                try {
+                    TestUtils.addDummyNamespaceToAllNodes((CompositeNodeWrapper) compositeNode);
+                    return ((CompositeNodeWrapper) compositeNode).unwrap();
+                } catch (URISyntaxException e) {
+                    LOG.error(e.getMessage());
+                    assertTrue(e.getMessage(), false);
+                }
+            }
+            return compositeNode;
+        } catch (IOException e) {
+            LOG.error(e.getMessage());
+            assertTrue(e.getMessage(), false);
+        }
+        return null;
+    }
+
+}
index 20dfb31..309fb64 100644 (file)
@@ -411,5 +411,20 @@ final class TestUtils {
             }
         }
     }
+    
+    public static void prepareMockForRestconfBeforeNormalization(Set<Module> modules, DataSchemaNode dataSchemaNode,
+            RestconfImpl restconf) {
+        ControllerContext instance = ControllerContext.getInstance();
+        instance.setSchemas(TestUtils.loadSchemaContext(modules));
+        restconf.setControllerContext(ControllerContext.getInstance());
+
+        BrokerFacade mockedBrokerFacade = mock(BrokerFacade.class);
+        when(mockedBrokerFacade.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class)))
+                .thenReturn(
+                        new DummyFuture.Builder().rpcResult(
+                                new DummyRpcResult.Builder<TransactionStatus>().result(TransactionStatus.COMMITED)
+                                        .build()).build());
+        restconf.setBroker(mockedBrokerFacade);
+    }
 
 }
index 69de9f8..d0f1805 100644 (file)
@@ -137,7 +137,7 @@ public class ToJsonBasicDataTypesTest {
                 assertEquals("bit3", jReader.nextString());
                 bitsChecked = true;
             } else if (keyName.equals("lfbinary")) {
-                assertEquals("AAaacdabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ%%-#^", jReader.nextString());
+                assertEquals("AAaacdabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", jReader.nextString());
                 lfbinaryChecked = true;
             } else if (keyName.equals("lfempty")) {
                 jReader.beginArray();
index ce1b4af..0ec2dd4 100644 (file)
@@ -4,11 +4,14 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
 import java.io.IOException;
-import java.util.regex.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import javax.ws.rs.WebApplicationException;
 
 import org.junit.*;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
 import org.opendaylight.yangtools.yang.data.api.*;
 import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
 
@@ -19,6 +22,7 @@ public class ToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader {
         dataLoad("/yang-to-json-conversion/identityref", 2, "identityref-module", "cont");
     }
 
+    @Ignore
     @Test
     public void identityrefToJsonTest() {
         String json = null;
@@ -40,9 +44,14 @@ public class ToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader {
     private CompositeNode prepareCompositeNode() {
         MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null,
                 ModifyAction.CREATE, null);
-        MutableSimpleNode<?> lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1"), cont,
+        MutableCompositeNode cont1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont1"), cont, null,
+                ModifyAction.CREATE, null);
+        cont.getChildren().add(cont1);
+
+        MutableSimpleNode<?> lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1"), cont1,
                 TestUtils.buildQName("name_test", "identityref:module", "2013-12-2"), ModifyAction.CREATE, null);
-        cont.getChildren().add(lf1);
+        cont1.getChildren().add(lf1);
+        cont1.init();
         cont.init();
 
         return cont;
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlToCnSnTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlToCnSnTest.java
new file mode 100644 (file)
index 0000000..5944334
--- /dev/null
@@ -0,0 +1,397 @@
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import static org.junit.Assert.*;
+
+import java.io.*;
+import java.net.URISyntaxException;
+import java.util.List;
+import java.util.Set;
+
+import javax.ws.rs.WebApplicationException;
+
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
+import org.opendaylight.controller.sal.restconf.impl.*;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.*;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class XmlToCnSnTest {
+    private static final Logger LOG = LoggerFactory.getLogger(XmlToCnSnTest.class);
+
+    /**
+     * top level element represents container. second level element is list with
+     * two elements.
+     */
+    @Test
+    public void testXmlDataContainer() {
+        CompositeNode compNode = compositeNodeFromXml("/xml-to-cnsn/data-container.xml", false);
+        assertNotNull(compNode);
+        DataSchemaNode dataSchemaNode = null;
+        try {
+            dataSchemaNode = TestUtils.obtainSchemaFromYang("/xml-to-cnsn/data-container-yang");
+        } catch (FileNotFoundException e) {
+            LOG.error(e.getMessage());
+            assertTrue(false);
+        }
+
+        assertNotNull(dataSchemaNode);
+        TestUtils.supplementNamespace(dataSchemaNode, compNode);
+
+        String nameSpace = "data:container:yang";
+        assertEquals(nameSpace, compNode.getNodeType().getNamespace().toString());
+
+        verifyNullAndEmptyStringSingleNode(compNode, nameSpace);
+        verifyCommonPartAOfXml(compNode, "", nameSpace);
+    }
+
+    private void verifyNullAndEmptyStringSingleNode(CompositeNode compNode, String nameSpace) {
+        assertEquals("cont", compNode.getNodeType().getLocalName());
+
+        SimpleNode<?> lf2 = null;
+        SimpleNode<?> lf3 = null;
+        int found = 0;
+        for (Node<?> child : compNode.getChildren()) {
+            if (found == 0x3)
+                break;
+            if (child instanceof SimpleNode<?>) {
+                SimpleNode<?> childSimple = (SimpleNode<?>) child;
+                if (childSimple.getNodeType().getLocalName().equals("lf3")) {
+                    lf3 = childSimple;
+                    found = found | (1 << 0);
+                } else if (childSimple.getNodeType().getLocalName().equals("lf2")) {
+                    lf2 = childSimple;
+                    found = found | (1 << 1);
+                }
+            }
+            assertEquals(nameSpace, child.getNodeType().getNamespace().toString());
+        }
+
+        assertEquals("", lf2.getValue());
+        assertEquals(null, lf3.getValue());
+    }
+
+    @Test
+    public void testXmlDataList() {
+        CompositeNode compNode = compositeNodeFromXml("/xml-to-cnsn/data-list.xml", false);
+        assertNotNull(compNode);
+
+        DataSchemaNode dataSchemaNode = null;
+        try {
+            dataSchemaNode = TestUtils.obtainSchemaFromYang("/xml-to-cnsn/data-list-yang", "data-container-yang");
+        } catch (FileNotFoundException e) {
+            LOG.error(e.getMessage());
+        }
+        assertNotNull(dataSchemaNode);
+        TestUtils.supplementNamespace(dataSchemaNode, compNode);
+
+        String nameSpaceList = "data:list:yang";
+        String nameSpaceCont = "data:container:yang";
+        assertEquals(nameSpaceCont, compNode.getNodeType().getNamespace().toString());
+        assertEquals("cont", compNode.getNodeType().getLocalName());
+        assertEquals(3, compNode.getChildren().size());
+        CompositeNode lst1_1 = null;
+        CompositeNode lst1_2 = null;
+        int loopCount = 0;
+        for (Node<?> node : compNode.getChildren()) {
+            if (node.getNodeType().getLocalName().equals("lf1")) {
+                assertEquals(nameSpaceList, node.getNodeType().getNamespace().toString());
+                assertTrue(node instanceof SimpleNode<?>);
+                assertEquals("lf1", node.getValue());
+            } else {
+                assertTrue(node instanceof CompositeNode);
+                switch (loopCount++) {
+                case 0:
+                    lst1_1 = (CompositeNode) node;
+                    break;
+                case 1:
+                    lst1_2 = (CompositeNode) node;
+                    break;
+                }
+                assertEquals(nameSpaceCont, node.getNodeType().getNamespace().toString());
+            }
+        }
+        // lst1_1
+        verifyCommonPartAOfXml(lst1_1, "1", nameSpaceCont);
+        // :lst1_1
+
+        // lst1_2
+        SimpleNode<?> lflst11 = null;
+        CompositeNode cont11 = null;
+        for (Node<?> node : lst1_2.getChildren()) {
+            String nodeName = node.getNodeType().getLocalName();
+            if (nodeName.equals("lflst11")) {
+                assertTrue(node instanceof SimpleNode<?>);
+                lflst11 = (SimpleNode<?>) node;
+
+            } else if (nodeName.equals("cont11")) {
+                assertTrue(node instanceof CompositeNode);
+                cont11 = (CompositeNode) node;
+            }
+            assertEquals(nameSpaceCont, compNode.getNodeType().getNamespace().toString());
+        }
+        assertEquals("221", lflst11.getValue());
+
+        assertEquals(1, cont11.getChildren().size());
+        assertTrue(cont11.getChildren().get(0) instanceof SimpleNode<?>);
+        SimpleNode<?> cont11_lf111 = (SimpleNode<?>) cont11.getChildren().get(0);
+        assertEquals(nameSpaceCont, cont11_lf111.getNodeType().getNamespace().toString());
+        assertEquals("lf111", cont11_lf111.getNodeType().getLocalName());
+        assertEquals((short) 100, cont11_lf111.getValue());
+        // :lst1_2
+
+    }
+
+    @Test
+    public void testXmlEmptyData() {
+        CompositeNode compNode = compositeNodeFromXml("/xml-to-cnsn/empty-data.xml", true);
+        assertEquals("cont", compNode.getNodeType().getLocalName());
+        SimpleNode<?> lf1 = null;
+        SimpleNode<?> lflst1_1 = null;
+        SimpleNode<?> lflst1_2 = null;
+        CompositeNode lst1 = null;
+        int lflst1Count = 0;
+        for (Node<?> node : compNode.getChildren()) {
+            if (node.getNodeType().getLocalName().equals("lf1")) {
+                assertTrue(node instanceof SimpleNode<?>);
+                lf1 = (SimpleNode<?>) node;
+            } else if (node.getNodeType().getLocalName().equals("lflst1")) {
+                assertTrue(node instanceof SimpleNode<?>);
+
+                switch (lflst1Count++) {
+                case 0:
+                    lflst1_1 = (SimpleNode<?>) node;
+                    break;
+                case 1:
+                    lflst1_2 = (SimpleNode<?>) node;
+                    break;
+                }
+            } else if (node.getNodeType().getLocalName().equals("lst1")) {
+                assertTrue(node instanceof CompositeNode);
+                lst1 = (CompositeNode) node;
+            }
+        }
+
+        assertNotNull(lf1);
+        assertNotNull(lflst1_1);
+        assertNotNull(lflst1_2);
+        assertNotNull(lst1);
+
+        assertEquals("", lf1.getValue());
+        assertEquals("", lflst1_1.getValue());
+        assertEquals("", lflst1_2.getValue());
+        assertEquals(1, lst1.getChildren().size());
+        assertEquals("lf11", lst1.getChildren().get(0).getNodeType().getLocalName());
+
+        assertTrue(lst1.getChildren().get(0) instanceof SimpleNode<?>);
+        assertEquals("", lst1.getChildren().get(0).getValue());
+
+    }
+
+    /**
+     * Test case like this <lf11 xmlns:x="namespace">x:identity</lf11>
+     */
+    @Test
+    public void testIdentityrefNmspcInElement() {
+        testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-nmspc-in-element.xml", "/xml-to-cnsn/identityref",
+                "identityref-module", "cont", 2, "iden", "identity:module");
+    }
+
+    /**
+     * 
+     * Test case like <lf11 xmlns="namespace1"
+     * xmlns:x="namespace">identity</lf11>
+     */
+
+    @Test
+    public void testIdentityrefDefaultNmspcInElement() {
+        testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-default-nmspc-in-element.xml",
+                "/xml-to-cnsn/identityref/yang-augments", "general-module", "cont", 3, "iden", "identityref:module");
+    }
+
+    /**
+     * 
+     * Test case like <cont1 xmlns="namespace1"> <lf11
+     * xmlns:x="namespace">identity</lf11> </cont1>
+     */
+    @Test
+    public void testIdentityrefDefaultNmspcInParrentElement() {
+        testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-default-nmspc-in-parrent-element.xml",
+                "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "identityref:module");
+    }
+
+    /**
+     * 
+     * Test case like <cont1 xmlns="namespace1" xmlns:x="namespace">
+     * <lf11>x:identity</lf11> </cont1>
+     */
+    @Test
+    public void testIdentityrefNmspcInParrentElement() {
+        testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-nmspc-in-parrent-element.xml",
+                "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "z:namespace");
+
+    }
+
+    /**
+     * 
+     * Test case like (without namespace in xml) <cont1> <lf11>x:identity</lf11>
+     * </cont1>
+     */
+    @Test
+    public void testIdentityrefNoNmspcValueWithPrefix() {
+        testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-no-nmspc-value-with-prefix.xml",
+                "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "x:iden", "identityref:module");
+    }
+
+    /**
+     * 
+     * Test case like (without namespace in xml) <cont1> <lf11>identity</lf11>
+     * </cont1>
+     */
+    @Test
+    public void testIdentityrefNoNmspcValueWithoutPrefix() {
+        testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-no-nmspc-value-without-prefix.xml",
+                "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "identityref:module");
+    }
+
+    private void verifyCommonPartAOfXml(CompositeNode compNode, String suf, String nameSpace) {
+        SimpleNode<?> lf1suf = null;
+        SimpleNode<?> lflst1suf_1 = null;
+        SimpleNode<?> lflst1suf_2 = null;
+        SimpleNode<?> lflst1suf_3 = null;
+        CompositeNode cont1suf = null;
+        CompositeNode lst1suf = null;
+
+        int lflstCount = 0;
+
+        for (Node<?> node : compNode.getChildren()) {
+            String localName = node.getNodeType().getLocalName();
+            if (localName.equals("lf1" + suf)) {
+                assertTrue(node instanceof SimpleNode<?>);
+                lf1suf = (SimpleNode<?>) node;
+            } else if (localName.equals("lflst1" + suf)) {
+                assertTrue(node instanceof SimpleNode<?>);
+                switch (lflstCount++) {
+                case 0:
+                    lflst1suf_1 = (SimpleNode<?>) node;
+                    break;
+                case 1:
+                    lflst1suf_2 = (SimpleNode<?>) node;
+                    break;
+                case 2:
+                    lflst1suf_3 = (SimpleNode<?>) node;
+                    break;
+                }
+            } else if (localName.equals("lst1" + suf)) {
+                assertTrue(node instanceof CompositeNode);
+                lst1suf = (CompositeNode) node;
+            } else if (localName.equals("cont1" + suf)) {
+                assertTrue(node instanceof CompositeNode);
+                cont1suf = (CompositeNode) node;
+            }
+            assertEquals(nameSpace, node.getNodeType().getNamespace().toString());
+        }
+
+        assertNotNull(lf1suf);
+        assertNotNull(lflst1suf_1);
+        assertNotNull(lflst1suf_2);
+        assertNotNull(lflst1suf_3);
+        assertNotNull(lst1suf);
+        assertNotNull(cont1suf);
+
+        assertEquals("str0", lf1suf.getValue());
+        assertEquals("121", lflst1suf_1.getValue());
+        assertEquals("131", lflst1suf_2.getValue());
+        assertEquals("str1", lflst1suf_3.getValue());
+
+        assertEquals(1, lst1suf.getChildren().size());
+
+        assertTrue(lst1suf.getChildren().get(0) instanceof SimpleNode<?>);
+        SimpleNode<?> lst11_lf11 = (SimpleNode<?>) lst1suf.getChildren().get(0);
+        assertEquals(nameSpace, lst11_lf11.getNodeType().getNamespace().toString());
+        assertEquals("lf11" + suf, lst11_lf11.getNodeType().getLocalName());
+        assertEquals("str2", lst11_lf11.getValue());
+
+        assertTrue(cont1suf.getChildren().get(0) instanceof SimpleNode<?>);
+        SimpleNode<?> cont1_lf11 = (SimpleNode<?>) cont1suf.getChildren().get(0);
+        assertEquals(nameSpace, cont1_lf11.getNodeType().getNamespace().toString());
+        assertEquals("lf11" + suf, cont1_lf11.getNodeType().getLocalName());
+        assertEquals((short) 100, cont1_lf11.getValue());
+    }
+
+    private CompositeNode compositeNodeFromXml(String xmlPath, boolean dummyNamespaces) {
+        XmlToCompositeNodeProvider xmlToCompositeNodeProvider = XmlToCompositeNodeProvider.INSTANCE;
+        try {
+            InputStream xmlStream = XmlToCnSnTest.class.getResourceAsStream(xmlPath);
+            CompositeNode compositeNode = xmlToCompositeNodeProvider.readFrom(null, null, null, null, null, xmlStream);
+            if (dummyNamespaces) {
+                try {
+                    TestUtils.addDummyNamespaceToAllNodes((CompositeNodeWrapper) compositeNode);
+                    return ((CompositeNodeWrapper) compositeNode).unwrap();
+                } catch (URISyntaxException e) {
+                    LOG.error(e.getMessage());
+                    assertTrue(e.getMessage(), false);
+                }
+            }
+            return compositeNode;
+
+        } catch (WebApplicationException | IOException e) {
+            LOG.error(e.getMessage());
+            assertTrue(false);
+        }
+        return null;
+    }
+
+    private void testIdentityrefToCnSn(String xmlPath, String yangPath, String moduleName, String schemaName,
+            int moduleCount, String resultLocalName, String resultNamespace) {
+        CompositeNode compositeNode = compositeNodeFromXml(xmlPath, false);
+        assertNotNull(compositeNode);
+
+        Set<Module> modules = TestUtils.resolveModules(yangPath);
+        assertEquals(moduleCount, modules.size());
+        Module module = TestUtils.resolveModule(moduleName, modules);
+        assertNotNull(module);
+        DataSchemaNode dataSchemaNode = TestUtils.resolveDataSchemaNode(module, null);
+        assertNotNull(dataSchemaNode);
+
+        RestconfImpl restconf = RestconfImpl.getInstance();
+        ControllerContext.getInstance().setSchemas(TestUtils.loadSchemaContext(modules));
+
+        TestUtils.prepareMockForRestconfBeforeNormalization(modules, dataSchemaNode, restconf);
+
+        restconf.createConfigurationData(moduleName + ":" + schemaName, compositeNode);
+
+        SimpleNode<?> lf11 = getLf11(compositeNode);
+        assertTrue(lf11.getValue() instanceof QName);
+        QName qName = (QName) lf11.getValue();
+        assertEquals(resultLocalName, qName.getLocalName());
+        assertEquals(resultNamespace, qName.getNamespace().toString());
+
+    }
+
+    private SimpleNode<?> getLf11(CompositeNode compositeNode) {
+        assertEquals("cont", compositeNode.getNodeType().getLocalName());
+
+        List<Node<?>> childs = compositeNode.getChildren();
+        assertEquals(1, childs.size());
+        Node<?> nd = childs.iterator().next();
+        assertTrue(nd instanceof CompositeNode);
+        assertEquals("cont1", nd.getNodeType().getLocalName());
+
+        childs = ((CompositeNode) nd).getChildren();
+        SimpleNode<?> lf11 = null;
+        for (Node<?> child : childs) {
+            assertTrue(child instanceof SimpleNode);
+            if (child.getNodeType().getLocalName().equals("lf11")) {
+                lf11 = (SimpleNode<?>) child;
+            }
+        }
+        assertNotNull(lf11);
+        return lf11;
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/identityref/identity-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/identityref/identity-module.yang
new file mode 100644 (file)
index 0000000..30890bf
--- /dev/null
@@ -0,0 +1,10 @@
+module identity-module {
+  namespace "identity:module";  
+
+  prefix "idemod";
+  revision 2013-12-2 {    
+  }
+  
+       identity iden {         
+       }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/identityref/identityref-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/identityref/identityref-module.yang
new file mode 100644 (file)
index 0000000..20f91b2
--- /dev/null
@@ -0,0 +1,21 @@
+module identityref-module {
+  namespace "identityref:module";  
+
+  prefix "iderefmod";
+  
+  import identity-module {prefix idemo; revision-date 2013-12-2;}
+   
+  revision 2013-12-2 {    
+  }
+  
+       container cont {
+          container cont1 {
+               leaf lf1 {
+                       type identityref {
+                               base "idemo:iden";
+                       }
+               }
+               }
+       }
+         
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/instance_identifier/aug-referenced-elements-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/instance_identifier/aug-referenced-elements-module.yang
new file mode 100644 (file)
index 0000000..1b861f5
--- /dev/null
@@ -0,0 +1,18 @@
+module aug-referenced-elements-module {
+  namespace "aug:referenced:elements:module";  
+
+  prefix "augrefelmo";
+  
+  import referenced-elements-module {prefix refelmo; revision-date 2013-12-3;}
+   
+  revision 2013-12-3 {    
+  }
+  
+  augment "/refelmo:cont" {
+    leaf lf2 {
+        type boolean;
+    }
+  }
+  
+         
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/instance_identifier/eferenced-elements-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/instance_identifier/eferenced-elements-module.yang
new file mode 100644 (file)
index 0000000..fd6e0fb
--- /dev/null
@@ -0,0 +1,20 @@
+module referenced-elements-module {
+  namespace "referenced:elements:module";  
+
+  prefix "refelmo";
+   
+  revision 2013-12-3 {    
+  }
+  
+       container cont {
+               leaf lf1 {
+                       type string;                            
+                       }
+               }
+               leaf-list lflst1 {
+                       type uint32;
+               }
+               
+       }
+         
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/instance_identifier/rinstance-identifier-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/instance_identifier/rinstance-identifier-module.yang
new file mode 100644 (file)
index 0000000..61ce822
--- /dev/null
@@ -0,0 +1,16 @@
+module instance-identifier-module {
+  namespace "instance:identifier:module";  
+
+  prefix "inidmod";
+   
+  revision 2013-12-3 {    
+  }
+  
+       container cont {
+               leaf lf1 {
+                       type instance-identifier {                              
+                       }
+               }
+       }
+         
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/array-with-null.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/array-with-null.json
new file mode 100644 (file)
index 0000000..a19d948
--- /dev/null
@@ -0,0 +1,5 @@
+{
+       "cont": {
+               "lf":[null]
+       }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/empty-data.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/empty-data.json
new file mode 100644 (file)
index 0000000..a6ad7f6
--- /dev/null
@@ -0,0 +1,6 @@
+{
+       "cont": {       
+               "lflst1":[],
+               "lflst2":[45]           
+       }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/empty-data1.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/empty-data1.json
new file mode 100644 (file)
index 0000000..10d964d
--- /dev/null
@@ -0,0 +1,5 @@
+{
+       "cont": {       
+               "lf":                           
+       }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/identityref/identity-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/identityref/identity-module.yang
new file mode 100644 (file)
index 0000000..30890bf
--- /dev/null
@@ -0,0 +1,10 @@
+module identity-module {
+  namespace "identity:module";  
+
+  prefix "idemod";
+  revision 2013-12-2 {    
+  }
+  
+       identity iden {         
+       }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/identityref/identityref-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/identityref/identityref-module.yang
new file mode 100644 (file)
index 0000000..b90b533
--- /dev/null
@@ -0,0 +1,39 @@
+module identityref-module {
+  namespace "identityref:module";  
+
+  prefix "iderefmod";
+  
+  import identity-module {prefix idemo; revision-date 2013-12-2;}
+   
+  revision 2013-12-2 {    
+  }
+  
+  identity iden_local {
+  }
+  
+       container cont {
+          container cont1 {
+               leaf lf11 {
+                       type identityref {
+                               base "idemo:iden";
+                       }
+               }
+               leaf lf12 {
+                       type identityref {
+                               base "iden_local";
+                       }
+               }
+               leaf lf13 {
+                       type identityref {
+                               base "iden_local";
+                       }
+               }
+               leaf lf14 {
+                       type identityref {
+                               base "iden_local";
+                       }
+               }
+               }
+       }
+         
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/identityref/json/data.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/identityref/json/data.json
new file mode 100644 (file)
index 0000000..320ee05
--- /dev/null
@@ -0,0 +1,10 @@
+{
+    "cont":{
+        "cont1":{
+            "lf11":"identity-module:iden",
+            "lf12":"iden_local",              
+            "identityref-module:lf13":"iden_local",
+            "identityref-module:lf14":"identity-module:iden_local"  
+        }
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/multiple-items-in-list.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/multiple-items-in-list.json
new file mode 100644 (file)
index 0000000..8e88266
--- /dev/null
@@ -0,0 +1,26 @@
+{
+       "lst":[
+               {
+                       "lst1": [
+                               {
+                                       "lf11":"lf11_1"
+                               },
+                               {
+                                       "lflst11":[
+                                               45
+                                       ]
+                               },
+                               {
+                                       "cont11":{
+                                       }
+                               },
+                               {
+                                       "lst11":[
+                                       {
+                                               }
+                                       ]
+                               }
+                       ]
+               }
+       ]
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/multiple-leaflist-items.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/multiple-leaflist-items.json
new file mode 100644 (file)
index 0000000..b61a8a8
--- /dev/null
@@ -0,0 +1,5 @@
+{
+       "cont": {
+               "lflst1":[45,55,66]
+       }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-container-yang/simple-container.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-container-yang/simple-container.yang
new file mode 100644 (file)
index 0000000..493101c
--- /dev/null
@@ -0,0 +1,20 @@
+module simple-container-yang {
+  namespace "simple:container:yang";  
+
+  prefix "smpdtp";
+  revision 2013-11-12 {    
+  }
+  
+  container cont {
+       container cont1 {
+       }
+       list lst1 {
+       }
+       leaf-list lflst1 {
+               type string;
+       }
+       leaf lf1 {
+               type string;
+       }
+  }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-container.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-container.json
new file mode 100644 (file)
index 0000000..1be4149
--- /dev/null
@@ -0,0 +1,15 @@
+{
+       "cont":{
+               "cont1":{
+               },
+               "lst1": [
+                       {
+                       }
+               ],
+               "lflst1":[
+                       "lflst1_1",
+                       "lflst1_2"
+               ],
+               "lf1":"lf1"
+       }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/simple-list1.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/simple-list1.yang
new file mode 100644 (file)
index 0000000..0ce8ea4
--- /dev/null
@@ -0,0 +1,20 @@
+module simple-list-yang1 {
+  namespace "simple:list:yang1";  
+
+  prefix "smplstyg";
+  revision 2013-11-12 {    
+  }
+  
+  list lst {
+       container cont1 {
+       }
+       list lst1 {
+       }
+       leaf-list lflst1 {
+               type string;
+       }
+       leaf lf1 {
+               type string;
+       }
+  }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/simple-list2.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/simple-list2.yang
new file mode 100644 (file)
index 0000000..0872a47
--- /dev/null
@@ -0,0 +1,20 @@
+module simple-list-yang2 {
+  namespace "simple:list:yang2";  
+
+  prefix "smplstyg";
+  revision 2013-11-12 {    
+  }
+  
+  list lst {
+       container cont1 {
+       }
+       list lst1 {
+       }
+       leaf-list lflst1 {
+               type string;
+       }
+       leaf lf1 {
+               type string;
+       }
+  }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list.json
new file mode 100644 (file)
index 0000000..fee6baa
--- /dev/null
@@ -0,0 +1,17 @@
+{
+       "lst":[
+               {
+                       "cont1":{
+                       },
+                       "lst1": [
+                               {
+                               }
+                       ],
+                       "lflst1":[
+                               "lflst1_1",
+                               "lflst1_2"
+                       ],
+                       "lf1":"lf1"
+               }
+       ]
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/wrong-top-level1.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/wrong-top-level1.json
new file mode 100644 (file)
index 0000000..3ae3a72
--- /dev/null
@@ -0,0 +1,9 @@
+{
+
+       "lst":[
+               {
+               },
+               {
+               }
+       ]
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/wrong-top-level2.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/wrong-top-level2.json
new file mode 100644 (file)
index 0000000..f0f5540
--- /dev/null
@@ -0,0 +1,9 @@
+{
+
+       "cont": {
+       },
+       "lst":[
+               {
+               }
+       ]
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/wrong-top-level3.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/wrong-top-level3.json
new file mode 100644 (file)
index 0000000..7288969
--- /dev/null
@@ -0,0 +1,3 @@
+{
+       "lf":"hello"
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-container-yang/data-container.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-container-yang/data-container.yang
new file mode 100644 (file)
index 0000000..b038eb1
--- /dev/null
@@ -0,0 +1,35 @@
+module data-container-yang {
+  namespace "data:container:yang";  
+
+  prefix "dtconyg";
+       revision 2013-11-19 {    
+  }
+  
+  container cont {
+       leaf lf1 {
+               type string;
+       }
+       
+       leaf lf2 {
+               type string;
+       }
+       
+       leaf lf3 {
+               type empty;
+       }
+       
+       leaf-list lflst1 {
+               type string;
+       }
+       list lst1 {
+               leaf lf11 {
+                       type string;
+               } 
+       }
+       container cont1 {
+               leaf lf11 {
+                       type uint8;
+               }
+       }
+  }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-container.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-container.xml
new file mode 100644 (file)
index 0000000..ce97dd1
--- /dev/null
@@ -0,0 +1,14 @@
+<cont>
+       <lf1>str0</lf1>
+       <lf2></lf2>
+       <lf3/>
+       <lflst1>121</lflst1>
+       <lflst1>131</lflst1>
+       <lflst1>str1</lflst1>
+       <lst1>
+               <lf11>str2</lf11>
+       </lst1>                 
+       <cont1>
+               <lf11>100</lf11>
+       </cont1>
+</cont>
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-list-yang/data-container.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-list-yang/data-container.yang
new file mode 100644 (file)
index 0000000..3df3413
--- /dev/null
@@ -0,0 +1,28 @@
+module data-container-yang {
+  namespace "data:container:yang";  
+
+  prefix "dtconyg";
+  revision 2013-11-19 {    
+  }
+  
+  container cont {     
+         list lst1 {
+               leaf lf11 {
+                       type string;
+               }
+               leaf-list lflst11 {
+                       type string;
+               }
+               list lst11 {
+                       leaf lf111 {
+                               type string;
+                       } 
+               }
+               container cont11 {
+                       leaf lf111 {
+                               type uint8;
+                       }
+               }
+         }  
+  }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-list-yang/data-list.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-list-yang/data-list.yang
new file mode 100644 (file)
index 0000000..47e2a45
--- /dev/null
@@ -0,0 +1,22 @@
+module data-list-yang {
+  namespace "data:list:yang"; 
+  
+  prefix "dtlstyg";
+
+  import data-container-yang {
+       prefix "dtconyg";
+       revision-date 2013-11-19;
+  }
+  
+  
+  revision 2013-11-19 {    
+  }
+       
+
+
+  augment "/dtconyg:cont" {
+       leaf lf1 {
+               type string;
+       }
+  }    
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-list.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-list.xml
new file mode 100644 (file)
index 0000000..cab23c6
--- /dev/null
@@ -0,0 +1,21 @@
+<cont>
+       <lst1>
+               <lf11>str0</lf11>
+               <lflst11>121</lflst11>
+               <lflst11>131</lflst11>
+               <lflst11>str1</lflst11>
+               <lst11>
+                       <lf111>str2</lf111>
+               </lst11>                        
+               <cont11>
+                       <lf111>100</lf111>
+               </cont11>
+       </lst1>
+       <lst1>
+               <lflst11>221</lflst11>
+               <cont11>
+                       <lf111>100</lf111>
+               </cont11>
+       </lst1> 
+       <lf1>lf1</lf1>
+</cont>
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-nmspc-in-attributes.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-nmspc-in-attributes.xml
new file mode 100644 (file)
index 0000000..848c020
--- /dev/null
@@ -0,0 +1,5 @@
+<cont xmlns:x="x:namespace" xmlns:y="y:namespace">
+    <cont1 xmlns:z="z:namespace" xmlns:a="a:namespace" xmlns:b="b:namespace">
+        <lf11 xmlns:c="identity:module">c:iden</lf11>
+    </cont1>
+</cont>
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/empty-data.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/empty-data.xml
new file mode 100644 (file)
index 0000000..162a556
--- /dev/null
@@ -0,0 +1,8 @@
+<cont>
+       <lf1></lf1>
+       <lflst1></lflst1>
+       <lflst1></lflst1>
+       <lst1>          
+               <lf11></lf11>
+       </lst1>                 
+</cont>
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/identity-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/identity-module.yang
new file mode 100644 (file)
index 0000000..30890bf
--- /dev/null
@@ -0,0 +1,10 @@
+module identity-module {
+  namespace "identity:module";  
+
+  prefix "idemod";
+  revision 2013-12-2 {    
+  }
+  
+       identity iden {         
+       }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/identityref-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/identityref-module.yang
new file mode 100644 (file)
index 0000000..a43d439
--- /dev/null
@@ -0,0 +1,21 @@
+module identityref-module {
+  namespace "identityref:module";  
+
+  prefix "iderefmod";
+  
+  import identity-module {prefix idemo; revision-date 2013-12-2;}
+   
+  revision 2013-12-2 {    
+  }
+  
+       container cont {
+          container cont1 {
+               leaf lf11 {
+                       type identityref {
+                               base "idemo:iden";
+                       }
+               }
+               }
+       }
+         
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-default-nmspc-in-element.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-default-nmspc-in-element.xml
new file mode 100644 (file)
index 0000000..aae2af3
--- /dev/null
@@ -0,0 +1,5 @@
+<cont xmlns="general:module" xmlns:x="x:namespace" xmlns:y="y:namespace">
+    <cont1 xmlns:z="z:namespace" xmlns:a="a:namespace" xmlns:b="b:namespace">        
+        <lf11 xmlns="identityref:module" xmlns:c="c:namespace">iden</lf11>  
+    </cont1>
+</cont>
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-default-nmspc-in-parrent-element.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-default-nmspc-in-parrent-element.xml
new file mode 100644 (file)
index 0000000..621d2bc
--- /dev/null
@@ -0,0 +1,5 @@
+<cont xmlns:x="x:namespace" xmlns:y="y:namespace">
+    <cont1 xmlns="identityref:module" xmlns:z="z:namespace" xmlns:a="a:namespace" xmlns:b="b:namespace">        
+        <lf11 xmlns:c="c:namespace">iden</lf11>  
+    </cont1>
+</cont>
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-nmspc-in-element.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-nmspc-in-element.xml
new file mode 100644 (file)
index 0000000..76de72d
--- /dev/null
@@ -0,0 +1,5 @@
+<cont xmlns="identityref:module" xmlns:x="x:namespace" xmlns:y="y:namespace">
+    <cont1 xmlns:z="z:namespace" xmlns:a="a:namespace" xmlns:b="b:namespace">
+        <lf11 xmlns:c="identity:module">c:iden</lf11>
+    </cont1>
+</cont>
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-nmspc-in-parrent-element.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-nmspc-in-parrent-element.xml
new file mode 100644 (file)
index 0000000..497c35f
--- /dev/null
@@ -0,0 +1,5 @@
+<cont xmlns="identityref:module" xmlns:x="x:namespace" xmlns:y="y:namespace">
+    <cont1 xmlns:c="identity:module" xmlns:z="z:namespace" xmlns:a="a:namespace" xmlns:b="b:namespace">        
+        <lf11>z:iden</lf11>  
+    </cont1>
+</cont>
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-no-nmspc-value-with-prefix.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-no-nmspc-value-with-prefix.xml
new file mode 100644 (file)
index 0000000..925442f
--- /dev/null
@@ -0,0 +1,5 @@
+<cont>
+    <cont1>   
+        <lf11>x:iden</lf11>  
+    </cont1>
+</cont>
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-no-nmspc-value-without-prefix.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-no-nmspc-value-without-prefix.xml
new file mode 100644 (file)
index 0000000..5a86eb0
--- /dev/null
@@ -0,0 +1,5 @@
+<cont>
+    <cont1>
+        <lf11>iden</lf11>  
+    </cont1>
+</cont>
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/yang-augments/general-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/yang-augments/general-module.yang
new file mode 100644 (file)
index 0000000..f1a1ea6
--- /dev/null
@@ -0,0 +1,14 @@
+module general-module {
+  namespace "general:module";  
+
+  prefix "genmod";
+  revision 2013-12-12 {    
+  }
+
+    container cont {
+       container cont1 {
+        }
+    }
+
+  
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/yang-augments/identity-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/yang-augments/identity-module.yang
new file mode 100644 (file)
index 0000000..30890bf
--- /dev/null
@@ -0,0 +1,10 @@
+module identity-module {
+  namespace "identity:module";  
+
+  prefix "idemod";
+  revision 2013-12-2 {    
+  }
+  
+       identity iden {         
+       }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/yang-augments/identityref-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/yang-augments/identityref-module.yang
new file mode 100644 (file)
index 0000000..719ac12
--- /dev/null
@@ -0,0 +1,20 @@
+module identityref-module {
+  namespace "identityref:module";  
+
+  prefix "iderefmod";
+  
+  import identity-module {prefix idemo; revision-date 2013-12-2;}
+  import general-module {prefix gmo; revision-date 2013-12-12;}
+   
+  revision 2013-12-2 {    
+  }
+  
+       augment "/gmo:cont/gmo:cont1" {
+               leaf lf11 {
+                       type identityref {
+                               base "idemo:iden";
+                       }
+               }
+       }
+         
+}
\ No newline at end of file
index 0d31e90..9398664 100644 (file)
@@ -22,7 +22,7 @@
        <lfdecimal6>33.12345</lfdecimal6>
        <lfenum>enum3</lfenum>
        <lfbits>bit3</lfbits>   
-       <lfbinary>AAaacdabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ%%-#^</lfbinary>
+       <lfbinary>AAaacdabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789</lfbinary>
        <lfempty></lfempty>
        <lfunion1>324</lfunion1>
        <lfunion2>33.3</lfunion2>