52c89e5eb964d5c56c92051c3cce447727a2bdfc
[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;
27 import org.opendaylight.restconf.nb.rfc8040.Rfc8040.IetfYangLibrary;
28 import org.opendaylight.restconf.nb.rfc8040.TestRestconfUtils;
29 import org.opendaylight.restconf.nb.rfc8040.handlers.SchemaContextHandler;
30 import org.opendaylight.restconf.nb.rfc8040.utils.parser.ParserIdentifier;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.monitoring.rev170126.RestconfState;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.monitoring.rev170126.restconf.state.Capabilities;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.module.list.module.Deviation;
34 import org.opendaylight.yangtools.yang.common.QName;
35 import org.opendaylight.yangtools.yang.common.Revision;
36 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
37 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
38 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
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.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         // FIXME: assemble these from dependencies
64         schemaContext =
65                 YangParserTestUtils.parseYangFiles(TestRestconfUtils.loadFiles("/modules/restconf-module-testing"));
66         schemaContextMonitoring = YangParserTestUtils.parseYangFiles(TestRestconfUtils.loadFiles("/modules"));
67         modules = schemaContextMonitoring.getModules();
68         modulesRest = YangParserTestUtils
69                 .parseYangFiles(TestRestconfUtils.loadFiles("/modules/restconf-module-testing")).getModules();
70     }
71
72     /**
73      * Test of writing modules into {@link RestconfModule#MODULE_LIST_SCHEMA_NODE} and checking if modules were
74      * correctly written.
75      */
76     @Test
77     public void restconfMappingNodeTest() {
78         // write modules into list module in Restconf
79         final ContainerNode mods = SchemaContextHandler.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(RestconfState.QNAME.getModule()).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.body()) {
96             if (child.getIdentifier().getNodeType().equals(Capabilities.QNAME)) {
97                 for (final DataContainerChild dataContainerChild : ((ContainerNode) child).body()) {
98                     for (final Object entry : ((LeafSetNode<?>) dataContainerChild).body()) {
99                         listOfValues.add(((LeafSetEntryNode<?>) entry).body());
100                     }
101                 }
102             }
103         }
104         assertTrue(listOfValues.contains(Rfc8040.Capabilities.DEPTH));
105         assertTrue(listOfValues.contains(Rfc8040.Capabilities.FIELDS));
106         assertTrue(listOfValues.contains(Rfc8040.Capabilities.FILTER));
107         assertTrue(listOfValues.contains(Rfc8040.Capabilities.REPLAY));
108         assertTrue(listOfValues.contains(Rfc8040.Capabilities.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 String streamName = "/nested-module:depth1-cont/depth2-leaf1";
119
120         final Map<QName, Object> map = prepareMap(streamName, uri, start, outputType);
121         final MapEntryNode mappedData = RestconfMappingNodeUtil.mapDataChangeNotificationStreamByIetfRestconfMonitoring(
122             path, start, outputType, uri, schemaContextMonitoring, streamName);
123         assertMappedData(map, mappedData);
124     }
125
126     @Test
127     public void toStreamEntryNodeNotifiTest() throws Exception {
128         final Instant start = Instant.now();
129         final String outputType = "JSON";
130         final URI uri = new URI("uri");
131
132         final Map<QName, Object> map = prepareMap("notifi", uri, start, outputType);
133         map.put(RestconfMappingNodeUtil.DESCRIPTION_QNAME, "Notifi");
134
135         final QName notifiQName = QName.create("urn:nested:module", "2014-06-03", "notifi");
136         final MapEntryNode mappedData = RestconfMappingNodeUtil.mapYangNotificationStreamByIetfRestconfMonitoring(
137             notifiQName, schemaContextMonitoring.getNotifications(), start, outputType, uri);
138         assertMappedData(map, mappedData);
139     }
140
141     private static Map<QName, Object> prepareMap(final String name, final URI uri, final Instant start,
142             final String outputType) {
143         final Map<QName, Object> map = new HashMap<>();
144         map.put(RestconfMappingNodeUtil.NAME_QNAME, name);
145         map.put(RestconfMappingNodeUtil.LOCATION_QNAME, uri.toString());
146         map.put(RestconfMappingNodeUtil.REPLAY_SUPPORT_QNAME, Boolean.TRUE);
147         map.put(RestconfMappingNodeUtil.REPLAY_LOG_CREATION_TIME, DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(
148             OffsetDateTime.ofInstant(start, ZoneId.systemDefault())));
149         map.put(RestconfMappingNodeUtil.ENCODING_QNAME, outputType);
150         return map;
151     }
152
153     private static void assertMappedData(final Map<QName, Object> map, final MapEntryNode mappedData) {
154         assertNotNull(mappedData);
155         for (final DataContainerChild child : mappedData.body()) {
156             if (child instanceof LeafNode) {
157                 final LeafNode<?> leaf = (LeafNode<?>) child;
158                 assertTrue(map.containsKey(leaf.getIdentifier().getNodeType()));
159                 assertEquals(map.get(leaf.getIdentifier().getNodeType()), leaf.body());
160             }
161         }
162     }
163
164     /**
165      * Verify whether the loaded modules contain any deviations.
166      *
167      * @param containerNode
168      *             modules
169      */
170     private static void verifyDeviations(final ContainerNode containerNode) {
171         int deviationsFound = 0;
172         for (final DataContainerChild child : containerNode.body()) {
173             if (child instanceof MapNode) {
174                 for (final MapEntryNode mapEntryNode : ((MapNode) child).body()) {
175                     for (final DataContainerChild dataContainerChild : mapEntryNode.body()) {
176                         if (dataContainerChild.getIdentifier().getNodeType().equals(Deviation.QNAME)) {
177                             deviationsFound++;
178                         }
179                     }
180                 }
181             }
182         }
183         assertTrue(deviationsFound > 0);
184     }
185
186     /**
187      * Verify loaded modules.
188      *
189      * @param containerNode
190      *             modules
191      */
192     private static void verifyLoadedModules(final ContainerNode containerNode) {
193         final Map<String, String> loadedModules = new HashMap<>();
194
195         for (final DataContainerChild child : containerNode.body()) {
196             if (child instanceof LeafNode) {
197                 assertEquals(IetfYangLibrary.MODULE_SET_ID_LEAF_QNAME, child.getIdentifier().getNodeType());
198             }
199             if (child instanceof MapNode) {
200                 assertEquals(IetfYangLibrary.MODULE_QNAME_LIST, child.getIdentifier().getNodeType());
201                 for (final MapEntryNode mapEntryNode : ((MapNode) child).body()) {
202                     String name = "";
203                     String revision = "";
204                     for (final DataContainerChild dataContainerChild : mapEntryNode.body()) {
205                         switch (dataContainerChild.getIdentifier().getNodeType().getLocalName()) {
206                             case "name":
207                                 name = String.valueOf(dataContainerChild.body());
208                                 break;
209                             case "revision":
210                                 revision = String.valueOf(dataContainerChild.body());
211                                 break;
212                             default :
213                                 LOG.info("Unknown local name '{}' of node.",
214                                         dataContainerChild.getIdentifier().getNodeType().getLocalName());
215                                 break;
216                         }
217                     }
218                     loadedModules.put(name, revision);
219                 }
220             }
221         }
222
223         verifyLoadedModules(RestconfMappingNodeUtilTest.modulesRest, loadedModules);
224     }
225
226     /**
227      * Verify if correct modules were loaded into Restconf module by comparison with modules from
228      * <code>SchemaContext</code>.
229      * @param expectedModules Modules from <code>SchemaContext</code>
230      * @param loadedModules Loaded modules into Restconf module
231      */
232     private static void verifyLoadedModules(final Collection<? extends Module> expectedModules,
233             final Map<String, String> loadedModules) {
234         assertEquals("Number of loaded modules is not as expected", expectedModules.size(), loadedModules.size());
235         for (final Module m : expectedModules) {
236             final String name = m.getName();
237
238             final String revision = loadedModules.get(name);
239             assertNotNull("Expected module not found", revision);
240             assertEquals("Incorrect revision of loaded module", Revision.ofNullable(revision), m.getRevision());
241
242             loadedModules.remove(name);
243         }
244     }
245 }