2 * Copyright (c) 2016 Cisco Systems, Inc. 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.rfc8040.rests.utils;
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNull;
12 import static org.junit.Assert.assertTrue;
13 import static org.mockito.Mockito.doReturn;
14 import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateFluentFuture;
16 import com.google.common.collect.ImmutableList;
17 import java.util.Optional;
18 import org.eclipse.jdt.annotation.NonNull;
19 import org.eclipse.jdt.annotation.Nullable;
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.dom.api.DOMDataBroker;
27 import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
28 import org.opendaylight.netconf.dom.api.NetconfDataTreeService;
29 import org.opendaylight.restconf.nb.rfc8040.ContentParam;
30 import org.opendaylight.restconf.nb.rfc8040.TestRestconfUtils;
31 import org.opendaylight.restconf.nb.rfc8040.WithDefaultsParam;
32 import org.opendaylight.restconf.nb.rfc8040.rests.transactions.MdsalRestconfStrategy;
33 import org.opendaylight.restconf.nb.rfc8040.rests.transactions.NetconfRestconfStrategy;
34 import org.opendaylight.restconf.nb.rfc8040.rests.transactions.RestconfStrategy;
35 import org.opendaylight.yangtools.yang.common.QName;
36 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
37 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
38 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
39 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
40 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
41 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
42 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
43 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
44 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
45 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
46 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
47 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
48 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
50 @RunWith(MockitoJUnitRunner.StrictStubs.class)
51 public class ReadDataTransactionUtilTest {
52 private static final TestData DATA = new TestData();
53 private static final NodeIdentifier NODE_IDENTIFIER =
54 new NodeIdentifier(QName.create("ns", "2016-02-28", "container"));
56 private RestconfStrategy mdsalStrategy;
57 private RestconfStrategy netconfStrategy;
59 private NetconfDataTreeService netconfService;
61 private DOMDataTreeReadTransaction read;
63 private EffectiveModelContext mockSchemaContext;
65 private DOMDataBroker mockDataBroker;
66 private EffectiveModelContext schemaContext;
69 public void setUp() throws Exception {
70 // FIXME: these tests need to be parameterized somehow. The trouble is we need mocking before we invoke
71 // the strategy. This needs some more thought.
72 doReturn(read).when(mockDataBroker).newReadOnlyTransaction();
73 mdsalStrategy = new MdsalRestconfStrategy(mockDataBroker);
74 netconfStrategy = new NetconfRestconfStrategy(netconfService);
75 schemaContext = YangParserTestUtils.parseYangFiles(
76 TestRestconfUtils.loadFiles("/modules"));
80 public void readDataConfigTest() {
81 doReturn(immediateFluentFuture(Optional.of(DATA.data3))).when(read)
82 .read(LogicalDatastoreType.CONFIGURATION, DATA.path);
83 doReturn(immediateFluentFuture(Optional.of(DATA.data3))).when(netconfService).getConfig(DATA.path);
84 NormalizedNode normalizedNode = readData(ContentParam.CONFIG, DATA.path, mdsalStrategy);
85 assertEquals(DATA.data3, normalizedNode);
87 normalizedNode = readData(ContentParam.CONFIG, DATA.path, netconfStrategy);
88 assertEquals(DATA.data3, normalizedNode);
92 public void readAllHavingOnlyConfigTest() {
93 doReturn(immediateFluentFuture(Optional.of(DATA.data3))).when(read)
94 .read(LogicalDatastoreType.CONFIGURATION, DATA.path);
95 doReturn(immediateFluentFuture(Optional.empty())).when(read)
96 .read(LogicalDatastoreType.OPERATIONAL, DATA.path);
97 doReturn(immediateFluentFuture(Optional.of(DATA.data3))).when(netconfService).getConfig(DATA.path);
98 doReturn(immediateFluentFuture(Optional.empty())).when(netconfService).get(DATA.path);
99 NormalizedNode normalizedNode = readData(ContentParam.ALL, DATA.path, mdsalStrategy);
100 assertEquals(DATA.data3, normalizedNode);
102 normalizedNode = readData(ContentParam.ALL, DATA.path, netconfStrategy);
103 assertEquals(DATA.data3, normalizedNode);
107 public void readAllHavingOnlyNonConfigTest() {
108 doReturn(immediateFluentFuture(Optional.of(DATA.data2))).when(read)
109 .read(LogicalDatastoreType.OPERATIONAL, DATA.path2);
110 doReturn(immediateFluentFuture(Optional.empty())).when(read)
111 .read(LogicalDatastoreType.CONFIGURATION, DATA.path2);
112 doReturn(immediateFluentFuture(Optional.of(DATA.data2))).when(netconfService).get(DATA.path2);
113 doReturn(immediateFluentFuture(Optional.empty())).when(netconfService).getConfig(DATA.path2);
114 NormalizedNode normalizedNode = readData(ContentParam.ALL, DATA.path2, mdsalStrategy);
115 assertEquals(DATA.data2, normalizedNode);
117 normalizedNode = readData(ContentParam.ALL, DATA.path2, netconfStrategy);
118 assertEquals(DATA.data2, normalizedNode);
122 public void readDataNonConfigTest() {
123 doReturn(immediateFluentFuture(Optional.of(DATA.data2))).when(read)
124 .read(LogicalDatastoreType.OPERATIONAL, DATA.path2);
125 doReturn(immediateFluentFuture(Optional.of(DATA.data2))).when(netconfService).get(DATA.path2);
126 NormalizedNode normalizedNode = readData(ContentParam.NONCONFIG, DATA.path2, mdsalStrategy);
127 assertEquals(DATA.data2, normalizedNode);
129 normalizedNode = readData(ContentParam.NONCONFIG, DATA.path2, netconfStrategy);
130 assertEquals(DATA.data2, normalizedNode);
134 public void readContainerDataAllTest() {
135 doReturn(immediateFluentFuture(Optional.of(DATA.data3))).when(read)
136 .read(LogicalDatastoreType.CONFIGURATION, DATA.path);
137 doReturn(immediateFluentFuture(Optional.of(DATA.data4))).when(read)
138 .read(LogicalDatastoreType.OPERATIONAL, DATA.path);
139 doReturn(immediateFluentFuture(Optional.of(DATA.data3))).when(netconfService).getConfig(DATA.path);
140 doReturn(immediateFluentFuture(Optional.of(DATA.data4))).when(netconfService).get(DATA.path);
141 final ContainerNode checkingData = Builders
143 .withNodeIdentifier(NODE_IDENTIFIER)
144 .withChild(DATA.contentLeaf)
145 .withChild(DATA.contentLeaf2)
147 NormalizedNode normalizedNode = readData(ContentParam.ALL, DATA.path, mdsalStrategy);
148 assertEquals(checkingData, normalizedNode);
150 normalizedNode = readData(ContentParam.ALL, DATA.path, netconfStrategy);
151 assertEquals(checkingData, normalizedNode);
155 public void readLeafWithDefaultParameters() {
156 final LeafNode leafNode = Builders.leafBuilder().withNodeIdentifier(
157 new NodeIdentifier(QName.create(DATA.base, "exampleLeaf"))).withValue("i am leaf").build();
159 final ContainerNode content = Builders.containerBuilder()
160 .withNodeIdentifier(new NodeIdentifier(QName.create(DATA.base, "cont")))
164 final YangInstanceIdentifier path = YangInstanceIdentifier.builder().node(content.getIdentifier()).build();
166 doReturn(immediateFluentFuture(Optional.of(content))).when(read)
167 .read(LogicalDatastoreType.CONFIGURATION, path);
168 doReturn(immediateFluentFuture(Optional.of(content))).when(read)
169 .read(LogicalDatastoreType.OPERATIONAL, path);
171 final NormalizedNode normalizedNode = ReadDataTransactionUtil.readData(
172 ContentParam.ALL, path, mdsalStrategy, WithDefaultsParam.TRIM, schemaContext);
173 assertEquals(content, normalizedNode);
177 public void readContainerWithDefaultParameters() {
178 final QName leafBool = QName.create(DATA.base, "leafBool");
179 final QName containerBool = QName.create(DATA.base, "containerBool");
180 final QName containerInt = QName.create(DATA.base, "containerInt");
181 final QName leafInt = QName.create(DATA.base, "leafInt");
182 final QName exampleList = QName.create(DATA.base, "exampleList");
183 final QName cont = QName.create(DATA.base, "cont");
185 final LeafNode leafNode = Builders.leafBuilder().withNodeIdentifier(
186 NodeIdentifier.create(leafBool))
187 .withValue(true).build();
188 final ContainerNode containerNode = Builders.containerBuilder().withNodeIdentifier(
189 NodeIdentifier.create(containerBool))
190 .withChild(leafNode).build();
191 final LeafNode leafNode1 = Builders.leafBuilder().withNodeIdentifier(
192 NodeIdentifier.create(leafInt))
193 .withValue(12).build();
194 final ContainerNode containerNode1 = Builders.containerBuilder().withNodeIdentifier(
195 NodeIdentifier.create(containerInt))
196 .withChild(leafNode1).build();
197 final MapEntryNode entryNode = Builders.mapEntryBuilder()
198 .withNodeIdentifier(YangInstanceIdentifier.NodeIdentifierWithPredicates.of(exampleList))
199 .withChild(containerNode)
200 .addChild(containerNode1).build();
201 final MapNode mapNode = Builders.mapBuilder().withNodeIdentifier(
202 NodeIdentifier.create(exampleList))
203 .withChild(entryNode).build();
204 final ContainerNode content = Builders.containerBuilder()
205 .withNodeIdentifier(new NodeIdentifier(cont))
206 .withChild(mapNode).build();
208 final YangInstanceIdentifier path = YangInstanceIdentifier.builder().node(cont).build();
210 doReturn(immediateFluentFuture(Optional.of(content))).when(read)
211 .read(LogicalDatastoreType.CONFIGURATION, path);
212 doReturn(immediateFluentFuture(Optional.of(content))).when(read)
213 .read(LogicalDatastoreType.OPERATIONAL, path);
215 final NormalizedNode normalizedNode = ReadDataTransactionUtil.readData(
216 ContentParam.ALL, path, mdsalStrategy, WithDefaultsParam.TRIM, schemaContext);
218 //assertEquals(content, normalizedNode); is not used because two duplicated child nodes are created in mapEntryNode
219 assertTrue(normalizedNode instanceof ContainerNode);
220 assertEquals(((MapNode) ((ContainerNode) normalizedNode).getChildByArg(
221 NodeIdentifier.create(exampleList))).getChildByArg(
222 YangInstanceIdentifier.NodeIdentifierWithPredicates.of(exampleList)),
223 ((MapNode) content.getChildByArg(
224 NodeIdentifier.create(exampleList))).childByArg(
225 YangInstanceIdentifier.NodeIdentifierWithPredicates.of(exampleList)));
229 public void readLeafInListWithDefaultParameters() {
230 final QName leafInList = QName.create(DATA.base, "leafInList");
231 final QName exampleList = QName.create(DATA.base, "exampleList");
232 final QName container = QName.create(DATA.base, "cont");
234 final LeafNode leafNode = Builders.leafBuilder().withNodeIdentifier(
235 NodeIdentifier.create(leafInList))
236 .withValue("I am leaf in list").build();
238 final MapEntryNode entryNode = Builders.mapEntryBuilder()
240 YangInstanceIdentifier.NodeIdentifierWithPredicates.of(exampleList))
241 .addChild(leafNode).build();
243 final MapNode mapNode = Builders.mapBuilder().withNodeIdentifier(
244 NodeIdentifier.create(QName.create(DATA.base, "exampleList")))
245 .withChild(entryNode).build();
247 final ContainerNode content = Builders.containerBuilder()
248 .withNodeIdentifier(new NodeIdentifier(container))
249 .withChild(mapNode).build();
251 final YangInstanceIdentifier path = YangInstanceIdentifier.builder().node(container).build();
253 doReturn(immediateFluentFuture(Optional.of(content))).when(read)
254 .read(LogicalDatastoreType.CONFIGURATION, path);
255 doReturn(immediateFluentFuture(Optional.of(content))).when(read)
256 .read(LogicalDatastoreType.OPERATIONAL, path);
258 final NormalizedNode normalizedNode = ReadDataTransactionUtil.readData(
259 ContentParam.ALL, path, mdsalStrategy, WithDefaultsParam.TRIM, schemaContext);
260 assertEquals(content, normalizedNode);
264 public void readContainerDataConfigNoValueOfContentTest() {
265 doReturn(immediateFluentFuture(Optional.of(DATA.data3))).when(read)
266 .read(LogicalDatastoreType.CONFIGURATION, DATA.path);
267 doReturn(immediateFluentFuture(Optional.of(DATA.data4))).when(read)
268 .read(LogicalDatastoreType.OPERATIONAL, DATA.path);
269 doReturn(immediateFluentFuture(Optional.of(DATA.data3))).when(netconfService).getConfig(DATA.path);
270 doReturn(immediateFluentFuture(Optional.of(DATA.data4))).when(netconfService).get(DATA.path);
271 final ContainerNode checkingData = Builders
273 .withNodeIdentifier(NODE_IDENTIFIER)
274 .withChild(DATA.contentLeaf)
275 .withChild(DATA.contentLeaf2)
277 NormalizedNode normalizedNode = readData(ContentParam.ALL, DATA.path, mdsalStrategy);
278 assertEquals(checkingData, normalizedNode);
280 normalizedNode = readData(ContentParam.ALL, DATA.path, netconfStrategy);
281 assertEquals(checkingData, normalizedNode);
285 public void readListDataAllTest() {
286 doReturn(immediateFluentFuture(Optional.of(DATA.listData))).when(read)
287 .read(LogicalDatastoreType.OPERATIONAL, DATA.path3);
288 doReturn(immediateFluentFuture(Optional.of(DATA.listData2))).when(read)
289 .read(LogicalDatastoreType.CONFIGURATION, DATA.path3);
290 doReturn(immediateFluentFuture(Optional.of(DATA.listData))).when(netconfService).get(DATA.path3);
291 doReturn(immediateFluentFuture(Optional.of(DATA.listData2))).when(netconfService).getConfig(DATA.path3);
292 final MapNode checkingData = Builders
294 .withNodeIdentifier(new NodeIdentifier(QName.create("ns", "2016-02-28", "list")))
295 .withChild(DATA.checkData)
297 NormalizedNode normalizedNode = readData(ContentParam.ALL, DATA.path3, mdsalStrategy);
298 assertEquals(checkingData, normalizedNode);
300 normalizedNode = readData(ContentParam.ALL, DATA.path3, netconfStrategy);
301 assertEquals(checkingData, normalizedNode);
305 public void readOrderedListDataAllTest() {
306 doReturn(immediateFluentFuture(Optional.of(DATA.orderedMapNode1))).when(read)
307 .read(LogicalDatastoreType.OPERATIONAL, DATA.path3);
308 doReturn(immediateFluentFuture(Optional.of(DATA.orderedMapNode2))).when(read)
309 .read(LogicalDatastoreType.CONFIGURATION, DATA.path3);
310 doReturn(immediateFluentFuture(Optional.of(DATA.orderedMapNode1))).when(netconfService).get(DATA.path3);
311 doReturn(immediateFluentFuture(Optional.of(DATA.orderedMapNode2))).when(netconfService)
312 .getConfig(DATA.path3);
313 final MapNode expectedData = Builders.orderedMapBuilder()
314 .withNodeIdentifier(new NodeIdentifier(DATA.listQname))
315 .withChild(DATA.checkData)
317 NormalizedNode normalizedNode = readData(ContentParam.ALL, DATA.path3,
319 assertEquals(expectedData, normalizedNode);
321 normalizedNode = readData(ContentParam.ALL, DATA.path3, netconfStrategy);
322 assertEquals(expectedData, normalizedNode);
326 public void readUnkeyedListDataAllTest() {
327 doReturn(immediateFluentFuture(Optional.of(DATA.unkeyedListNode1))).when(read)
328 .read(LogicalDatastoreType.OPERATIONAL, DATA.path3);
329 doReturn(immediateFluentFuture(Optional.of(DATA.unkeyedListNode2))).when(read)
330 .read(LogicalDatastoreType.CONFIGURATION, DATA.path3);
331 doReturn(immediateFluentFuture(Optional.of(DATA.unkeyedListNode1))).when(netconfService).get(DATA.path3);
332 doReturn(immediateFluentFuture(Optional.of(DATA.unkeyedListNode2))).when(netconfService)
333 .getConfig(DATA.path3);
334 final UnkeyedListNode expectedData = Builders.unkeyedListBuilder()
335 .withNodeIdentifier(new NodeIdentifier(DATA.listQname))
336 .withChild(Builders.unkeyedListEntryBuilder()
337 .withNodeIdentifier(new NodeIdentifier(DATA.listQname))
338 .withChild(DATA.unkeyedListEntryNode1.body().iterator().next())
339 .withChild(DATA.unkeyedListEntryNode2.body().iterator().next()).build()).build();
340 NormalizedNode normalizedNode = readData(ContentParam.ALL, DATA.path3, mdsalStrategy);
341 assertEquals(expectedData, normalizedNode);
343 normalizedNode = readData(ContentParam.ALL, DATA.path3, netconfStrategy);
344 assertEquals(expectedData, normalizedNode);
348 public void readLeafListDataAllTest() {
349 doReturn(immediateFluentFuture(Optional.of(DATA.leafSetNode1))).when(read)
350 .read(LogicalDatastoreType.OPERATIONAL, DATA.leafSetNodePath);
351 doReturn(immediateFluentFuture(Optional.of(DATA.leafSetNode2))).when(read)
352 .read(LogicalDatastoreType.CONFIGURATION, DATA.leafSetNodePath);
353 doReturn(immediateFluentFuture(Optional.of(DATA.leafSetNode1))).when(netconfService)
354 .get(DATA.leafSetNodePath);
355 doReturn(immediateFluentFuture(Optional.of(DATA.leafSetNode2))).when(netconfService)
356 .getConfig(DATA.leafSetNodePath);
357 final LeafSetNode<String> expectedData = Builders.<String>leafSetBuilder()
358 .withNodeIdentifier(new NodeIdentifier(DATA.leafListQname))
359 .withValue(ImmutableList.<LeafSetEntryNode<String>>builder()
360 .addAll(DATA.leafSetNode1.body())
361 .addAll(DATA.leafSetNode2.body())
364 NormalizedNode normalizedNode = readData(ContentParam.ALL, DATA.leafSetNodePath,
366 assertEquals(expectedData, normalizedNode);
368 normalizedNode = readData(ContentParam.ALL, DATA.leafSetNodePath, netconfStrategy);
369 assertEquals(expectedData, normalizedNode);
373 public void readOrderedLeafListDataAllTest() {
374 doReturn(immediateFluentFuture(Optional.of(DATA.orderedLeafSetNode1))).when(read)
375 .read(LogicalDatastoreType.OPERATIONAL, DATA.leafSetNodePath);
376 doReturn(immediateFluentFuture(Optional.of(DATA.orderedLeafSetNode2))).when(read)
377 .read(LogicalDatastoreType.CONFIGURATION, DATA.leafSetNodePath);
378 doReturn(immediateFluentFuture(Optional.of(DATA.orderedLeafSetNode1))).when(netconfService)
379 .get(DATA.leafSetNodePath);
380 doReturn(immediateFluentFuture(Optional.of(DATA.orderedLeafSetNode2))).when(netconfService)
381 .getConfig(DATA.leafSetNodePath);
382 final LeafSetNode<String> expectedData = Builders.<String>orderedLeafSetBuilder()
383 .withNodeIdentifier(new NodeIdentifier(DATA.leafListQname))
384 .withValue(ImmutableList.<LeafSetEntryNode<String>>builder()
385 .addAll(DATA.orderedLeafSetNode1.body())
386 .addAll(DATA.orderedLeafSetNode2.body())
389 NormalizedNode normalizedNode = readData(ContentParam.ALL, DATA.leafSetNodePath,
391 assertEquals(expectedData, normalizedNode);
393 normalizedNode = readData(ContentParam.ALL, DATA.leafSetNodePath, netconfStrategy);
394 assertEquals(expectedData, normalizedNode);
398 public void readDataWrongPathOrNoContentTest() {
399 doReturn(immediateFluentFuture(Optional.empty())).when(read)
400 .read(LogicalDatastoreType.CONFIGURATION, DATA.path2);
401 doReturn(immediateFluentFuture(Optional.empty())).when(netconfService).getConfig(DATA.path2);
402 NormalizedNode normalizedNode = readData(ContentParam.CONFIG, DATA.path2, mdsalStrategy);
403 assertNull(normalizedNode);
405 normalizedNode = readData(ContentParam.CONFIG, DATA.path2, netconfStrategy);
406 assertNull(normalizedNode);
410 * Read specific type of data from data store via transaction.
412 * @param content type of data to read (config, state, all)
413 * @param strategy {@link RestconfStrategy} - wrapper for variables
414 * @return {@link NormalizedNode}
416 private @Nullable NormalizedNode readData(final @NonNull ContentParam content,
417 final YangInstanceIdentifier path, final @NonNull RestconfStrategy strategy) {
418 return ReadDataTransactionUtil.readData(content, path, strategy, null, mockSchemaContext);