Create MdsalRestconfServer
[netconf.git] / restconf / restconf-nb / src / test / java / org / opendaylight / restconf / nb / rfc8040 / rests / transactions / NetconfRestconfStrategyTest.java
1 /*
2  * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.restconf.nb.rfc8040.rests.transactions;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.mockito.ArgumentMatchers.any;
12 import static org.mockito.Mockito.doReturn;
13 import static org.mockito.Mockito.mock;
14 import static org.mockito.Mockito.verify;
15 import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateFailedFluentFuture;
16 import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateFluentFuture;
17
18 import com.google.common.util.concurrent.Futures;
19 import java.util.Optional;
20 import org.junit.Before;
21 import org.junit.Test;
22 import org.junit.runner.RunWith;
23 import org.mockito.Mock;
24 import org.mockito.junit.MockitoJUnitRunner;
25 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
26 import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
27 import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult;
28 import org.opendaylight.netconf.api.NetconfDocumentedException;
29 import org.opendaylight.netconf.dom.api.NetconfDataTreeService;
30 import org.opendaylight.restconf.common.patch.PatchStatusContext;
31 import org.opendaylight.yangtools.yang.common.ErrorSeverity;
32 import org.opendaylight.yangtools.yang.common.ErrorTag;
33 import org.opendaylight.yangtools.yang.common.ErrorType;
34 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
35 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
36 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
37 import org.w3c.dom.DOMException;
38
39 @RunWith(MockitoJUnitRunner.StrictStubs.class)
40 public final class NetconfRestconfStrategyTest extends AbstractRestconfStrategyTest {
41     @Mock
42     private NetconfDataTreeService netconfService;
43
44     @Before
45     public void before() {
46         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
47         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).discardChanges();
48         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).unlock();
49         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).lock();
50         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
51             .delete(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.of());
52         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).merge(any(), any(),
53             any(), any());
54     }
55
56     @Override
57     RestconfStrategy testDeleteDataStrategy() {
58         return new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService, null);
59     }
60
61     @Override
62     RestconfStrategy testNegativeDeleteDataStrategy() {
63         doReturn(Futures.immediateFailedFuture(new TransactionCommitFailedException(
64             "Commit of transaction " + this + " failed", new NetconfDocumentedException("id",
65                 ErrorType.RPC, ErrorTag.DATA_MISSING, ErrorSeverity.ERROR)))).when(netconfService).commit();
66         return new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService, null);
67     }
68
69     @Override
70     RestconfStrategy testPostContainerDataStrategy() {
71         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
72         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
73             .create(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, EMPTY_JUKEBOX, Optional.empty());
74         return new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService, null);
75     }
76
77     @Override
78     RestconfStrategy testPostListDataStrategy(final MapEntryNode entryNode, final YangInstanceIdentifier node) {
79         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
80             // FIXME: exact match
81             .merge(any(), any(), any(), any());
82         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
83         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).create(
84             LogicalDatastoreType.CONFIGURATION, node, entryNode, Optional.empty());
85         return new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService, null);
86     }
87
88     @Override
89     RestconfStrategy testPostDataFailStrategy(final DOMException domException) {
90         doReturn(immediateFailedFluentFuture(domException)).when(netconfService)
91             // FIXME: exact match
92             .create(any(), any(), any(), any());
93         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).discardChanges();
94         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).unlock();
95         return new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService, null);
96     }
97
98     @Override
99     RestconfStrategy testPatchContainerDataStrategy() {
100         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).merge(any(), any(),any(),
101             any());
102         return new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService, null);
103     }
104
105     @Override
106     RestconfStrategy testPatchLeafDataStrategy() {
107         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
108             .merge(any(), any(), any(), any());
109         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
110         return new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService, null);
111     }
112
113     @Override
114     RestconfStrategy testPatchListDataStrategy() {
115         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
116         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
117             .merge(any(), any(),any(),any());
118         return new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService, null);
119     }
120
121     @Test
122     public void testPutCreateContainerData() {
123         doReturn(immediateFluentFuture(Optional.empty())).when(netconfService).getConfig(JUKEBOX_IID);
124         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
125         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
126             .replace(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, EMPTY_JUKEBOX, Optional.empty());
127
128         new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService, null).putData(JUKEBOX_IID, EMPTY_JUKEBOX, null);
129         verify(netconfService).lock();
130         verify(netconfService).getConfig(JUKEBOX_IID);
131         verify(netconfService).replace(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, EMPTY_JUKEBOX,
132             Optional.empty());
133     }
134
135     @Test
136     public void testPutReplaceContainerData() {
137         doReturn(immediateFluentFuture(Optional.of(mock(NormalizedNode.class)))).when(netconfService)
138             .getConfig(JUKEBOX_IID);
139         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
140         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
141             .replace(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, EMPTY_JUKEBOX, Optional.empty());
142
143         new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService, null).putData(JUKEBOX_IID, EMPTY_JUKEBOX, null);
144         verify(netconfService).getConfig(JUKEBOX_IID);
145         verify(netconfService).replace(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, EMPTY_JUKEBOX,
146             Optional.empty());
147     }
148
149     @Test
150     public void testPutCreateLeafData() {
151         doReturn(immediateFluentFuture(Optional.empty())).when(netconfService).getConfig(GAP_IID);
152         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
153         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
154             .replace(LogicalDatastoreType.CONFIGURATION, GAP_IID, GAP_LEAF, Optional.empty());
155
156         new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService, null).putData(GAP_IID, GAP_LEAF, null);
157         verify(netconfService).getConfig(GAP_IID);
158         verify(netconfService).replace(LogicalDatastoreType.CONFIGURATION, GAP_IID, GAP_LEAF, Optional.empty());
159     }
160
161     @Test
162     public void testPutReplaceLeafData() {
163         doReturn(immediateFluentFuture(Optional.of(mock(NormalizedNode.class)))).when(netconfService)
164             .getConfig(GAP_IID);
165         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
166         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
167             .replace(LogicalDatastoreType.CONFIGURATION, GAP_IID, GAP_LEAF, Optional.empty());
168
169         new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService, null).putData(GAP_IID, GAP_LEAF, null);
170         verify(netconfService).getConfig(GAP_IID);
171         verify(netconfService).replace(LogicalDatastoreType.CONFIGURATION, GAP_IID, GAP_LEAF, Optional.empty());
172     }
173
174     @Test
175     public void testPutCreateListData() {
176         doReturn(immediateFluentFuture(Optional.empty())).when(netconfService).getConfig(JUKEBOX_IID);
177         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
178         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
179             .replace(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, JUKEBOX_WITH_BANDS, Optional.empty());
180
181         new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService, null)
182             .putData(JUKEBOX_IID, JUKEBOX_WITH_BANDS, null);
183         verify(netconfService).getConfig(JUKEBOX_IID);
184         verify(netconfService).replace(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, JUKEBOX_WITH_BANDS,
185             Optional.empty());
186     }
187
188     @Test
189     public void testPutReplaceListData() {
190         doReturn(immediateFluentFuture(Optional.of(mock(NormalizedNode.class)))).when(netconfService)
191             .getConfig(JUKEBOX_IID);
192         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
193         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
194             .replace(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, JUKEBOX_WITH_BANDS, Optional.empty());
195
196         new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService, null)
197             .putData(JUKEBOX_IID, JUKEBOX_WITH_BANDS, null);
198         verify(netconfService).getConfig(JUKEBOX_IID);
199         verify(netconfService).replace(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, JUKEBOX_WITH_BANDS,
200             Optional.empty());
201     }
202
203     @Override
204     RestconfStrategy testPatchDataReplaceMergeAndRemoveStrategy() {
205         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
206             .remove(LogicalDatastoreType.CONFIGURATION, ARTIST_IID);
207         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
208             // FIXME: exact match
209             .replace(any(), any(), any(), any());
210         return new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService, null);
211     }
212
213     @Override
214     RestconfStrategy testPatchDataCreateAndDeleteStrategy() {
215         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
216             .create(LogicalDatastoreType.CONFIGURATION, PLAYER_IID, EMPTY_JUKEBOX, Optional.empty());
217         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
218             .delete(LogicalDatastoreType.CONFIGURATION, CREATE_AND_DELETE_TARGET);
219         return new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService, null);
220     }
221
222     @Override
223     RestconfStrategy testPatchMergePutContainerStrategy() {
224         return new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService, null);
225     }
226
227     @Override
228     RestconfStrategy deleteNonexistentDataTestStrategy() {
229         doReturn(Futures.immediateFailedFuture(
230             new TransactionCommitFailedException("Commit of transaction " + this + " failed",
231                 new NetconfDocumentedException("id", ErrorType.RPC, ErrorTag.DATA_MISSING, ErrorSeverity.ERROR))))
232             .when(netconfService).commit();
233         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
234             .delete(LogicalDatastoreType.CONFIGURATION, CREATE_AND_DELETE_TARGET);
235         return new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService, null);
236     }
237
238     @Override
239     void assertTestDeleteNonexistentData(final PatchStatusContext status) {
240         final var globalErrors = status.globalErrors();
241         assertEquals(1, globalErrors.size());
242         final var globalError = globalErrors.get(0);
243         assertEquals(ErrorType.PROTOCOL, globalError.getErrorType());
244         assertEquals(ErrorTag.DATA_MISSING, globalError.getErrorTag());
245     }
246
247     @Override
248     RestconfStrategy readDataConfigTestStrategy() {
249         doReturn(immediateFluentFuture(Optional.of(DATA_3))).when(netconfService).getConfig(PATH);
250         return new NetconfRestconfStrategy(mockSchemaContext, netconfService, null);
251     }
252
253     @Override
254     RestconfStrategy readAllHavingOnlyConfigTestStrategy() {
255         doReturn(immediateFluentFuture(Optional.of(DATA_3))).when(netconfService).getConfig(PATH);
256         doReturn(immediateFluentFuture(Optional.empty())).when(netconfService).get(PATH);
257         return new NetconfRestconfStrategy(mockSchemaContext, netconfService, null);
258     }
259
260     @Override
261     RestconfStrategy readAllHavingOnlyNonConfigTestStrategy() {
262         doReturn(immediateFluentFuture(Optional.of(DATA_2))).when(netconfService).get(PATH_2);
263         doReturn(immediateFluentFuture(Optional.empty())).when(netconfService).getConfig(PATH_2);
264         return new NetconfRestconfStrategy(mockSchemaContext, netconfService, null);
265     }
266
267     @Override
268     RestconfStrategy readDataNonConfigTestStrategy() {
269         doReturn(immediateFluentFuture(Optional.of(DATA_2))).when(netconfService).get(PATH_2);
270         return new NetconfRestconfStrategy(mockSchemaContext, netconfService, null);
271     }
272
273     @Override
274     RestconfStrategy readContainerDataAllTestStrategy() {
275         doReturn(immediateFluentFuture(Optional.of(DATA_3))).when(netconfService).getConfig(PATH);
276         doReturn(immediateFluentFuture(Optional.of(DATA_4))).when(netconfService).get(PATH);
277         return new NetconfRestconfStrategy(mockSchemaContext, netconfService, null);
278     }
279
280     @Override
281     RestconfStrategy readContainerDataConfigNoValueOfContentTestStrategy() {
282         doReturn(immediateFluentFuture(Optional.of(DATA_3))).when(netconfService).getConfig(PATH);
283         doReturn(immediateFluentFuture(Optional.of(DATA_4))).when(netconfService).get(PATH);
284         return new NetconfRestconfStrategy(mockSchemaContext, netconfService, null);
285     }
286
287     @Override
288     RestconfStrategy readListDataAllTestStrategy() {
289         doReturn(immediateFluentFuture(Optional.of(LIST_DATA))).when(netconfService).get(PATH_3);
290         doReturn(immediateFluentFuture(Optional.of(LIST_DATA_2))).when(netconfService).getConfig(PATH_3);
291         return new NetconfRestconfStrategy(mockSchemaContext, netconfService, null);
292     }
293
294     @Override
295     RestconfStrategy readOrderedListDataAllTestStrategy() {
296         doReturn(immediateFluentFuture(Optional.of(ORDERED_MAP_NODE_1))).when(netconfService).get(PATH_3);
297         doReturn(immediateFluentFuture(Optional.of(ORDERED_MAP_NODE_2))).when(netconfService).getConfig(PATH_3);
298         return new NetconfRestconfStrategy(mockSchemaContext, netconfService, null);
299     }
300
301     @Override
302     RestconfStrategy readUnkeyedListDataAllTestStrategy() {
303         doReturn(immediateFluentFuture(Optional.of(UNKEYED_LIST_NODE_1))).when(netconfService).get(PATH_3);
304         doReturn(immediateFluentFuture(Optional.of(UNKEYED_LIST_NODE_2))).when(netconfService).getConfig(PATH_3);
305         return new NetconfRestconfStrategy(mockSchemaContext, netconfService, null);
306     }
307
308     @Override
309     RestconfStrategy readLeafListDataAllTestStrategy() {
310         doReturn(immediateFluentFuture(Optional.of(LEAF_SET_NODE_1))).when(netconfService)
311             .get(LEAF_SET_NODE_PATH);
312         doReturn(immediateFluentFuture(Optional.of(LEAF_SET_NODE_2))).when(netconfService)
313             .getConfig(LEAF_SET_NODE_PATH);
314         return new NetconfRestconfStrategy(mockSchemaContext, netconfService, null);
315     }
316
317     @Override
318     RestconfStrategy readOrderedLeafListDataAllTestStrategy() {
319         doReturn(immediateFluentFuture(Optional.of(ORDERED_LEAF_SET_NODE_1))).when(netconfService)
320             .get(LEAF_SET_NODE_PATH);
321         doReturn(immediateFluentFuture(Optional.of(ORDERED_LEAF_SET_NODE_2))).when(netconfService)
322             .getConfig(LEAF_SET_NODE_PATH);
323         return new NetconfRestconfStrategy(mockSchemaContext, netconfService, null);
324     }
325
326     @Override
327     RestconfStrategy readDataWrongPathOrNoContentTestStrategy() {
328         doReturn(immediateFluentFuture(Optional.empty())).when(netconfService).getConfig(PATH_2);
329         return new NetconfRestconfStrategy(mockSchemaContext, netconfService, null);
330     }
331 }