Fix RPC XML payload missing namespace 62/107762/17
authorMatej Sramcik <matej.sramcik@pantheon.tech>
Mon, 25 Sep 2023 06:39:17 +0000 (08:39 +0200)
committerMatej Sramcik <matej.sramcik@pantheon.tech>
Thu, 5 Oct 2023 05:43:05 +0000 (07:43 +0200)
XML payload for RPCs is missing namespace.
Add namespace parameter to schema builder.
Add test to check if namespace is present.
Edit expected outcome from affected tests.

JIRA: NETCONF-1139
Change-Id: I17b99e0afa6acdcac98a63baef625c671a6ce29e
Signed-off-by: Matej Sramcik <matej.sramcik@pantheon.tech>
restconf/restconf-openapi/src/main/java/org/opendaylight/restconf/openapi/impl/DefinitionGenerator.java
restconf/restconf-openapi/src/main/java/org/opendaylight/restconf/openapi/model/builder/OperationBuilder.java
restconf/restconf-openapi/src/test/java/org/opendaylight/restconf/openapi/impl/DefinitionGeneratorTest.java
restconf/restconf-openapi/src/test/java/org/opendaylight/restconf/openapi/impl/OpenApiGeneratorRFC8040Test.java
restconf/restconf-openapi/src/test/java/org/opendaylight/restconf/openapi/mountpoints/MountPointOpenApiTest.java
restconf/restconf-openapi/src/test/resources/openapi-document/controller-all.json
restconf/restconf-openapi/src/test/resources/openapi-document/controller-toaster.json
restconf/restconf-openapi/src/test/resources/openapi-document/device-all.json
restconf/restconf-openapi/src/test/resources/openapi-document/device-toaster.json

index 0e818dc2ad294d1e35962a5dfc5a23f54ce16c5c..3e447d9683cd04a3e4f8cd7cca7f3b6f83a31106 100644 (file)
@@ -286,7 +286,7 @@ public final class DefinitionGenerator {
             final Schema.Builder childSchemaBuilder = new Schema.Builder()
                 .title(filename)
                 .type(OBJECT_TYPE)
-                .xml(new Xml(isInput ? INPUT : OUTPUT, null, null));
+                .xml(new Xml(isInput ? INPUT : OUTPUT, container.getQName().getNamespace().toString(), null));
             processChildren(childSchemaBuilder, container.getChildNodes(), parentName, definitions, definitionNames,
                 stack, module, false);
             final String discriminator =
index 39e1ef160865ea725b0255e4f3b6ab1563bd8cbf..9f4d895a2dde6ad5199cef582defb26e6fada90d 100644 (file)
@@ -225,7 +225,7 @@ public final class OperationBuilder {
             final SimpleEntry<String, MediaTypeObject> jsonEntry = new SimpleEntry<>(MediaType.APPLICATION_JSON,
                 jsonTypeValue);
 
-            final Xml xml = new Xml(INPUT_KEY, null, null);
+            final Xml xml = new Xml(INPUT_KEY, input.getQName().getNamespace().toString(), null);
             final Schema xmlSchema = new Schema.Builder()
                 .type(OBJECT)
                 .xml(xml)
index d88727dcd17c514ce81c8263102765870cba745e..ae07af5a352c25fa766603762b86e3060c317b31 100644 (file)
@@ -144,4 +144,38 @@ public final class DefinitionGeneratorTest {
         assertEquals("0000-00-00T00:00:00Z", properties.get("login-date-time").example().toString());
         assertEquals("0.0.0.0", properties.get("ipv4-address").example().toString());
     }
+
+    /**
+     * 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 jsonObject = DefinitionGenerator.convertToSchemas(module, context, new DefinitionNames(), true);
+        assertNotNull(jsonObject);
+        final var schema = jsonObject.get("toaster_make-toast_input");
+        assertNotNull(schema);
+        final var xml = schema.xml();
+        assertNotNull(xml);
+        final var namespace = xml.namespace();
+        assertNotNull(namespace);
+        assertEquals("http://netconfcentral.org/ns/toaster", namespace);
+    }
+
+    /**
+     * 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 jsonObject = DefinitionGenerator.convertToSchemas(module, context, new DefinitionNames(), true);
+        assertNotNull(jsonObject);
+        final var schema = jsonObject.get("action-types_container-action_input");
+        assertNotNull(schema);
+        final var xml = schema.xml();
+        assertNotNull(xml);
+        final var namespace = xml.namespace();
+        assertNotNull(namespace);
+        assertEquals("urn:ietf:params:xml:ns:yang:test:action:types", namespace);
+    }
 }
index 60348abd9f92d684d5d19f06e0006a99c17c6a16..175c24f9852c3684fcf3ed665baac73588bdbac2 100644 (file)
@@ -401,6 +401,48 @@ public final class OpenApiGeneratorRFC8040Test {
         }
     }
 
+    /**
+     * Test that checks if namespace for rpc is present.
+     */
+    @Test
+    public void testRpcNamespace() {
+        final var doc = generator.getApiDeclaration("toaster", "2009-11-20", uriInfo);
+        assertNotNull("Failed to find Datastore API", doc);
+        final var paths = doc.paths();
+        final var path = paths.get("/rests/operations/toaster:cancel-toast");
+        assertNotNull(path);
+        final var content = path.post().requestBody().content().get("application/xml");
+        assertNotNull(content);
+        final var schema = content.schema();
+        assertNotNull(schema);
+        final var xml = schema.xml();
+        assertNotNull(xml);
+        final var namespace = xml.namespace();
+        assertNotNull(namespace);
+        assertEquals("http://netconfcentral.org/ns/toaster", namespace);
+    }
+
+    /**
+     * Test that checks if namespace for actions is present.
+     */
+    @Test
+    public void testActionsNamespace() {
+        final var doc = generator.getApiDeclaration("action-types", null, uriInfo);
+        assertNotNull("Failed to find Datastore API", doc);
+        final var paths = doc.paths();
+        final var path = paths.get("/rests/operations/action-types:multi-container/inner-container/action");
+        assertNotNull(path);
+        final var content = path.post().requestBody().content().get("application/xml");
+        assertNotNull(content);
+        final var schema = content.schema();
+        assertNotNull(schema);
+        final var xml = schema.xml();
+        assertNotNull(xml);
+        final var namespace = xml.namespace();
+        assertNotNull(namespace);
+        assertEquals("urn:ietf:params:xml:ns:yang:test:action:types", namespace);
+    }
+
     /**
      *  Test JSON and XML references for request operation.
      */
index d042c652dc731016e01bad1185704a2308c9753d..22310d93fae01d4776d194321efb74399312156d 100644 (file)
@@ -342,4 +342,52 @@ public final class MountPointOpenApiTest {
         // 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() throws Exception {
+        final var mockInfo = DocGenTestHelper.createMockUriInfo(HTTP_URL);
+        openApi.onMountPointCreated(INSTANCE_ID);
+
+        final var mountPointApi = openApi.getMountPointApi(mockInfo, 1L, null);
+        assertNotNull("Failed to find Datastore API", mountPointApi);
+        final var paths = mountPointApi.paths();
+        final var path = paths.get("/rests/operations/nodes/node=123/yang-ext:mount/toaster:cancel-toast");
+        assertNotNull(path);
+        final var content = path.post().requestBody().content().get("application/xml");
+        assertNotNull(content);
+        final var schema = content.schema();
+        assertNotNull(schema);
+        final var xml = schema.xml();
+        assertNotNull(xml);
+        final var namespace = xml.namespace();
+        assertNotNull(namespace);
+        assertEquals("http://netconfcentral.org/ns/toaster", namespace);
+    }
+
+    /**
+     * Test that checks if namespace for actions is present.
+     */
+    @Test
+    public void testActionsNamespace() throws Exception {
+        final var mockInfo = DocGenTestHelper.createMockUriInfo(HTTP_URL);
+        openApi.onMountPointCreated(INSTANCE_ID);
+        final var mountPointApi = openApi.getMountPointApi(mockInfo, 1L, null);
+        assertNotNull("Failed to find Datastore API", mountPointApi);
+        final var paths = mountPointApi.paths();
+        final var path = paths.get(
+            "/rests/operations/nodes/node=123/yang-ext:mount/action-types:multi-container/inner-container/action");
+        assertNotNull(path);
+        final var content = path.post().requestBody().content().get("application/xml");
+        assertNotNull(content);
+        final var schema = content.schema();
+        assertNotNull(schema);
+        final var xml = schema.xml();
+        assertNotNull(xml);
+        final var namespace = xml.namespace();
+        assertNotNull(namespace);
+        assertEquals("urn:ietf:params:xml:ns:yang:test:action:types", namespace);
+    }
 }
index 36c6da0f1dfcc06062d888fcc074012822d9546c..297a236be36039cae9239c76b19715f2003e7070 100644 (file)
@@ -33,7 +33,8 @@
             "application/xml": {
               "schema": {
                 "xml": {
-                  "name": "input"
+                  "name": "input",
+                  "namespace": "http://netconfcentral.org/ns/toaster"
                 },
                 "type": "object"
               }
           }
         },
         "xml": {
-          "name": "input"
+          "name": "input",
+          "namespace": "http://netconfcentral.org/ns/toaster"
         },
         "title": "toaster_make-toast_input",
         "type": "object"
           }
         },
         "xml": {
-          "name": "input"
+          "name": "input",
+          "namespace": "http://netconfcentral.org/ns/toaster"
         },
         "title": "toaster_restock-toaster_input",
         "type": "object"
index a9a869a38601854ab1a7c07c928ac8abcaf8865c..f77a1c8455692014b3e66d23ae17f1d0f67faa42 100644 (file)
@@ -63,7 +63,8 @@
             "application/xml": {
               "schema": {
                 "xml": {
-                  "name": "input"
+                  "name": "input",
+                  "namespace": "http://netconfcentral.org/ns/toaster"
                 },
                 "type": "object"
               }
           }
         },
         "xml": {
-          "name": "input"
+          "name": "input",
+          "namespace": "http://netconfcentral.org/ns/toaster"
         },
         "title": "toaster_make-toast_input",
         "type": "object"
           }
         },
         "xml": {
-          "name": "input"
+          "name": "input",
+          "namespace": "http://netconfcentral.org/ns/toaster"
         },
         "title": "toaster_restock-toaster_input",
         "type": "object"
index 0a405351ca1b441ac66f84b1e20933f6b2be5e89..c4194c09eff9e3ed7195c0cf04b7ce56039c100c 100644 (file)
             "application/xml": {
               "schema": {
                 "xml": {
-                  "name": "input"
+                  "name": "input",
+                  "namespace": "http://netconfcentral.org/ns/toaster"
                 },
                 "type": "object"
               }
           }
         },
         "xml": {
-          "name": "input"
+          "name": "input",
+          "namespace": "http://netconfcentral.org/ns/toaster"
         },
         "title": "toaster_make-toast_input",
         "type": "object"
           }
         },
         "xml": {
-          "name": "input"
+          "name": "input",
+          "namespace": "http://netconfcentral.org/ns/toaster"
         },
         "title": "toaster_restock-toaster_input",
         "type": "object"
index 4353b7d1ec8e3aefd9f5e1ee239bcf2128426b5b..d40e6a33645138c6603ad9eef133285185e7810a 100644 (file)
             "application/xml": {
               "schema": {
                 "xml": {
-                  "name": "input"
+                  "name": "input",
+                  "namespace": "http://netconfcentral.org/ns/toaster"
                 },
                 "type": "object"
               }
           }
         },
         "xml": {
-          "name": "input"
+          "name": "input",
+          "namespace": "http://netconfcentral.org/ns/toaster"
         },
         "title": "toaster_make-toast_input",
         "type": "object"
           }
         },
         "xml": {
-          "name": "input"
+          "name": "input",
+          "namespace": "http://netconfcentral.org/ns/toaster"
         },
         "title": "toaster_restock-toaster_input",
         "type": "object"