Add (plain) PATCH method to OpenApi 60/104960/4
authorYaroslav Lastivka <yaroslav.lastivka@pantheon.tech>
Thu, 16 Mar 2023 12:33:42 +0000 (14:33 +0200)
committerIvan Hrasko <ivan.hrasko@pantheon.tech>
Tue, 4 Apr 2023 08:24:34 +0000 (10:24 +0200)
ODL supports also plain PATCH method according to RFC.
PATCH method was added to apidocs.

JIRA: NETCONF-978
Change-Id: Ibaf22388585c4560e163bd5cda35c582135d7ad5
Signed-off-by: Yaroslav Lastivka <yaroslav.lastivka@pantheon.tech>
restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/BaseYangSwaggerGenerator.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

index 71a26dcf1f14d4836f94ffa7c687a8e2491d5183..2b9dc0b3cd5c0164e86bf6bea871ec5c0527da5d 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.netconf.sal.rest.doc.impl;
 import static org.opendaylight.netconf.sal.rest.doc.model.builder.OperationBuilder.TOP;
 import static org.opendaylight.netconf.sal.rest.doc.model.builder.OperationBuilder.buildDelete;
 import static org.opendaylight.netconf.sal.rest.doc.model.builder.OperationBuilder.buildGet;
+import static org.opendaylight.netconf.sal.rest.doc.model.builder.OperationBuilder.buildPatch;
 import static org.opendaylight.netconf.sal.rest.doc.model.builder.OperationBuilder.buildPost;
 import static org.opendaylight.netconf.sal.rest.doc.model.builder.OperationBuilder.buildPostOperation;
 import static org.opendaylight.netconf.sal.rest.doc.model.builder.OperationBuilder.buildPut;
@@ -432,6 +433,10 @@ public abstract class BaseYangSwaggerGenerator {
                     node.getDescription().orElse(""), pathParams, oaversion);
             operations.put("put", put);
 
+            final ObjectNode patch = buildPatch(parentName, nodeName, moduleName, deviceName,
+                    node.getDescription().orElse(""), pathParams, oaversion);
+            operations.put("patch", patch);
+
             final ObjectNode delete = buildDelete(node, moduleName, deviceName, pathParams, oaversion);
             operations.put("delete", delete);
 
index 861888c7ab8cb8af33166ae9043a704babe22c13..40c4382308cf0902efa3ac80f05feafa7db6e949 100644 (file)
@@ -12,6 +12,7 @@ import static org.opendaylight.netconf.sal.rest.doc.impl.DefinitionGenerator.INP
 import static org.opendaylight.netconf.sal.rest.doc.impl.DefinitionGenerator.INPUT_SUFFIX;
 import static org.opendaylight.netconf.sal.rest.doc.impl.DefinitionGenerator.OUTPUT_SUFFIX;
 
+import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.fasterxml.jackson.databind.node.JsonNodeFactory;
 import com.fasterxml.jackson.databind.node.ObjectNode;
@@ -170,6 +171,30 @@ public final class OperationBuilder {
         return value;
     }
 
+    public static ObjectNode buildPatch(final String parentName, final String nodeName, final String moduleName,
+            final Optional<String> deviceName, final String description, final ArrayNode pathParams,
+            final OAversion oaversion) {
+        final ObjectNode value = JsonNodeFactory.instance.objectNode();
+        value.put(DESCRIPTION_KEY, description);
+        value.put(SUMMARY_KEY, buildSummaryValue(HttpMethod.PATCH, moduleName, deviceName, nodeName));
+        value.set(TAGS_KEY, buildTagsValue(deviceName, moduleName));
+        final ArrayNode parameters = JsonUtil.copy(pathParams);
+        final String defName = parentName + CONFIG + "_" + nodeName + TOP;
+        final String xmlDefName = parentName + CONFIG + "_" + nodeName;
+        insertRequestBodyParameter(parameters, value, defName, xmlDefName, nodeName + CONFIG, oaversion);
+        value.set(PARAMETERS_KEY, parameters);
+
+        final ObjectNode responses = JsonNodeFactory.instance.objectNode();
+        responses.set(String.valueOf(Response.Status.OK.getStatusCode()),
+                buildResponse(Response.Status.OK.getReasonPhrase(), Optional.empty(), oaversion));
+        responses.set(String.valueOf(Response.Status.NO_CONTENT.getStatusCode()),
+                buildResponse("Updated", Optional.empty(), oaversion));
+
+        value.set(RESPONSES_KEY, responses);
+        setConsumesIfNeeded(value, oaversion);
+        return value;
+    }
+
     public static ObjectNode buildDelete(final DataSchemaNode node, final String moduleName,
             final Optional<String> deviceName, final ArrayNode pathParams, final OAversion oaversion) {
         final ObjectNode value = JsonNodeFactory.instance.objectNode();
@@ -267,8 +292,14 @@ public final class OperationBuilder {
         final ObjectNode payload = JsonNodeFactory.instance.objectNode();
         if (oaversion.equals(OAversion.V3_0)) {
             final ObjectNode content = JsonNodeFactory.instance.objectNode();
-            content.set(MediaType.APPLICATION_JSON, buildMimeTypeValue(defName));
-            content.set(MediaType.APPLICATION_XML, buildMimeTypeValue(xmlDefName));
+            final JsonNode node = operation.get(SUMMARY_KEY);
+            if (node != null && node.asText().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));
+            }
             payload.set(CONTENT_KEY, content);
             payload.put(DESCRIPTION_KEY, name);
             operation.set(REQUEST_BODY_KEY, payload);
index cf7e22aa86f1b8ec5d1f53311b92936c32f61f93..9617d247c56842ad13adc65ebdd31af20eb3f750 100644 (file)
@@ -53,7 +53,7 @@ public final class ApiDocGeneratorRFC8040Test extends AbstractApiDocTest {
     }
 
     /**
-     * Test that generated configuration paths allow to use operations: get, put, delete and post.
+     * Test that generated configuration paths allow to use operations: get, put, patch, delete and post.
      */
     @Test
     public void testConfigPaths() {
@@ -73,6 +73,7 @@ public final class ApiDocGeneratorRFC8040Test extends AbstractApiDocTest {
             assertFalse(node.path("put").isMissingNode());
             assertFalse(node.path("delete").isMissingNode());
             assertFalse(node.path("post").isMissingNode());
+            assertFalse(node.path("patch").isMissingNode());
         }
     }