Use schemaless builders in RestconfMappingNodeUtil
[netconf.git] / restconf / restconf-nb-rfc8040 / src / test / java / org / opendaylight / restconf / nb / rfc8040 / utils / mapping / RestconfMappingNodeUtilTest.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.utils.mapping;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNotNull;
12 import static org.junit.Assert.assertTrue;
13
14 import java.net.URI;
15 import java.time.Instant;
16 import java.time.OffsetDateTime;
17 import java.time.ZoneId;
18 import java.time.format.DateTimeFormatter;
19 import java.util.ArrayList;
20 import java.util.Collection;
21 import java.util.HashMap;
22 import java.util.List;
23 import java.util.Map;
24 import org.junit.BeforeClass;
25 import org.junit.Test;
26 import org.opendaylight.restconf.nb.rfc8040.Rfc8040.IetfYangLibrary;
27 import org.opendaylight.restconf.nb.rfc8040.Rfc8040.MonitoringModule;
28 import org.opendaylight.restconf.nb.rfc8040.Rfc8040.MonitoringModule.QueryParams;
29 import org.opendaylight.restconf.nb.rfc8040.Rfc8040.RestconfModule;
30 import org.opendaylight.restconf.nb.rfc8040.TestRestconfUtils;
31 import org.opendaylight.restconf.nb.rfc8040.utils.parser.ParserIdentifier;
32 import org.opendaylight.yangtools.yang.common.QName;
33 import org.opendaylight.yangtools.yang.common.Revision;
34 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
35 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
36 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
37 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
38 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
39 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
40 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
41 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
42 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
43 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
44 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
45 import org.opendaylight.yangtools.yang.model.api.Module;
46 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49
50 /**
51  * Unit tests for {@link RestconfMappingNodeUtil}.
52  */
53 public class RestconfMappingNodeUtilTest {
54     private static final Logger LOG = LoggerFactory.getLogger(RestconfMappingNodeUtilTest.class);
55
56     private static Collection<? extends Module> modules;
57     private static EffectiveModelContext schemaContext;
58     private static EffectiveModelContext schemaContextMonitoring;
59     private static Collection<? extends Module> modulesRest;
60
61     @BeforeClass
62     public static void loadTestSchemaContextAndModules() throws Exception {
63         schemaContext =
64                 YangParserTestUtils.parseYangFiles(TestRestconfUtils.loadFiles("/modules/restconf-module-testing"));
65         schemaContextMonitoring = YangParserTestUtils.parseYangFiles(TestRestconfUtils.loadFiles("/modules"));
66         modules = schemaContextMonitoring.getModules();
67         modulesRest = YangParserTestUtils
68                 .parseYangFiles(TestRestconfUtils.loadFiles("/modules/restconf-module-testing")).getModules();
69     }
70
71     /**
72      * Test of writing modules into {@link RestconfModule#MODULE_LIST_SCHEMA_NODE} and checking if modules were
73      * correctly written.
74      */
75     @Test
76     public void restconfMappingNodeTest() {
77         // write modules into list module in Restconf
78         final Module ietfYangLibMod = schemaContext.findModule(IetfYangLibrary.MODULE_QNAME).get();
79         final ContainerNode mods = RestconfMappingNodeUtil.mapModulesByIetfYangLibraryYang(
80             RestconfMappingNodeUtilTest.modules, schemaContext, "1");
81
82         // verify loaded modules
83         verifyLoadedModules(mods);
84         // verify deviations
85         verifyDeviations(mods);
86     }
87
88     @Test
89     public void restconfStateCapabilitesTest() {
90         final Module monitoringModule = schemaContextMonitoring.findModule(MonitoringModule.MODULE_QNAME).get();
91         final ContainerNode normNode = RestconfMappingNodeUtil.mapCapabilites(monitoringModule);
92         assertNotNull(normNode);
93         final List<Object> listOfValues = new ArrayList<>();
94
95         for (final DataContainerChild<?, ?> child : normNode.getValue()) {
96             if (child.getNodeType().equals(MonitoringModule.CONT_CAPABILITES_QNAME)) {
97                 for (final DataContainerChild<?, ?> dataContainerChild : ((ContainerNode) child).getValue()) {
98                     for (final Object entry : ((LeafSetNode<?>) dataContainerChild).getValue()) {
99                         listOfValues.add(((LeafSetEntryNode<?>) entry).getValue());
100                     }
101                 }
102             }
103         }
104         assertTrue(listOfValues.contains(QueryParams.DEPTH));
105         assertTrue(listOfValues.contains(QueryParams.FIELDS));
106         assertTrue(listOfValues.contains(QueryParams.FILTER));
107         assertTrue(listOfValues.contains(QueryParams.REPLAY));
108         assertTrue(listOfValues.contains(QueryParams.WITH_DEFAULTS));
109     }
110
111     @Test
112     public void toStreamEntryNodeTest() throws Exception {
113         final YangInstanceIdentifier path = ParserIdentifier.toInstanceIdentifier(
114                 "nested-module:depth1-cont/depth2-leaf1", schemaContextMonitoring, null).getInstanceIdentifier();
115         final Instant start = Instant.now();
116         final String outputType = "XML";
117         final URI uri = new URI("uri");
118         final Module monitoringModule = schemaContextMonitoring.findModule(MonitoringModule.MODULE_QNAME).orElse(null);
119         final boolean exist = true;
120
121         final Map<QName, Object> map =
122                 prepareMap(path.getLastPathArgument().getNodeType().getLocalName(), uri, start, outputType);
123
124         final NormalizedNode<?, ?> mappedData =
125                 RestconfMappingNodeUtil.mapDataChangeNotificationStreamByIetfRestconfMonitoring(
126                         path, start, outputType, uri, monitoringModule, exist, schemaContextMonitoring);
127         assertNotNull(mappedData);
128         testData(map, mappedData);
129     }
130
131     @Test
132     public void toStreamEntryNodeNotifiTest() throws Exception {
133         final Instant start = Instant.now();
134         final String outputType = "JSON";
135         final URI uri = new URI("uri");
136         final Module monitoringModule = schemaContextMonitoring.findModule(MonitoringModule.MODULE_QNAME).orElse(null);
137         final boolean exist = true;
138
139         final Map<QName, Object> map = prepareMap("notifi", uri, start, outputType);
140         map.put(MonitoringModule.LEAF_DESCR_STREAM_QNAME, "Notifi");
141
142         final QName notifiQName = QName.create("urn:nested:module", "2014-06-03", "notifi");
143         final NormalizedNode<?, ?> mappedData =
144                 RestconfMappingNodeUtil.mapYangNotificationStreamByIetfRestconfMonitoring(notifiQName,
145                     schemaContextMonitoring.getNotifications(), start, outputType, uri, monitoringModule, exist);
146         assertNotNull(mappedData);
147         testData(map, mappedData);
148     }
149
150     private static Map<QName, Object> prepareMap(final String name, final URI uri, final Instant start,
151             final String outputType) {
152         final Map<QName, Object> map = new HashMap<>();
153         map.put(MonitoringModule.LEAF_NAME_STREAM_QNAME, name);
154         map.put(MonitoringModule.LEAF_LOCATION_ACCESS_QNAME, uri.toString());
155         map.put(MonitoringModule.LEAF_REPLAY_SUPP_STREAM_QNAME, Boolean.TRUE);
156         map.put(MonitoringModule.LEAF_START_TIME_STREAM_QNAME, DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(
157             OffsetDateTime.ofInstant(start, ZoneId.systemDefault())));
158         map.put(MonitoringModule.LEAF_ENCODING_ACCESS_QNAME, outputType);
159         return map;
160     }
161
162     private static void testData(final Map<QName, Object> map, final NormalizedNode<?, ?> mappedData) {
163         for (final DataContainerChild<? extends PathArgument, ?> child : ((MapEntryNode) mappedData).getValue()) {
164             if (child instanceof LeafNode) {
165                 final LeafNode<?> leaf = (LeafNode<?>) child;
166                 assertTrue(map.containsKey(leaf.getNodeType()));
167                 assertEquals(map.get(leaf.getNodeType()), leaf.getValue());
168             }
169         }
170     }
171
172     /**
173      * Verify whether the loaded modules contain any deviations.
174      *
175      * @param containerNode
176      *             modules
177      */
178     private static void verifyDeviations(final ContainerNode containerNode) {
179         int deviationsFound = 0;
180         for (final DataContainerChild<?, ?> child : containerNode.getValue()) {
181             if (child instanceof MapNode) {
182                 for (final MapEntryNode mapEntryNode : ((MapNode) child).getValue()) {
183                     for (final DataContainerChild<?, ?> dataContainerChild : mapEntryNode.getValue()) {
184                         if (dataContainerChild.getNodeType()
185                                 .equals(IetfYangLibrary.SPECIFIC_MODULE_DEVIATION_LIST_QNAME)) {
186                             deviationsFound++;
187                         }
188                     }
189                 }
190             }
191         }
192         assertTrue(deviationsFound > 0);
193     }
194
195     /**
196      * Verify loaded modules.
197      *
198      * @param containerNode
199      *             modules
200      */
201     private static void verifyLoadedModules(final ContainerNode containerNode) {
202
203         final Map<String, String> loadedModules = new HashMap<>();
204
205         for (final DataContainerChild<? extends PathArgument, ?> child : containerNode.getValue()) {
206             if (child instanceof LeafNode) {
207                 assertEquals(IetfYangLibrary.MODULE_SET_ID_LEAF_QNAME, child.getNodeType());
208             }
209             if (child instanceof MapNode) {
210                 assertEquals(IetfYangLibrary.MODULE_QNAME_LIST, child.getNodeType());
211                 for (final MapEntryNode mapEntryNode : ((MapNode) child).getValue()) {
212                     String name = "";
213                     String revision = "";
214                     for (final DataContainerChild<? extends PathArgument, ?> dataContainerChild : mapEntryNode
215                             .getValue()) {
216                         switch (dataContainerChild.getNodeType().getLocalName()) {
217                             case IetfYangLibrary.SPECIFIC_MODULE_NAME_LEAF:
218                                 name = String.valueOf(dataContainerChild.getValue());
219                                 break;
220                             case IetfYangLibrary.SPECIFIC_MODULE_REVISION_LEAF:
221                                 revision = String.valueOf(dataContainerChild.getValue());
222                                 break;
223                             default :
224                                 LOG.info("Unknown local name '{}' of node.",
225                                         dataContainerChild.getNodeType().getLocalName());
226                                 break;
227                         }
228                     }
229                     loadedModules.put(name, revision);
230                 }
231             }
232         }
233
234         verifyLoadedModules(RestconfMappingNodeUtilTest.modulesRest, loadedModules);
235     }
236
237     /**
238      * Verify if correct modules were loaded into Restconf module by comparison with modules from
239      * <code>SchemaContext</code>.
240      * @param expectedModules Modules from <code>SchemaContext</code>
241      * @param loadedModules Loaded modules into Restconf module
242      */
243     private static void verifyLoadedModules(final Collection<? extends Module> expectedModules,
244             final Map<String, String> loadedModules) {
245         assertEquals("Number of loaded modules is not as expected", expectedModules.size(), loadedModules.size());
246         for (final Module m : expectedModules) {
247             final String name = m.getName();
248
249             final String revision = loadedModules.get(name);
250             assertNotNull("Expected module not found", revision);
251             assertEquals("Incorrect revision of loaded module", Revision.ofNullable(revision), m.getRevision());
252
253             loadedModules.remove(name);
254         }
255     }
256 }