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