Do not use TOP schemas in RPC requests 59/107359/14
authorOleksandr Zharov <[email protected]>
Tue, 8 Aug 2023 10:36:28 +0000 (12:36 +0200)
committerIvan Hrasko <[email protected]>
Thu, 17 Aug 2023 13:16:26 +0000 (15:16 +0200)
Refactored RPC operations in order to stop using TOP schemas for
generation of it's request body.

JIRA: NETCONF-1057
Change-Id: Ib5bf2a258a8aa9df515a9a466ddcbc5a99a0dea4
Signed-off-by: Oleksandr Zharov <[email protected]>
restconf/restconf-openapi/src/main/java/org/opendaylight/restconf/openapi/model/builder/OperationBuilder.java
restconf/restconf-openapi/src/test/java/org/opendaylight/restconf/openapi/OperationalDataTest.java
restconf/restconf-openapi/src/test/java/org/opendaylight/restconf/openapi/impl/OpenApiGeneratorRFC8040Test.java

index 558513280c91a8bcc4040b451cd7fad462796e37..1184162b033ec3b1c56734f1aa40bc575ebef2d5 100644 (file)
@@ -56,12 +56,9 @@ public final class OperationBuilder {
         final var summary = SUMMARY_TEMPLATE.formatted(HttpMethod.POST, deviceName, moduleName, nodeName);
         final List<String> tags = List.of(deviceName + " " + moduleName);
         final List<Parameter> parameters = new ArrayList<>(pathParams);
-        final ObjectNode ref = JsonNodeFactory.instance.objectNode();
         final String cleanDefName = parentName + "_" + nodeName;
         final String defName = cleanDefName + discriminator;
-        final String xmlDefName = cleanDefName + discriminator;
-        ref.put(REF_KEY, COMPONENTS_PREFIX + defName);
-        final ObjectNode requestBody = createRequestBodyParameter(defName, xmlDefName, nodeName, summary);
+        final ObjectNode requestBody = createPostDataRequestBodyParameter(defName, nodeName);
         final ObjectNode responses = JsonNodeFactory.instance.objectNode();
         responses.set(String.valueOf(Response.Status.CREATED.getStatusCode()),
                 buildResponse(Response.Status.CREATED.getReasonPhrase()));
@@ -91,7 +88,7 @@ public final class OperationBuilder {
         final boolean isList = node instanceof ListSchemaNode;
         final ObjectNode response;
         if (isConfig) {
-            response = createRequestBodyParameter1(defName, nodeName, isList, summary,
+            response = createRequestBodyParameter(defName, nodeName, isList, summary,
                 String.valueOf(Response.Status.OK.getStatusCode()));
         } else {
             response = JsonNodeFactory.instance.objectNode();
@@ -130,7 +127,7 @@ public final class OperationBuilder {
         final List<Parameter> parameters = new ArrayList<>(pathParams);
         final String defName = parentName + "_" + nodeName;
         final boolean isList = node instanceof ListSchemaNode;
-        final ObjectNode requestBody = createRequestBodyParameter1(defName, fullName, isList, summary, nodeName);
+        final ObjectNode requestBody = createRequestBodyParameter(defName, fullName, isList, summary, nodeName);
 
         final ObjectNode responses = JsonNodeFactory.instance.objectNode();
         responses.set(String.valueOf(Response.Status.CREATED.getStatusCode()),
@@ -155,7 +152,7 @@ public final class OperationBuilder {
         final List<Parameter> parameters = new ArrayList<>(pathParams);
         final String defName = parentName + "_" + nodeName;
         final boolean isList = node instanceof ListSchemaNode;
-        final ObjectNode requestBody = createRequestBodyParameter1(defName, fullName, isList, summary, nodeName);
+        final ObjectNode requestBody = createRequestBodyParameter(defName, fullName, isList, summary, nodeName);
 
         final ObjectNode responses = JsonNodeFactory.instance.objectNode();
         responses.set(String.valueOf(Response.Status.OK.getStatusCode()),
@@ -207,8 +204,7 @@ public final class OperationBuilder {
             final String discriminator = definitionNames.getDiscriminator(input);
             final String clearDefName = parentName + "_" + operationName + INPUT_SUFFIX;
             final String defName = clearDefName + discriminator;
-            final String defTopName = clearDefName + TOP + discriminator;
-            requestBody = createRequestBodyParameter(defTopName, defName, inputName, summary);
+            requestBody = createRequestBodyParameter(defName, INPUT_KEY, false, summary, inputName);
         } else {
             final ObjectNode payload = JsonNodeFactory.instance.objectNode();
             final ObjectNode jsonSchema = JsonNodeFactory.instance.objectNode();
@@ -241,7 +237,7 @@ public final class OperationBuilder {
 
         if (!output.getChildNodes().isEmpty()) {
             final ObjectNode schema = JsonNodeFactory.instance.objectNode();
-            final String defName = parentName + "_" + operationName + OUTPUT_SUFFIX + TOP
+            final String defName = parentName + "_" + operationName + OUTPUT_SUFFIX
                     + definitionNames.getDiscriminator(output);
             schema.put(REF_KEY, COMPONENTS_PREFIX + defName);
             responses.set(String.valueOf(Response.Status.OK.getStatusCode()), buildResponse(description, schema));
@@ -260,25 +256,18 @@ public final class OperationBuilder {
             .build();
     }
 
-    private static ObjectNode createRequestBodyParameter(final String defName, final String xmlDefName,
-            final String name, final String summary) {
+    private static ObjectNode createPostDataRequestBodyParameter(final String defName, final String name) {
         final ObjectNode payload = JsonNodeFactory.instance.objectNode();
         final ObjectNode content = JsonNodeFactory.instance.objectNode();
-        if (summary != null && summary.contains(HttpMethod.PATCH)) {
-            content.set("application/yang-data+json", buildMimeTypeValue(defName));
-            content.set("application/yang-data+xml", buildMimeTypeValue(xmlDefName));
-        } else {
-            content.set(MediaType.APPLICATION_JSON, buildMimeTypeValue(defName));
-            content.set(MediaType.APPLICATION_XML, buildMimeTypeValue(xmlDefName));
-        }
+        final ObjectNode value = buildMimeTypeValue(defName);
+        content.set(MediaType.APPLICATION_JSON, value);
+        content.set(MediaType.APPLICATION_XML, value);
         payload.set(CONTENT_KEY, content);
         payload.put(DESCRIPTION_KEY, name);
         return payload;
     }
 
-    // TODO change name after this method will be finished.(for now it's just PUT and PATCH but there might be more
-    //  in next patches)
-    private static ObjectNode createRequestBodyParameter1(final String defName, final String name,
+    private static ObjectNode createRequestBodyParameter(final String defName, final String name,
             final boolean isList, final String summary, final String description) {
         final ObjectNode payload = JsonNodeFactory.instance.objectNode();
         final ObjectNode content = JsonNodeFactory.instance.objectNode();
index 5fae1d2a700c8afbf9181bf12cebca723bea34b9..1c644c0ec983005a4fca8096c16f3b8b8253cc57 100644 (file)
@@ -111,28 +111,27 @@ public class OperationalDataTest {
                 final var content = response.get("content");
                 // In case of 200 no content and Operational data
                 if (content != null) {
-                    verifyOperationHaveCorrectReference(content.get("application/xml"));
-                    // TODO re-enable it in next patch after refactoring
-//                    verifyOperationHaveCorrectReference(content.get("application/json"));
+                    verifyOperationHaveCorrectXmlReference(content.get("application/xml").get("schema"));
+                    verifyOperationHaveCorrectJsonReference(content.get("application/json").get("schema"));
                 }
             }
             if (path.put() != null) {
                 final var responses = path.put().requestBody();
                 final var content = responses.get("content");
-                verifyOperationHaveCorrectReference(content.get("application/xml"));
-                verifyOperationHaveCorrectJsonReference(content.get("application/json"));
+                verifyOperationHaveCorrectXmlReference(content.get("application/xml").get("schema"));
+                verifyOperationHaveCorrectJsonReference(content.get("application/json").get("schema"));
             }
             if (path.post() != null) {
                 final var responses = path.post().requestBody();
                 final var content = responses.get("content");
-                verifyOperationHaveCorrectReference(content.get("application/xml"));
-                verifyOperationHaveCorrectReference(content.get("application/json"));
+                verifyOperationHaveCorrectXmlReference(content.get("application/xml").get("schema"));
+                verifyOperationHaveCorrectJsonReference(content.get("application/json").get("schema"));
             }
             if (path.patch() != null) {
                 final var responses = path.patch().requestBody();
                 final var content = responses.get("content");
-                verifyOperationHaveCorrectReference(content.get("application/yang-data+xml"));
-                verifyOperationHaveCorrectJsonReference(content.get("application/yang-data+json"));
+                verifyOperationHaveCorrectXmlReference(content.get("application/yang-data+xml").get("schema"));
+                verifyOperationHaveCorrectJsonReference(content.get("application/yang-data+json").get("schema"));
             }
         }
     }
@@ -207,8 +206,7 @@ public class OperationalDataTest {
         assertEquals(Set.of("ca-output"), actualProperties);
     }
 
-    private static void verifyOperationHaveCorrectReference(final JsonNode jsonNode) {
-        final var schema = jsonNode.get("schema");
+    private static void verifyOperationHaveCorrectXmlReference(final JsonNode schema) {
         final var ref = schema.get("$ref");
         // In case of a POST RPC with a direct input body and no reference value
         if (ref != null) {
index 39350e108aa2bdff495eab9ef2d0472e124a7159..f387ae4edc93985c0525b58dcd4c0827b010164c 100644 (file)
@@ -318,10 +318,10 @@ public final class OpenApiGeneratorRFC8040Test {
 
         assertEquals(Set.of("/rests/data", "/rests/data/my-yang:data"), doc.paths().keySet());
         final var JsonNodeMyYangData = doc.paths().get("/rests/data/my-yang:data");
-        verifyRequestRef(JsonNodeMyYangData.post(), "#/components/schemas/my-yang_data",
+        verifyPostDataRequestRef(JsonNodeMyYangData.post(), "#/components/schemas/my-yang_data",
             "#/components/schemas/my-yang_data");
-        verifyRequestRef1(JsonNodeMyYangData.put(), "#/components/schemas/my-yang_data", CONTAINER);
-        verifyRequestRef1(JsonNodeMyYangData.get(), "#/components/schemas/my-yang_data", CONTAINER);
+        verifyRequestRef(JsonNodeMyYangData.put(), "#/components/schemas/my-yang_data", CONTAINER);
+        verifyRequestRef(JsonNodeMyYangData.get(), "#/components/schemas/my-yang_data", CONTAINER);
 
         // Test `components/schemas` objects
         final var definitions = doc.components().schemas();
@@ -336,42 +336,41 @@ public final class OpenApiGeneratorRFC8040Test {
         final var doc = generator.getApiDeclaration(TOASTER_2, REVISION_DATE, uriInfo);
 
         final var jsonNodeToaster = doc.paths().get("/rests/data/toaster2:toaster");
-        verifyRequestRef(jsonNodeToaster.post(), "#/components/schemas/toaster2_toaster",
+        verifyPostDataRequestRef(jsonNodeToaster.post(), "#/components/schemas/toaster2_toaster",
             "#/components/schemas/toaster2_toaster");
-        verifyRequestRef1(jsonNodeToaster.put(), "#/components/schemas/toaster2_toaster", CONTAINER);
-        verifyRequestRef1(jsonNodeToaster.get(), "#/components/schemas/toaster2_toaster", CONTAINER);
+        verifyRequestRef(jsonNodeToaster.put(), "#/components/schemas/toaster2_toaster", CONTAINER);
+        verifyRequestRef(jsonNodeToaster.get(), "#/components/schemas/toaster2_toaster", CONTAINER);
 
         final var jsonNodeToasterSlot = doc.paths().get("/rests/data/toaster2:toaster/toasterSlot={slotId}");
-        verifyRequestRef(jsonNodeToasterSlot.post(), "#/components/schemas/toaster2_toaster_toasterSlot",
+        verifyPostDataRequestRef(jsonNodeToasterSlot.post(), "#/components/schemas/toaster2_toaster_toasterSlot",
             "#/components/schemas/toaster2_toaster_toasterSlot");
-        verifyRequestRef1(jsonNodeToasterSlot.put(), "#/components/schemas/toaster2_toaster_toasterSlot", LIST);
-        verifyRequestRef1(jsonNodeToasterSlot.get(), "#/components/schemas/toaster2_toaster_toasterSlot", LIST);
+        verifyRequestRef(jsonNodeToasterSlot.put(), "#/components/schemas/toaster2_toaster_toasterSlot", LIST);
+        verifyRequestRef(jsonNodeToasterSlot.get(), "#/components/schemas/toaster2_toaster_toasterSlot", LIST);
 
         final var jsonNodeSlotInfo = doc.paths().get(
             "/rests/data/toaster2:toaster/toasterSlot={slotId}/toaster-augmented:slotInfo");
-        verifyRequestRef(jsonNodeSlotInfo.post(), "#/components/schemas/toaster2_toaster_toasterSlot_slotInfo",
+        verifyPostDataRequestRef(jsonNodeSlotInfo.post(), "#/components/schemas/toaster2_toaster_toasterSlot_slotInfo",
             "#/components/schemas/toaster2_toaster_toasterSlot_slotInfo");
-        verifyRequestRef1(jsonNodeSlotInfo.put(), "#/components/schemas/toaster2_toaster_toasterSlot_slotInfo",
+        verifyRequestRef(jsonNodeSlotInfo.put(), "#/components/schemas/toaster2_toaster_toasterSlot_slotInfo",
             CONTAINER);
-        verifyRequestRef1(jsonNodeSlotInfo.get(), "#/components/schemas/toaster2_toaster_toasterSlot_slotInfo",
+        verifyRequestRef(jsonNodeSlotInfo.get(), "#/components/schemas/toaster2_toaster_toasterSlot_slotInfo",
             CONTAINER);
 
         final var jsonNodeLst = doc.paths().get("/rests/data/toaster2:lst={lf1}");
-        verifyRequestRef(jsonNodeLst.post(), "#/components/schemas/toaster2_lst",
+        verifyPostDataRequestRef(jsonNodeLst.post(), "#/components/schemas/toaster2_lst",
             "#/components/schemas/toaster2_lst");
-        verifyRequestRef1(jsonNodeLst.put(), "#/components/schemas/toaster2_lst", LIST);
-        verifyRequestRef1(jsonNodeLst.get(), "#/components/schemas/toaster2_lst", LIST);
+        verifyRequestRef(jsonNodeLst.put(), "#/components/schemas/toaster2_lst", LIST);
+        verifyRequestRef(jsonNodeLst.get(), "#/components/schemas/toaster2_lst", LIST);
 
         final var jsonNodeLst1 = doc.paths().get("/rests/data/toaster2:lst={lf1}/lst1={key1},{key2}");
-        verifyRequestRef(jsonNodeLst1.post(), "#/components/schemas/toaster2_lst_lst1",
+        verifyPostDataRequestRef(jsonNodeLst1.post(), "#/components/schemas/toaster2_lst_lst1",
             "#/components/schemas/toaster2_lst_lst1");
-        verifyRequestRef1(jsonNodeLst1.put(), "#/components/schemas/toaster2_lst_lst1", LIST);
-        verifyRequestRef1(jsonNodeLst1.get(), "#/components/schemas/toaster2_lst_lst1", LIST);
+        verifyRequestRef(jsonNodeLst1.put(), "#/components/schemas/toaster2_lst_lst1", LIST);
+        verifyRequestRef(jsonNodeLst1.get(), "#/components/schemas/toaster2_lst_lst1", LIST);
 
         final var jsonNodeMakeToast = doc.paths().get("/rests/operations/toaster2:make-toast");
         assertNull(jsonNodeMakeToast.get());
-        verifyRequestRef(jsonNodeMakeToast.post(), "#/components/schemas/toaster2_make-toast_input_TOP",
-            "#/components/schemas/toaster2_make-toast_input");
+        verifyRequestRef(jsonNodeMakeToast.post(), "#/components/schemas/toaster2_make-toast_input", CONTAINER);
 
         final var jsonNodeCancelToast = doc.paths().get("/rests/operations/toaster2:cancel-toast");
         assertNull(jsonNodeCancelToast.get());
@@ -404,7 +403,7 @@ public final class OpenApiGeneratorRFC8040Test {
     /**
      *  Test JSON and XML references for request operation.
      */
-    private static void verifyRequestRef(final Operation operation, final String expectedJsonRef,
+    private static void verifyPostDataRequestRef(final Operation operation, final String expectedJsonRef,
             final String expectedXmlRef) {
         final JsonNode postContent;
         if (operation.requestBody() != null) {
@@ -421,8 +420,7 @@ public final class OpenApiGeneratorRFC8040Test {
         assertEquals(expectedXmlRef, postXmlRef.textValue());
     }
 
-    private static void verifyRequestRef1(final Operation operation, final String expectedRef,
-            final String nodeType) {
+    private static void verifyRequestRef(final Operation operation, final String expectedRef, final String nodeType) {
         final JsonNode postContent;
         if (operation.requestBody() != null) {
             postContent = operation.requestBody().path("content");