Json with prefix for augmented elements 05/3105/2
authorJozef Gloncak <jgloncak@cisco.com>
Tue, 26 Nov 2013 15:32:47 +0000 (16:32 +0100)
committerJozef Gloncak <jgloncak@cisco.com>
Wed, 27 Nov 2013 09:10:13 +0000 (10:10 +0100)
Json elements which are created via augmentation are written with
prefix which is equal to module name from where augmentation was defined.

Change-Id: I92b7e2854cea3abf052f9fadc2783d29f1e82391
Signed-off-by: Jozef Gloncak <jgloncak@cisco.com>
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/StructuredDataToJsonProvider.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/StructuredData.java
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/ToJsonWithAugmentTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-container.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-leaf.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-leaflist.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-list.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/xml/data.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/yang.yang [new file with mode: 0644]

index 073b24e033914a1fe2e227d6e78c351b1c75b8a0..217ef14c647813aa8595f42fda26a2207091751a 100644 (file)
@@ -7,9 +7,8 @@ import java.util.*;
 
 import javax.activation.UnsupportedDataTypeException;
 
-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.controller.sal.restconf.impl.ControllerContext;
+import org.opendaylight.yangtools.yang.data.api.*;
 import org.opendaylight.yangtools.yang.model.api.*;
 import org.opendaylight.yangtools.yang.model.api.type.*;
 
@@ -103,14 +102,15 @@ class JsonMapper {
     }
 
     private void writeContainer(JsonWriter writer, CompositeNode node, ContainerSchemaNode schema) throws IOException {
-        writer.name(node.getNodeType().getLocalName());
+        writeName(node, schema, writer);
         writer.beginObject();
         writeChildrenOfParent(writer, node, schema);
         writer.endObject();
     }
 
-    private void writeList(JsonWriter writer, CompositeNode nodeParent, CompositeNode node, ListSchemaNode schema) throws IOException {
-        writer.name(node.getNodeType().getLocalName());
+    private void writeList(JsonWriter writer, CompositeNode nodeParent, CompositeNode node, ListSchemaNode schema)
+            throws IOException {
+        writeName(node, schema, writer);
         writer.beginArray();
 
         if (nodeParent != null) {
@@ -129,8 +129,9 @@ class JsonMapper {
         writer.endArray();
     }
 
-    private void writeLeafList(JsonWriter writer, CompositeNode nodeParent, SimpleNode<?> node, LeafListSchemaNode schema) throws IOException {
-        writer.name(node.getNodeType().getLocalName());
+    private void writeLeafList(JsonWriter writer, CompositeNode nodeParent, SimpleNode<?> node,
+            LeafListSchemaNode schema) throws IOException {
+        writeName(node, schema, writer);
         writer.beginArray();
 
         List<SimpleNode<?>> nodeLeafLists = nodeParent.getSimpleNodesByName(node.getNodeType());
@@ -142,7 +143,7 @@ class JsonMapper {
     }
 
     private void writeLeaf(JsonWriter writer, SimpleNode<?> node, LeafSchemaNode schema) throws IOException {
-        writer.name(node.getNodeType().getLocalName());
+        writeName(node, schema, writer);
         writeValueOfNodeByType(writer, node, schema.getType());
     }
 
@@ -244,6 +245,19 @@ class JsonMapper {
         return type.getBaseType() != null ? resolveBaseTypeFrom(type.getBaseType()) : type;
     }
 
+    private void writeName(Node<?> node, DataSchemaNode schema, JsonWriter writer) throws IOException {
+        String nameForOutput = node.getNodeType().getLocalName();
+        if (schema.isAugmenting()) {
+            ControllerContext contContext = ControllerContext.getInstance();
+            CharSequence moduleName;
+            moduleName = contContext.toRestconfIdentifier(schema.getQName());
+            if (moduleName != null) {
+                nameForOutput = moduleName.toString();
+            }
+        }
+        writer.name(nameForOutput);
+    }
+
     private static final class NumberForJsonWriter extends Number {
 
         private static final long serialVersionUID = -3147729419814417666L;
index 90e6d2affc5cde925d4adc941b24d42005aad117..39e41045adadd669c0ad1c81495ff39d076d8f61 100644 (file)
@@ -24,10 +24,10 @@ import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 import com.google.gson.stream.JsonWriter;
 
 @Provider
-@Produces({API+RestconfService.JSON})
+@Produces({ API + RestconfService.JSON })
 public enum StructuredDataToJsonProvider implements MessageBodyWriter<StructuredData> {
     INSTANCE;
-    
+
     @Override
     public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
         return true;
index 12f33d4562526b25feef31e8dd9e7c6a9dfa352c..62a9ae05814b3a2d7a7d259c0811d484c580f99e 100644 (file)
@@ -1,13 +1,13 @@
 package org.opendaylight.controller.sal.restconf.impl;
 
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.*;
 
 public class StructuredData {
-    
+
     private final CompositeNode data;
     private final DataSchemaNode schema;
-    
+
     public StructuredData(CompositeNode data, DataSchemaNode schema) {
         this.data = data;
         this.schema = schema;
@@ -20,5 +20,4 @@ public class StructuredData {
     public DataSchemaNode getSchema() {
         return schema;
     }
-    
 }
index c43de5d9e8525091eb535703381cb222ac42b9ca..bc941b997e35dd63c8a3250cb52e8ccf66e27314 100644 (file)
@@ -13,9 +13,7 @@ import java.util.*;
 import java.util.concurrent.Future;
 
 import javax.ws.rs.WebApplicationException;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.*;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.transform.*;
 import javax.xml.transform.dom.DOMSource;
@@ -24,8 +22,7 @@ import javax.xml.transform.stream.StreamResult;
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
 import org.opendaylight.controller.sal.restconf.impl.*;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.*;
 import org.opendaylight.yangtools.yang.data.api.*;
 import org.opendaylight.yangtools.yang.data.impl.XmlTreeBuilder;
 import org.opendaylight.yangtools.yang.model.api.*;
@@ -99,7 +96,7 @@ final class TestUtils {
         }
         return (CompositeNode) dataTree;
     }
-    
+
     public static Document loadDocumentFrom(InputStream inputStream) {
         try {
             DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
@@ -135,6 +132,11 @@ final class TestUtils {
     }
 
     static String convertCompositeNodeDataAndYangToJson(CompositeNode compositeNode, String yangPath, String outputPath) {
+        return convertCompositeNodeDataAndYangToJson(compositeNode, yangPath, outputPath, null, null);
+    }
+
+    static String convertCompositeNodeDataAndYangToJson(CompositeNode compositeNode, String yangPath,
+            String outputPath, String searchedModuleName, String searchedDataSchemaName) {
         String jsonResult = null;
         Set<Module> modules = null;
 
@@ -145,30 +147,54 @@ final class TestUtils {
         }
         assertNotNull("modules can't be null.", modules);
 
+        Module module = null;
+        if (searchedModuleName != null) {
+            for (Module m : modules) {
+                if (m.getName().equals(searchedModuleName)) {
+                    module = m;
+                    break;
+                }
+            }
+        } else if (modules.size() == 1) {
+            module = modules.iterator().next();
+        }
+        assertNotNull("Module is missing", module);
+
         assertNotNull("Composite node can't be null", compositeNode);
 
         StructuredDataToJsonProvider structuredDataToJsonProvider = StructuredDataToJsonProvider.INSTANCE;
-        for (Module module : modules) {
-            ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();
-            for (DataSchemaNode dataSchemaNode : module.getChildNodes()) {
-                StructuredData structuredData = new StructuredData(compositeNode, dataSchemaNode);
-                try {
-                    structuredDataToJsonProvider.writeTo(structuredData, null, null, null, null, null, byteArrayOS);
-                } catch (WebApplicationException | IOException e) {
-                    e.printStackTrace();
+        ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();
+        DataSchemaNode dataSchemaNode = null;
+        if (searchedDataSchemaName != null) {
+            for (DataSchemaNode dsn : module.getChildNodes()) {
+                if (dsn.getQName().getLocalName().equals(searchedDataSchemaName)) {
+                    dataSchemaNode = dsn;
                 }
-                assertFalse(
-                        "Returning JSON string can't be empty for node " + dataSchemaNode.getQName().getLocalName(),
-                        byteArrayOS.toString().isEmpty());
-            }
-            jsonResult = byteArrayOS.toString();
-            try {
-                outputToFile(byteArrayOS, outputPath);
-            } catch (IOException e) {
-                System.out.println("Output file wasn't cloased sucessfuly.");
             }
+        } else if (module.getChildNodes().size() == 1) {
+            dataSchemaNode = module.getChildNodes().iterator().next();
+        }
+        assertNotNull(dataSchemaNode);
+        // SchemaContextUtil.
 
+        ControllerContext controllerContext = ControllerContext.getInstance();
+        controllerContext.setSchemas(loadSchemaContext(modules));
+        StructuredData structuredData = new StructuredData(compositeNode, dataSchemaNode);
+        try {
+            structuredDataToJsonProvider.writeTo(structuredData, null, null, null, null, null, byteArrayOS);
+        } catch (WebApplicationException | IOException e) {
+            e.printStackTrace();
         }
+        assertFalse("Returning JSON string can't be empty for node " + dataSchemaNode.getQName().getLocalName(),
+                byteArrayOS.toString().isEmpty());
+
+        jsonResult = byteArrayOS.toString();
+        try {
+            outputToFile(byteArrayOS, outputPath);
+        } catch (IOException e) {
+            System.out.println("Output file wasn't cloased sucessfuly.");
+        }
+
         return jsonResult;
     }
 
@@ -296,7 +322,8 @@ final class TestUtils {
         RpcResult<TransactionStatus> rpcResult = DummyRpcResult.builder().result(TransactionStatus.COMMITED).build();
         Future<RpcResult<TransactionStatus>> future = DummyFuture.builder().rpcResult(rpcResult).build();
         when(controllerContext.toInstanceIdentifier(any(String.class))).thenReturn(instIdAndSchema);
-        when(broker.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(future);
+        when(broker.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(
+                future);
 
         restconf.setControllerContext(controllerContext);
         restconf.setBroker(broker);
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ToJsonWithAugmentTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ToJsonWithAugmentTest.java
new file mode 100644 (file)
index 0000000..994916d
--- /dev/null
@@ -0,0 +1,27 @@
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+public class ToJsonWithAugmentTest {
+
+    /**
+     * Test of json output when as input are specified composite node with empty
+     * data + YANG file
+     */
+    @Test
+    public void augmentedElementsToJson() {
+        String jsonOutput = TestUtils.convertCompositeNodeDataAndYangToJson(
+                TestUtils.loadCompositeNode("/yang-to-json-conversion/augmentation/xml/data.xml"),
+                "/yang-to-json-conversion/augmentation", "/yang-to-json-conversion/augmentation/xml", "yang", "cont");
+
+        assertTrue(jsonOutput.contains("\"augment-leaf:lf2\": \"lf2\""));
+        assertTrue(jsonOutput.contains("\"augment-container:cont1\": {"));
+        assertTrue(jsonOutput.contains("\"augment-container:lf11\": \"lf11\""));
+        assertTrue(jsonOutput.contains("\"augment-list:lst1\": ["));
+        assertTrue(jsonOutput.contains("\"augment-list:lf11\": \"lf1_1\""));
+        assertTrue(jsonOutput.contains("\"augment-list:lf11\": \"lf1_2\""));
+        assertTrue(jsonOutput.contains("\"augment-leaflist:lflst1\": ["));
+    }
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-container.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-container.yang
new file mode 100644 (file)
index 0000000..7efe4f7
--- /dev/null
@@ -0,0 +1,22 @@
+module augment-container {
+  namespace "ns:augment:container";  
+  prefix "augcont";
+
+  
+  import yang {prefix yng; revision-date 2013-11-26;}  
+
+
+  revision "2013-11-26" {    
+  }
+  
+       augment "/yng:cont" {
+               container cont1 {
+                       leaf lf11 {
+                               type string;
+                       }
+               }
+       }
+       
+
+         
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-leaf.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-leaf.yang
new file mode 100644 (file)
index 0000000..248d3bb
--- /dev/null
@@ -0,0 +1,18 @@
+module augment-leaf {
+  namespace "ns:augment:leaf";  
+  prefix "auglf";
+
+  
+  import yang {prefix yng; revision-date 2013-11-26;}  
+
+
+  revision "2013-11-26" {    
+  }
+  
+       augment "/yng:cont" {
+               leaf lf2 {
+                       type string;
+               }
+       }
+       
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-leaflist.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-leaflist.yang
new file mode 100644 (file)
index 0000000..1f4b937
--- /dev/null
@@ -0,0 +1,20 @@
+module augment-leaflist {
+  namespace "ns:augment:leaflist";  
+  prefix "auglflst";
+
+  
+  import yang {prefix yng; revision-date 2013-11-26;}  
+
+
+  revision "2013-11-26" {    
+  }
+  
+       augment "/yng:cont" {
+               leaf-list lflst1 {
+                       type string;
+               }
+       }
+       
+
+         
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-list.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-list.yang
new file mode 100644 (file)
index 0000000..a35a87e
--- /dev/null
@@ -0,0 +1,22 @@
+module augment-list {
+  namespace "ns:augment:list";  
+  prefix "auglst";
+
+  
+  import yang {prefix yng; revision-date 2013-11-26;}  
+
+
+  revision "2013-11-26" {    
+  }
+  
+       augment "/yng:cont" {
+               list lst1 {
+                       leaf lf11 {
+                               type string;
+                       }
+               }
+       }
+       
+
+         
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/xml/data.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/xml/data.xml
new file mode 100644 (file)
index 0000000..08cdb34
--- /dev/null
@@ -0,0 +1,16 @@
+<cont>
+       <lf1>lf1</lf1>
+       <lf2>lf2</lf2>
+       <cont1>
+               <lf11>lf11</lf11>
+       </cont1>
+       <lst1>
+               <lf11>lf1_1</lf11>
+       </lst1>
+       <lst1>
+               <lf11>lf1_2</lf11>
+       </lst1>
+       <lflst1>lflst1_1</lflst1>
+       <lflst1>lflst1_2</lflst1>
+       <lflst1>lflst1_3</lflst1>
+</cont>
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/yang.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/yang.yang
new file mode 100644 (file)
index 0000000..aeb9737
--- /dev/null
@@ -0,0 +1,17 @@
+module yang {
+  namespace "ns:yang";  
+
+  prefix "yng";
+  revision 2013-11-26 {    
+  }
+  
+       container cont {
+               leaf lf1 {
+                       type string;
+               }
+               
+       }
+       
+
+         
+}
\ No newline at end of file