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