Migrate users of YangInstanceIdentifier.empty()
[netconf.git] / restconf / restconf-nb / src / test / java / org / opendaylight / restconf / nb / rfc8040 / rests / utils / PutDataTransactionUtilTest.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. 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.utils;
9
10 import static org.junit.Assert.assertThrows;
11 import static org.mockito.Mockito.doNothing;
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.immediateFalseFluentFuture;
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.CommitInfo;
26 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
27 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
28 import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
29 import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
30 import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
31 import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult;
32 import org.opendaylight.netconf.dom.api.NetconfDataTreeService;
33 import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
34 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
35 import org.opendaylight.restconf.nb.rfc8040.TestRestconfUtils;
36 import org.opendaylight.restconf.nb.rfc8040.WriteDataParams;
37 import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload;
38 import org.opendaylight.restconf.nb.rfc8040.rests.services.impl.RestconfDataServiceImpl;
39 import org.opendaylight.restconf.nb.rfc8040.rests.transactions.MdsalRestconfStrategy;
40 import org.opendaylight.restconf.nb.rfc8040.rests.transactions.NetconfRestconfStrategy;
41 import org.opendaylight.yangtools.yang.common.QName;
42 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
43 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
44 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
45 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
46 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
47 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
48 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
49 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
50 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
51 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
52 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
53
54 @RunWith(MockitoJUnitRunner.StrictStubs.class)
55 public class PutDataTransactionUtilTest {
56     private static final String PATH_FOR_NEW_SCHEMA_CONTEXT = "/jukebox";
57
58     @Mock
59     private DOMDataTreeReadWriteTransaction readWrite;
60     @Mock
61     private DOMDataTreeReadTransaction read;
62     @Mock
63     private DOMDataTreeWriteTransaction write;
64     @Mock
65     private DOMDataBroker mockDataBroker;
66     @Mock
67     private NetconfDataTreeService netconfService;
68
69     private LeafNode<?> buildLeaf;
70     private ContainerNode buildBaseCont;
71     private ContainerNode buildBaseContWithList;
72     private MapEntryNode buildListEntry;
73     private EffectiveModelContext schema;
74     private YangInstanceIdentifier iid;
75     private YangInstanceIdentifier iid2;
76     private YangInstanceIdentifier iid3;
77
78     @Before
79     public void setUp() throws Exception {
80         schema =
81                 YangParserTestUtils.parseYangFiles(TestRestconfUtils.loadFiles(PATH_FOR_NEW_SCHEMA_CONTEXT));
82
83         final QName baseQName = QName.create("http://example.com/ns/example-jukebox", "2015-04-04", "jukebox");
84         final QName containerQname = QName.create(baseQName, "player");
85         final QName leafQname = QName.create(baseQName, "gap");
86         final QName listQname = QName.create(baseQName, "playlist");
87         final QName listKeyQname = QName.create(baseQName, "name");
88
89         final NodeIdentifierWithPredicates nodeWithKey =
90                 NodeIdentifierWithPredicates.of(listQname, listKeyQname, "name of band");
91         final NodeIdentifierWithPredicates nodeWithKey2 =
92                 NodeIdentifierWithPredicates.of(listQname, listKeyQname, "name of band 2");
93
94         iid = YangInstanceIdentifier.builder()
95                 .node(baseQName)
96                 .node(containerQname)
97                 .node(leafQname)
98                 .build();
99
100         iid2 = YangInstanceIdentifier.builder()
101                 .node(baseQName)
102                 .build();
103
104         iid3 = YangInstanceIdentifier.builder()
105                 .node(baseQName)
106                 .node(listQname)
107                 .node(nodeWithKey)
108                 .build();
109
110         buildLeaf = Builders.leafBuilder()
111                 .withNodeIdentifier(new NodeIdentifier(leafQname))
112                 .withValue(0.2)
113                 .build();
114         final ContainerNode buildPlayerCont = Builders.containerBuilder()
115                 .withNodeIdentifier(new NodeIdentifier(containerQname))
116                 .withChild(buildLeaf)
117                 .build();
118         buildBaseCont = Builders.containerBuilder()
119                 .withNodeIdentifier(new NodeIdentifier(baseQName))
120                 .withChild(buildPlayerCont)
121                 .build();
122         final LeafNode<Object> content = Builders.leafBuilder()
123                 .withNodeIdentifier(new NodeIdentifier(QName.create(baseQName, "name")))
124                 .withValue("name of band")
125                 .build();
126         final LeafNode<Object> content2 = Builders.leafBuilder()
127                 .withNodeIdentifier(new NodeIdentifier(QName.create(baseQName, "description")))
128                 .withValue("band description")
129                 .build();
130         buildListEntry = Builders.mapEntryBuilder()
131                 .withNodeIdentifier(nodeWithKey)
132                 .withChild(content)
133                 .withChild(content2)
134                 .build();
135         final LeafNode<Object> content3 = Builders.leafBuilder()
136                 .withNodeIdentifier(new NodeIdentifier(QName.create(baseQName, "name")))
137                 .withValue("name of band 2")
138                 .build();
139         final LeafNode<Object> content4 = Builders.leafBuilder()
140                 .withNodeIdentifier(new NodeIdentifier(QName.create(baseQName, "description")))
141                 .withValue("band description 2")
142                 .build();
143         final MapEntryNode buildListEntry2 = Builders.mapEntryBuilder()
144                 .withNodeIdentifier(nodeWithKey2)
145                 .withChild(content3)
146                 .withChild(content4)
147                 .build();
148         final MapNode buildList = Builders.mapBuilder()
149                 .withNodeIdentifier(new NodeIdentifier(listQname))
150                 .withChild(buildListEntry)
151                 .withChild(buildListEntry2)
152                 .build();
153         buildBaseContWithList = Builders.containerBuilder()
154                 .withNodeIdentifier(new NodeIdentifier(baseQName))
155                 .withChild(buildList)
156                 .build();
157
158         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).lock();
159         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).unlock();
160     }
161
162     @Test
163     public void testValidInputData() {
164         RestconfDataServiceImpl.validInputData(true, NormalizedNodePayload.of(
165             InstanceIdentifierContext.ofLocalPath(schema, iid), buildLeaf));
166     }
167
168     @Test
169     public void testValidTopLevelNodeName() {
170         RestconfDataServiceImpl.validTopLevelNodeName(iid, NormalizedNodePayload.of(
171             InstanceIdentifierContext.ofLocalPath(schema, iid), buildLeaf));
172         RestconfDataServiceImpl.validTopLevelNodeName(iid2, NormalizedNodePayload.of(
173             InstanceIdentifierContext.ofLocalPath(schema, iid2), buildBaseCont));
174     }
175
176     @Test
177     public void testValidTopLevelNodeNamePathEmpty() {
178         final InstanceIdentifierContext iidContext = InstanceIdentifierContext.ofLocalPath(schema, iid);
179         final NormalizedNodePayload payload = NormalizedNodePayload.of(iidContext, buildLeaf);
180
181         // FIXME: more asserts
182         assertThrows(RestconfDocumentedException.class,
183             () -> RestconfDataServiceImpl.validTopLevelNodeName(YangInstanceIdentifier.of(), payload));
184     }
185
186     @Test
187     public void testValidTopLevelNodeNameWrongTopIdentifier() {
188         final InstanceIdentifierContext iidContext = InstanceIdentifierContext.ofLocalPath(schema, iid);
189         final NormalizedNodePayload payload = NormalizedNodePayload.of(iidContext, buildLeaf);
190
191         // FIXME: more asserts
192         assertThrows(RestconfDocumentedException.class,
193             () -> RestconfDataServiceImpl.validTopLevelNodeName(iid.getAncestor(1), payload));
194     }
195
196     @Test
197     public void testValidateListKeysEqualityInPayloadAndUri() {
198         final InstanceIdentifierContext iidContext = InstanceIdentifierContext.ofLocalPath(schema, iid3);
199         final NormalizedNodePayload payload = NormalizedNodePayload.of(iidContext, buildListEntry);
200         RestconfDataServiceImpl.validateListKeysEqualityInPayloadAndUri(payload);
201     }
202
203     @Test
204     public void testPutContainerData() {
205         final InstanceIdentifierContext iidContext = InstanceIdentifierContext.ofLocalPath(schema, iid2);
206         final NormalizedNodePayload payload = NormalizedNodePayload.of(iidContext, buildBaseCont);
207
208         doReturn(readWrite).when(mockDataBroker).newReadWriteTransaction();
209         doReturn(read).when(mockDataBroker).newReadOnlyTransaction();
210         doReturn(immediateFalseFluentFuture()).when(read).exists(LogicalDatastoreType.CONFIGURATION, iid2);
211         doNothing().when(readWrite).put(LogicalDatastoreType.CONFIGURATION, iid2, payload.getData());
212         doReturn(CommitInfo.emptyFluentFuture()).when(readWrite).commit();
213
214         PutDataTransactionUtil.putData(payload, schema, new MdsalRestconfStrategy(mockDataBroker),
215             WriteDataParams.empty());
216         verify(read).exists(LogicalDatastoreType.CONFIGURATION, iid2);
217         verify(readWrite).put(LogicalDatastoreType.CONFIGURATION, iid2, payload.getData());
218     }
219
220     @Test
221     public void testPutCreateContainerData() {
222         final InstanceIdentifierContext iidContext = InstanceIdentifierContext.ofLocalPath(schema, iid2);
223         final NormalizedNodePayload payload = NormalizedNodePayload.of(iidContext, buildBaseCont);
224
225         doReturn(immediateFluentFuture(Optional.empty())).when(netconfService).getConfig(iid2);
226         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
227         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
228             .replace(LogicalDatastoreType.CONFIGURATION, iid2, payload.getData(), Optional.empty());
229
230         PutDataTransactionUtil.putData(payload, schema, new NetconfRestconfStrategy(netconfService),
231             WriteDataParams.empty());
232         verify(netconfService).lock();
233         verify(netconfService).getConfig(iid2);
234         verify(netconfService).replace(LogicalDatastoreType.CONFIGURATION, iid2, payload.getData(), Optional.empty());
235     }
236
237     @Test
238     public void testPutReplaceContainerData() {
239         final InstanceIdentifierContext iidContext = InstanceIdentifierContext.ofLocalPath(schema, iid2);
240         final NormalizedNodePayload payload = NormalizedNodePayload.of(iidContext, buildBaseCont);
241
242         doReturn(immediateFluentFuture(Optional.of(mock(NormalizedNode.class)))).when(netconfService).getConfig(iid2);
243         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
244         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
245             .replace(LogicalDatastoreType.CONFIGURATION, iid2, payload.getData(), Optional.empty());
246
247         PutDataTransactionUtil.putData(payload, schema, new NetconfRestconfStrategy(netconfService),
248             WriteDataParams.empty());
249         verify(netconfService).getConfig(iid2);
250         verify(netconfService).replace(LogicalDatastoreType.CONFIGURATION, iid2, payload.getData(), Optional.empty());
251     }
252
253     @Test
254     public void testPutLeafData() {
255         final InstanceIdentifierContext iidContext = InstanceIdentifierContext.ofLocalPath(schema, iid);
256         final NormalizedNodePayload payload = NormalizedNodePayload.of(iidContext, buildLeaf);
257
258         doReturn(readWrite).when(mockDataBroker).newReadWriteTransaction();
259         doReturn(read).when(mockDataBroker).newReadOnlyTransaction();
260         doReturn(immediateFalseFluentFuture()).when(read).exists(LogicalDatastoreType.CONFIGURATION, iid);
261         doNothing().when(readWrite).put(LogicalDatastoreType.CONFIGURATION, iid, payload.getData());
262         doReturn(CommitInfo.emptyFluentFuture()).when(readWrite).commit();
263
264         PutDataTransactionUtil.putData(payload, schema, new MdsalRestconfStrategy(mockDataBroker),
265             WriteDataParams.empty());
266         verify(read).exists(LogicalDatastoreType.CONFIGURATION, iid);
267         verify(readWrite).put(LogicalDatastoreType.CONFIGURATION, iid, payload.getData());
268     }
269
270     @Test
271     public void testPutCreateLeafData() {
272         final InstanceIdentifierContext iidContext = InstanceIdentifierContext.ofLocalPath(schema, iid);
273         final NormalizedNodePayload payload = NormalizedNodePayload.of(iidContext, buildLeaf);
274
275         doReturn(immediateFluentFuture(Optional.empty())).when(netconfService).getConfig(iid);
276         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
277         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
278             .replace(LogicalDatastoreType.CONFIGURATION, iid, payload.getData(), Optional.empty());
279
280         PutDataTransactionUtil.putData(payload, schema, new NetconfRestconfStrategy(netconfService),
281             WriteDataParams.empty());
282         verify(netconfService).getConfig(iid);
283         verify(netconfService).replace(LogicalDatastoreType.CONFIGURATION, iid, payload.getData(), Optional.empty());
284     }
285
286     @Test
287     public void testPutReplaceLeafData() {
288         final InstanceIdentifierContext iidContext = InstanceIdentifierContext.ofLocalPath(schema, iid);
289         final NormalizedNodePayload payload = NormalizedNodePayload.of(iidContext, buildLeaf);
290
291         doReturn(immediateFluentFuture(Optional.of(mock(NormalizedNode.class)))).when(netconfService).getConfig(iid);
292         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
293         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
294             .replace(LogicalDatastoreType.CONFIGURATION, iid, payload.getData(), Optional.empty());
295
296         PutDataTransactionUtil.putData(payload, schema, new NetconfRestconfStrategy(netconfService),
297             WriteDataParams.empty());
298         verify(netconfService).getConfig(iid);
299         verify(netconfService).replace(LogicalDatastoreType.CONFIGURATION, iid, payload.getData(), Optional.empty());
300     }
301
302     @Test
303     public void testPutListData() {
304         final InstanceIdentifierContext iidContext = InstanceIdentifierContext.ofLocalPath(schema, iid2);
305         final NormalizedNodePayload payload = NormalizedNodePayload.of(iidContext, buildBaseContWithList);
306
307         doReturn(readWrite).when(mockDataBroker).newReadWriteTransaction();
308         doReturn(read).when(mockDataBroker).newReadOnlyTransaction();
309         doReturn(immediateFalseFluentFuture())
310                 .when(read).exists(LogicalDatastoreType.CONFIGURATION, iid2);
311         doNothing().when(readWrite).put(LogicalDatastoreType.CONFIGURATION, iid2, payload.getData());
312         doReturn(CommitInfo.emptyFluentFuture()).when(readWrite).commit();
313         PutDataTransactionUtil.putData(payload, schema, new MdsalRestconfStrategy(mockDataBroker),
314             WriteDataParams.empty());
315         verify(read).exists(LogicalDatastoreType.CONFIGURATION, iid2);
316         verify(readWrite).put(LogicalDatastoreType.CONFIGURATION, iid2, payload.getData());
317     }
318
319     @Test
320     public void testPutCreateListData() {
321         final InstanceIdentifierContext iidContext = InstanceIdentifierContext.ofLocalPath(schema, iid2);
322         final NormalizedNodePayload payload = NormalizedNodePayload.of(iidContext, buildBaseContWithList);
323
324         doReturn(immediateFluentFuture(Optional.empty())).when(netconfService)
325                 .getConfig(iid2);
326         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
327         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
328             .replace(LogicalDatastoreType.CONFIGURATION, iid2, payload.getData(), Optional.empty());
329
330         PutDataTransactionUtil.putData(payload, schema, new NetconfRestconfStrategy(netconfService),
331             WriteDataParams.empty());
332         verify(netconfService).getConfig(iid2);
333         verify(netconfService).replace(LogicalDatastoreType.CONFIGURATION, iid2,
334                 payload.getData(), Optional.empty());
335     }
336
337     @Test
338     public void testPutReplaceListData() {
339         final InstanceIdentifierContext iidContext = InstanceIdentifierContext.ofLocalPath(schema, iid2);
340         final NormalizedNodePayload payload = NormalizedNodePayload.of(iidContext, buildBaseContWithList);
341
342         doReturn(immediateFluentFuture(Optional.of(mock(NormalizedNode.class)))).when(netconfService)
343                 .getConfig(iid2);
344         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
345         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
346             .replace(LogicalDatastoreType.CONFIGURATION,
347                 iid2, payload.getData(), Optional.empty());
348
349         PutDataTransactionUtil.putData(payload, schema, new NetconfRestconfStrategy(netconfService),
350             WriteDataParams.empty());
351         verify(netconfService).getConfig(iid2);
352         verify(netconfService).replace(LogicalDatastoreType.CONFIGURATION, iid2, payload.getData(), Optional.empty());
353     }
354 }