Introduce asynchronous RestconfServer.readData()
[netconf.git] / restconf / restconf-nb / src / test / java / org / opendaylight / restconf / nb / rfc8040 / rests / services / impl / RestconfDataServiceImplTest.java
index 0967368b365ca422f4523479b928395f898ff09b..29cd849a9e4c63a1a01f654b06e67a4e30cb59da 100644 (file)
@@ -12,7 +12,6 @@ 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;
@@ -26,7 +25,6 @@ import java.io.ByteArrayInputStream;
 import java.io.InputStream;
 import java.net.URI;
 import java.nio.charset.StandardCharsets;
-import java.util.Collection;
 import java.util.List;
 import java.util.Optional;
 import java.util.Set;
@@ -61,10 +59,8 @@ import org.opendaylight.restconf.common.patch.PatchEntity;
 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.streams.StreamsConfiguration;
-import org.opendaylight.restconf.nb.rfc8040.streams.listeners.ListenersBroker;
 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;
@@ -72,7 +68,6 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
@@ -113,8 +108,6 @@ public class RestconfDataServiceImplTest extends AbstractJukeboxTest {
     @Mock
     private DOMRpcService rpcService;
     @Mock
-    private RestconfStreamsSubscriptionService delegRestconfSubscrService;
-    @Mock
     private MultivaluedMap<String, String> queryParamenters;
     @Mock
     private AsyncResponse asyncResponse;
@@ -134,9 +127,9 @@ public class RestconfDataServiceImplTest extends AbstractJukeboxTest {
         doReturn(read).when(dataBroker).newReadOnlyTransaction();
         doReturn(readWrite).when(dataBroker).newReadWriteTransaction();
 
-        dataService = new RestconfDataServiceImpl(() -> DatabindContext.ofModel(JUKEBOX_SCHEMA),
-            new MdsalRestconfServer(dataBroker, rpcService, mountPointService), dataBroker, delegRestconfSubscrService,
-            actionService, new ListenersBroker(), new StreamsConfiguration(0, 1, 0, false));
+        final DatabindProvider databindProvider = () -> DatabindContext.ofModel(JUKEBOX_SCHEMA);
+        dataService = new RestconfDataServiceImpl(databindProvider,
+            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)
@@ -155,8 +148,10 @@ public class RestconfDataServiceImplTest extends AbstractJukeboxTest {
                 .read(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID);
         doReturn(immediateFluentFuture(Optional.empty()))
                 .when(read).read(LogicalDatastoreType.OPERATIONAL, JUKEBOX_IID);
-        final Response response = dataService.readData("example-jukebox:jukebox", uriInfo);
-        assertNotNull(response);
+
+        doReturn(true).when(asyncResponse).resume(responseCaptor.capture());
+        dataService.dataGET("example-jukebox:jukebox", uriInfo, asyncResponse);
+        final var response = responseCaptor.getValue();
         assertEquals(200, response.getStatus());
         assertEquals(EMPTY_JUKEBOX, ((NormalizedNodePayload) response.getEntity()).data());
     }
@@ -170,15 +165,16 @@ public class RestconfDataServiceImplTest extends AbstractJukeboxTest {
         doReturn(immediateFluentFuture(Optional.of(wrapNodeByDataRootContainer(OPER_JUKEBOX))))
                 .when(read)
                 .read(LogicalDatastoreType.OPERATIONAL, YangInstanceIdentifier.of());
-        final Response response = dataService.readData(uriInfo);
-        assertNotNull(response);
+
+        doReturn(true).when(asyncResponse).resume(responseCaptor.capture());
+        dataService.dataGET(uriInfo, asyncResponse);
+        final var response = responseCaptor.getValue();
         assertEquals(200, response.getStatus());
 
-        final NormalizedNode data = ((NormalizedNodePayload) response.getEntity()).data();
-        assertTrue(data instanceof ContainerNode);
-        final Collection<DataContainerChild> rootNodes = ((ContainerNode) data).body();
+        final var data = assertInstanceOf(ContainerNode.class, ((NormalizedNodePayload) response.getEntity()).data());
+        final var rootNodes = data.body();
         assertEquals(1, rootNodes.size());
-        final Collection<DataContainerChild> allDataChildren = ((ContainerNode) rootNodes.iterator().next()).body();
+        final var allDataChildren = assertInstanceOf(ContainerNode.class, rootNodes.iterator().next()).body();
         assertEquals(3, allDataChildren.size());
     }
 
@@ -201,19 +197,17 @@ public class RestconfDataServiceImplTest extends AbstractJukeboxTest {
         doReturn(immediateFluentFuture(Optional.of(OPER_JUKEBOX))).when(read)
                 .read(LogicalDatastoreType.OPERATIONAL, JUKEBOX_IID);
 
-        final Response response = dataService.readData(
-                "example-jukebox:jukebox/yang-ext:mount/example-jukebox:jukebox", uriInfo);
-
-        assertNotNull(response);
+        doReturn(true).when(asyncResponse).resume(responseCaptor.capture());
+        dataService.dataGET("example-jukebox:jukebox/yang-ext:mount/example-jukebox:jukebox", uriInfo, asyncResponse);
+        final var response = responseCaptor.getValue();
         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()).data();
-        assertTrue(data instanceof ContainerNode);
-        assertEquals(3, ((ContainerNode) data).size());
-        assertNotNull(((ContainerNode) data).childByArg(CONT_PLAYER.name()));
-        assertNotNull(((ContainerNode) data).childByArg(LIBRARY_NID));
-        assertNotNull(((ContainerNode) data).childByArg(PLAYLIST_NID));
+        final var data = assertInstanceOf(ContainerNode.class, ((NormalizedNodePayload) response.getEntity()).data());
+        assertEquals(3, data.size());
+        assertNotNull(data.childByArg(CONT_PLAYER.name()));
+        assertNotNull(data.childByArg(LIBRARY_NID));
+        assertNotNull(data.childByArg(PLAYLIST_NID));
     }
 
     @Test
@@ -224,8 +218,11 @@ public class RestconfDataServiceImplTest extends AbstractJukeboxTest {
         doReturn(immediateFluentFuture(Optional.empty()))
                 .when(read).read(LogicalDatastoreType.OPERATIONAL, JUKEBOX_IID);
 
-        final var errors = assertThrows(RestconfDocumentedException.class,
-            () -> dataService.readData("example-jukebox:jukebox", uriInfo)).getErrors();
+        final var rdeCaptor = ArgumentCaptor.forClass(RestconfDocumentedException.class);
+        doReturn(true).when(asyncResponse).resume(rdeCaptor.capture());
+        dataService.dataGET("example-jukebox:jukebox", uriInfo, asyncResponse);
+
+        final var errors = rdeCaptor.getValue().getErrors();
         assertEquals(1, errors.size());
         final var error = errors.get(0);
         assertEquals(ErrorType.PROTOCOL, error.getErrorType());
@@ -246,20 +243,20 @@ public class RestconfDataServiceImplTest extends AbstractJukeboxTest {
         doReturn(immediateFluentFuture(Optional.of(CONFIG_JUKEBOX))).when(read)
                 .read(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID);
 
-        final Response response = dataService.readData("example-jukebox:jukebox", uriInfo);
-
-        assertNotNull(response);
+        doReturn(true).when(asyncResponse).resume(responseCaptor.capture());
+        dataService.dataGET("example-jukebox:jukebox", uriInfo, asyncResponse);
+        final var response = responseCaptor.getValue();
         assertEquals(200, response.getStatus());
 
         // response must contain only config data
-        final NormalizedNode data = ((NormalizedNodePayload) response.getEntity()).data();
+        final var data = assertInstanceOf(ContainerNode.class, ((NormalizedNodePayload) response.getEntity()).data());
 
         // config data present
-        assertNotNull(((ContainerNode) data).childByArg(CONT_PLAYER.name()));
-        assertNotNull(((ContainerNode) data).childByArg(LIBRARY_NID));
+        assertNotNull(data.childByArg(CONT_PLAYER.name()));
+        assertNotNull(data.childByArg(LIBRARY_NID));
 
         // state data absent
-        assertNull(((ContainerNode) data).childByArg(PLAYLIST_NID));
+        assertNull(data.childByArg(PLAYLIST_NID));
     }
 
     /**
@@ -274,20 +271,21 @@ public class RestconfDataServiceImplTest extends AbstractJukeboxTest {
         doReturn(immediateFluentFuture(Optional.of(OPER_JUKEBOX))).when(read)
                 .read(LogicalDatastoreType.OPERATIONAL, JUKEBOX_IID);
 
-        final Response response = dataService.readData("example-jukebox:jukebox", uriInfo);
+        doReturn(true).when(asyncResponse).resume(responseCaptor.capture());
+        dataService.dataGET("example-jukebox:jukebox", uriInfo, asyncResponse);
+        final var response = responseCaptor.getValue();
 
-        assertNotNull(response);
         assertEquals(200, response.getStatus());
 
         // response must contain only operational data
-        final NormalizedNode data = ((NormalizedNodePayload) response.getEntity()).data();
+        final var data = assertInstanceOf(ContainerNode.class, ((NormalizedNodePayload) response.getEntity()).data());
 
         // state data present
-        assertNotNull(((ContainerNode) data).childByArg(CONT_PLAYER.name()));
-        assertNotNull(((ContainerNode) data).childByArg(PLAYLIST_NID));
+        assertNotNull(data.childByArg(CONT_PLAYER.name()));
+        assertNotNull(data.childByArg(PLAYLIST_NID));
 
         // config data absent
-        assertNull(((ContainerNode) data).childByArg(LIBRARY_NID));
+        assertNull(data.childByArg(LIBRARY_NID));
     }
 
     @Test
@@ -295,15 +293,17 @@ public class RestconfDataServiceImplTest extends AbstractJukeboxTest {
         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());
     }
 
@@ -312,14 +312,16 @@ public class RestconfDataServiceImplTest extends AbstractJukeboxTest {
         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());
     }
 
@@ -335,11 +337,14 @@ public class RestconfDataServiceImplTest extends AbstractJukeboxTest {
             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());
     }
@@ -352,14 +357,16 @@ public class RestconfDataServiceImplTest extends AbstractJukeboxTest {
         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());
@@ -470,7 +477,7 @@ public class RestconfDataServiceImplTest extends AbstractJukeboxTest {
         doReturn(true).when(asyncResponse).resume(responseCaptor.capture());
         dataService.yangPatchData(JUKEBOX_SCHEMA, patch, null, asyncResponse);
         final var response = responseCaptor.getValue();
-        assertEquals(200, response.getStatus());
+        assertEquals(409, response.getStatus());
         final var status = assertInstanceOf(PatchStatusContext.class, response.getEntity());
 
         assertFalse(status.ok());