2 * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.restconf.nb.jaxrs;
10 import static org.junit.jupiter.api.Assertions.assertNull;
11 import static org.mockito.ArgumentMatchers.any;
12 import static org.mockito.ArgumentMatchers.eq;
13 import static org.mockito.Mockito.doNothing;
14 import static org.mockito.Mockito.doReturn;
15 import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateFalseFluentFuture;
16 import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateFluentFuture;
17 import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateTrueFluentFuture;
19 import java.util.List;
20 import java.util.Optional;
21 import javax.ws.rs.core.MultivaluedHashMap;
22 import javax.ws.rs.core.MultivaluedMap;
23 import org.junit.jupiter.api.BeforeEach;
24 import org.junit.jupiter.api.Test;
25 import org.junit.jupiter.api.extension.ExtendWith;
26 import org.mockito.Mock;
27 import org.mockito.junit.jupiter.MockitoExtension;
28 import org.opendaylight.mdsal.common.api.CommitInfo;
29 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
30 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
31 import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
32 import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
33 import org.opendaylight.mdsal.dom.api.DOMRpcService;
34 import org.opendaylight.mdsal.dom.api.DOMSchemaService;
35 import org.opendaylight.mdsal.dom.spi.FixedDOMSchemaService;
36 import org.opendaylight.netconf.dom.api.NetconfDataTreeService;
37 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
39 @ExtendWith(MockitoExtension.class)
40 class RestconfDataPutTest extends AbstractRestconfTest {
41 private final MultivaluedMap<String, String> queryParamenters = new MultivaluedHashMap<>();
44 private DOMDataTreeReadTransaction readTx;
46 private DOMDataTreeReadWriteTransaction rwTx;
50 doReturn(readTx).when(dataBroker).newReadOnlyTransaction();
51 doReturn(rwTx).when(dataBroker).newReadWriteTransaction();
52 doReturn(CommitInfo.emptyFluentFuture()).when(rwTx).commit();
57 doReturn(queryParamenters).when(uriInfo).getQueryParameters();
58 doReturn(immediateTrueFluentFuture()).when(readTx).exists(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID);
59 doNothing().when(rwTx).put(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, EMPTY_JUKEBOX);
61 assertNull(assertEntity(204, ar -> restconf.dataJsonPUT(JUKEBOX_API_PATH, uriInfo, stringInputStream("""
63 "example-jukebox:jukebox" : {
72 void testPutDataWithMountPoint() {
73 doReturn(queryParamenters).when(uriInfo).getQueryParameters();
74 doReturn(immediateTrueFluentFuture()).when(readTx).exists(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID);
75 doNothing().when(rwTx).put(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, EMPTY_JUKEBOX);
76 doReturn(Optional.of(mountPoint)).when(mountPointService).getMountPoint(any());
77 doReturn(Optional.of(FixedDOMSchemaService.of(JUKEBOX_SCHEMA))).when(mountPoint)
78 .getService(DOMSchemaService.class);
79 doReturn(Optional.of(dataBroker)).when(mountPoint).getService(DOMDataBroker.class);
80 doReturn(Optional.of(rpcService)).when(mountPoint).getService(DOMRpcService.class);
81 doReturn(Optional.empty()).when(mountPoint).getService(NetconfDataTreeService.class);
83 assertNull(assertEntity(204, ar -> restconf.dataXmlPUT(
84 new JaxRsApiPath("example-jukebox:jukebox/yang-ext:mount/example-jukebox:jukebox"), uriInfo,
86 <jukebox xmlns="http://example.com/ns/example-jukebox">
90 </jukebox>"""), ar)));
94 public void testPutDataWithInsertLast() {
95 // Mocking the query parameters to include 'insert=last'
96 final var queryParams = new MultivaluedHashMap<String, String>();
97 queryParams.put("insert", List.of("last"));
98 doReturn(queryParams).when(uriInfo).getQueryParameters();
100 doReturn(immediateFalseFluentFuture()).when(readTx)
101 .exists(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class));
103 assertNull(assertEntity(201, ar -> restconf.dataJsonPUT(
104 new JaxRsApiPath("example-jukebox:jukebox/playlist=0/song=3"), uriInfo, stringInputStream("""
106 "example-jukebox:song" : [
115 public void testPutDataWithInsertFirst() {
116 // Mocking the query parameters to include 'insert=first'
117 final var queryParams = new MultivaluedHashMap<String, String>();
118 queryParams.put("insert", List.of("first"));
119 doReturn(queryParams).when(uriInfo).getQueryParameters();
121 doReturn(immediateFalseFluentFuture()).when(readTx)
122 .exists(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class));
123 // Mocking existed playlist with two songs in DS
124 doReturn(immediateFluentFuture(Optional.of(PLAYLIST_WITH_SONGS))).when(rwTx)
125 .read(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class));
127 assertNull(assertEntity(201, ar -> restconf.dataJsonPUT(
128 new JaxRsApiPath("example-jukebox:jukebox/playlist=0/song=3"), uriInfo, stringInputStream("""
130 "example-jukebox:song" : [
139 public void testPutDataWithInsertBefore() {
140 // Mocking the query parameters to include 'insert=before' and 'point=example-jukebox:jukebox/playlist=0/song=2'
141 final var queryParams = new MultivaluedHashMap<String, String>();
142 queryParams.put("insert", List.of("before"));
143 queryParams.put("point", List.of("example-jukebox:jukebox/playlist=0/song=2"));
144 doReturn(queryParams).when(uriInfo).getQueryParameters();
146 doReturn(immediateFalseFluentFuture()).when(readTx)
147 .exists(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class));
148 // Mocking existed playlist with two songs in DS
149 doReturn(immediateFluentFuture(Optional.of(PLAYLIST_WITH_SONGS))).when(rwTx)
150 .read(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class));
152 assertNull(assertEntity(201, ar -> restconf.dataJsonPUT(
153 new JaxRsApiPath("example-jukebox:jukebox/playlist=0/song=3"), uriInfo, stringInputStream("""
155 "example-jukebox:song" : [
165 public void testPutDataWithInsertAfter() {
166 // Mocking the query parameters to include 'insert=after' and 'point=example-jukebox:jukebox/playlist=0/song=1'
167 final var queryParams = new MultivaluedHashMap<String, String>();
168 queryParams.put("insert", List.of("after"));
169 queryParams.put("point", List.of("example-jukebox:jukebox/playlist=0/song=1"));
170 doReturn(queryParams).when(uriInfo).getQueryParameters();
172 doReturn(immediateFalseFluentFuture()).when(readTx)
173 .exists(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class));
174 doReturn(immediateFluentFuture(Optional.of(PLAYLIST_WITH_SONGS))).when(rwTx)
175 .read(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class));
177 assertNull(assertEntity(201, ar -> restconf.dataJsonPUT(
178 new JaxRsApiPath("example-jukebox:jukebox/playlist=0/song=3"), uriInfo, stringInputStream("""
180 "example-jukebox:song" : [