Add RestconfServer.dataPATCH() 12/109012/2
authorRobert Varga <robert.varga@pantheon.tech>
Fri, 17 Nov 2023 19:02:33 +0000 (20:02 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Sat, 18 Nov 2023 08:00:58 +0000 (09:00 +0100)
Plain patch method is a rather simple operation, define it in
RestconfServer and migrate JAX-RS implementation to RestconfImpl.

JIRA: NETCONF-773
Change-Id: I26be45eb6eaa77d52df6197bcb43a6d0ee12df94
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/MdsalRestconfServer.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfDataServiceImpl.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfImpl.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/server/api/RestconfServer.java

index ef896539cb498eae32464e7842472366c990e133..0fe82776ae7bddb64ace15181891be796c01a08c 100644 (file)
@@ -176,6 +176,21 @@ public final class MdsalRestconfServer implements RestconfServer {
         return RestconfFuture.of(new NormalizedNodePayload(reqPath.inference(), node, queryParams));
     }
 
+    @Override
+    public RestconfFuture<Empty> dataPATCH(final ResourceBody body) {
+        return dataPATCH(bindRequestRoot(), body);
+    }
+
+    @Override
+    public RestconfFuture<Empty> dataPATCH(final String identifier, final ResourceBody body) {
+        return dataPATCH(bindRequestPath(identifier), body);
+    }
+
+    private @NonNull RestconfFuture<Empty> dataPATCH(final InstanceIdentifierContext reqPath, final ResourceBody body) {
+        final var req = bindResourceRequest(reqPath, body);
+        return req.strategy().merge(req.path(), req.data());
+    }
+
     // FIXME: should follow the same pattern as operationsPOST() does
     RestconfFuture<DOMActionResult> dataInvokePOST(final InstanceIdentifierContext reqPath,
             final OperationInputBody body) {
index 16621c130d0b4416a05369de1074ccfafb1c871c..3e45435cac09f9a1ee71c19551ec9cbdbdd5035b 100644 (file)
@@ -337,130 +337,6 @@ public final class RestconfDataServiceImpl {
         return uriInfo.getBaseUriBuilder().path("data").path(IdentifierCodec.serialize(path, schemaContext)).build();
     }
 
-    /**
-     * Partially modify the target data store, as defined in
-     * <a href="https://www.rfc-editor.org/rfc/rfc8040#section-4.6.1">RFC8040, section 4.6.1</a>.
-     *
-     * @param body data node for put to config DS
-     * @param ar {@link AsyncResponse} which needs to be completed
-     */
-    @PATCH
-    @Path("/data")
-    @Consumes({
-        MediaTypes.APPLICATION_YANG_DATA_XML,
-        MediaType.APPLICATION_XML,
-        MediaType.TEXT_XML
-    })
-    public void plainPatchDataXML(final InputStream body, @Suspended final AsyncResponse ar) {
-        try (var xmlBody = new XmlResourceBody(body)) {
-            plainPatchData(xmlBody, ar);
-        }
-    }
-
-    /**
-     * Partially modify the target data resource, as defined in
-     * <a href="https://www.rfc-editor.org/rfc/rfc8040#section-4.6.1">RFC8040, section 4.6.1</a>.
-     *
-     * @param identifier path to target
-     * @param body data node for put to config DS
-     * @param ar {@link AsyncResponse} which needs to be completed
-     */
-    @PATCH
-    @Path("/data/{identifier:.+}")
-    @Consumes({
-        MediaTypes.APPLICATION_YANG_DATA_XML,
-        MediaType.APPLICATION_XML,
-        MediaType.TEXT_XML
-    })
-    public void plainPatchDataXML(@Encoded @PathParam("identifier") final String identifier, final InputStream body,
-            @Suspended final AsyncResponse ar) {
-        try (var xmlBody = new XmlResourceBody(body)) {
-            plainPatchData(identifier, xmlBody, ar);
-        }
-    }
-
-    /**
-     * Partially modify the target data store, as defined in
-     * <a href="https://www.rfc-editor.org/rfc/rfc8040#section-4.6.1">RFC8040, section 4.6.1</a>.
-     *
-     * @param body data node for put to config DS
-     * @param ar {@link AsyncResponse} which needs to be completed
-     */
-    @PATCH
-    @Path("/data")
-    @Consumes({
-        MediaTypes.APPLICATION_YANG_DATA_JSON,
-        MediaType.APPLICATION_JSON,
-    })
-    public void plainPatchDataJSON(final InputStream body, @Suspended final AsyncResponse ar) {
-        try (var jsonBody = new JsonResourceBody(body)) {
-            plainPatchData(jsonBody, ar);
-        }
-    }
-
-    /**
-     * Partially modify the target data resource, as defined in
-     * <a href="https://www.rfc-editor.org/rfc/rfc8040#section-4.6.1">RFC8040, section 4.6.1</a>.
-     *
-     * @param identifier path to target
-     * @param body data node for put to config DS
-     * @param ar {@link AsyncResponse} which needs to be completed
-     */
-    @PATCH
-    @Path("/data/{identifier:.+}")
-    @Consumes({
-        MediaTypes.APPLICATION_YANG_DATA_JSON,
-        MediaType.APPLICATION_JSON,
-    })
-    public void plainPatchDataJSON(@Encoded @PathParam("identifier") final String identifier, final InputStream body,
-            @Suspended final AsyncResponse ar) {
-        try (var jsonBody = new JsonResourceBody(body)) {
-            plainPatchData(identifier, jsonBody, ar);
-        }
-    }
-
-    /**
-     * Partially modify the target data resource, as defined in
-     * <a href="https://www.rfc-editor.org/rfc/rfc8040#section-4.6.1">RFC8040, section 4.6.1</a>.
-     *
-     * @param body data node for put to config DS
-     * @param ar {@link AsyncResponse} which needs to be completed
-     */
-    private void plainPatchData(final ResourceBody body, final AsyncResponse ar) {
-        plainPatchData(server.bindRequestRoot(), body, ar);
-    }
-
-    /**
-     * Partially modify the target data resource, as defined in
-     * <a href="https://www.rfc-editor.org/rfc/rfc8040#section-4.6.1">RFC8040, section 4.6.1</a>.
-     *
-     * @param identifier path to target
-     * @param body data node for put to config DS
-     * @param ar {@link AsyncResponse} which needs to be completed
-     */
-    private void plainPatchData(final String identifier, final ResourceBody body, final AsyncResponse ar) {
-        plainPatchData(server.bindRequestPath(identifier), body, ar);
-    }
-
-    /**
-     * Partially modify the target data resource, as defined in
-     * <a href="https://www.rfc-editor.org/rfc/rfc8040#section-4.6.1">RFC8040, section 4.6.1</a>.
-     *
-     * @param reqPath path to target
-     * @param body data node for put to config DS
-     * @param ar {@link AsyncResponse} which needs to be completed
-     */
-    private void plainPatchData(final InstanceIdentifierContext reqPath, final ResourceBody body,
-            final AsyncResponse ar) {
-        final var req = server.bindResourceRequest(reqPath, body);
-        req.strategy().merge(req.path(), req.data()).addCallback(new JaxRsRestconfCallback<>(ar) {
-            @Override
-            Response transform(final Empty result) {
-                return Response.ok().build();
-            }
-        });
-    }
-
     /**
      * Ordered list of edits that are applied to the target datastore by the server, as defined in
      * <a href="https://www.rfc-editor.org/rfc/rfc8072#section-2">RFC8072, section 2</a>.
index f51abaa36888b08de51072ce688e692d1f1d661d..8039fcb25bbcd90cc8eb49c7c2fb046d6d5bab9d 100644 (file)
@@ -18,6 +18,7 @@ import javax.ws.rs.DELETE;
 import javax.ws.rs.Encoded;
 import javax.ws.rs.GET;
 import javax.ws.rs.NotFoundException;
+import javax.ws.rs.PATCH;
 import javax.ws.rs.POST;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
@@ -34,8 +35,10 @@ import org.opendaylight.restconf.common.errors.RestconfFuture;
 import org.opendaylight.restconf.nb.rfc8040.MediaTypes;
 import org.opendaylight.restconf.nb.rfc8040.ReadDataParams;
 import org.opendaylight.restconf.nb.rfc8040.databind.JsonOperationInputBody;
+import org.opendaylight.restconf.nb.rfc8040.databind.JsonResourceBody;
 import org.opendaylight.restconf.nb.rfc8040.databind.OperationInputBody;
 import org.opendaylight.restconf.nb.rfc8040.databind.XmlOperationInputBody;
+import org.opendaylight.restconf.nb.rfc8040.databind.XmlResourceBody;
 import org.opendaylight.restconf.nb.rfc8040.databind.jaxrs.QueryParams;
 import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload;
 import org.opendaylight.restconf.server.api.OperationsContent;
@@ -140,6 +143,97 @@ public final class RestconfImpl {
         });
     }
 
+    /**
+     * Partially modify the target data store, as defined in
+     * <a href="https://www.rfc-editor.org/rfc/rfc8040#section-4.6.1">RFC8040, section 4.6.1</a>.
+     *
+     * @param body data node for put to config DS
+     * @param ar {@link AsyncResponse} which needs to be completed
+     */
+    @PATCH
+    @Path("/data")
+    @Consumes({
+        MediaTypes.APPLICATION_YANG_DATA_XML,
+        MediaType.APPLICATION_XML,
+        MediaType.TEXT_XML
+    })
+    public void dataXmlPATCH(final InputStream body, @Suspended final AsyncResponse ar) {
+        try (var xmlBody = new XmlResourceBody(body)) {
+            completeDataPATCH(server.dataPATCH(xmlBody), ar);
+        }
+    }
+
+    /**
+     * Partially modify the target data resource, as defined in
+     * <a href="https://www.rfc-editor.org/rfc/rfc8040#section-4.6.1">RFC8040, section 4.6.1</a>.
+     *
+     * @param identifier path to target
+     * @param body data node for put to config DS
+     * @param ar {@link AsyncResponse} which needs to be completed
+     */
+    @PATCH
+    @Path("/data/{identifier:.+}")
+    @Consumes({
+        MediaTypes.APPLICATION_YANG_DATA_XML,
+        MediaType.APPLICATION_XML,
+        MediaType.TEXT_XML
+    })
+    public void dataXmlPATCH(@Encoded @PathParam("identifier") final String identifier, final InputStream body,
+            @Suspended final AsyncResponse ar) {
+        try (var xmlBody = new XmlResourceBody(body)) {
+            completeDataPATCH(server.dataPATCH(identifier, xmlBody), ar);
+        }
+    }
+
+    /**
+     * Partially modify the target data store, as defined in
+     * <a href="https://www.rfc-editor.org/rfc/rfc8040#section-4.6.1">RFC8040, section 4.6.1</a>.
+     *
+     * @param body data node for put to config DS
+     * @param ar {@link AsyncResponse} which needs to be completed
+     */
+    @PATCH
+    @Path("/data")
+    @Consumes({
+        MediaTypes.APPLICATION_YANG_DATA_JSON,
+        MediaType.APPLICATION_JSON,
+    })
+    public void dataJsonPATCH(final InputStream body, @Suspended final AsyncResponse ar) {
+        try (var jsonBody = new JsonResourceBody(body)) {
+            completeDataPATCH(server.dataPATCH(jsonBody), ar);
+        }
+    }
+
+    /**
+     * Partially modify the target data resource, as defined in
+     * <a href="https://www.rfc-editor.org/rfc/rfc8040#section-4.6.1">RFC8040, section 4.6.1</a>.
+     *
+     * @param identifier path to target
+     * @param body data node for put to config DS
+     * @param ar {@link AsyncResponse} which needs to be completed
+     */
+    @PATCH
+    @Path("/data/{identifier:.+}")
+    @Consumes({
+        MediaTypes.APPLICATION_YANG_DATA_JSON,
+        MediaType.APPLICATION_JSON,
+    })
+    public void dataJsonPATCH(@Encoded @PathParam("identifier") final String identifier, final InputStream body,
+            @Suspended final AsyncResponse ar) {
+        try (var jsonBody = new JsonResourceBody(body)) {
+            completeDataPATCH(server.dataPATCH(identifier, jsonBody), ar);
+        }
+    }
+
+    private static void completeDataPATCH(final RestconfFuture<Empty> future, final AsyncResponse ar) {
+        future.addCallback(new JaxRsRestconfCallback<>(ar) {
+            @Override
+            Response transform(final Empty result) {
+                return Response.ok().build();
+            }
+        });
+    }
+
     /**
      * List RPC and action operations in RFC7951 format.
      *
index 4c266dd4673bb11723c7791ae67f47df13f85965..a8bd8e0e0deba1e73e15ccffe0b57f9afb175bdf 100644 (file)
@@ -14,6 +14,7 @@ import org.opendaylight.restconf.api.ApiPath;
 import org.opendaylight.restconf.common.errors.RestconfFuture;
 import org.opendaylight.restconf.nb.rfc8040.ReadDataParams;
 import org.opendaylight.restconf.nb.rfc8040.databind.OperationInputBody;
+import org.opendaylight.restconf.nb.rfc8040.databind.ResourceBody;
 import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload;
 import org.opendaylight.restconf.server.spi.OperationOutput;
 import org.opendaylight.yangtools.yang.common.Empty;
@@ -50,6 +51,25 @@ public interface RestconfServer {
      */
     RestconfFuture<NormalizedNodePayload> dataGET(String identifier, ReadDataParams readParams);
 
+    /**
+     * Partially modify the target data resource, as defined in
+     * <a href="https://www.rfc-editor.org/rfc/rfc8040#section-4.6.1">RFC8040, section 4.6.1</a>.
+     *
+     * @param body data node for put to config DS
+     * @return A {@link RestconfFuture} of the operation
+     */
+    RestconfFuture<Empty> dataPATCH(ResourceBody body);
+
+    /**
+     * Partially modify the target data resource, as defined in
+     * <a href="https://www.rfc-editor.org/rfc/rfc8040#section-4.6.1">RFC8040, section 4.6.1</a>.
+     *
+     * @param identifier resource identifier
+     * @param body data node for put to config DS
+     * @return A {@link RestconfFuture} of the operation
+     */
+    RestconfFuture<Empty> dataPATCH(String identifier, ResourceBody body);
+
     /**
      * Return the set of supported RPCs supported by {@link #operationsPOST(URI, String, OperationInputBody)}.
      *