2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.restconf.nb.rfc8040.utils.mapping;
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNotNull;
12 import static org.mockito.Mockito.when;
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;
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.restconf.nb.rfc8040.Rfc8040.IetfYangLibrary;
34 import org.opendaylight.restconf.nb.rfc8040.Rfc8040.MonitoringModule;
35 import org.opendaylight.restconf.nb.rfc8040.Rfc8040.MonitoringModule.QueryParams;
36 import org.opendaylight.restconf.nb.rfc8040.Rfc8040.RestconfModule;
37 import org.opendaylight.restconf.nb.rfc8040.TestRestconfUtils;
38 import org.opendaylight.restconf.nb.rfc8040.utils.parser.ParserIdentifier;
39 import org.opendaylight.yangtools.yang.common.QName;
40 import org.opendaylight.yangtools.yang.common.Revision;
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 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
61 * Unit tests for {@link RestconfMappingNodeUtil}.
63 public class RestconfMappingNodeUtilTest {
65 private static final Logger LOG = LoggerFactory.getLogger(RestconfMappingNodeUtilTest.class);
68 public ExpectedException thrown = ExpectedException.none();
70 @Mock private ListSchemaNode mockStreamList;
71 @Mock private LeafSchemaNode leafName;
72 @Mock private LeafSchemaNode leafDescription;
73 @Mock private LeafSchemaNode leafReplaySupport;
74 @Mock private LeafSchemaNode leafReplayLog;
75 @Mock private LeafSchemaNode leafEvents;
77 private static Set<Module> modules;
78 private static SchemaContext schemaContext;
79 private static SchemaContext schemaContextMonitoring;
81 private static Set<Module> modulesRest;
84 public static void loadTestSchemaContextAndModules() throws Exception {
86 YangParserTestUtils.parseYangFiles(TestRestconfUtils.loadFiles("/modules/restconf-module-testing"));
87 schemaContextMonitoring = YangParserTestUtils.parseYangFiles(TestRestconfUtils.loadFiles("/modules"));
88 modules = schemaContextMonitoring.getModules();
89 modulesRest = YangParserTestUtils
90 .parseYangFiles(TestRestconfUtils.loadFiles("/modules/restconf-module-testing")).getModules();
94 public void setup() throws Exception {
95 MockitoAnnotations.initMocks(this);
97 when(this.leafName.getQName()).thenReturn(QName.create("", RestconfMappingNodeConstants.NAME));
98 when(this.leafDescription.getQName()).thenReturn(QName.create("", RestconfMappingNodeConstants.DESCRIPTION));
99 when(this.leafReplaySupport.getQName()).thenReturn(
100 QName.create("", RestconfMappingNodeConstants.REPLAY_SUPPORT));
101 when(this.leafReplayLog.getQName()).thenReturn(QName.create("", RestconfMappingNodeConstants.REPLAY_LOG));
102 when(this.leafEvents.getQName()).thenReturn(QName.create("", RestconfMappingNodeConstants.EVENTS));
106 * Test of writing modules into {@link RestconfModule#MODULE_LIST_SCHEMA_NODE} and checking if modules were
110 public void restconfMappingNodeTest() {
111 // write modules into list module in Restconf
112 final Module ietfYangLibMod = schemaContext.findModule(IetfYangLibrary.MODULE_QNAME).get();
113 final NormalizedNode<NodeIdentifier, Collection<DataContainerChild<? extends PathArgument, ?>>> mods =
114 RestconfMappingNodeUtil.mapModulesByIetfYangLibraryYang(RestconfMappingNodeUtilTest.modules,
115 ietfYangLibMod, schemaContext, "1");
117 // verify loaded modules
118 verifyLoadedModules((ContainerNode) mods);
120 verifyDeviations((ContainerNode) mods);
124 public void restconfStateCapabilitesTest() {
125 final Module monitoringModule = schemaContextMonitoring.findModule(MonitoringModule.MODULE_QNAME).get();
126 final NormalizedNode<NodeIdentifier, Collection<DataContainerChild<? extends PathArgument, ?>>> normNode =
127 RestconfMappingNodeUtil.mapCapabilites(monitoringModule);
128 assertNotNull(normNode);
129 final List<Object> listOfValues = new ArrayList<>();
131 for (final DataContainerChild<? extends PathArgument, ?> child : normNode.getValue()) {
132 if (child.getNodeType().equals(MonitoringModule.CONT_CAPABILITES_QNAME)) {
133 for (final DataContainerChild<? extends PathArgument, ?> dataContainerChild : ((ContainerNode) child)
135 for (final Object entry : ((LeafSetNode<?>) dataContainerChild).getValue()) {
136 listOfValues.add(((LeafSetEntryNode<?>) entry).getValue());
141 Assert.assertTrue(listOfValues.contains(QueryParams.DEPTH));
142 Assert.assertTrue(listOfValues.contains(QueryParams.FIELDS));
143 Assert.assertTrue(listOfValues.contains(QueryParams.FILTER));
144 Assert.assertTrue(listOfValues.contains(QueryParams.REPLAY));
145 Assert.assertTrue(listOfValues.contains(QueryParams.WITH_DEFAULTS));
149 public void toStreamEntryNodeTest() throws Exception {
150 final YangInstanceIdentifier path = ParserIdentifier.toInstanceIdentifier(
151 "nested-module:depth1-cont/depth2-leaf1", schemaContextMonitoring, null).getInstanceIdentifier();
152 final Instant start = Instant.now();
153 final String outputType = "XML";
154 final URI uri = new URI("uri");
155 final Module monitoringModule = schemaContextMonitoring.findModule(MonitoringModule.MODULE_QNAME).orElse(null);
156 final boolean exist = true;
158 final Map<QName, Object> map =
159 prepareMap(path.getLastPathArgument().getNodeType().getLocalName(), uri, start, outputType);
161 final NormalizedNode<?, ?> mappedData =
162 RestconfMappingNodeUtil.mapDataChangeNotificationStreamByIetfRestconfMonitoring(
163 path, start, outputType, uri, monitoringModule, exist, schemaContextMonitoring);
164 assertNotNull(mappedData);
165 testData(map, mappedData);
169 public void toStreamEntryNodeNotifiTest() throws Exception {
170 final Instant start = Instant.now();
171 final String outputType = "JSON";
172 final URI uri = new URI("uri");
173 final Module monitoringModule = schemaContextMonitoring.findModule(MonitoringModule.MODULE_QNAME).orElse(null);
174 final boolean exist = true;
176 final Map<QName, Object> map = prepareMap("notifi", uri, start, outputType);
177 map.put(MonitoringModule.LEAF_DESCR_STREAM_QNAME, "Notifi");
179 final QName notifiQName = QName.create("urn:nested:module", "2014-06-03", "notifi");
180 final NormalizedNode<?, ?> mappedData =
181 RestconfMappingNodeUtil.mapYangNotificationStreamByIetfRestconfMonitoring(notifiQName,
182 schemaContextMonitoring.getNotifications(), start, outputType, uri, monitoringModule, exist);
183 assertNotNull(mappedData);
184 testData(map, mappedData);
187 private static Map<QName, Object> prepareMap(final String name, final URI uri, final Instant start,
188 final String outputType) {
189 final Map<QName, Object> map = new HashMap<>();
190 map.put(MonitoringModule.LEAF_NAME_STREAM_QNAME, name);
191 map.put(MonitoringModule.LEAF_LOCATION_ACCESS_QNAME, uri.toString());
192 map.put(MonitoringModule.LEAF_REPLAY_SUPP_STREAM_QNAME, Boolean.TRUE);
193 map.put(MonitoringModule.LEAF_START_TIME_STREAM_QNAME, DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(
194 OffsetDateTime.ofInstant(start, ZoneId.systemDefault())));
195 map.put(MonitoringModule.LEAF_ENCODING_ACCESS_QNAME, outputType);
199 private static void testData(final Map<QName, Object> map, final NormalizedNode<?, ?> mappedData) {
200 for (final DataContainerChild<? extends PathArgument, ?> child : ((MapEntryNode) mappedData).getValue()) {
201 if (child instanceof LeafNode) {
202 final LeafNode<?> leaf = (LeafNode<?>) child;
203 Assert.assertTrue(map.containsKey(leaf.getNodeType()));
204 Assert.assertEquals(map.get(leaf.getNodeType()), leaf.getValue());
210 * Verify whether the loaded modules contain any deviations.
212 * @param containerNode
215 private static void verifyDeviations(final ContainerNode containerNode) {
216 int deviationsFound = 0;
217 for (final DataContainerChild child : containerNode.getValue()) {
218 if (child instanceof MapNode) {
219 for (final MapEntryNode mapEntryNode : ((MapNode) child).getValue()) {
220 for (final DataContainerChild dataContainerChild : mapEntryNode
222 if (dataContainerChild.getNodeType()
223 .equals(IetfYangLibrary.SPECIFIC_MODULE_DEVIATION_LIST_QNAME)) {
230 Assert.assertTrue(deviationsFound > 0);
234 * Verify loaded modules.
236 * @param containerNode
239 private static void verifyLoadedModules(final ContainerNode containerNode) {
241 final Map<String, String> loadedModules = new HashMap<>();
243 for (final DataContainerChild<? extends PathArgument, ?> child : containerNode.getValue()) {
244 if (child instanceof LeafNode) {
245 assertEquals(IetfYangLibrary.MODULE_SET_ID_LEAF_QNAME, child.getNodeType());
247 if (child instanceof MapNode) {
248 assertEquals(IetfYangLibrary.MODULE_QNAME_LIST, child.getNodeType());
249 for (final MapEntryNode mapEntryNode : ((MapNode) child).getValue()) {
251 String revision = "";
252 for (final DataContainerChild<? extends PathArgument, ?> dataContainerChild : mapEntryNode
254 switch (dataContainerChild.getNodeType().getLocalName()) {
255 case IetfYangLibrary.SPECIFIC_MODULE_NAME_LEAF:
256 name = String.valueOf(dataContainerChild.getValue());
258 case IetfYangLibrary.SPECIFIC_MODULE_REVISION_LEAF:
259 revision = String.valueOf(dataContainerChild.getValue());
262 LOG.info("Unknown local name '{}' of node.",
263 dataContainerChild.getNodeType().getLocalName());
267 loadedModules.put(name, revision);
272 verifyLoadedModules(RestconfMappingNodeUtilTest.modulesRest, loadedModules);
276 * Verify if correct modules were loaded into Restconf module by comparison with modules from
277 * <code>SchemaContext</code>.
278 * @param expectedModules Modules from <code>SchemaContext</code>
279 * @param loadedModules Loaded modules into Restconf module
281 private static void verifyLoadedModules(final Set<Module> expectedModules,
282 final Map<String, String> loadedModules) {
283 assertEquals("Number of loaded modules is not as expected", expectedModules.size(), loadedModules.size());
284 for (final Module m : expectedModules) {
285 final String name = m.getName();
287 final String revision = loadedModules.get(name);
288 assertNotNull("Expected module not found", revision);
289 assertEquals("Incorrect revision of loaded module", Revision.ofNullable(revision), m.getRevision());
291 loadedModules.remove(name);