import static org.junit.jupiter.api.Assertions.assertNull;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
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.immediateFluentFuture;
import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateTrueFluentFuture;
+import java.util.List;
import java.util.Optional;
import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.MultivaluedMap;
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.data.api.YangInstanceIdentifier;
@ExtendWith(MockitoExtension.class)
class RestconfDataPutTest extends AbstractRestconfTest {
@BeforeEach
void beforeEach() {
- doReturn(queryParamenters).when(uriInfo).getQueryParameters();
doReturn(readTx).when(dataBroker).newReadOnlyTransaction();
doReturn(rwTx).when(dataBroker).newReadWriteTransaction();
doReturn(CommitInfo.emptyFluentFuture()).when(rwTx).commit();
@Test
void testPutData() {
+ doReturn(queryParamenters).when(uriInfo).getQueryParameters();
doReturn(immediateTrueFluentFuture()).when(readTx).exists(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID);
doNothing().when(rwTx).put(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, EMPTY_JUKEBOX);
@Test
void testPutDataWithMountPoint() {
+ doReturn(queryParamenters).when(uriInfo).getQueryParameters();
doReturn(immediateTrueFluentFuture()).when(readTx).exists(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID);
doNothing().when(rwTx).put(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, EMPTY_JUKEBOX);
doReturn(Optional.of(mountPoint)).when(mountPointService).getMountPoint(any());
</player>
</jukebox>"""), ar)));
}
+
+ @Test
+ public void testPutDataWithInsertLast() {
+ // Mocking the query parameters to include 'insert=last'
+ final var queryParams = new MultivaluedHashMap<String, String>();
+ queryParams.put("insert", List.of("last"));
+ doReturn(queryParams).when(uriInfo).getQueryParameters();
+
+ doReturn(immediateFalseFluentFuture()).when(readTx)
+ .exists(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class));
+
+ assertNull(assertEntity(201, ar -> restconf.dataJsonPUT(
+ "example-jukebox:jukebox/playlist=0/song=3", uriInfo, stringInputStream("""
+ {
+ "example-jukebox:song" : [
+ {
+ "index": "3"
+ }
+ ]
+ }"""), ar)));
+ }
+
+ @Test
+ public void testPutDataWithInsertFirst() {
+ // Mocking the query parameters to include 'insert=first'
+ final var queryParams = new MultivaluedHashMap<String, String>();
+ queryParams.put("insert", List.of("first"));
+ doReturn(queryParams).when(uriInfo).getQueryParameters();
+
+ doReturn(immediateFalseFluentFuture()).when(readTx)
+ .exists(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class));
+ // Mocking existed playlist with two songs in DS
+ doReturn(immediateFluentFuture(Optional.of(PLAYLIST_WITH_SONGS))).when(rwTx)
+ .read(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class));
+
+ assertNull(assertEntity(201, ar -> restconf.dataJsonPUT(
+ "example-jukebox:jukebox/playlist=0/song=3", uriInfo, stringInputStream("""
+ {
+ "example-jukebox:song" : [
+ {
+ "index": "3"
+ }
+ ]
+ }"""), ar)));
+ }
+
+ @Test
+ public void testPutDataWithInsertBefore() {
+ // Mocking the query parameters to include 'insert=before' and 'point=example-jukebox:jukebox/playlist=0/song=2'
+ final var queryParams = new MultivaluedHashMap<String, String>();
+ queryParams.put("insert", List.of("before"));
+ queryParams.put("point", List.of("example-jukebox:jukebox/playlist=0/song=2"));
+ doReturn(queryParams).when(uriInfo).getQueryParameters();
+
+ doReturn(immediateFalseFluentFuture()).when(readTx)
+ .exists(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class));
+ // Mocking existed playlist with two songs in DS
+ doReturn(immediateFluentFuture(Optional.of(PLAYLIST_WITH_SONGS))).when(rwTx)
+ .read(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class));
+
+ assertNull(assertEntity(201, ar -> restconf.dataJsonPUT(
+ "example-jukebox:jukebox/playlist=0/song=3", uriInfo, stringInputStream("""
+ {
+ "example-jukebox:song" : [
+ {
+ "index": "3",
+ "id" = "C"
+ }
+ ]
+ }"""), ar)));
+ }
+
+ @Test
+ public void testPutDataWithInsertAfter() {
+ // Mocking the query parameters to include 'insert=after' and 'point=example-jukebox:jukebox/playlist=0/song=1'
+ final var queryParams = new MultivaluedHashMap<String, String>();
+ queryParams.put("insert", List.of("after"));
+ queryParams.put("point", List.of("example-jukebox:jukebox/playlist=0/song=1"));
+ doReturn(queryParams).when(uriInfo).getQueryParameters();
+
+ doReturn(immediateFalseFluentFuture()).when(readTx)
+ .exists(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class));
+ doReturn(immediateFluentFuture(Optional.of(PLAYLIST_WITH_SONGS))).when(rwTx)
+ .read(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class));
+
+ assertNull(assertEntity(201, ar -> restconf.dataJsonPUT(
+ "example-jukebox:jukebox/playlist=0/song=3", uriInfo, stringInputStream("""
+ {
+ "example-jukebox:song" : [
+ {
+ "index": "3",
+ "id" = "C"
+ }
+ ]
+ }"""), ar)));
+ }
}
import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.SystemMapNode;
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;
protected static final QName PLAYER_QNAME = QName.create(JUKEBOX_QNAME, "player");
// container library
protected static final QName LIBRARY_QNAME = QName.create(JUKEBOX_QNAME, "library");
+ // list song
+ protected static final QName SONG_QNAME = QName.create(JUKEBOX_QNAME, "song");
+ // leaf id
+ protected static final QName SONG_ID_QNAME = QName.create(JUKEBOX_QNAME, "id");
+ // leaf index
+ protected static final QName SONG_INDEX_QNAME = QName.create(JUKEBOX_QNAME, "index");
// list artist
protected static final QName ARTIST_QNAME = QName.create(JUKEBOX_QNAME, "artist");
// list album
.withChild(ImmutableNodes.leafNode(NAME_QNAME, "name of band"))
.withChild(ImmutableNodes.leafNode(DESCRIPTION_QNAME, "band description"))
.build();
+ protected static final MapEntryNode SONG1 = Builders.mapEntryBuilder()
+ .withNodeIdentifier(YangInstanceIdentifier.NodeIdentifierWithPredicates.of(SONG_QNAME, SONG_INDEX_QNAME,
+ "1"))
+ .withChild(ImmutableNodes.leafNode(SONG_ID_QNAME, "A"))
+ .build();
+ protected static final MapEntryNode SONG2 = Builders.mapEntryBuilder()
+ .withNodeIdentifier(YangInstanceIdentifier.NodeIdentifierWithPredicates.of(SONG_QNAME, SONG_INDEX_QNAME,
+ "2"))
+ .withChild(ImmutableNodes.leafNode(SONG_ID_QNAME, "B"))
+ .build();
+ protected static final SystemMapNode PLAYLIST_WITH_SONGS = Builders.mapBuilder()
+ .withNodeIdentifier(new NodeIdentifier(JUKEBOX_QNAME))
+ .withChild(Builders.mapEntryBuilder()
+ .withNodeIdentifier(YangInstanceIdentifier.NodeIdentifierWithPredicates.of(PLAYLIST_QNAME, NAME_QNAME,
+ "0"))
+ .withChild(Builders.orderedMapBuilder()
+ .withNodeIdentifier(new NodeIdentifier(SONG_QNAME))
+ .withChild(SONG1)
+ .withChild(SONG2)
+ .build())
+ .build())
+ .build();
protected static final @NonNull EffectiveModelContext JUKEBOX_SCHEMA =
YangParserTestUtils.parseYangResourceDirectory("/jukebox");