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.junit.Assert.assertTrue;
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;
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.model.api.EffectiveModelContext;
44 import org.opendaylight.yangtools.yang.model.api.Module;
45 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
50 * Unit tests for {@link RestconfMappingNodeUtil}.
52 public class RestconfMappingNodeUtilTest {
53 private static final Logger LOG = LoggerFactory.getLogger(RestconfMappingNodeUtilTest.class);
55 private static Collection<? extends Module> modules;
56 private static EffectiveModelContext schemaContext;
57 private static EffectiveModelContext schemaContextMonitoring;
58 private static Collection<? extends Module> modulesRest;
61 public static void loadTestSchemaContextAndModules() throws Exception {
62 // FIXME: assemble these from dependencies
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();
72 * Test of writing modules into {@link RestconfModule#MODULE_LIST_SCHEMA_NODE} and checking if modules were
76 public void restconfMappingNodeTest() {
77 // write modules into list module in Restconf
78 final ContainerNode mods = RestconfMappingNodeUtil.mapModulesByIetfYangLibraryYang(
79 RestconfMappingNodeUtilTest.modules, schemaContext, "1");
81 // verify loaded modules
82 verifyLoadedModules(mods);
84 verifyDeviations(mods);
88 public void restconfStateCapabilitesTest() {
89 final Module monitoringModule = schemaContextMonitoring.findModule(MonitoringModule.MODULE_QNAME).get();
90 final ContainerNode normNode = RestconfMappingNodeUtil.mapCapabilites(monitoringModule);
91 assertNotNull(normNode);
92 final List<Object> listOfValues = new ArrayList<>();
94 for (final DataContainerChild<?, ?> child : normNode.getValue()) {
95 if (child.getNodeType().equals(MonitoringModule.CONT_CAPABILITES_QNAME)) {
96 for (final DataContainerChild<?, ?> dataContainerChild : ((ContainerNode) child).getValue()) {
97 for (final Object entry : ((LeafSetNode<?>) dataContainerChild).getValue()) {
98 listOfValues.add(((LeafSetEntryNode<?>) entry).getValue());
103 assertTrue(listOfValues.contains(QueryParams.DEPTH));
104 assertTrue(listOfValues.contains(QueryParams.FIELDS));
105 assertTrue(listOfValues.contains(QueryParams.FILTER));
106 assertTrue(listOfValues.contains(QueryParams.REPLAY));
107 assertTrue(listOfValues.contains(QueryParams.WITH_DEFAULTS));
111 public void toStreamEntryNodeTest() throws Exception {
112 final YangInstanceIdentifier path = ParserIdentifier.toInstanceIdentifier(
113 "nested-module:depth1-cont/depth2-leaf1", schemaContextMonitoring, null).getInstanceIdentifier();
114 final Instant start = Instant.now();
115 final String outputType = "XML";
116 final URI uri = new URI("uri");
117 final Module monitoringModule = schemaContextMonitoring.findModule(MonitoringModule.MODULE_QNAME).orElse(null);
119 final Map<QName, Object> map = prepareMap(path.getLastPathArgument().getNodeType().getLocalName(), uri, start,
122 final MapEntryNode mappedData = RestconfMappingNodeUtil.mapDataChangeNotificationStreamByIetfRestconfMonitoring(
123 path, start, outputType, uri, monitoringModule, schemaContextMonitoring);
124 assertMappedData(map, mappedData);
128 public void toStreamEntryNodeNotifiTest() throws Exception {
129 final Instant start = Instant.now();
130 final String outputType = "JSON";
131 final URI uri = new URI("uri");
132 final Module monitoringModule = schemaContextMonitoring.findModule(MonitoringModule.MODULE_QNAME).orElse(null);
134 final Map<QName, Object> map = prepareMap("notifi", uri, start, outputType);
135 map.put(MonitoringModule.LEAF_DESCR_STREAM_QNAME, "Notifi");
137 final QName notifiQName = QName.create("urn:nested:module", "2014-06-03", "notifi");
138 final MapEntryNode mappedData = RestconfMappingNodeUtil.mapYangNotificationStreamByIetfRestconfMonitoring(
139 notifiQName, schemaContextMonitoring.getNotifications(), start, outputType, uri, monitoringModule);
140 assertMappedData(map, mappedData);
143 private static Map<QName, Object> prepareMap(final String name, final URI uri, final Instant start,
144 final String outputType) {
145 final Map<QName, Object> map = new HashMap<>();
146 map.put(MonitoringModule.LEAF_NAME_STREAM_QNAME, name);
147 map.put(MonitoringModule.LEAF_LOCATION_ACCESS_QNAME, uri.toString());
148 map.put(MonitoringModule.LEAF_REPLAY_SUPP_STREAM_QNAME, Boolean.TRUE);
149 map.put(MonitoringModule.LEAF_START_TIME_STREAM_QNAME, DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(
150 OffsetDateTime.ofInstant(start, ZoneId.systemDefault())));
151 map.put(MonitoringModule.LEAF_ENCODING_ACCESS_QNAME, outputType);
155 private static void assertMappedData(final Map<QName, Object> map, final MapEntryNode mappedData) {
156 assertNotNull(mappedData);
157 for (final DataContainerChild<?, ?> child : mappedData.getValue()) {
158 if (child instanceof LeafNode) {
159 final LeafNode<?> leaf = (LeafNode<?>) child;
160 assertTrue(map.containsKey(leaf.getNodeType()));
161 assertEquals(map.get(leaf.getNodeType()), leaf.getValue());
167 * Verify whether the loaded modules contain any deviations.
169 * @param containerNode
172 private static void verifyDeviations(final ContainerNode containerNode) {
173 int deviationsFound = 0;
174 for (final DataContainerChild<?, ?> child : containerNode.getValue()) {
175 if (child instanceof MapNode) {
176 for (final MapEntryNode mapEntryNode : ((MapNode) child).getValue()) {
177 for (final DataContainerChild<?, ?> dataContainerChild : mapEntryNode.getValue()) {
178 if (dataContainerChild.getNodeType()
179 .equals(IetfYangLibrary.SPECIFIC_MODULE_DEVIATION_LIST_QNAME)) {
186 assertTrue(deviationsFound > 0);
190 * Verify loaded modules.
192 * @param containerNode
195 private static void verifyLoadedModules(final ContainerNode containerNode) {
197 final Map<String, String> loadedModules = new HashMap<>();
199 for (final DataContainerChild<? extends PathArgument, ?> child : containerNode.getValue()) {
200 if (child instanceof LeafNode) {
201 assertEquals(IetfYangLibrary.MODULE_SET_ID_LEAF_QNAME, child.getNodeType());
203 if (child instanceof MapNode) {
204 assertEquals(IetfYangLibrary.MODULE_QNAME_LIST, child.getNodeType());
205 for (final MapEntryNode mapEntryNode : ((MapNode) child).getValue()) {
207 String revision = "";
208 for (final DataContainerChild<? extends PathArgument, ?> dataContainerChild : mapEntryNode
210 switch (dataContainerChild.getNodeType().getLocalName()) {
211 case IetfYangLibrary.SPECIFIC_MODULE_NAME_LEAF:
212 name = String.valueOf(dataContainerChild.getValue());
214 case IetfYangLibrary.SPECIFIC_MODULE_REVISION_LEAF:
215 revision = String.valueOf(dataContainerChild.getValue());
218 LOG.info("Unknown local name '{}' of node.",
219 dataContainerChild.getNodeType().getLocalName());
223 loadedModules.put(name, revision);
228 verifyLoadedModules(RestconfMappingNodeUtilTest.modulesRest, loadedModules);
232 * Verify if correct modules were loaded into Restconf module by comparison with modules from
233 * <code>SchemaContext</code>.
234 * @param expectedModules Modules from <code>SchemaContext</code>
235 * @param loadedModules Loaded modules into Restconf module
237 private static void verifyLoadedModules(final Collection<? extends Module> expectedModules,
238 final Map<String, String> loadedModules) {
239 assertEquals("Number of loaded modules is not as expected", expectedModules.size(), loadedModules.size());
240 for (final Module m : expectedModules) {
241 final String name = m.getName();
243 final String revision = loadedModules.get(name);
244 assertNotNull("Expected module not found", revision);
245 assertEquals("Incorrect revision of loaded module", Revision.ofNullable(revision), m.getRevision());
247 loadedModules.remove(name);