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