Fix RPC XML payload missing namespace 71/108271/8
authorMatej Sramcik <matej.sramcik@pantheon.tech>
Fri, 6 Oct 2023 06:47:00 +0000 (08:47 +0200)
committerIvan Hrasko <ivan.hrasko@pantheon.tech>
Wed, 11 Oct 2023 07:13:04 +0000 (07:13 +0000)
XML payload for RPCs is missing namespace.
Add namespace parameter to schema builder.
Add test to check if namespace is present.

JIRA: NETCONF-1139
Change-Id: I17b99e0afa6acdcac98a63baef625c671a6ce29e
Signed-off-by: Matej Sramcik <matej.sramcik@pantheon.tech>
(cherry picked from commit 9dc5513792f3af8eba4ca3a1eb5617c7c243fc6f)

restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/DefinitionGenerator.java
restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/model/builder/OperationBuilder.java
restconf/sal-rest-docgen/src/test/java/org/opendaylight/netconf/sal/rest/doc/impl/ApiDocGeneratorRFC8040Test.java
restconf/sal-rest-docgen/src/test/java/org/opendaylight/netconf/sal/rest/doc/impl/MountPointSwaggerTest.java
restconf/sal-rest-docgen/src/test/java/org/opendaylight/netconf/sal/rest/doc/impl/SwaggerObjectTest.java

index 602f3e3b891292703e72ee39f2132b08652418f8..77be90af9d42f9de73f60318aecd9f041dbdcb76 100644 (file)
@@ -318,6 +318,7 @@ public class DefinitionGenerator {
             childSchema.put(TYPE_KEY, OBJECT_TYPE);
             final ObjectNode xml = JsonNodeFactory.instance.objectNode();
             xml.put(NAME_KEY, isInput ? INPUT : OUTPUT);
+            xml.put(NAMESPACE_KEY, container.getQName().getNamespace().toString());
             childSchema.set(XML_KEY, xml);
             childSchema.put(TITLE_KEY, filename);
             final String discriminator =
index 71fc9df101575395aeb2f71ed5e5226b7020c556..429df3997ead20b17f38b1a7528115a4ec696557 100644 (file)
@@ -237,6 +237,7 @@ public final class OperationBuilder {
                 xmlSchema.put(TYPE_KEY, OBJECT);
                 final ObjectNode xml = JsonNodeFactory.instance.objectNode();
                 xml.put(NAME_KEY, INPUT);
+                xml.put("namespace", input.getQName().getNamespace().toString());
                 xmlSchema.set(XML_KEY, xml);
                 final ObjectNode xmlTypeValue = JsonNodeFactory.instance.objectNode();
                 xmlTypeValue.set(SCHEMA_KEY, xmlSchema);
index a21e55dc2e94f2dcdbed042165c48bcbe4bdee4d..c982de432b0c6951686e730ea9c1db98cd42cc13 100644 (file)
@@ -437,6 +437,60 @@ public final class ApiDocGeneratorRFC8040Test extends AbstractApiDocTest {
         }
     }
 
+    /**
+     * Test that checks if namespace for rpc is present.
+     */
+    @Test
+    public void testRpcNamespace() {
+        final var doc = (OpenApiObject) generator.getApiDeclaration(NAME_2, REVISION_DATE, URI_INFO,
+            ApiDocServiceImpl.OAversion.V3_0);
+        assertNotNull(doc);
+        final var path = doc.getPaths().get("/rests/operations/toaster:cancel-toast");
+        assertNotNull(path);
+        final var post = path.get("post");
+        assertNotNull(post);
+        final var requestBody = post.get("requestBody");
+        assertNotNull(requestBody);
+        final var content = requestBody.get("content");
+        assertNotNull(content);
+        final var application = content.get("application/xml");
+        assertNotNull(application);
+        final var schema = application.get("schema");
+        assertNotNull(schema);
+        final var xml = schema.get("xml");
+        assertNotNull(xml);
+        final var namespace = xml.get("namespace");
+        assertNotNull(namespace);
+        assertEquals("http://netconfcentral.org/ns/toaster", namespace.asText());
+    }
+
+    /**
+     * Test that checks if namespace for actions is present.
+     */
+    @Test
+    public void testActionsNamespace() {
+        final var doc = (OpenApiObject) generator.getApiDeclaration("action-types", null, URI_INFO,
+            ApiDocServiceImpl.OAversion.V3_0);
+        assertNotNull(doc);
+        final var path = doc.getPaths().get("/rests/operations/action-types:multi-container/inner-container/action");
+        assertNotNull(path);
+        final var post = path.get("post");
+        assertNotNull(post);
+        final var requestBody = post.get("requestBody");
+        assertNotNull(requestBody);
+        final var content = requestBody.get("content");
+        assertNotNull(content);
+        final var application = content.get("application/xml");
+        assertNotNull(application);
+        final var schema = application.get("schema");
+        assertNotNull(schema);
+        final var xml = schema.get("xml");
+        assertNotNull(xml);
+        final var namespace = xml.get("namespace");
+        assertNotNull(namespace);
+        assertEquals("urn:ietf:params:xml:ns:yang:test:action:types", namespace.asText());
+    }
+
     /**
      *  Test JSON and XML references for request operation.
      */
index 582e671651aaff70f373129f727127e68dd4dd41..97790128aab83f197c96fd2ffa24c08eaf10da5d 100644 (file)
@@ -238,4 +238,60 @@ public final class MountPointSwaggerTest extends AbstractApiDocTest {
         // verify that the filtered set (from openapi for all modules) is the same as the set from openapi for toaster
         assertEquals(toasterPathsFromToaster, toasterPathsFromAll);
     }
+
+    /**
+     * Test that checks if namespace for rpc is present.
+     */
+    @Test
+    public void testRpcNamespace() {
+        swagger.onMountPointCreated(INSTANCE_ID);
+        final OpenApiObject openApiToaster = (OpenApiObject) swagger.getMountPointApi(uriDeviceToaster, DEVICE_ID,
+            TOASTER, TOASTER_REVISION, OAversion.V3_0);
+        final var path = openApiToaster
+            .getPaths().get("/rests/operations/nodes/node=123/yang-ext:mount/toaster:cancel-toast");
+        assertNotNull(path);
+        final var post = path.get("post");
+        assertNotNull(post);
+        final var requestBody = post.get("requestBody");
+        assertNotNull(requestBody);
+        final var content = requestBody.get("content");
+        assertNotNull(content);
+        final var application = content.get("application/xml");
+        assertNotNull(application);
+        final var schema = application.get("schema");
+        assertNotNull(schema);
+        final var xml = schema.get("xml");
+        assertNotNull(xml);
+        final var namespace = xml.get("namespace");
+        assertNotNull(namespace);
+        assertEquals("http://netconfcentral.org/ns/toaster", namespace.asText());
+    }
+
+    /**
+     * Test that checks if namespace for actions is present.
+     */
+    @Test
+    public void testActionsNamespace() {
+        swagger.onMountPointCreated(INSTANCE_ID);
+        final var openApiAll = (OpenApiObject) swagger.getMountPointApi(uriDeviceAll, DEVICE_ID,
+            Optional.empty(), OAversion.V3_0);
+        final var path = openApiAll.getPaths().get(
+            "/rests/operations/nodes/node=123/yang-ext:mount/action-types:multi-container/inner-container/action");
+        assertNotNull(path);
+        final var post = path.get("post");
+        assertNotNull(post);
+        final var requestBody = post.get("requestBody");
+        assertNotNull(requestBody);
+        final var content = requestBody.get("content");
+        assertNotNull(content);
+        final var application = content.get("application/xml");
+        assertNotNull(application);
+        final var schema = application.get("schema");
+        assertNotNull(schema);
+        final var xml = schema.get("xml");
+        assertNotNull(xml);
+        final var namespace = xml.get("namespace");
+        assertNotNull(namespace);
+        assertEquals("urn:ietf:params:xml:ns:yang:test:action:types", namespace.asText());
+    }
 }
index 461422ba9ea72dfbce562d62001f973de3312ea6..42cbf37d392d69a35d33d618e637b816b68b3baa 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.netconf.sal.rest.doc.impl;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 
 import com.fasterxml.jackson.databind.node.ObjectNode;
@@ -41,4 +42,42 @@ public final class SwaggerObjectTest extends AbstractApiDocTest {
             ApiDocServiceImpl.OAversion.V2_0, true);
         assertNotNull(jsonObject);
     }
+
+    /**
+     * Test that checks if namespace for rpc is present.
+     */
+    @Test
+    public void testRpcNamespace() throws Exception {
+        final var module = CONTEXT.findModule("toaster", Revision.of("2009-11-20")).orElseThrow();
+        final var generator = new DefinitionGenerator();
+        final var jsonObject = generator.convertToJsonSchema(module, CONTEXT, new DefinitionNames(),
+            ApiDocServiceImpl.OAversion.V2_0, true);
+        assertNotNull(jsonObject);
+        final var schema = jsonObject.get("toaster_make-toast_input");
+        assertNotNull(schema);
+        final var xml = schema.get("xml");
+        assertNotNull(xml);
+        final var namespace = xml.get("namespace");
+        assertNotNull(namespace);
+        assertEquals("http://netconfcentral.org/ns/toaster", namespace.asText());
+    }
+
+    /**
+     * Test that checks if namespace for actions is present.
+     */
+    @Test
+    public void testActionsNamespace() throws IOException {
+        final var module = CONTEXT.findModule("action-types").orElseThrow();
+        final var generator = new DefinitionGenerator();
+        final var jsonObject = generator.convertToJsonSchema(module, CONTEXT, new DefinitionNames(),
+            ApiDocServiceImpl.OAversion.V2_0, true);
+        assertNotNull(jsonObject);
+        final var schema = jsonObject.get("action-types_container-action_input");
+        assertNotNull(schema);
+        final var xml = schema.get("xml");
+        assertNotNull(xml);
+        final var namespace = xml.get("namespace");
+        assertNotNull(namespace);
+        assertEquals("urn:ietf:params:xml:ns:yang:test:action:types", namespace.asText());
+    }
 }