*/
package org.opendaylight.restconf.nb.rfc8040.rests.services.impl;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThrows;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.opendaylight.mdsal.common.api.CommitInfo;
import org.opendaylight.mdsal.dom.api.DOMDataBroker;
import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
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.api.DOMTransactionChain;
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.PatchStatusContext;
import org.opendaylight.restconf.nb.rfc8040.AbstractJukeboxTest;
import org.opendaylight.restconf.nb.rfc8040.databind.DatabindContext;
+import org.opendaylight.restconf.nb.rfc8040.databind.DatabindProvider;
import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload;
-import org.opendaylight.restconf.nb.rfc8040.rests.services.api.RestconfStreamsSubscriptionService;
-import org.opendaylight.restconf.nb.rfc8040.rests.transactions.MdsalRestconfStrategy;
-import org.opendaylight.restconf.nb.rfc8040.rests.transactions.NetconfRestconfStrategy;
-import org.opendaylight.restconf.nb.rfc8040.rests.transactions.RestconfStrategy;
-import org.opendaylight.restconf.nb.rfc8040.streams.StreamsConfiguration;
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;
.withChild(Builders.mapBuilder().withNodeIdentifier(PLAYLIST_NID).build())
.build();
- private RestconfDataServiceImpl dataService;
-
- @Mock
- private DOMTransactionChain domTransactionChain;
@Mock
private UriInfo uriInfo;
@Mock
@Mock
private DOMDataTreeReadTransaction read;
@Mock
- private DOMDataTreeWriteTransaction write;
- @Mock
private DOMMountPointService mountPointService;
@Mock
private DOMMountPoint mountPoint;
@Mock
private DOMActionService actionService;
@Mock
- private RestconfStreamsSubscriptionService delegRestconfSubscrService;
+ private DOMRpcService rpcService;
@Mock
private MultivaluedMap<String, String> queryParamenters;
@Mock
private AsyncResponse asyncResponse;
+ @Captor
+ private ArgumentCaptor<Response> responseCaptor;
+
+ private RestconfDataServiceImpl dataService;
@Before
public void setUp() throws Exception {
doReturn(read).when(dataBroker).newReadOnlyTransaction();
doReturn(readWrite).when(dataBroker).newReadWriteTransaction();
- dataService = new RestconfDataServiceImpl(() -> DatabindContext.ofModel(JUKEBOX_SCHEMA), dataBroker,
- mountPointService, delegRestconfSubscrService, actionService, new StreamsConfiguration(0, 1, 0, false));
+ final DatabindProvider databindProvider = () -> DatabindContext.ofModel(JUKEBOX_SCHEMA);
+ dataService = new RestconfDataServiceImpl(databindProvider,
+ new MdsalRestconfServer(databindProvider, dataBroker, rpcService, mountPointService), actionService);
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(mountDataBroker)).when(mountPoint).getService(DOMDataBroker.class);
+ doReturn(Optional.of(rpcService)).when(mountPoint).getService(DOMRpcService.class);
doReturn(Optional.empty()).when(mountPoint).getService(NetconfDataTreeService.class);
doReturn(read).when(mountDataBroker).newReadOnlyTransaction();
doReturn(readWrite).when(mountDataBroker).newReadWriteTransaction();
final Response response = dataService.readData("example-jukebox:jukebox", uriInfo);
assertNotNull(response);
assertEquals(200, response.getStatus());
- assertEquals(EMPTY_JUKEBOX, ((NormalizedNodePayload) response.getEntity()).getData());
+ assertEquals(EMPTY_JUKEBOX, ((NormalizedNodePayload) response.getEntity()).data());
}
@Test
assertNotNull(response);
assertEquals(200, response.getStatus());
- final NormalizedNode data = ((NormalizedNodePayload) response.getEntity()).getData();
+ final NormalizedNode data = ((NormalizedNodePayload) response.getEntity()).data();
assertTrue(data instanceof ContainerNode);
final Collection<DataContainerChild> rootNodes = ((ContainerNode) data).body();
assertEquals(1, rootNodes.size());
assertEquals(200, response.getStatus());
// response must contain all child nodes from config and operational containers merged in one container
- final NormalizedNode data = ((NormalizedNodePayload) response.getEntity()).getData();
+ final NormalizedNode data = ((NormalizedNodePayload) response.getEntity()).data();
assertTrue(data instanceof ContainerNode);
assertEquals(3, ((ContainerNode) data).size());
assertNotNull(((ContainerNode) data).childByArg(CONT_PLAYER.name()));
assertEquals(200, response.getStatus());
// response must contain only config data
- final NormalizedNode data = ((NormalizedNodePayload) response.getEntity()).getData();
+ final NormalizedNode data = ((NormalizedNodePayload) response.getEntity()).data();
// config data present
assertNotNull(((ContainerNode) data).childByArg(CONT_PLAYER.name()));
assertEquals(200, response.getStatus());
// response must contain only operational data
- final NormalizedNode data = ((NormalizedNodePayload) response.getEntity()).getData();
+ final NormalizedNode data = ((NormalizedNodePayload) response.getEntity()).data();
// state data present
assertNotNull(((ContainerNode) data).childByArg(CONT_PLAYER.name()));
doReturn(immediateTrueFluentFuture()).when(read)
.exists(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID);
doNothing().when(readWrite).put(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, EMPTY_JUKEBOX);
- final var response = dataService.putDataJSON("example-jukebox:jukebox", uriInfo, stringInputStream("""
+
+ doReturn(true).when(asyncResponse).resume(responseCaptor.capture());
+ dataService.putDataJSON("example-jukebox:jukebox", uriInfo, stringInputStream("""
{
"example-jukebox:jukebox" : {
"player": {
"gap": "0.2"
}
}
- }"""));
- assertNotNull(response);
+ }"""), asyncResponse);
+ final var response = responseCaptor.getValue();
assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
}
doReturn(immediateTrueFluentFuture()).when(read)
.exists(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID);
doNothing().when(readWrite).put(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, EMPTY_JUKEBOX);
- final var response = dataService.putDataXML("example-jukebox:jukebox/yang-ext:mount/example-jukebox:jukebox",
+
+ doReturn(true).when(asyncResponse).resume(responseCaptor.capture());
+ dataService.putDataXML("example-jukebox:jukebox/yang-ext:mount/example-jukebox:jukebox",
uriInfo, stringInputStream("""
<jukebox xmlns="http://example.com/ns/example-jukebox">
<player>
<gap>0.2</gap>
</player>
- </jukebox>"""));
- assertNotNull(response);
+ </jukebox>"""), asyncResponse);
+ final var response = responseCaptor.getValue();
assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
}
Builders.containerBuilder().withNodeIdentifier(new NodeIdentifier(JUKEBOX_QNAME)).build());
doReturn(UriBuilder.fromUri("http://localhost:8181/rests/")).when(uriInfo).getBaseUriBuilder();
- final var response = dataService.postDataJSON(new ByteArrayInputStream("""
+ final var captor = ArgumentCaptor.forClass(Response.class);
+ doReturn(true).when(asyncResponse).resume(captor.capture());
+ dataService.postDataJSON(stringInputStream("""
{
"example-jukebox:jukebox" : {
}
- }""".getBytes(StandardCharsets.UTF_8)), uriInfo);
+ }"""), uriInfo, asyncResponse);
+ final var response = captor.getValue();
assertEquals(201, response.getStatus());
assertEquals(URI.create("http://localhost:8181/rests/data/example-jukebox:jukebox"), response.getLocation());
}
doNothing().when(readWrite).put(LogicalDatastoreType.CONFIGURATION, node, BAND_ENTRY);
doReturn(UriBuilder.fromUri("http://localhost:8181/rests/")).when(uriInfo).getBaseUriBuilder();
- final var response = dataService.postDataJSON("example-jukebox:jukebox", new ByteArrayInputStream("""
+ final var captor = ArgumentCaptor.forClass(Response.class);
+ doReturn(true).when(asyncResponse).resume(captor.capture());
+ dataService.postDataJSON("example-jukebox:jukebox", stringInputStream("""
{
"example-jukebox:playlist" : {
"name" : "name of band",
"description" : "band description"
}
- }""".getBytes(StandardCharsets.UTF_8)),
- uriInfo);
+ }"""), uriInfo, asyncResponse);
+ final var response = captor.getValue();
assertEquals(201, response.getStatus());
assertEquals(URI.create("http://localhost:8181/rests/data/example-jukebox:jukebox/playlist=name%20of%20band"),
response.getLocation());
.when(readWrite).exists(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID);
doReturn(immediateTrueFluentFuture())
.when(readWrite).exists(LogicalDatastoreType.CONFIGURATION, GAP_IID);
- final var status = dataService.yangPatchData(JUKEBOX_SCHEMA, patch, null);
+ doReturn(true).when(asyncResponse).resume(responseCaptor.capture());
+ dataService.yangPatchData(JUKEBOX_SCHEMA, patch, null, asyncResponse);
+ final var response = responseCaptor.getValue();
+ assertEquals(200, response.getStatus());
+ final var status = assertInstanceOf(PatchStatusContext.class, response.getEntity());
+
assertTrue(status.ok());
assertEquals(3, status.editCollection().size());
assertEquals("replace data", status.editCollection().get(1).getEditId());
.when(readWrite).exists(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID);
doReturn(immediateTrueFluentFuture()).when(readWrite).exists(LogicalDatastoreType.CONFIGURATION, GAP_IID);
- final var status = dataService.yangPatchData(JUKEBOX_SCHEMA, patch, mountPoint);
+ doReturn(true).when(asyncResponse).resume(responseCaptor.capture());
+ dataService.yangPatchData(JUKEBOX_SCHEMA, patch, mountPoint, asyncResponse);
+ final var response = responseCaptor.getValue();
+ assertEquals(200, response.getStatus());
+ final var status = assertInstanceOf(PatchStatusContext.class, response.getEntity());
+
assertTrue(status.ok());
assertEquals(3, status.editCollection().size());
assertNull(status.globalErrors());
@Test
public void testPatchDataDeleteNotExist() {
- final PatchContext patch = new PatchContext("test patch id", List.of(
+ final var patch = new PatchContext("test patch id", List.of(
new PatchEntity("create data", Operation.Create, JUKEBOX_IID, EMPTY_JUKEBOX),
new PatchEntity("remove data", Operation.Remove, GAP_IID),
new PatchEntity("delete data", Operation.Delete, GAP_IID)));
.when(readWrite).exists(LogicalDatastoreType.CONFIGURATION, GAP_IID);
doReturn(true).when(readWrite).cancel();
- final PatchStatusContext status = dataService.yangPatchData(JUKEBOX_SCHEMA, patch, null);
+ doReturn(true).when(asyncResponse).resume(responseCaptor.capture());
+ dataService.yangPatchData(JUKEBOX_SCHEMA, patch, null, asyncResponse);
+ final var response = responseCaptor.getValue();
+ assertEquals(409, response.getStatus());
+ final var status = assertInstanceOf(PatchStatusContext.class, response.getEntity());
assertFalse(status.ok());
assertEquals(3, status.editCollection().size());
final String errorMessage = status.editCollection().get(2).getEditErrors().get(0).getErrorMessage();
assertEquals("Data does not exist", errorMessage);
}
-
- @Test
- public void testGetRestconfStrategy() {
- RestconfStrategy restconfStrategy = dataService.getRestconfStrategy(mountPoint);
- assertTrue(restconfStrategy instanceof MdsalRestconfStrategy);
-
- doReturn(Optional.of(netconfService)).when(mountPoint).getService(NetconfDataTreeService.class);
- restconfStrategy = dataService.getRestconfStrategy(mountPoint);
- assertTrue(restconfStrategy instanceof NetconfRestconfStrategy);
- }
}