Merge "Propagate error status codes correctly" into stable/fluorine
authorJakub Morvay <jakub.morvay@gmail.com>
Wed, 16 Jan 2019 11:54:10 +0000 (11:54 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Wed, 16 Jan 2019 11:54:10 +0000 (11:54 +0000)
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/NormalizedNodeJsonBodyWriter.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/utils/ReadDataTransactionUtil.java
restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/JSONRestconfServiceRfc8040ImplTest.java

index 59a976743cb9ee1c5f0b35f5a76af63f0c7965a0..2f586909f835b14fe930a06a90332d8d84dfa8fe 100644 (file)
@@ -42,6 +42,7 @@ import org.opendaylight.yangtools.yang.data.codec.gson.JSONNormalizedNodeStreamW
 import org.opendaylight.yangtools.yang.data.codec.gson.JsonWriterFactory;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
@@ -113,7 +114,8 @@ public class NormalizedNodeJsonBodyWriter implements MessageBodyWriter<Normalize
                     jsonWriter,
                     depth,
                     fields);
-            jsonWriter.name("output");
+            final Module module = context.getSchemaContext().findModule(data.getNodeType().getModule()).get();
+            jsonWriter.name(module.getName() + ":output");
             jsonWriter.beginObject();
             writeChildren(nnWriter, (ContainerNode) data);
             jsonWriter.endObject();
@@ -151,21 +153,24 @@ public class NormalizedNodeJsonBodyWriter implements MessageBodyWriter<Normalize
         final SchemaNode schema = context.getSchemaNode();
         final JSONCodecFactory codecs = getCodecFactory(context);
 
-        final URI initialNs;
-        if (schema instanceof DataSchemaNode
-                && !((DataSchemaNode)schema).isAugmenting()
-                && !(schema instanceof SchemaContext)) {
-            initialNs = schema.getQName().getNamespace();
-        } else if (schema instanceof RpcDefinition) {
-            initialNs = schema.getQName().getNamespace();
-        } else {
-            initialNs = null;
-        }
         final NormalizedNodeStreamWriter streamWriter = JSONNormalizedNodeStreamWriter.createNestedWriter(
-                codecs, path, initialNs, jsonWriter);
+                codecs, path, initialNamespaceFor(schema, depth), jsonWriter);
+
         return ParameterAwareNormalizedNodeWriter.forStreamWriter(streamWriter, depth, fields);
     }
 
+    private static URI initialNamespaceFor(final SchemaNode schema, final Integer depth) {
+        if (schema instanceof RpcDefinition) {
+            return schema.getQName().getNamespace();
+        }
+        // For top-level elements we always want to use namespace prefix, hence use a null initial namespace
+        if (depth == null || depth == 0 || schema instanceof SchemaContext) {
+            return null;
+        }
+        return schema instanceof DataSchemaNode && !((DataSchemaNode)schema).isAugmenting()
+                ? schema.getQName().getNamespace() : null;
+    }
+
     private static JsonWriter createJsonWriter(final OutputStream entityStream, final boolean prettyPrint) {
         if (prettyPrint) {
             return JsonWriterFactory.createJsonWriter(
index b54afbac506494568fcb600488dd1d22a55a2190..a562843bc14c9a6ffb014297a754aea54bd0aa38 100644 (file)
@@ -495,11 +495,11 @@ public final class ReadDataTransactionUtil {
         }
 
         // merge data from config and state
-        return mapNode(stateDataNode, configDataNode);
+        return mergeStateAndConfigData(stateDataNode, configDataNode);
     }
 
     /**
-     * Map data by type of read node.
+     * Merge state and config data into a single NormalizedNode.
      *
      * @param stateDataNode
      *             data node of state data
@@ -508,9 +508,9 @@ public final class ReadDataTransactionUtil {
      * @return {@link NormalizedNode}
      */
     @Nonnull
-    private static NormalizedNode<?, ?> mapNode(@Nonnull final NormalizedNode<?, ?> stateDataNode,
-                                                         @Nonnull final NormalizedNode<?, ?> configDataNode) {
-        validPossibilityOfMergeNodes(stateDataNode, configDataNode);
+    private static NormalizedNode<?, ?> mergeStateAndConfigData(@Nonnull final NormalizedNode<?, ?> stateDataNode,
+                                                                @Nonnull final NormalizedNode<?, ?> configDataNode) {
+        validateNodeMerge(stateDataNode, configDataNode);
         if (configDataNode instanceof RpcDefinition) {
             return prepareRpcData(configDataNode, stateDataNode);
         } else {
@@ -519,19 +519,19 @@ public final class ReadDataTransactionUtil {
     }
 
     /**
-     * Valid of can be data merged together.
+     * Validates whether the two NormalizedNodes can be merged.
      *
      * @param stateDataNode
      *             data node of state data
      * @param configDataNode
      *             data node of config data
      */
-    private static void validPossibilityOfMergeNodes(@Nonnull final NormalizedNode<?, ?> stateDataNode,
-                                                     @Nonnull final NormalizedNode<?, ?> configDataNode) {
+    private static void validateNodeMerge(@Nonnull final NormalizedNode<?, ?> stateDataNode,
+                                          @Nonnull final NormalizedNode<?, ?> configDataNode) {
         final QNameModule moduleOfStateData = stateDataNode.getIdentifier().getNodeType().getModule();
         final QNameModule moduleOfConfigData = configDataNode.getIdentifier().getNodeType().getModule();
-        if (moduleOfStateData != moduleOfConfigData) {
-            throw new RestconfDocumentedException("It is not possible to merge ");
+        if (!moduleOfStateData.equals(moduleOfConfigData)) {
+            throw new RestconfDocumentedException("Unable to merge data from different modules.");
         }
     }
 
index 7e82357cf53c4a6c3d48fb98081ed7c81a372ff8..e2ab773ad316768db00eefba05ea13e39b1229f5 100644 (file)
@@ -523,6 +523,7 @@ public class JSONRestconfServiceRfc8040ImplTest {
 
         assertEquals("Output present", true, output.isPresent());
         assertNotNull("Returned null response", output.get());
+        assertThat("Output element is missing namespace", output.get(), containsString("\"toaster:output\""));
         assertThat("Missing \"textOut\"", output.get(), containsString("\"textOut\":\"foo\""));
 
         verify(mockRpcService).invokeRpc(eq(path), isNull(NormalizedNode.class));
@@ -557,6 +558,8 @@ public class JSONRestconfServiceRfc8040ImplTest {
         final String jsonResp = optionalResp.get();
 
         assertNotNull("Returned null response", jsonResp);
+        assertThat("Top level module has incorrect format", jsonResp, containsString("\"ietf-interfaces:interface\""));
+        assertThat("Missing \"name\"", jsonResp, containsString("\"name\":\"eth0\""));
         assertThat("Missing \"name\"", jsonResp, containsString("\"name\":\"eth0\""));
         assertThat("Missing \"type\"", jsonResp, containsString("\"type\":\"ethernetCsmacd\""));
         assertThat("Missing \"enabled\"", jsonResp, containsString("\"enabled\":true"));