Move action invocation to MdsalRestconfServer 07/109007/4
authorRobert Varga <robert.varga@pantheon.tech>
Fri, 17 Nov 2023 15:06:00 +0000 (16:06 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Sat, 18 Nov 2023 08:00:58 +0000 (09:00 +0100)
This code is quite clear-cut and JAX-RS free, move it to
MdsalRestconfServer. The actual interface is still TBD.

This allows us to clean up JaxRsNorthbound of quite a few unnecessary
services.

JIRA: NETCONF-773
Change-Id: If030a80eaab55dd4cb5ccc6889c94b7cc06e97cd
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
12 files changed:
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/JaxRsNorthbound.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/RestconfApplication.java
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/server/api/RestconfServer.java
restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/MdsalRestconfServerTest.java
restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/Netconf799Test.java
restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/Netconf822Test.java
restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfDataServiceImplTest.java
restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfImplTest.java
restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfOperationsGetTest.java
restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfOperationsPostTest.java

index 363a4257676b6d691d6f7966effc5a55ce54cd9f..73d53e5fbb2286a3ed59ceaba8e3df0f4d385211 100644 (file)
@@ -17,11 +17,7 @@ import org.opendaylight.aaa.web.WebContext;
 import org.opendaylight.aaa.web.WebContextSecurer;
 import org.opendaylight.aaa.web.WebServer;
 import org.opendaylight.aaa.web.servlet.ServletSupport;
-import org.opendaylight.mdsal.dom.api.DOMActionService;
-import org.opendaylight.mdsal.dom.api.DOMDataBroker;
 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
-import org.opendaylight.mdsal.dom.api.DOMNotificationService;
-import org.opendaylight.mdsal.dom.api.DOMRpcService;
 import org.opendaylight.mdsal.dom.api.DOMSchemaService;
 import org.opendaylight.restconf.nb.rfc8040.databind.DatabindProvider;
 import org.opendaylight.restconf.nb.rfc8040.rests.services.impl.MdsalRestconfServer;
@@ -45,12 +41,9 @@ public final class JaxRsNorthbound implements AutoCloseable {
     public JaxRsNorthbound(@Reference final WebServer webServer, @Reference final WebContextSecurer webContextSecurer,
             @Reference final ServletSupport servletSupport,
             @Reference final CustomFilterAdapterConfiguration filterAdapterConfiguration,
-            @Reference final DOMActionService actionService, @Reference final DOMDataBroker dataBroker,
-            @Reference final DOMMountPointService mountPointService,
-            @Reference final DOMNotificationService notificationService, @Reference final DOMRpcService rpcService,
-            @Reference final DOMSchemaService schemaService, @Reference final DatabindProvider databindProvider,
-            @Reference final MdsalRestconfServer server, @Reference final RestconfStreamServletFactory servletFactory)
-                throws ServletException {
+            @Reference final DOMMountPointService mountPointService, @Reference final DOMSchemaService schemaService,
+            @Reference final DatabindProvider databindProvider, @Reference final MdsalRestconfServer server,
+            @Reference final RestconfStreamServletFactory servletFactory) throws ServletException {
         final var restconfBuilder = WebContext.builder()
             .name("RFC8040 RESTCONF")
             .contextPath("/" + URLConstants.BASE_PATH)
@@ -58,8 +51,7 @@ public final class JaxRsNorthbound implements AutoCloseable {
             .addServlet(ServletDetails.builder()
                 .addUrlPattern("/*")
                 .servlet(servletSupport.createHttpServletBuilder(
-                    new RestconfApplication(databindProvider, server, mountPointService, dataBroker, actionService,
-                        notificationService, schemaService))
+                    new RestconfApplication(databindProvider, server, mountPointService, schemaService))
                     .build())
                 .asyncSupported(true)
                 .build())
index 490d7c5e9dc00449a265212368895fd0e7dfb491..070ac1305d93dea99acf8ce01dab02a42a76d9b2 100644 (file)
@@ -9,10 +9,7 @@ package org.opendaylight.restconf.nb.rfc8040;
 
 import java.util.Set;
 import javax.ws.rs.core.Application;
-import org.opendaylight.mdsal.dom.api.DOMActionService;
-import org.opendaylight.mdsal.dom.api.DOMDataBroker;
 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
-import org.opendaylight.mdsal.dom.api.DOMNotificationService;
 import org.opendaylight.mdsal.dom.api.DOMSchemaService;
 import org.opendaylight.restconf.nb.rfc8040.databind.DatabindProvider;
 import org.opendaylight.restconf.nb.rfc8040.jersey.providers.JsonNormalizedNodeBodyWriter;
@@ -31,12 +28,10 @@ final class RestconfApplication extends Application {
     private final Set<Object> singletons;
 
     RestconfApplication(final DatabindProvider databindProvider, final MdsalRestconfServer server,
-            final DOMMountPointService mountPointService, final DOMDataBroker dataBroker,
-            final DOMActionService actionService, final DOMNotificationService notificationService,
-            final DOMSchemaService domSchemaService) {
+            final DOMMountPointService mountPointService, final DOMSchemaService domSchemaService) {
         singletons = Set.of(
             new RestconfDocumentedExceptionMapper(databindProvider),
-            new RestconfDataServiceImpl(databindProvider, server, actionService),
+            new RestconfDataServiceImpl(databindProvider, server),
             new RestconfImpl(server),
             new RestconfSchemaServiceImpl(domSchemaService, mountPointService));
     }
index 55b434ad8acd80d64ce3423a4207de258708162e..13fb7dad9d73fa34f169f3afd2ff41a87976a5bd 100644 (file)
@@ -16,6 +16,9 @@ import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.ImmutableSetMultimap;
 import com.google.common.collect.Maps;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.MoreExecutors;
 import java.io.IOException;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.VarHandle;
@@ -23,16 +26,24 @@ import java.net.URI;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Map.Entry;
+import java.util.concurrent.CancellationException;
 import javax.inject.Inject;
 import javax.inject.Singleton;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.dom.api.DOMActionException;
+import org.opendaylight.mdsal.dom.api.DOMActionResult;
+import org.opendaylight.mdsal.dom.api.DOMActionService;
 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
 import org.opendaylight.mdsal.dom.api.DOMMountPoint;
 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
 import org.opendaylight.mdsal.dom.api.DOMRpcService;
+import org.opendaylight.mdsal.dom.spi.SimpleDOMActionResult;
 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
 import org.opendaylight.restconf.common.errors.RestconfFuture;
+import org.opendaylight.restconf.common.errors.SettableRestconfFuture;
 import org.opendaylight.restconf.nb.rfc8040.databind.DatabindContext;
 import org.opendaylight.restconf.nb.rfc8040.databind.DatabindProvider;
 import org.opendaylight.restconf.nb.rfc8040.databind.OperationInputBody;
@@ -54,11 +65,14 @@ import org.opendaylight.yangtools.yang.common.ErrorType;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.common.Revision;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.opendaylight.yangtools.yang.common.XMLNamespace;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 import org.opendaylight.yangtools.yang.model.api.stmt.RpcEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
 import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
@@ -92,6 +106,7 @@ public final class MdsalRestconfServer implements RestconfServer {
     private final @NonNull DatabindProvider databindProvider;
     private final @NonNull DOMDataBroker dataBroker;
     private final @Nullable DOMRpcService rpcService;
+    private final @Nullable DOMActionService actionService;
 
     @SuppressWarnings("unused")
     private volatile RestconfStrategy localStrategy;
@@ -100,19 +115,101 @@ public final class MdsalRestconfServer implements RestconfServer {
     @Activate
     public MdsalRestconfServer(@Reference final DatabindProvider databindProvider,
             @Reference final DOMDataBroker dataBroker, @Reference final DOMRpcService rpcService,
+            @Reference final DOMActionService actionService,
             @Reference final DOMMountPointService mountPointService,
             @Reference final List<RpcImplementation> localRpcs) {
         this.databindProvider = requireNonNull(databindProvider);
         this.dataBroker = requireNonNull(dataBroker);
         this.rpcService = requireNonNull(rpcService);
+        this.actionService = requireNonNull(actionService);
         this.mountPointService = requireNonNull(mountPointService);
         this.localRpcs = Maps.uniqueIndex(localRpcs, RpcImplementation::qname);
     }
 
     public MdsalRestconfServer(final DatabindProvider databindProvider, final DOMDataBroker dataBroker,
-            final DOMRpcService rpcService, final DOMMountPointService mountPointService,
-            final RpcImplementation... localRpcs) {
-        this(databindProvider, dataBroker, rpcService, mountPointService, List.of(localRpcs));
+            final DOMRpcService rpcService, final DOMActionService actionService,
+            final DOMMountPointService mountPointService, final RpcImplementation... localRpcs) {
+        this(databindProvider, dataBroker, rpcService, actionService, mountPointService, List.of(localRpcs));
+    }
+
+    RestconfFuture<DOMActionResult> dataInvokePOST(final InstanceIdentifierContext reqPath,
+            final OperationInputBody body) {
+        final var yangIIdContext = reqPath.getInstanceIdentifier();
+        final var inference = reqPath.inference();
+        final ContainerNode input;
+        try {
+            input = body.toContainerNode(inference);
+        } catch (IOException e) {
+            LOG.debug("Error reading input", e);
+            return RestconfFuture.failed(new RestconfDocumentedException("Error parsing input: " + e.getMessage(),
+                ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE, e));
+        }
+
+        final var mountPoint = reqPath.getMountPoint();
+        final var schemaPath = inference.toSchemaInferenceStack().toSchemaNodeIdentifier();
+        return mountPoint != null ? dataInvokePOST(input, schemaPath, yangIIdContext, mountPoint)
+            : dataInvokePOST(input, schemaPath, yangIIdContext, actionService);
+    }
+
+    /**
+     * Invoke Action via ActionServiceHandler.
+     *
+     * @param data input data
+     * @param yangIId invocation context
+     * @param schemaPath schema path of data
+     * @param actionService action service to invoke action
+     * @return {@link DOMActionResult}
+     */
+    private static RestconfFuture<DOMActionResult> dataInvokePOST(final ContainerNode data, final Absolute schemaPath,
+            final YangInstanceIdentifier yangIId, final DOMActionService actionService) {
+        final var ret = new SettableRestconfFuture<DOMActionResult>();
+
+        Futures.addCallback(actionService.invokeAction(schemaPath,
+            new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL, yangIId.getParent()), data),
+            new FutureCallback<DOMActionResult>() {
+                @Override
+                public void onSuccess(final DOMActionResult result) {
+                    final var errors = result.getErrors();
+                    LOG.debug("InvokeAction Error Message {}", errors);
+                    if (errors.isEmpty()) {
+                        ret.set(result);
+                    } else {
+                        ret.setFailure(new RestconfDocumentedException("InvokeAction Error Message ", null, errors));
+                    }
+                }
+
+                @Override
+                public void onFailure(final Throwable cause) {
+                    if (cause instanceof DOMActionException) {
+                        ret.set(new SimpleDOMActionResult(List.of(RpcResultBuilder.newError(
+                            ErrorType.RPC, ErrorTag.OPERATION_FAILED, cause.getMessage()))));
+                    } else if (cause instanceof RestconfDocumentedException e) {
+                        ret.setFailure(e);
+                    } else if (cause instanceof CancellationException) {
+                        ret.setFailure(new RestconfDocumentedException("Action cancelled while executing",
+                            ErrorType.RPC, ErrorTag.PARTIAL_OPERATION, cause));
+                    } else {
+                        ret.setFailure(new RestconfDocumentedException("Invocation failed", cause));
+                    }
+                }
+            }, MoreExecutors.directExecutor());
+
+        return ret;
+    }
+
+    /**
+     * Invoking Action via mount point.
+     *
+     * @param mountPoint mount point
+     * @param data input data
+     * @param schemaPath schema path of data
+     * @return {@link DOMActionResult}
+     */
+    private static RestconfFuture<DOMActionResult> dataInvokePOST(final ContainerNode data,
+            final Absolute schemaPath, final YangInstanceIdentifier yangIId, final DOMMountPoint mountPoint) {
+        final var actionService = mountPoint.getService(DOMActionService.class);
+        return actionService.isPresent() ? dataInvokePOST(data, schemaPath, yangIId, actionService.orElseThrow())
+            : RestconfFuture.failed(new RestconfDocumentedException("DOMActionService is missing."));
     }
 
     @Override
index 22e986cfd3657174ce82b1f475af494e24667a7a..738ef9be9035db8b215a02bf95af0d7196c5ad67 100644 (file)
@@ -10,9 +10,6 @@ package org.opendaylight.restconf.nb.rfc8040.rests.services.impl;
 import static java.util.Objects.requireNonNull;
 
 import com.google.common.annotations.VisibleForTesting;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.MoreExecutors;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URI;
@@ -20,7 +17,6 @@ import java.time.Clock;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.List;
-import java.util.concurrent.CancellationException;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.Encoded;
@@ -40,16 +36,9 @@ import javax.ws.rs.core.Response.Status;
 import javax.ws.rs.core.UriInfo;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMActionException;
 import org.opendaylight.mdsal.dom.api.DOMActionResult;
-import org.opendaylight.mdsal.dom.api.DOMActionService;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
 import org.opendaylight.mdsal.dom.api.DOMMountPoint;
-import org.opendaylight.mdsal.dom.spi.SimpleDOMActionResult;
 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.restconf.common.errors.RestconfFuture;
-import org.opendaylight.restconf.common.errors.SettableRestconfFuture;
 import org.opendaylight.restconf.common.patch.PatchContext;
 import org.opendaylight.restconf.common.patch.PatchStatusContext;
 import org.opendaylight.restconf.common.patch.PatchStatusEntity;
@@ -79,16 +68,13 @@ import org.opendaylight.yangtools.yang.common.ErrorTag;
 import org.opendaylight.yangtools.yang.common.ErrorType;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.Revision;
-import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.model.api.ActionDefinition;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
 import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -103,14 +89,11 @@ public final class RestconfDataServiceImpl {
     private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MMM-dd HH:mm:ss");
 
     private final DatabindProvider databindProvider;
-    private final DOMActionService actionService;
     private final MdsalRestconfServer server;
 
-    public RestconfDataServiceImpl(final DatabindProvider databindProvider, final MdsalRestconfServer server,
-            final DOMActionService actionService) {
+    public RestconfDataServiceImpl(final DatabindProvider databindProvider, final MdsalRestconfServer server) {
         this.databindProvider = requireNonNull(databindProvider);
         this.server = requireNonNull(server);
-        this.actionService = requireNonNull(actionService);
     }
 
     /**
@@ -740,90 +723,13 @@ public final class RestconfDataServiceImpl {
      */
     private void invokeAction(final InstanceIdentifierContext reqPath, final OperationInputBody body,
             final AsyncResponse ar) {
-        final var yangIIdContext = reqPath.getInstanceIdentifier();
-        final ContainerNode input;
-        try {
-            input = body.toContainerNode(reqPath.inference());
-        } catch (IOException e) {
-            LOG.debug("Error reading input", e);
-            throw new RestconfDocumentedException("Error parsing input: " + e.getMessage(), ErrorType.PROTOCOL,
-                    ErrorTag.MALFORMED_MESSAGE, e);
-        }
-
-        final var mountPoint = reqPath.getMountPoint();
-        final var inference = reqPath.inference();
-        final var schemaPath = inference.toSchemaInferenceStack().toSchemaNodeIdentifier();
-        final var response = mountPoint != null ? invokeAction(input, schemaPath, yangIIdContext, mountPoint)
-            : invokeAction(input, schemaPath, yangIIdContext, actionService);
-
-        response.addCallback(new JaxRsRestconfCallback<>(ar) {
+        server.dataInvokePOST(reqPath, body).addCallback(new JaxRsRestconfCallback<>(ar) {
             @Override
             Response transform(final DOMActionResult result) {
                 final var output = result.getOutput().orElse(null);
                 return output == null || output.isEmpty() ? Response.status(Status.NO_CONTENT).build()
-                    : Response.status(Status.OK).entity(new NormalizedNodePayload(inference, output)).build();
+                    : Response.status(Status.OK).entity(new NormalizedNodePayload(reqPath.inference(), output)).build();
             }
         });
     }
-
-    /**
-     * Invoking Action via mount point.
-     *
-     * @param mountPoint mount point
-     * @param data input data
-     * @param schemaPath schema path of data
-     * @return {@link DOMActionResult}
-     */
-    private static RestconfFuture<DOMActionResult> invokeAction(final ContainerNode data,
-            final Absolute schemaPath, final YangInstanceIdentifier yangIId, final DOMMountPoint mountPoint) {
-        final var actionService = mountPoint.getService(DOMActionService.class);
-        return actionService.isPresent() ? invokeAction(data, schemaPath, yangIId, actionService.orElseThrow())
-            : RestconfFuture.failed(new RestconfDocumentedException("DOMActionService is missing."));
-    }
-
-    /**
-     * Invoke Action via ActionServiceHandler.
-     *
-     * @param data input data
-     * @param yangIId invocation context
-     * @param schemaPath schema path of data
-     * @param actionService action service to invoke action
-     * @return {@link DOMActionResult}
-     */
-    private static RestconfFuture<DOMActionResult> invokeAction(final ContainerNode data, final Absolute schemaPath,
-            final YangInstanceIdentifier yangIId, final DOMActionService actionService) {
-        final var ret = new SettableRestconfFuture<DOMActionResult>();
-
-        Futures.addCallback(actionService.invokeAction(schemaPath,
-            new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL, yangIId.getParent()), data),
-            new FutureCallback<DOMActionResult>() {
-                @Override
-                public void onSuccess(final DOMActionResult result) {
-                    final var errors = result.getErrors();
-                    LOG.debug("InvokeAction Error Message {}", errors);
-                    if (errors.isEmpty()) {
-                        ret.set(result);
-                    } else {
-                        ret.setFailure(new RestconfDocumentedException("InvokeAction Error Message ", null, errors));
-                    }
-                }
-
-                @Override
-                public void onFailure(final Throwable cause) {
-                    if (cause instanceof DOMActionException) {
-                        ret.set(new SimpleDOMActionResult(List.of(RpcResultBuilder.newError(
-                            ErrorType.RPC, ErrorTag.OPERATION_FAILED, cause.getMessage()))));
-                    } else if (cause instanceof RestconfDocumentedException e) {
-                        ret.setFailure(e);
-                    } else if (cause instanceof CancellationException) {
-                        ret.setFailure(new RestconfDocumentedException("Action cancelled while executing",
-                            ErrorType.RPC, ErrorTag.PARTIAL_OPERATION, cause));
-                    } else {
-                        ret.setFailure(new RestconfDocumentedException("Invocation failed", cause));
-                    }
-                }
-            }, MoreExecutors.directExecutor());
-
-        return ret;
-    }
 }
index 92f57ad1798455a345bbd5be012a7383ce7b3a02..4fe667a284aa012d13dc0fbb8dd08e1ae62a73ab 100644 (file)
@@ -22,17 +22,6 @@ import org.opendaylight.restconf.server.spi.OperationOutput;
  */
 @NonNullByDefault
 public interface RestconfServer {
-    /**
-     * Return the revision of {@code ietf-yang-library} module implemented by this server, as defined in
-     * <a href="https://www.rfc-editor.org/rfc/rfc8040#section-3.3.3">RFC8040 {+restconf}/yang-library-version</a>.
-     *
-     * @return A {@code yang-library-version} element
-     */
-    // FIXME: this is a simple coning-variadic return, similar to how OperationsContent is handled use a common
-    //        construct for both cases
-    // FIXME: RestconfFuture if we transition to being used by restconf-client implementation
-    NormalizedNodePayload yangLibraryVersionGET();
-
     /**
      * Return the set of supported RPCs supported by {@link #operationsPOST(URI, String, OperationInputBody)}.
      *
@@ -66,4 +55,15 @@ public interface RestconfServer {
     //        and hence it is a path right now
     // FIXME: use ApiPath instead of String
     RestconfFuture<OperationOutput> operationsPOST(URI restconfURI, String operation, OperationInputBody body);
+
+    /**
+     * Return the revision of {@code ietf-yang-library} module implemented by this server, as defined in
+     * <a href="https://www.rfc-editor.org/rfc/rfc8040#section-3.3.3">RFC8040 {+restconf}/yang-library-version</a>.
+     *
+     * @return A {@code yang-library-version} element
+     */
+    // FIXME: this is a simple coning-variadic return, similar to how OperationsContent is handled use a common
+    //        construct for both cases
+    // FIXME: RestconfFuture if we transition to being used by restconf-client implementation
+    NormalizedNodePayload yangLibraryVersionGET();
 }
index 2552b2c9e0746b7c4b6cdb1251422506e6980b23..6a99f8a9b463b5642335d936e8b0d87e4c510631 100644 (file)
@@ -20,6 +20,7 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnitRunner;
+import org.opendaylight.mdsal.dom.api.DOMActionService;
 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
 import org.opendaylight.mdsal.dom.api.DOMMountPoint;
 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
@@ -48,6 +49,8 @@ public class MdsalRestconfServerTest extends AbstractJukeboxTest {
     private NetconfDataTreeService netconfService;
     @Mock
     private DOMRpcService rpcService;
+    @Mock
+    private DOMActionService actionService;
 
     private MdsalRestconfServer server;
 
@@ -58,7 +61,7 @@ public class MdsalRestconfServerTest extends AbstractJukeboxTest {
 
     @Before
     public void before() {
-        server = new MdsalRestconfServer(DATABIND_PROVIDER, dataBroker, rpcService, mountPointService);
+        server = new MdsalRestconfServer(DATABIND_PROVIDER, dataBroker, rpcService, actionService, mountPointService);
         doReturn(Optional.of(rpcService)).when(mountPoint).getService(DOMRpcService.class);
     }
 
index e2bb2d6c9016fbd8055c74aed340ca890abc7928..0296f77113e7d94ced675307fcb9c9ccd1d18d75 100644 (file)
@@ -60,7 +60,7 @@ public class Netconf799Test extends AbstractInstanceIdentifierTest {
 
         final DatabindProvider databindProvider = () -> DatabindContext.ofModel(IID_SCHEMA);
         final var dataService = new RestconfDataServiceImpl(databindProvider,
-            new MdsalRestconfServer(databindProvider, dataBroker, rpcService, mountPointService), actionService);
+            new MdsalRestconfServer(databindProvider, dataBroker, rpcService, actionService, mountPointService));
 
         doReturn(true).when(asyncResponse).resume(captor.capture());
         dataService.postDataJSON("instance-identifier-module:cont/cont1/reset",
index b27285e0ee52ccd1e2db97a354bcaa8a00fd4e8d..8961860380c3e9f90b00034a8cfd9be7d4c52af3 100644 (file)
@@ -16,6 +16,7 @@ import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
+import org.opendaylight.mdsal.dom.api.DOMActionService;
 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
 import org.opendaylight.mdsal.dom.api.DOMRpcService;
@@ -32,13 +33,15 @@ class Netconf822Test {
     @Mock
     private DOMRpcService rpcService;
     @Mock
+    private DOMActionService actionService;
+    @Mock
     private DOMMountPointService mountPointService;
 
     private MdsalRestconfServer server;
 
     @BeforeEach
     void beforeEach() {
-        server = new MdsalRestconfServer(() -> DATABIND, dataBroker, rpcService, mountPointService);
+        server = new MdsalRestconfServer(() -> DATABIND, dataBroker, rpcService, actionService, mountPointService);
     }
 
     @Test
index be6b7e861afc21644f05bbb9480f9475790f8c82..385bb2952c331a4bcfab6e08ef2df0fb54955878 100644 (file)
@@ -132,7 +132,7 @@ public class RestconfDataServiceImplTest extends AbstractJukeboxTest {
 
         final DatabindProvider databindProvider = () -> DatabindContext.ofModel(JUKEBOX_SCHEMA);
         dataService = new RestconfDataServiceImpl(databindProvider,
-            new MdsalRestconfServer(databindProvider, dataBroker, rpcService, mountPointService), actionService);
+            new MdsalRestconfServer(databindProvider, dataBroker, rpcService, actionService, mountPointService));
         doReturn(Optional.of(mountPoint)).when(mountPointService)
                 .getMountPoint(any(YangInstanceIdentifier.class));
         doReturn(Optional.of(FixedDOMSchemaService.of(JUKEBOX_SCHEMA))).when(mountPoint)
index 96943b3654166945cfe35bed3fb00e55b30167cc..6985987f0016461dcb66b3c7cb3b60a7820f73ce 100644 (file)
@@ -14,6 +14,7 @@ import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
+import org.opendaylight.mdsal.dom.api.DOMActionService;
 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
 import org.opendaylight.mdsal.dom.api.DOMRpcService;
@@ -28,13 +29,15 @@ class RestconfImplTest {
     @Mock
     private DOMRpcService rpcService;
     @Mock
+    private DOMActionService actionService;
+    @Mock
     private DOMMountPointService mountPointService;
 
     @Test
     void testLibraryVersion() {
         final var context = DatabindContext.ofModel(YangParserTestUtils.parseYangResourceDirectory("/restconf/impl"));
         final var restconfImpl = new RestconfImpl(new MdsalRestconfServer(() -> context, dataBroker, rpcService,
-            mountPointService));
+            actionService, mountPointService));
         final var libraryVersion = assertInstanceOf(LeafNode.class, restconfImpl.yangLibraryVersionGET().data());
         assertEquals("2019-01-04", libraryVersion.body());
     }
index 190fa00cc3d18258fba404c51456c119f780eaad..6d5b2e4b61ec381ca95f390d0c7ba6c862278dfd 100644 (file)
@@ -18,6 +18,7 @@ import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 import org.opendaylight.mdsal.binding.runtime.spi.BindingRuntimeHelpers;
+import org.opendaylight.mdsal.dom.api.DOMActionService;
 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
 import org.opendaylight.mdsal.dom.api.DOMMountPoint;
 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
@@ -27,7 +28,6 @@ import org.opendaylight.restconf.nb.rfc8040.databind.DatabindContext;
 import org.opendaylight.yang.gen.v1.module._1.rev140101.Module1Data;
 import org.opendaylight.yang.gen.v1.module._2.rev140102.Module2Data;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 
 @ExtendWith(MockitoExtension.class)
 class RestconfOperationsGetTest {
@@ -51,8 +51,8 @@ class RestconfOperationsGetTest {
           <dummy-rpc2-module2 xmlns="module:2"/>
         </operations>""";
 
-    private static final EffectiveModelContext SCHEMA = BindingRuntimeHelpers.createRuntimeContext(
-        Module1Data.class, Module2Data.class, NetworkTopology.class).getEffectiveModelContext();
+    private static final DatabindContext DATABIND = DatabindContext.ofModel(BindingRuntimeHelpers.createRuntimeContext(
+        Module1Data.class, Module2Data.class, NetworkTopology.class).getEffectiveModelContext());
 
     @Mock
     private DOMMountPointService mountPointService;
@@ -64,13 +64,15 @@ class RestconfOperationsGetTest {
     private DOMDataBroker dataBroker;
     @Mock
     private DOMRpcService rpcService;
+    @Mock
+    private DOMActionService actionService;
 
     private RestconfImpl restconf;
 
     @BeforeEach
     void beforeEach() {
         restconf = new RestconfImpl(
-            new MdsalRestconfServer(() -> DatabindContext.ofModel(SCHEMA), dataBroker, rpcService, mountPointService));
+            new MdsalRestconfServer(() -> DATABIND, dataBroker, rpcService, actionService, mountPointService));
     }
 
     @Test
@@ -86,7 +88,7 @@ class RestconfOperationsGetTest {
     }
 
     private void mockMountPoint() {
-        doReturn(SCHEMA).when(schemaService).getGlobalContext();
+        doReturn(DATABIND.modelContext()).when(schemaService).getGlobalContext();
         doReturn(Optional.of(schemaService)).when(mountPoint).getService(DOMSchemaService.class);
         doReturn(Optional.of(mountPoint)).when(mountPointService).getMountPoint(any());
     }
index b84077619a215c0aa55bec0ea6640e04e3b628b0..6a91904d7ff0579869d9e1ada4ae0a6d1772a8f0 100644 (file)
@@ -33,6 +33,7 @@ import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
+import org.opendaylight.mdsal.dom.api.DOMActionService;
 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
 import org.opendaylight.mdsal.dom.api.DOMMountPoint;
 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
@@ -79,6 +80,8 @@ class RestconfOperationsPostTest {
     @Mock
     private DOMRpcService rpcService;
     @Mock
+    private DOMActionService actionService;
+    @Mock
     private DOMMountPoint mountPoint;
     @Mock
     private DOMMountPointService mountPointService;
@@ -90,7 +93,7 @@ class RestconfOperationsPostTest {
 
     @BeforeEach
     void beforeEach() {
-        server = new MdsalRestconfServer(() -> CONTEXT, dataBroker, rpcService, mountPointService);
+        server = new MdsalRestconfServer(() -> CONTEXT, dataBroker, rpcService, actionService, mountPointService);
         restconf = new RestconfImpl(server);
     }