import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev170126.YangApi;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev170126.restconf.Restconf;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.YangLibrary;
+import org.opendaylight.yangtools.yang.common.Empty;
import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.opendaylight.yangtools.yang.common.QName;
this(databindProvider, dataBroker, rpcService, actionService, mountPointService, List.of(localRpcs));
}
+ @Override
+ public RestconfFuture<Empty> dataDELETE(final String identifier) {
+ final var reqPath = bindRequestPath(identifier);
+ final var strategy = getRestconfStrategy(reqPath.getSchemaContext(), reqPath.getMountPoint());
+ return strategy.delete(reqPath.getInstanceIdentifier());
+ }
+
@Override
public RestconfFuture<NormalizedNodePayload> dataGET(final ReadDataParams readParams) {
return readData(bindRequestRoot(), readParams);
import java.net.URI;
import java.util.List;
import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
import javax.ws.rs.Encoded;
import javax.ws.rs.PATCH;
import javax.ws.rs.POST;
return uriInfo.getBaseUriBuilder().path("data").path(IdentifierCodec.serialize(path, schemaContext)).build();
}
- /**
- * Delete the target data resource.
- *
- * @param identifier path to target
- * @param ar {@link AsyncResponse} which needs to be completed
- */
- @DELETE
- @Path("/data/{identifier:.+}")
- public void deleteData(@Encoded @PathParam("identifier") final String identifier,
- @Suspended final AsyncResponse ar) {
- final var reqPath = server.bindRequestPath(identifier);
- final var strategy = server.getRestconfStrategy(reqPath.getSchemaContext(), reqPath.getMountPoint());
-
- strategy.delete(reqPath.getInstanceIdentifier()).addCallback(new JaxRsRestconfCallback<>(ar) {
- @Override
- Response transform(final Empty result) {
- return Response.noContent().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>.
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
import javax.ws.rs.Encoded;
import javax.ws.rs.GET;
import javax.ws.rs.NotFoundException;
import org.opendaylight.restconf.nb.rfc8040.databind.jaxrs.QueryParams;
import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload;
import org.opendaylight.restconf.server.api.OperationsContent;
+import org.opendaylight.restconf.server.api.RestconfServer;
import org.opendaylight.restconf.server.spi.OperationOutput;
+import org.opendaylight.yangtools.yang.common.Empty;
import org.opendaylight.yangtools.yang.common.Revision;
/**
public final class RestconfImpl {
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MMM-dd HH:mm:ss");
- private final MdsalRestconfServer server;
+ private final RestconfServer server;
- public RestconfImpl(final MdsalRestconfServer server) {
+ public RestconfImpl(final RestconfServer server) {
this.server = requireNonNull(server);
}
+ /**
+ * Delete the target data resource.
+ *
+ * @param identifier path to target
+ * @param ar {@link AsyncResponse} which needs to be completed
+ */
+ @DELETE
+ @Path("/data/{identifier:.+}")
+ @SuppressWarnings("checkstyle:abbreviationAsWordInName")
+ public void dataDELETE(@Encoded @PathParam("identifier") final String identifier,
+ @Suspended final AsyncResponse ar) {
+ server.dataDELETE(identifier).addCallback(new JaxRsRestconfCallback<>(ar) {
+ @Override
+ Response transform(final Empty result) {
+ return Response.noContent().build();
+ }
+ });
+ }
+
/**
* Get target data resource from data root.
*
import org.opendaylight.restconf.nb.rfc8040.databind.OperationInputBody;
import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload;
import org.opendaylight.restconf.server.spi.OperationOutput;
+import org.opendaylight.yangtools.yang.common.Empty;
/**
* An implementation of a RESTCONF server, implementing the
*/
@NonNullByDefault
public interface RestconfServer {
+ /**
+ * Delete a data resource.
+ *
+ * @param identifier resource identifier
+ * @return A {@link RestconfFuture} of the operation
+ */
+ @SuppressWarnings("checkstyle:abbreviationAsWordInName")
+ RestconfFuture<Empty> dataDELETE(String identifier);
+
/**
* Return the content of the datastore.
*
RestconfFuture<NormalizedNodePayload> dataGET(ReadDataParams readParams);
/**
- * Return the content of a resource.
+ * Return the content of a data resource.
*
* @param identifier resource identifier
* @param readParams {@link ReadDataParams} for this request
--- /dev/null
+/*
+ * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.nb.rfc8040.rests.services.impl;
+
+import javax.ws.rs.container.AsyncResponse;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import org.eclipse.jdt.annotation.NonNull;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+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;
+import org.opendaylight.mdsal.dom.api.DOMRpcService;
+import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
+import org.opendaylight.restconf.nb.rfc8040.AbstractJukeboxTest;
+import org.opendaylight.restconf.nb.rfc8040.databind.DatabindContext;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
+
+@ExtendWith(MockitoExtension.class)
+abstract class AbstractRestconfTest extends AbstractJukeboxTest {
+ @Mock
+ UriInfo uriInfo;
+ @Mock
+ AsyncResponse asyncResponse;
+ @Mock
+ DOMDataBroker dataBroker;
+ @Mock
+ DOMActionService actionService;
+ @Mock
+ DOMRpcService rpcService;
+ @Mock
+ DOMMountPointService mountPointService;
+ @Mock
+ DOMMountPoint mountPoint;
+ @Captor
+ ArgumentCaptor<Response> responseCaptor;
+ @Captor
+ ArgumentCaptor<RestconfDocumentedException> exceptionCaptor;
+
+ MdsalRestconfServer server;
+ RestconfImpl restconf;
+
+ @BeforeEach
+ final void setupRestconf() {
+ server = new MdsalRestconfServer(() -> DatabindContext.ofModel(modelContext()), dataBroker, rpcService,
+ actionService, mountPointService);
+ restconf = new RestconfImpl(server);
+ }
+
+ @NonNull EffectiveModelContext modelContext() {
+ return JUKEBOX_SCHEMA;
+ }
+}
import static org.junit.jupiter.api.Assertions.assertNotNull;
import org.eclipse.jdt.annotation.NonNull;
-import org.junit.jupiter.api.BeforeEach;
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;
-import org.opendaylight.restconf.nb.rfc8040.databind.DatabindContext;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
@ExtendWith(MockitoExtension.class)
-class Netconf822Test {
- private static final @NonNull DatabindContext DATABIND =
- DatabindContext.ofModel(YangParserTestUtils.parseYangResourceDirectory("/nc822"));
+class Netconf822Test extends AbstractRestconfTest {
+ private static final @NonNull EffectiveModelContext MODEL_CONTEXT =
+ YangParserTestUtils.parseYangResourceDirectory("/nc822");
- @Mock
- private DOMDataBroker dataBroker;
- @Mock
- private DOMRpcService rpcService;
- @Mock
- private DOMActionService actionService;
- @Mock
- private DOMMountPointService mountPointService;
-
- private MdsalRestconfServer server;
-
- @BeforeEach
- void beforeEach() {
- server = new MdsalRestconfServer(() -> DATABIND, dataBroker, rpcService, actionService, mountPointService);
+ @Override
+ @NonNull EffectiveModelContext modelContext() {
+ return MODEL_CONTEXT;
}
@Test
--- /dev/null
+/*
+ * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.nb.rfc8040.rests.services.impl;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateFalseFluentFuture;
+import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateTrueFluentFuture;
+
+import java.util.Optional;
+import org.junit.jupiter.api.BeforeEach;
+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.common.api.CommitInfo;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.dom.api.DOMDataBroker;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
+import org.opendaylight.mdsal.dom.api.DOMRpcService;
+import org.opendaylight.mdsal.dom.api.DOMSchemaService;
+import org.opendaylight.mdsal.dom.spi.FixedDOMSchemaService;
+import org.opendaylight.netconf.dom.api.NetconfDataTreeService;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
+import org.opendaylight.yangtools.yang.common.ErrorType;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+@ExtendWith(MockitoExtension.class)
+class RestconfDataDeleteTest extends AbstractRestconfTest {
+ @Mock
+ private DOMDataTreeReadWriteTransaction tx;
+
+ @BeforeEach
+ void beforeEach() {
+ doReturn(tx).when(dataBroker).newReadWriteTransaction();
+ }
+
+ @Test
+ public void testDeleteData() {
+ doNothing().when(tx).delete(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID);
+ doReturn(immediateTrueFluentFuture())
+ .when(tx).exists(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID);
+ doReturn(CommitInfo.emptyFluentFuture()).when(tx).commit();
+ doReturn(true).when(asyncResponse).resume(responseCaptor.capture());
+ restconf.dataDELETE("example-jukebox:jukebox", asyncResponse);
+
+ assertEquals(204, responseCaptor.getValue().getStatus());
+ }
+
+ @Test
+ public void testDeleteDataNotExisting() {
+ doReturn(immediateFalseFluentFuture())
+ .when(tx).exists(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID);
+ doReturn(true).when(tx).cancel();
+
+ doReturn(true).when(asyncResponse).resume(exceptionCaptor.capture());
+ restconf.dataDELETE("example-jukebox:jukebox", asyncResponse);
+
+ final var errors = exceptionCaptor.getValue().getErrors();
+ assertEquals(1, errors.size());
+ final var error = errors.get(0);
+ assertEquals(ErrorType.PROTOCOL, error.getErrorType());
+ assertEquals(ErrorTag.DATA_MISSING, error.getErrorTag());
+ }
+
+ /**
+ * Test of deleting data on mount point.
+ */
+ @Test
+ public void testDeleteDataMountPoint() {
+ doReturn(Optional.of(mountPoint)).when(mountPointService).getMountPoint(any(YangInstanceIdentifier.class));
+ doReturn(Optional.of(FixedDOMSchemaService.of(JUKEBOX_SCHEMA))).when(mountPoint)
+ .getService(DOMSchemaService.class);
+ doReturn(Optional.of(dataBroker)).when(mountPoint).getService(DOMDataBroker.class);
+ doReturn(Optional.of(rpcService)).when(mountPoint).getService(DOMRpcService.class);
+ doReturn(Optional.empty()).when(mountPoint).getService(NetconfDataTreeService.class);
+
+ doNothing().when(tx).delete(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID);
+ doReturn(immediateTrueFluentFuture())
+ .when(tx).exists(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID);
+ doReturn(CommitInfo.emptyFluentFuture()).when(tx).commit();
+ doReturn(true).when(asyncResponse).resume(responseCaptor.capture());
+ restconf.dataDELETE("example-jukebox:jukebox/yang-ext:mount/example-jukebox:jukebox", asyncResponse);
+
+ assertEquals(204, responseCaptor.getValue().getStatus());
+ }
+}
import java.util.List;
import java.util.Optional;
-import javax.ws.rs.container.AsyncResponse;
import javax.ws.rs.core.MultivaluedHashMap;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMActionService;
import org.opendaylight.mdsal.dom.api.DOMDataBroker;
import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
-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.api.DOMSchemaService;
import org.opendaylight.mdsal.dom.spi.FixedDOMSchemaService;
import org.opendaylight.netconf.dom.api.NetconfDataTreeService;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.restconf.nb.rfc8040.AbstractJukeboxTest;
-import org.opendaylight.restconf.nb.rfc8040.databind.DatabindContext;
import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload;
import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
@ExtendWith(MockitoExtension.class)
-class RestconfDataGetTest extends AbstractJukeboxTest {
+class RestconfDataGetTest extends AbstractRestconfTest {
private static final NodeIdentifier PLAYLIST_NID = new NodeIdentifier(PLAYLIST_QNAME);
private static final NodeIdentifier LIBRARY_NID = new NodeIdentifier(LIBRARY_QNAME);
.withChild(Builders.mapBuilder().withNodeIdentifier(PLAYLIST_NID).build())
.build();
- @Mock
- private UriInfo uriInfo;
- @Mock
- private AsyncResponse asyncResponse;
- @Mock
- private DOMDataBroker dataBroker;
- @Mock
- private DOMActionService actionService;
- @Mock
- private DOMRpcService rpcService;
- @Mock
- private DOMMountPointService mountPointService;
@Mock
private DOMDataTreeReadTransaction tx;
- @Mock
- private DOMMountPoint mountPoint;
- @Captor
- private ArgumentCaptor<Response> responseCaptor;
- @Captor
- private ArgumentCaptor<RestconfDocumentedException> exceptionCaptor;
-
- private RestconfImpl restconf;
@BeforeEach
void beforeEach() {
- restconf = new RestconfImpl(new MdsalRestconfServer(() -> DatabindContext.ofModel(JUKEBOX_SCHEMA), dataBroker,
- rpcService, actionService, mountPointService));
doReturn(tx).when(dataBroker).newReadOnlyTransaction();
}
import org.opendaylight.mdsal.dom.api.DOMSchemaService;
import org.opendaylight.mdsal.dom.spi.FixedDOMSchemaService;
import org.opendaylight.netconf.dom.api.NetconfDataTreeService;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
import org.opendaylight.restconf.common.patch.PatchContext;
import org.opendaylight.restconf.common.patch.PatchEntity;
import org.opendaylight.restconf.common.patch.PatchStatusContext;
import org.opendaylight.restconf.nb.rfc8040.databind.DatabindContext;
import org.opendaylight.restconf.nb.rfc8040.databind.DatabindProvider;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.patch.rev170222.yang.patch.yang.patch.Edit.Operation;
-import org.opendaylight.yangtools.yang.common.ErrorTag;
-import org.opendaylight.yangtools.yang.common.ErrorType;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
response.getLocation());
}
- @Test
- public void testDeleteData() {
- doNothing().when(readWrite).delete(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID);
- doReturn(immediateTrueFluentFuture())
- .when(readWrite).exists(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID);
- final var captor = ArgumentCaptor.forClass(Response.class);
- doReturn(true).when(asyncResponse).resume(captor.capture());
- dataService.deleteData("example-jukebox:jukebox", asyncResponse);
-
- assertEquals(204, captor.getValue().getStatus());
- }
-
- @Test
- public void testDeleteDataNotExisting() {
- doReturn(immediateFalseFluentFuture())
- .when(readWrite).exists(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID);
- final var captor = ArgumentCaptor.forClass(RestconfDocumentedException.class);
- doReturn(true).when(asyncResponse).resume(captor.capture());
- dataService.deleteData("example-jukebox:jukebox", asyncResponse);
-
- final var errors = captor.getValue().getErrors();
- assertEquals(1, errors.size());
- final var error = errors.get(0);
- assertEquals(ErrorType.PROTOCOL, error.getErrorType());
- assertEquals(ErrorTag.DATA_MISSING, error.getErrorTag());
- }
-
- /**
- * Test of deleting data on mount point.
- */
- @Test
- public void testDeleteDataMountPoint() {
- doNothing().when(readWrite).delete(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID);
- doReturn(immediateTrueFluentFuture())
- .when(readWrite).exists(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID);
- final var captor = ArgumentCaptor.forClass(Response.class);
- doReturn(true).when(asyncResponse).resume(captor.capture());
- dataService.deleteData("example-jukebox:jukebox/yang-ext:mount/example-jukebox:jukebox", asyncResponse);
-
- assertEquals(204, captor.getValue().getStatus());
- }
-
@Test
public void testPatchData() {
final var patch = new PatchContext("test patch id", List.of(
import static org.mockito.Mockito.doReturn;
import java.util.Optional;
-import org.junit.jupiter.api.BeforeEach;
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.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;
-import org.opendaylight.mdsal.dom.api.DOMRpcService;
import org.opendaylight.mdsal.dom.api.DOMSchemaService;
-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 {
+class RestconfOperationsGetTest extends AbstractRestconfTest {
private static final String DEVICE_ID = "network-topology:network-topology/topology=topology-netconf/"
+ "node=device/yang-ext:mount";
private static final String DEVICE_RPC1_MODULE1_ID = DEVICE_ID + "module1:dummy-rpc1-module1";
<dummy-rpc2-module2 xmlns="module:2"/>
</operations>""";
- private static final DatabindContext DATABIND = DatabindContext.ofModel(BindingRuntimeHelpers.createRuntimeContext(
- Module1Data.class, Module2Data.class, NetworkTopology.class).getEffectiveModelContext());
+ private static final EffectiveModelContext MODEL_CONTEXT = BindingRuntimeHelpers.createRuntimeContext(
+ Module1Data.class, Module2Data.class, NetworkTopology.class).getEffectiveModelContext();
- @Mock
- private DOMMountPointService mountPointService;
- @Mock
- private DOMMountPoint mountPoint;
@Mock
private DOMSchemaService schemaService;
- @Mock
- private DOMDataBroker dataBroker;
- @Mock
- private DOMRpcService rpcService;
- @Mock
- private DOMActionService actionService;
-
- private RestconfImpl restconf;
- @BeforeEach
- void beforeEach() {
- restconf = new RestconfImpl(
- new MdsalRestconfServer(() -> DATABIND, dataBroker, rpcService, actionService, mountPointService));
+ @Override
+ EffectiveModelContext modelContext() {
+ return MODEL_CONTEXT;
}
@Test
}
private void mockMountPoint() {
- doReturn(DATABIND.modelContext()).when(schemaService).getGlobalContext();
+ doReturn(MODEL_CONTEXT).when(schemaService).getGlobalContext();
doReturn(Optional.of(schemaService)).when(mountPoint).getService(DOMSchemaService.class);
doReturn(Optional.of(mountPoint)).when(mountPointService).getMountPoint(any());
}
import javax.ws.rs.container.AsyncResponse;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
-import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
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;
import org.opendaylight.mdsal.dom.api.DOMNotificationService;
import org.opendaylight.mdsal.dom.api.DOMRpcImplementationNotAvailableException;
import org.opendaylight.mdsal.dom.api.DOMRpcResult;
import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
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.SchemaNodeIdentifier.Absolute;
import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
@ExtendWith(MockitoExtension.class)
-class RestconfOperationsPostTest {
+class RestconfOperationsPostTest extends AbstractRestconfTest {
private static final URI RESTCONF_URI = URI.create("/restconf");
private static final QName RPC = QName.create("invoke:rpc:module", "2013-12-03", "rpc-test");
private static final ContainerNode INPUT = Builders.containerBuilder()
.withNodeIdentifier(new NodeIdentifier(QName.create(RPC, "output")))
.withChild(ImmutableNodes.leafNode(QName.create(RPC, "content"), "operation result"))
.build();
- private static final DatabindContext CONTEXT =
- DatabindContext.ofModel(YangParserTestUtils.parseYangResourceDirectory("/invoke-rpc"));
- private static final OperationInput OPER_INPUT = new OperationInput(CONTEXT,
- SchemaInferenceStack.of(CONTEXT.modelContext(), Absolute.of(RPC)).toInference(), INPUT);
+ private static final EffectiveModelContext MODEL_CONTEXT =
+ YangParserTestUtils.parseYangResourceDirectory("/invoke-rpc");
+ private static final OperationInput OPER_INPUT = new OperationInput(DatabindContext.ofModel(MODEL_CONTEXT),
+ SchemaInferenceStack.of(MODEL_CONTEXT, Absolute.of(RPC)).toInference(), INPUT);
- @Mock
- private DOMDataBroker dataBroker;
- @Mock
- private DOMRpcService rpcService;
- @Mock
- private DOMActionService actionService;
- @Mock
- private DOMMountPoint mountPoint;
- @Mock
- private DOMMountPointService mountPointService;
@Mock
private DOMNotificationService notificationService;
- private RestconfImpl restconf;
- private MdsalRestconfServer server;
-
- @BeforeEach
- void beforeEach() {
- server = new MdsalRestconfServer(() -> CONTEXT, dataBroker, rpcService, actionService, mountPointService);
- restconf = new RestconfImpl(server);
+ @Override
+ EffectiveModelContext modelContext() {
+ return MODEL_CONTEXT;
}
@Test
doReturn(Futures.immediateFuture(new DefaultDOMRpcResult(OUTPUT, List.of()))).when(rpcService)
.invokeRpc(RPC, INPUT);
assertEquals(OUTPUT,
- Futures.getDone(
- server.getRestconfStrategy(CONTEXT.modelContext(), null).invokeRpc(RESTCONF_URI, RPC, OPER_INPUT))
+ Futures.getDone(server.getRestconfStrategy(MODEL_CONTEXT, null).invokeRpc(RESTCONF_URI, RPC, OPER_INPUT))
.output());
}
doReturn(Futures.immediateFailedFuture(exception)).when(rpcService).invokeRpc(errorRpc, INPUT);
final var ex = assertInstanceOf(RestconfDocumentedException.class,
assertThrows(ExecutionException.class,
- () -> Futures.getDone(server.getRestconfStrategy(CONTEXT.modelContext(), null)
+ () -> Futures.getDone(server.getRestconfStrategy(MODEL_CONTEXT, null)
.invokeRpc(RESTCONF_URI, errorRpc, OPER_INPUT))).getCause());
final var errorList = ex.getErrors();
assertEquals(1, errorList.size());
.invokeRpc(RPC, INPUT);
assertEquals(OUTPUT,
Futures.getDone(
- server.getRestconfStrategy(CONTEXT.modelContext(), mountPoint).invokeRpc(RESTCONF_URI, RPC, OPER_INPUT))
+ server.getRestconfStrategy(MODEL_CONTEXT, mountPoint).invokeRpc(RESTCONF_URI, RPC, OPER_INPUT))
.output());
}
doReturn(Optional.empty()).when(mountPoint).getService(DOMRpcService.class);
doReturn(Optional.empty()).when(mountPoint).getService(NetconfDataTreeService.class);
doReturn(Optional.of(dataBroker)).when(mountPoint).getService(DOMDataBroker.class);
- final var strategy = server.getRestconfStrategy(CONTEXT.modelContext(), mountPoint);
+ final var strategy = server.getRestconfStrategy(MODEL_CONTEXT, mountPoint);
final var ex = assertInstanceOf(RestconfDocumentedException.class,
assertThrows(ExecutionException.class,
() -> Futures.getDone(strategy.invokeRpc(RESTCONF_URI, RPC, OPER_INPUT))).getCause());
doReturn(Futures.immediateFuture(new DefaultDOMRpcResult(OUTPUT, List.of())))
.when(rpcService).invokeRpc(RPC, INPUT);
assertEquals(OUTPUT,
- Futures.getDone(server.getRestconfStrategy(CONTEXT.modelContext(), null)
- .invokeRpc(RESTCONF_URI, RPC, OPER_INPUT))
+ Futures.getDone(server.getRestconfStrategy(MODEL_CONTEXT, null).invokeRpc(RESTCONF_URI, RPC, OPER_INPUT))
.output());
}