8755114fa7fc4db30dd5e119d4186f6ab1f28884
[netconf.git] / restconf / restconf-nb-rfc8040 / src / test / java / org / opendaylight / restconf / nb / rfc8040 / rests / utils / ReadDataTransactionUtilTest.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.assertEquals;
11 import static org.junit.Assert.assertFalse;
12 import static org.junit.Assert.assertNotNull;
13 import static org.junit.Assert.assertNull;
14 import static org.junit.Assert.assertSame;
15 import static org.junit.Assert.assertThrows;
16 import static org.junit.Assert.assertTrue;
17 import static org.mockito.Mockito.doReturn;
18 import static org.mockito.Mockito.mock;
19 import static org.mockito.Mockito.when;
20 import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateFluentFuture;
21
22 import com.google.common.collect.ImmutableList;
23 import java.util.List;
24 import java.util.Optional;
25 import java.util.Set;
26 import javax.ws.rs.core.MultivaluedHashMap;
27 import javax.ws.rs.core.UriInfo;
28 import org.eclipse.jdt.annotation.NonNull;
29 import org.eclipse.jdt.annotation.Nullable;
30 import org.junit.Before;
31 import org.junit.Test;
32 import org.junit.runner.RunWith;
33 import org.mockito.Mock;
34 import org.mockito.junit.MockitoJUnitRunner;
35 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
36 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
37 import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
38 import org.opendaylight.netconf.dom.api.NetconfDataTreeService;
39 import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
40 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
41 import org.opendaylight.restconf.common.errors.RestconfError;
42 import org.opendaylight.restconf.nb.rfc8040.ContentParameter;
43 import org.opendaylight.restconf.nb.rfc8040.DepthParameter;
44 import org.opendaylight.restconf.nb.rfc8040.WithDefaultsParameter;
45 import org.opendaylight.restconf.nb.rfc8040.legacy.QueryParameters;
46 import org.opendaylight.restconf.nb.rfc8040.rests.transactions.MdsalRestconfStrategy;
47 import org.opendaylight.restconf.nb.rfc8040.rests.transactions.NetconfRestconfStrategy;
48 import org.opendaylight.restconf.nb.rfc8040.rests.transactions.RestconfStrategy;
49 import org.opendaylight.yangtools.yang.common.ErrorTag;
50 import org.opendaylight.yangtools.yang.common.ErrorType;
51 import org.opendaylight.yangtools.yang.common.QName;
52 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
53 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
54 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
55 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
56 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
57 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
58 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
59 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
60 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
61 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
62 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
63 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
64
65 @RunWith(MockitoJUnitRunner.StrictStubs.class)
66 public class ReadDataTransactionUtilTest {
67
68     private static final TestData DATA = new TestData();
69     private static final NodeIdentifier NODE_IDENTIFIER =
70         new NodeIdentifier(QName.create("ns", "2016-02-28", "container"));
71
72     private RestconfStrategy mdsalStrategy;
73     private RestconfStrategy netconfStrategy;
74     @Mock
75     private NetconfDataTreeService netconfService;
76     @Mock
77     private InstanceIdentifierContext<ContainerSchemaNode> context;
78     @Mock
79     private DOMDataTreeReadTransaction read;
80     @Mock
81     private EffectiveModelContext schemaContext;
82     @Mock
83     private ContainerSchemaNode containerSchemaNode;
84     @Mock
85     private LeafSchemaNode containerChildNode;
86     private QName containerChildQName;
87
88     @Before
89     public void setUp() {
90         containerChildQName = QName.create("ns", "2016-02-28", "container-child");
91
92         when(context.getSchemaContext()).thenReturn(schemaContext);
93         when(context.getSchemaNode()).thenReturn(containerSchemaNode);
94         when(containerSchemaNode.getQName()).thenReturn(NODE_IDENTIFIER.getNodeType());
95         when(containerChildNode.getQName()).thenReturn(containerChildQName);
96         when(containerSchemaNode.dataChildByName(containerChildQName)).thenReturn(containerChildNode);
97
98         DOMDataBroker mockDataBroker = mock(DOMDataBroker.class);
99         doReturn(read).when(mockDataBroker).newReadOnlyTransaction();
100         mdsalStrategy = new MdsalRestconfStrategy(mockDataBroker);
101         netconfStrategy = new NetconfRestconfStrategy(netconfService);
102     }
103
104     @Test
105     public void readDataConfigTest() {
106         doReturn(immediateFluentFuture(Optional.of(DATA.data3))).when(read)
107                 .read(LogicalDatastoreType.CONFIGURATION, DATA.path);
108         doReturn(immediateFluentFuture(Optional.of(DATA.data3))).when(netconfService).getConfig(DATA.path);
109         NormalizedNode normalizedNode = readData(ContentParameter.CONFIG, DATA.path, mdsalStrategy);
110         assertEquals(DATA.data3, normalizedNode);
111
112         normalizedNode = readData(ContentParameter.CONFIG, DATA.path, netconfStrategy);
113         assertEquals(DATA.data3, normalizedNode);
114     }
115
116     @Test
117     public void readAllHavingOnlyConfigTest() {
118         doReturn(immediateFluentFuture(Optional.of(DATA.data3))).when(read)
119                 .read(LogicalDatastoreType.CONFIGURATION, DATA.path);
120         doReturn(immediateFluentFuture(Optional.empty())).when(read)
121                 .read(LogicalDatastoreType.OPERATIONAL, DATA.path);
122         doReturn(immediateFluentFuture(Optional.of(DATA.data3))).when(netconfService).getConfig(DATA.path);
123         doReturn(immediateFluentFuture(Optional.empty())).when(netconfService).get(DATA.path);
124         NormalizedNode normalizedNode = readData(ContentParameter.ALL, DATA.path, mdsalStrategy);
125         assertEquals(DATA.data3, normalizedNode);
126
127         normalizedNode = readData(ContentParameter.ALL, DATA.path, netconfStrategy);
128         assertEquals(DATA.data3, normalizedNode);
129     }
130
131     @Test
132     public void readAllHavingOnlyNonConfigTest() {
133         doReturn(immediateFluentFuture(Optional.of(DATA.data2))).when(read)
134                 .read(LogicalDatastoreType.OPERATIONAL, DATA.path2);
135         doReturn(immediateFluentFuture(Optional.empty())).when(read)
136                 .read(LogicalDatastoreType.CONFIGURATION, DATA.path2);
137         doReturn(immediateFluentFuture(Optional.of(DATA.data2))).when(netconfService).get(DATA.path2);
138         doReturn(immediateFluentFuture(Optional.empty())).when(netconfService).getConfig(DATA.path2);
139         NormalizedNode normalizedNode = readData(ContentParameter.ALL, DATA.path2, mdsalStrategy);
140         assertEquals(DATA.data2, normalizedNode);
141
142         normalizedNode = readData(ContentParameter.ALL, DATA.path2, netconfStrategy);
143         assertEquals(DATA.data2, normalizedNode);
144     }
145
146     @Test
147     public void readDataNonConfigTest() {
148         doReturn(immediateFluentFuture(Optional.of(DATA.data2))).when(read)
149                 .read(LogicalDatastoreType.OPERATIONAL, DATA.path2);
150         doReturn(immediateFluentFuture(Optional.of(DATA.data2))).when(netconfService).get(DATA.path2);
151         NormalizedNode normalizedNode = readData(ContentParameter.NONCONFIG, DATA.path2, mdsalStrategy);
152         assertEquals(DATA.data2, normalizedNode);
153
154         normalizedNode = readData(ContentParameter.NONCONFIG, DATA.path2, netconfStrategy);
155         assertEquals(DATA.data2, normalizedNode);
156     }
157
158     @Test
159     public void readContainerDataAllTest() {
160         doReturn(immediateFluentFuture(Optional.of(DATA.data3))).when(read)
161                 .read(LogicalDatastoreType.CONFIGURATION, DATA.path);
162         doReturn(immediateFluentFuture(Optional.of(DATA.data4))).when(read)
163                 .read(LogicalDatastoreType.OPERATIONAL, DATA.path);
164         doReturn(immediateFluentFuture(Optional.of(DATA.data3))).when(netconfService).getConfig(DATA.path);
165         doReturn(immediateFluentFuture(Optional.of(DATA.data4))).when(netconfService).get(DATA.path);
166         final ContainerNode checkingData = Builders
167                 .containerBuilder()
168                 .withNodeIdentifier(NODE_IDENTIFIER)
169                 .withChild(DATA.contentLeaf)
170                 .withChild(DATA.contentLeaf2)
171                 .build();
172         NormalizedNode normalizedNode = readData(ContentParameter.ALL, DATA.path, mdsalStrategy);
173         assertEquals(checkingData, normalizedNode);
174
175         normalizedNode = readData(ContentParameter.ALL, DATA.path, netconfStrategy);
176         assertEquals(checkingData, normalizedNode);
177     }
178
179     @Test
180     public void readContainerDataConfigNoValueOfContentTest() {
181         doReturn(immediateFluentFuture(Optional.of(DATA.data3))).when(read)
182                 .read(LogicalDatastoreType.CONFIGURATION, DATA.path);
183         doReturn(immediateFluentFuture(Optional.of(DATA.data4))).when(read)
184                 .read(LogicalDatastoreType.OPERATIONAL, DATA.path);
185         doReturn(immediateFluentFuture(Optional.of(DATA.data3))).when(netconfService).getConfig(DATA.path);
186         doReturn(immediateFluentFuture(Optional.of(DATA.data4))).when(netconfService).get(DATA.path);
187         final ContainerNode checkingData = Builders
188                 .containerBuilder()
189                 .withNodeIdentifier(NODE_IDENTIFIER)
190                 .withChild(DATA.contentLeaf)
191                 .withChild(DATA.contentLeaf2)
192                 .build();
193         NormalizedNode normalizedNode = readData(ContentParameter.ALL, DATA.path, mdsalStrategy);
194         assertEquals(checkingData, normalizedNode);
195
196         normalizedNode = readData(ContentParameter.ALL, DATA.path, netconfStrategy);
197         assertEquals(checkingData, normalizedNode);
198     }
199
200     @Test
201     public void readListDataAllTest() {
202         doReturn(immediateFluentFuture(Optional.of(DATA.listData))).when(read)
203                 .read(LogicalDatastoreType.OPERATIONAL, DATA.path3);
204         doReturn(immediateFluentFuture(Optional.of(DATA.listData2))).when(read)
205                 .read(LogicalDatastoreType.CONFIGURATION, DATA.path3);
206         doReturn(immediateFluentFuture(Optional.of(DATA.listData))).when(netconfService).get(DATA.path3);
207         doReturn(immediateFluentFuture(Optional.of(DATA.listData2))).when(netconfService).getConfig(DATA.path3);
208         final MapNode checkingData = Builders
209                 .mapBuilder()
210                 .withNodeIdentifier(new NodeIdentifier(QName.create("ns", "2016-02-28", "list")))
211                 .withChild(DATA.checkData)
212                 .build();
213         NormalizedNode normalizedNode = readData(ContentParameter.ALL, DATA.path3, mdsalStrategy);
214         assertEquals(checkingData, normalizedNode);
215
216         normalizedNode = readData(ContentParameter.ALL, DATA.path3, netconfStrategy);
217         assertEquals(checkingData, normalizedNode);
218     }
219
220     @Test
221     public void readOrderedListDataAllTest() {
222         doReturn(immediateFluentFuture(Optional.of(DATA.orderedMapNode1))).when(read)
223                 .read(LogicalDatastoreType.OPERATIONAL, DATA.path3);
224         doReturn(immediateFluentFuture(Optional.of(DATA.orderedMapNode2))).when(read)
225                 .read(LogicalDatastoreType.CONFIGURATION, DATA.path3);
226         doReturn(immediateFluentFuture(Optional.of(DATA.orderedMapNode1))).when(netconfService).get(DATA.path3);
227         doReturn(immediateFluentFuture(Optional.of(DATA.orderedMapNode2))).when(netconfService)
228                 .getConfig(DATA.path3);
229         final MapNode expectedData = Builders.orderedMapBuilder()
230                 .withNodeIdentifier(new NodeIdentifier(DATA.listQname))
231                 .withChild(DATA.checkData)
232                 .build();
233         NormalizedNode normalizedNode = readData(ContentParameter.ALL, DATA.path3,
234                 mdsalStrategy);
235         assertEquals(expectedData, normalizedNode);
236
237         normalizedNode = readData(ContentParameter.ALL, DATA.path3, netconfStrategy);
238         assertEquals(expectedData, normalizedNode);
239     }
240
241     @Test
242     public void readUnkeyedListDataAllTest() {
243         doReturn(immediateFluentFuture(Optional.of(DATA.unkeyedListNode1))).when(read)
244                 .read(LogicalDatastoreType.OPERATIONAL, DATA.path3);
245         doReturn(immediateFluentFuture(Optional.of(DATA.unkeyedListNode2))).when(read)
246                 .read(LogicalDatastoreType.CONFIGURATION, DATA.path3);
247         doReturn(immediateFluentFuture(Optional.of(DATA.unkeyedListNode1))).when(netconfService).get(DATA.path3);
248         doReturn(immediateFluentFuture(Optional.of(DATA.unkeyedListNode2))).when(netconfService)
249                 .getConfig(DATA.path3);
250         final UnkeyedListNode expectedData = Builders.unkeyedListBuilder()
251                 .withNodeIdentifier(new NodeIdentifier(DATA.listQname))
252                 .withChild(Builders.unkeyedListEntryBuilder()
253                         .withNodeIdentifier(new NodeIdentifier(DATA.listQname))
254                         .withChild(DATA.unkeyedListEntryNode1.body().iterator().next())
255                         .withChild(DATA.unkeyedListEntryNode2.body().iterator().next()).build()).build();
256         NormalizedNode normalizedNode = readData(ContentParameter.ALL, DATA.path3, mdsalStrategy);
257         assertEquals(expectedData, normalizedNode);
258
259         normalizedNode = readData(ContentParameter.ALL, DATA.path3, netconfStrategy);
260         assertEquals(expectedData, normalizedNode);
261     }
262
263     @Test
264     public void readLeafListDataAllTest() {
265         doReturn(immediateFluentFuture(Optional.of(DATA.leafSetNode1))).when(read)
266                 .read(LogicalDatastoreType.OPERATIONAL, DATA.leafSetNodePath);
267         doReturn(immediateFluentFuture(Optional.of(DATA.leafSetNode2))).when(read)
268                 .read(LogicalDatastoreType.CONFIGURATION, DATA.leafSetNodePath);
269         doReturn(immediateFluentFuture(Optional.of(DATA.leafSetNode1))).when(netconfService)
270                 .get(DATA.leafSetNodePath);
271         doReturn(immediateFluentFuture(Optional.of(DATA.leafSetNode2))).when(netconfService)
272                 .getConfig(DATA.leafSetNodePath);
273         final LeafSetNode<String> expectedData = Builders.<String>leafSetBuilder()
274                 .withNodeIdentifier(new NodeIdentifier(DATA.leafListQname))
275                 .withValue(ImmutableList.<LeafSetEntryNode<String>>builder()
276                         .addAll(DATA.leafSetNode1.body())
277                         .addAll(DATA.leafSetNode2.body())
278                         .build())
279                 .build();
280         NormalizedNode normalizedNode = readData(ContentParameter.ALL, DATA.leafSetNodePath,
281                 mdsalStrategy);
282         assertEquals(expectedData, normalizedNode);
283
284         normalizedNode = readData(ContentParameter.ALL, DATA.leafSetNodePath, netconfStrategy);
285         assertEquals(expectedData, normalizedNode);
286     }
287
288     @Test
289     public void readOrderedLeafListDataAllTest() {
290         doReturn(immediateFluentFuture(Optional.of(DATA.orderedLeafSetNode1))).when(read)
291                 .read(LogicalDatastoreType.OPERATIONAL, DATA.leafSetNodePath);
292         doReturn(immediateFluentFuture(Optional.of(DATA.orderedLeafSetNode2))).when(read)
293                 .read(LogicalDatastoreType.CONFIGURATION, DATA.leafSetNodePath);
294         doReturn(immediateFluentFuture(Optional.of(DATA.orderedLeafSetNode1))).when(netconfService)
295                 .get(DATA.leafSetNodePath);
296         doReturn(immediateFluentFuture(Optional.of(DATA.orderedLeafSetNode2))).when(netconfService)
297                 .getConfig(DATA.leafSetNodePath);
298         final LeafSetNode<String> expectedData = Builders.<String>orderedLeafSetBuilder()
299                 .withNodeIdentifier(new NodeIdentifier(DATA.leafListQname))
300                 .withValue(ImmutableList.<LeafSetEntryNode<String>>builder()
301                         .addAll(DATA.orderedLeafSetNode1.body())
302                         .addAll(DATA.orderedLeafSetNode2.body())
303                         .build())
304                 .build();
305         NormalizedNode normalizedNode = readData(ContentParameter.ALL, DATA.leafSetNodePath,
306                 mdsalStrategy);
307         assertEquals(expectedData, normalizedNode);
308
309         normalizedNode = readData(ContentParameter.ALL, DATA.leafSetNodePath, netconfStrategy);
310         assertEquals(expectedData, normalizedNode);
311     }
312
313     @Test
314     public void readDataWrongPathOrNoContentTest() {
315         doReturn(immediateFluentFuture(Optional.empty())).when(read)
316                 .read(LogicalDatastoreType.CONFIGURATION, DATA.path2);
317         doReturn(immediateFluentFuture(Optional.empty())).when(netconfService).getConfig(DATA.path2);
318         NormalizedNode normalizedNode = readData(ContentParameter.CONFIG, DATA.path2, mdsalStrategy);
319         assertNull(normalizedNode);
320
321         normalizedNode = readData(ContentParameter.CONFIG, DATA.path2, netconfStrategy);
322         assertNull(normalizedNode);
323     }
324
325     /**
326      * Test of parsing default parameters from URI request.
327      */
328     @Test
329     public void parseUriParametersDefaultTest() {
330         final UriInfo uriInfo = mock(UriInfo.class);
331         final MultivaluedHashMap<String, String> parameters = new MultivaluedHashMap<>();
332
333         // no parameters, default values should be used
334         when(uriInfo.getQueryParameters()).thenReturn(parameters);
335
336         final QueryParameters parsedParameters = ReadDataTransactionUtil.parseUriParameters(context, uriInfo);
337
338         assertEquals(ContentParameter.ALL, parsedParameters.getContent());
339         assertNull(parsedParameters.getDepth());
340         assertNull(parsedParameters.getFields());
341     }
342
343     /**
344      * Test of parsing user defined parameters from URI request.
345      */
346     @Test
347     public void parseUriParametersUserDefinedTest() {
348         final UriInfo uriInfo = mock(UriInfo.class);
349         final MultivaluedHashMap<String, String> parameters = new MultivaluedHashMap<>();
350
351         final String depth = "10";
352         final String fields = containerChildQName.getLocalName();
353
354         parameters.put("content", List.of("config"));
355         parameters.put("depth", List.of(depth));
356         parameters.put("fields", List.of(fields));
357
358         when(uriInfo.getQueryParameters()).thenReturn(parameters);
359
360         final QueryParameters parsedParameters = ReadDataTransactionUtil.parseUriParameters(context, uriInfo);
361
362         // content
363         assertEquals(ContentParameter.CONFIG, parsedParameters.getContent());
364
365         // depth
366         assertNotNull("Not correctly parsed URI parameter",
367                 parsedParameters.getDepth());
368         assertEquals("Not correctly parsed URI parameter",
369                 depth, parsedParameters.getDepth().toString());
370
371         // fields
372         assertNotNull("Not correctly parsed URI parameter",
373                 parsedParameters.getFields());
374         assertEquals("Not correctly parsed URI parameter",
375                 1, parsedParameters.getFields().size());
376         assertEquals("Not correctly parsed URI parameter",
377                 1, parsedParameters.getFields().get(0).size());
378         assertEquals("Not correctly parsed URI parameter",
379                 containerChildQName, parsedParameters.getFields().get(0).iterator().next());
380     }
381
382     /**
383      * Negative test of parsing request URI parameters when content parameter has not allowed value.
384      */
385     @Test
386     public void parseUriParametersContentParameterNegativeTest() {
387         final UriInfo uriInfo = mock(UriInfo.class);
388         final MultivaluedHashMap<String, String> parameters = new MultivaluedHashMap<>();
389
390         parameters.put("content", List.of("not-allowed-parameter-value"));
391         when(uriInfo.getQueryParameters()).thenReturn(parameters);
392
393         final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
394             () -> ReadDataTransactionUtil.parseUriParameters(context, uriInfo));
395         // Bad request
396         assertEquals("Error type is not correct", ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
397         assertEquals("Error tag is not correct", ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
398     }
399
400     /**
401      * Negative test of parsing request URI parameters when depth parameter has not allowed value.
402      */
403     @Test
404     public void parseUriParametersDepthParameterNegativeTest() {
405         final UriInfo uriInfo = mock(UriInfo.class);
406         final MultivaluedHashMap<String, String> parameters = new MultivaluedHashMap<>();
407
408         // inserted value is not allowed
409         parameters.put("depth", List.of("bounded"));
410         when(uriInfo.getQueryParameters()).thenReturn(parameters);
411
412         RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
413             () -> ReadDataTransactionUtil.parseUriParameters(context, uriInfo));
414         // Bad request
415         assertEquals("Error type is not correct", ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
416         assertEquals("Error tag is not correct", ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
417     }
418
419     /**
420      * Negative test of parsing request URI parameters when depth parameter has not allowed value (less than minimum).
421      */
422     @Test
423     public void parseUriParametersDepthMinimalParameterNegativeTest() {
424         final UriInfo uriInfo = mock(UriInfo.class);
425         final MultivaluedHashMap<String, String> parameters = new MultivaluedHashMap<>();
426
427         // inserted value is too low
428         parameters.put("depth", List.of("0"));
429         when(uriInfo.getQueryParameters()).thenReturn(parameters);
430
431         RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
432             () -> ReadDataTransactionUtil.parseUriParameters(context, uriInfo));
433         // Bad request
434         assertEquals("Error type is not correct", ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
435         assertEquals("Error tag is not correct", ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
436     }
437
438     /**
439      * Negative test of parsing request URI parameters when depth parameter has not allowed value (more than maximum).
440      */
441     @Test
442     public void parseUriParametersDepthMaximalParameterNegativeTest() {
443         final UriInfo uriInfo = mock(UriInfo.class);
444         final MultivaluedHashMap<String, String> parameters = new MultivaluedHashMap<>();
445
446         // inserted value is too high
447         parameters.put("depth", List.of("65536"));
448         when(uriInfo.getQueryParameters()).thenReturn(parameters);
449
450         RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
451             () -> ReadDataTransactionUtil.parseUriParameters(context, uriInfo));
452         // Bad request
453         assertEquals("Error type is not correct", ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
454         assertEquals("Error tag is not correct", ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
455     }
456
457     /**
458      * Testing parsing of with-defaults parameter which value doesn't match report-all or report-all-tagged patterns
459      * - non-reporting setting.
460      */
461     @Test
462     public void parseUriParametersWithDefaultAndNonTaggedTest() {
463         // preparation of input data
464         final UriInfo uriInfo = mock(UriInfo.class);
465         final MultivaluedHashMap<String, String> parameters = new MultivaluedHashMap<>();
466         parameters.put("with-defaults", List.of("explicit"));
467         when(uriInfo.getQueryParameters()).thenReturn(parameters);
468
469         final QueryParameters writerParameters = ReadDataTransactionUtil.parseUriParameters(context, uriInfo);
470         assertSame(WithDefaultsParameter.EXPLICIT, writerParameters.getWithDefault());
471         assertFalse(writerParameters.isTagged());
472     }
473
474     /**
475      * Testing parsing of with-defaults parameter which value which is not supported.
476      */
477     @Test
478     public void parseUriParametersWithDefaultInvalidTest() {
479         // preparation of input data
480         final UriInfo uriInfo = mock(UriInfo.class);
481         final MultivaluedHashMap<String, String> parameters = new MultivaluedHashMap<>();
482         parameters.put("with-defaults", List.of("invalid"));
483         when(uriInfo.getQueryParameters()).thenReturn(parameters);
484
485         final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
486             () -> ReadDataTransactionUtil.parseUriParameters(context, uriInfo));
487         final List<RestconfError> errors = ex.getErrors();
488         assertEquals(1, errors.size());
489         assertEquals(ErrorTag.INVALID_VALUE, errors.get(0).getErrorTag());
490     }
491
492     /**
493      * Testing parsing of with-defaults parameter which value matches 'report-all-tagged' setting - default value should
494      * be set to {@code null} and tagged flag should be set to {@code true}.
495      */
496     @Test
497     public void parseUriParametersWithDefaultAndTaggedTest() {
498         // preparation of input data
499         final UriInfo uriInfo = mock(UriInfo.class);
500         final MultivaluedHashMap<String, String> parameters = new MultivaluedHashMap<>();
501         parameters.put("with-defaults", List.of("report-all-tagged"));
502         when(uriInfo.getQueryParameters()).thenReturn(parameters);
503
504         final QueryParameters writerParameters = ReadDataTransactionUtil.parseUriParameters(context, uriInfo);
505         assertNull(writerParameters.getWithDefault());
506         assertTrue(writerParameters.isTagged());
507     }
508
509     /**
510      * Testing parsing of with-defaults parameter which value matches 'report-all' setting - default value should
511      * be set to {@code null} and tagged flag should be set to {@code false}.
512      */
513     @Test
514     public void parseUriParametersWithDefaultAndReportAllTest() {
515         // preparation of input data
516         final UriInfo uriInfo = mock(UriInfo.class);
517         final MultivaluedHashMap<String, String> parameters = new MultivaluedHashMap<>();
518         parameters.put("with-defaults", List.of("report-all"));
519         when(uriInfo.getQueryParameters()).thenReturn(parameters);
520
521         final QueryParameters writerParameters = ReadDataTransactionUtil.parseUriParameters(context, uriInfo);
522         assertNull(writerParameters.getWithDefault());
523         assertFalse(writerParameters.isTagged());
524     }
525
526     /**
527      * Test when parameter is present at most once.
528      */
529     @Test
530     public void checkParameterCountTest() {
531         ReadDataTransactionUtil.checkParameterCount(List.of("all"), ContentParameter.uriName());
532     }
533
534     /**
535      * Test when parameter is present more than once.
536      */
537     @Test
538     public void checkParameterCountNegativeTest() {
539         final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
540             () -> ReadDataTransactionUtil.checkParameterCount(List.of("config", "nonconfig", "all"),
541                     ContentParameter.uriName()));
542         final List<RestconfError> errors = ex.getErrors();
543         assertEquals(1, errors.size());
544
545         final RestconfError error = errors.get(0);
546         assertEquals("Error type is not correct", ErrorType.PROTOCOL, error.getErrorType());
547         assertEquals("Error tag is not correct", ErrorTag.INVALID_VALUE, error.getErrorTag());
548     }
549
550
551     /**
552      * Test when all parameters are allowed.
553      */
554     @Test
555     public void checkParametersTypesTest() {
556         ReadDataTransactionUtil.checkParametersTypes(Set.of("content"),
557             Set.of(ContentParameter.uriName(), DepthParameter.uriName()));
558     }
559
560     /**
561      * Test when not allowed parameter type is used.
562      */
563     @Test
564     public void checkParametersTypesNegativeTest() {
565         final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
566             () -> ReadDataTransactionUtil.checkParametersTypes(Set.of("not-allowed-parameter"),
567                 Set.of(ContentParameter.uriName(), DepthParameter.uriName())));
568         final List<RestconfError> errors = ex.getErrors();
569         assertEquals(1, errors.size());
570
571         final RestconfError error = errors.get(0);
572         assertEquals("Error type is not correct", ErrorType.PROTOCOL, error.getErrorType());
573         assertEquals("Error tag is not correct", ErrorTag.INVALID_VALUE, error.getErrorTag());
574     }
575
576     /**
577      * Read specific type of data from data store via transaction.
578      *
579      * @param content        type of data to read (config, state, all)
580      * @param strategy       {@link RestconfStrategy} - wrapper for variables
581      * @return {@link NormalizedNode}
582      */
583     private @Nullable NormalizedNode readData(final @NonNull ContentParameter content,
584             final YangInstanceIdentifier path, final @NonNull RestconfStrategy strategy) {
585         return ReadDataTransactionUtil.readData(content, path, strategy, null, schemaContext);
586     }
587 }