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.utils.mapping;
11 import java.time.Instant;
12 import java.time.OffsetDateTime;
13 import java.time.ZoneId;
14 import java.time.format.DateTimeFormatter;
15 import java.util.Collection;
17 import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
18 import org.opendaylight.restconf.Rfc8040.IetfYangLibrary;
19 import org.opendaylight.restconf.Rfc8040.MonitoringModule;
20 import org.opendaylight.restconf.Rfc8040.MonitoringModule.QueryParams;
21 import org.opendaylight.restconf.utils.parser.ParserIdentifier;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev160621.module.list.Module.ConformanceType;
23 import org.opendaylight.yangtools.yang.common.QName;
24 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
25 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
26 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
27 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
28 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
29 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
30 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
31 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
32 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
33 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
34 import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
35 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
36 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
37 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
38 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.ListNodeBuilder;
39 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
40 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
41 import org.opendaylight.yangtools.yang.model.api.Deviation;
42 import org.opendaylight.yangtools.yang.model.api.FeatureDefinition;
43 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
44 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
45 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
46 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
47 import org.opendaylight.yangtools.yang.model.api.Module;
48 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
49 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
50 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
53 * Util class for mapping nodes
56 public final class RestconfMappingNodeUtil {
58 private RestconfMappingNodeUtil() {
59 throw new UnsupportedOperationException("Util class");
63 * Map data from modules to {@link NormalizedNode}
66 * - modules for mapping
67 * @param ietfYangLibraryModule
68 * - ietf-yang-library module
72 * - module-set-id of actual set
73 * @return mapped data as {@link NormalizedNode}
75 public static NormalizedNode<NodeIdentifier, Collection<DataContainerChild<? extends PathArgument, ?>>>
76 mapModulesByIetfYangLibraryYang(final Set<Module> modules, final Module ietfYangLibraryModule,
77 final SchemaContext context, final String moduleSetId) {
78 final DataSchemaNode modulesStateSch =
79 ietfYangLibraryModule.getDataChildByName(IetfYangLibrary.MODUELS_STATE_CONT_QNAME);
80 final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> modulesStateBuilder =
81 Builders.containerBuilder((ContainerSchemaNode) modulesStateSch);
83 final DataSchemaNode moduleSetIdSch =
84 ((ContainerSchemaNode) modulesStateSch).getDataChildByName(IetfYangLibrary.MODULE_SET_ID_LEAF_QNAME);
86 .withChild(Builders.leafBuilder((LeafSchemaNode) moduleSetIdSch).withValue(moduleSetId).build());
88 final DataSchemaNode moduleSch = findNodeInGroupings(IetfYangLibrary.MODULE_QNAME_LIST, ietfYangLibraryModule);
89 final CollectionNodeBuilder<MapEntryNode, OrderedMapNode> mapBuilder =
90 Builders.orderedMapBuilder((ListSchemaNode) moduleSch);
91 for (final Module module : context.getModules()) {
92 fillMapByModules(mapBuilder, moduleSch, false, module, ietfYangLibraryModule, context);
94 return modulesStateBuilder.withChild(mapBuilder.build()).build();
98 * Map data by the specific module or submodule
101 * - ordered list builder for children
103 * - schema of list for entryMapBuilder
105 * - true if module is specified as submodule, false otherwise
107 * - specific module or submodule
108 * @param ietfYangLibraryModule
109 * - ietf-yang-library module
113 private static void fillMapByModules(final CollectionNodeBuilder<MapEntryNode, OrderedMapNode> mapBuilder,
114 final DataSchemaNode moduleSch, final boolean isSubmodule, final Module module,
115 final Module ietfYangLibraryModule, final SchemaContext context) {
116 final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder =
117 Builders.mapEntryBuilder((ListSchemaNode) moduleSch);
118 addCommonLeafs(module, mapEntryBuilder, ietfYangLibraryModule);
119 addChildOfModuleBySpecificModuleInternal(
120 IetfYangLibrary.SPECIFIC_MODULE_SCHEMA_LEAF_QNAME, mapEntryBuilder, IetfYangLibrary.BASE_URI_OF_SCHEMA
121 + module.getName() + "/" + module.getQNameModule().getFormattedRevision(),
122 ietfYangLibraryModule);
124 addChildOfModuleBySpecificModuleOfListChild(IetfYangLibrary.SPECIFIC_MODULE_NAMESPACE_LEAF_QNAME,
125 mapEntryBuilder, module.getNamespace().toString(), ietfYangLibraryModule);
127 // features - not mandatory
128 if ((module.getFeatures() != null) && !module.getFeatures().isEmpty()) {
129 addFeatureLeafList(IetfYangLibrary.SPECIFIC_MODULE_FEATURE_LEAF_LIST_QNAME, mapEntryBuilder,
130 module.getFeatures(), ietfYangLibraryModule);
132 // deviations - not mandatory
133 if ((module.getDeviations() != null) && !module.getDeviations().isEmpty()) {
134 addDeviationList(module, mapEntryBuilder, ietfYangLibraryModule, context);
135 addChildOfModuleBySpecificModuleOfListChild(IetfYangLibrary.SPECIFIC_MODULE_CONFORMANCE_LEAF_QNAME,
136 mapEntryBuilder, ConformanceType.Implement.getName(), ietfYangLibraryModule);
138 addChildOfModuleBySpecificModuleOfListChild(IetfYangLibrary.SPECIFIC_MODULE_CONFORMANCE_LEAF_QNAME,
139 mapEntryBuilder, ConformanceType.Import.getName(), ietfYangLibraryModule);
141 // submodules - not mandatory
142 if ((module.getSubmodules() != null) && !module.getSubmodules().isEmpty()) {
143 addSubmodules(module, mapEntryBuilder, ietfYangLibraryModule, context);
146 mapBuilder.withChild(mapEntryBuilder.build());
150 * Mapping submodules of specific module
153 * - module with submodules
154 * @param mapEntryBuilder
155 * - mapEntryBuilder of parent for mapping children
156 * @param ietfYangLibraryModule
157 * - ietf-yang-library module
161 private static void addSubmodules(final Module module,
162 final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder,
163 final Module ietfYangLibraryModule, final SchemaContext context) {
164 final DataSchemaNode listSubm = findSchemaInListOfModulesSchema(
165 IetfYangLibrary.SPECIFIC_MODULE_SUBMODULE_LIST_QNAME, ietfYangLibraryModule);
166 final CollectionNodeBuilder<MapEntryNode, OrderedMapNode> mapBuilder =
167 Builders.orderedMapBuilder((ListSchemaNode) listSubm);
168 for (final Module submodule : module.getSubmodules()) {
169 fillMapByModules(mapBuilder, listSubm, true, submodule, ietfYangLibraryModule, context);
171 mapEntryBuilder.withChild(mapBuilder.build());
175 * Mapping deviations of specific module
178 * - module with deviations
179 * @param mapEntryBuilder
180 * - mapEntryBuilder of parent for mapping children
181 * @param ietfYangLibraryModule
182 * - ietf-yang-library module
186 private static void addDeviationList(final Module module,
187 final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder,
188 final Module ietfYangLibraryModule, final SchemaContext context) {
189 final DataSchemaNode deviationsSchema = findSchemaInListOfModulesSchema(
190 IetfYangLibrary.SPECIFIC_MODULE_DEVIATION_LIST_QNAME, ietfYangLibraryModule);
191 final CollectionNodeBuilder<MapEntryNode, MapNode> deviations =
192 Builders.mapBuilder((ListSchemaNode) deviationsSchema);
193 for (final Deviation deviation : module.getDeviations()) {
194 final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> deviationEntryNode =
195 Builders.mapEntryBuilder((ListSchemaNode) deviationsSchema);
196 final QName lastComponent = deviation.getTargetPath().getLastComponent();
197 addChildOfModuleBySpecificModule(IetfYangLibrary.SPECIFIC_MODULE_NAME_LEAF_QNAME, deviationEntryNode,
198 context.findModuleByNamespaceAndRevision(lastComponent.getNamespace(), lastComponent.getRevision())
200 ietfYangLibraryModule);
201 addChildOfModuleBySpecificModule(IetfYangLibrary.SPECIFIC_MODULE_REVISION_LEAF_QNAME, deviationEntryNode,
202 lastComponent.getRevision(), ietfYangLibraryModule);
203 deviations.withChild(deviationEntryNode.build());
205 mapEntryBuilder.withChild(deviations.build());
209 * Mapping features of specific module
211 * @param qnameOfFeaturesLeafList
212 * - qname of feature leaf-list in ietf-yang-library module
213 * @param mapEntryBuilder
214 * - mapEntryBuilder of parent for mapping children
216 * - features of specific module
217 * @param ietfYangLibraryModule
218 * - ieat-yang-library module
220 private static void addFeatureLeafList(final QName qnameOfFeaturesLeafList,
221 final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder,
222 final Set<FeatureDefinition> features, final Module ietfYangLibraryModule) {
223 final DataSchemaNode schemaNode =
224 findSchemaInListOfModulesSchema(qnameOfFeaturesLeafList, ietfYangLibraryModule);
225 final ListNodeBuilder<Object, LeafSetEntryNode<Object>> leafSetBuilder =
226 Builders.leafSetBuilder((LeafListSchemaNode) schemaNode);
227 for (final FeatureDefinition feature : features) {
228 leafSetBuilder.withChild(Builders.leafSetEntryBuilder((LeafListSchemaNode) schemaNode)
229 .withValue(feature.getQName().getLocalName()).build());
231 mapEntryBuilder.withChild(leafSetBuilder.build());
235 * Mapping common leafs (grouping common-leafs in ietf-yang-library) of
239 * - specific module for getting name and revision
240 * @param mapEntryBuilder
241 * - mapEntryBuilder of parent for mapping children
242 * @param ietfYangLibraryModule
243 * - ietf-yang-library module
245 private static void addCommonLeafs(final Module module,
246 final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder,
247 final Module ietfYangLibraryModule) {
248 addChildOfModuleBySpecificModuleInternal(IetfYangLibrary.SPECIFIC_MODULE_NAME_LEAF_QNAME, mapEntryBuilder,
249 module.getName(), ietfYangLibraryModule);
250 addChildOfModuleBySpecificModuleInternal(IetfYangLibrary.SPECIFIC_MODULE_REVISION_LEAF_QNAME, mapEntryBuilder,
251 module.getQNameModule().getFormattedRevision(), ietfYangLibraryModule);
255 * Mapping data child of grouping module-list by ietf-yang-library
257 * @param specificQName
258 * - qname of leaf in module-list grouping
259 * @param mapEntryBuilder
260 * - mapEntryBuilder of parent for mapping children
263 * @param ietfYangLibraryModule
264 * - ietf-yang-library module
266 private static void addChildOfModuleBySpecificModuleOfListChild(final QName specificQName,
267 final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder,
268 final Object value, final Module ietfYangLibraryModule) {
269 final DataSchemaNode leafSch = findSchemaInListOfModulesSchema(specificQName, ietfYangLibraryModule);
270 mapEntryBuilder.withChild(Builders.leafBuilder((LeafSchemaNode) leafSch).withValue(value).build());
274 * Find specific schema in gourping module-lsit
276 * @param specificQName
278 * @param ietfYangLibraryModule
279 * - ietf-yang-library module
280 * @return schemaNode of specific child
282 private static DataSchemaNode findSchemaInListOfModulesSchema(final QName specificQName,
283 final Module ietfYangLibraryModule) {
284 for (final GroupingDefinition groupingDefinition : ietfYangLibraryModule.getGroupings()) {
285 if (groupingDefinition.getQName().equals(IetfYangLibrary.GROUPING_MODULE_LIST_QNAME)) {
286 final DataSchemaNode dataChildByName =
287 groupingDefinition.getDataChildByName(IetfYangLibrary.MODULE_QNAME_LIST);
288 return ((ListSchemaNode) dataChildByName).getDataChildByName(specificQName);
291 throw new RestconfDocumentedException(specificQName.getLocalName() + " doesn't exist.");
295 * Mapping data child of internal groupings in module-list grouping
297 * @param specifiLeafQName
298 * - qnmae of leaf for mapping
299 * @param mapEntryBuilder
300 * - mapEntryBuilder of parent for mapping children
303 * @param ietfYangLibraryModule
304 * - ietf-yang-library module
306 private static void addChildOfModuleBySpecificModuleInternal(final QName specifiLeafQName,
307 final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder,
308 final Object value, final Module ietfYangLibraryModule) {
309 final DataSchemaNode nameLeaf = findNodeInInternGroupings(specifiLeafQName, ietfYangLibraryModule);
310 mapEntryBuilder.withChild(Builders.leafBuilder((LeafSchemaNode) nameLeaf).withValue(value).build());
314 * Find schema node of leaf by qname in internal groupings of module-list
317 * @param qnameOfSchema
319 * @param ietfYangLibraryModule
320 * - ietf-yang-library module
321 * @return schema node of specific leaf
323 private static DataSchemaNode findNodeInInternGroupings(final QName qnameOfSchema,
324 final Module ietfYangLibraryModule) {
325 for (final GroupingDefinition groupingDefinition : ietfYangLibraryModule.getGroupings()) {
326 if (groupingDefinition.getQName().equals(IetfYangLibrary.GROUPING_MODULE_LIST_QNAME)) {
327 for (final GroupingDefinition internalGrouping : groupingDefinition.getGroupings()) {
328 if (internalGrouping.getDataChildByName(qnameOfSchema) != null) {
329 return internalGrouping.getDataChildByName(qnameOfSchema);
334 throw new RestconfDocumentedException(qnameOfSchema.getLocalName() + " doesn't exist.");
338 * Mapping childrens of list-module
340 * @param specifiLeafQName
342 * @param mapEntryBuilder
343 * - maptEntryBuilder of parent for mapping children
346 * @param ietfYangLibraryModule
347 * - ietf-yang-library module
349 private static void addChildOfModuleBySpecificModule(final QName specifiLeafQName,
350 final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder,
351 final Object value, final Module ietfYangLibraryModule) {
352 final DataSchemaNode nameLeaf = findNodeInGroupings(specifiLeafQName, ietfYangLibraryModule);
353 mapEntryBuilder.withChild(Builders.leafBuilder((LeafSchemaNode) nameLeaf).withValue(value).build());
357 * Find schema of specific leaf in list-module grouping
359 * @param qnameOfSchema
361 * @param ietfYangLibraryModule
362 * - ietf-yang-library module
363 * @return schemaNode of specific leaf
365 private static DataSchemaNode findNodeInGroupings(final QName qnameOfSchema, final Module ietfYangLibraryModule) {
366 for (final GroupingDefinition groupingDefinition : ietfYangLibraryModule.getGroupings()) {
367 if (groupingDefinition.getDataChildByName(qnameOfSchema) != null) {
368 return groupingDefinition.getDataChildByName(qnameOfSchema);
371 throw new RestconfDocumentedException(qnameOfSchema.getLocalName() + " doesn't exist.");
375 * Map capabilites by ietf-restconf-monitoring
377 * @param monitoringModule
378 * - ietf-restconf-monitoring module
379 * @return mapped capabilites
381 public static NormalizedNode<NodeIdentifier, Collection<DataContainerChild<? extends PathArgument, ?>>>
382 mapCapabilites(final Module monitoringModule) {
383 final DataSchemaNode restconfState =
384 monitoringModule.getDataChildByName(MonitoringModule.CONT_RESTCONF_STATE_QNAME);
385 final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> restStateContBuilder =
386 Builders.containerBuilder((ContainerSchemaNode) restconfState);
387 final DataSchemaNode capabilitesContSchema =
388 getChildOfCont((ContainerSchemaNode) restconfState, MonitoringModule.CONT_CAPABILITES_QNAME);
389 final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> capabilitesContBuilder =
390 Builders.containerBuilder((ContainerSchemaNode) capabilitesContSchema);
391 final DataSchemaNode leafListCapa = getChildOfCont((ContainerSchemaNode) capabilitesContSchema,
392 MonitoringModule.LEAF_LIST_CAPABILITY_QNAME);
393 final ListNodeBuilder<Object, LeafSetEntryNode<Object>> leafListCapaBuilder =
394 Builders.orderedLeafSetBuilder((LeafListSchemaNode) leafListCapa);
395 fillLeafListCapa(leafListCapaBuilder, (LeafListSchemaNode) leafListCapa);
397 return restStateContBuilder.withChild(capabilitesContBuilder.withChild(leafListCapaBuilder.build()).build())
402 * Map data to leaf-list
405 * - builder of parent for children
406 * @param leafListSchema
408 @SuppressWarnings({ "unchecked", "rawtypes" })
409 private static void fillLeafListCapa(final ListNodeBuilder builder, final LeafListSchemaNode leafListSchema) {
410 builder.withChild(leafListEntryBuild(leafListSchema, QueryParams.DEPTH));
411 builder.withChild(leafListEntryBuild(leafListSchema, QueryParams.FIELDS));
412 builder.withChild(leafListEntryBuild(leafListSchema, QueryParams.FILTER));
413 builder.withChild(leafListEntryBuild(leafListSchema, QueryParams.REPLAY));
414 builder.withChild(leafListEntryBuild(leafListSchema, QueryParams.WITH_DEFAULTS));
418 * Map value to leaf list entry node
420 * @param leafListSchema
421 * - leaf list schema of leaf list entry
423 * - value of leaf entry
426 @SuppressWarnings("rawtypes")
427 private static LeafSetEntryNode leafListEntryBuild(final LeafListSchemaNode leafListSchema, final String value) {
428 return Builders.leafSetEntryBuilder(leafListSchema).withValue(value).build();
432 * Find specific schema node by qname in parent {@link ContainerSchemaNode}
437 * - specific qname of child
438 * @return schema node of child by qname
440 private static DataSchemaNode getChildOfCont(final ContainerSchemaNode parent, final QName childQName) {
441 for (final DataSchemaNode child : parent.getChildNodes()) {
442 if (child.getQName().equals(childQName)) {
446 throw new RestconfDocumentedException(
447 childQName.getLocalName() + " doesn't exist in container " + MonitoringModule.CONT_RESTCONF_STATE_NAME);
451 * Map data of yang notification to normalized node according to
452 * ietf-restconf-monitoring
455 * - qname of notification from listener
456 * @param notifications
457 * - list of notifications for find schema of notification by
460 * - start-time query parameter of notification
462 * - output type of notification
464 * - location of registered listener for sending data of
466 * @param monitoringModule
467 * - ietf-restconf-monitoring module
469 * - true if data of parent -
470 * ietf-restconf-monitoring:restconf-state/streams - exist in DS
471 * @return mapped data of notification - map entry node if parent exists,
472 * container streams with list and map entry node if not
474 @SuppressWarnings("rawtypes")
475 public static NormalizedNode mapYangNotificationStreamByIetfRestconfMonitoring(final QName notifiQName,
476 final Set<NotificationDefinition> notifications, final Instant start, final String outputType,
477 final URI uri, final Module monitoringModule, final boolean existParent) {
478 for (final NotificationDefinition notificationDefinition : notifications) {
479 if (notificationDefinition.getQName().equals(notifiQName)) {
480 final DataSchemaNode streamListSchema = ((ContainerSchemaNode) ((ContainerSchemaNode) monitoringModule
481 .getDataChildByName(MonitoringModule.CONT_RESTCONF_STATE_QNAME))
482 .getDataChildByName(MonitoringModule.CONT_STREAMS_QNAME))
483 .getDataChildByName(MonitoringModule.LIST_STREAM_QNAME);
484 final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> streamEntry =
485 Builders.mapEntryBuilder((ListSchemaNode) streamListSchema);
487 final ListSchemaNode listSchema = ((ListSchemaNode) streamListSchema);
488 prepareLeafAndFillEntryBuilder(streamEntry,
489 listSchema.getDataChildByName(MonitoringModule.LEAF_NAME_STREAM_QNAME),
490 notificationDefinition.getQName().getLocalName());
491 if ((notificationDefinition.getDescription() != null)
492 && !notificationDefinition.getDescription().equals("")) {
493 prepareLeafAndFillEntryBuilder(streamEntry,
494 listSchema.getDataChildByName(MonitoringModule.LEAF_DESCR_STREAM_QNAME),
495 notificationDefinition.getDescription());
497 prepareLeafAndFillEntryBuilder(streamEntry,
498 listSchema.getDataChildByName(MonitoringModule.LEAF_REPLAY_SUPP_STREAM_QNAME), true);
500 prepareLeafAndFillEntryBuilder(streamEntry,
501 listSchema.getDataChildByName(MonitoringModule.LEAF_START_TIME_STREAM_QNAME),
502 DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(OffsetDateTime.ofInstant(start,
503 ZoneId.systemDefault())));
505 prepareListAndFillEntryBuilder(streamEntry,
506 (ListSchemaNode) listSchema.getDataChildByName(MonitoringModule.LIST_ACCESS_STREAM_QNAME),
510 final DataSchemaNode contStreamsSchema = ((ContainerSchemaNode) monitoringModule
511 .getDataChildByName(MonitoringModule.CONT_RESTCONF_STATE_QNAME))
512 .getDataChildByName(MonitoringModule.CONT_STREAMS_QNAME);
513 return Builders.containerBuilder((ContainerSchemaNode) contStreamsSchema).withChild(Builders
514 .mapBuilder((ListSchemaNode) streamListSchema).withChild(streamEntry.build()).build())
517 return streamEntry.build();
521 throw new RestconfDocumentedException(notifiQName + " doesn't exist in any modul");
524 private static void prepareListAndFillEntryBuilder(
525 final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> streamEntry,
526 final ListSchemaNode listSchemaNode, final String outputType, final URI uriToWebsocketServer) {
527 final CollectionNodeBuilder<MapEntryNode, MapNode> accessListBuilder = Builders.mapBuilder(listSchemaNode);
528 final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entryAccessList =
529 Builders.mapEntryBuilder(listSchemaNode);
530 prepareLeafAndFillEntryBuilder(entryAccessList,
531 listSchemaNode.getDataChildByName(MonitoringModule.LEAF_ENCODING_ACCESS_QNAME), outputType);
532 prepareLeafAndFillEntryBuilder(entryAccessList,
533 listSchemaNode.getDataChildByName(MonitoringModule.LEAF_LOCATION_ACCESS_QNAME),
534 uriToWebsocketServer.toString());
535 streamEntry.withChild(accessListBuilder.withChild(entryAccessList.build()).build());
540 * @param dataChildByName
543 private static void prepareLeafAndFillEntryBuilder(
544 final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> streamEntry,
545 final DataSchemaNode leafSchema, final Object value) {
546 streamEntry.withChild(Builders.leafBuilder((LeafSchemaNode) leafSchema).withValue(value).build());
550 * Map data of data change notification to normalized node according to
551 * ietf-restconf-monitoring
554 * - path of data to listen on
556 * - start-time query parameter of notification
558 * - output type of notification
560 * - location of registered listener for sending data of
562 * @param monitoringModule
563 * - ietf-restconf-monitoring module
565 * - true if data of parent -
566 * ietf-restconf-monitoring:restconf-state/streams - exist in DS
567 * @param schemaContext
568 * - schemaContext for parsing instance identifier to get schema
570 * @return mapped data of notification - map entry node if parent exists,
571 * container streams with list and map entry node if not
573 @SuppressWarnings("rawtypes")
574 public static NormalizedNode mapDataChangeNotificationStreamByIetfRestconfMonitoring(
575 final YangInstanceIdentifier path, final Instant start, final String outputType, final URI uri,
576 final Module monitoringModule, final boolean existParent, final SchemaContext schemaContext) {
577 final SchemaNode schemaNode = ParserIdentifier
578 .toInstanceIdentifier(ParserIdentifier.stringFromYangInstanceIdentifier(path, schemaContext),
581 final DataSchemaNode streamListSchema = ((ContainerSchemaNode) ((ContainerSchemaNode) monitoringModule
582 .getDataChildByName(MonitoringModule.CONT_RESTCONF_STATE_QNAME))
583 .getDataChildByName(MonitoringModule.CONT_STREAMS_QNAME))
584 .getDataChildByName(MonitoringModule.LIST_STREAM_QNAME);
585 final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> streamEntry =
586 Builders.mapEntryBuilder((ListSchemaNode) streamListSchema);
588 final ListSchemaNode listSchema = ((ListSchemaNode) streamListSchema);
589 prepareLeafAndFillEntryBuilder(streamEntry,
590 listSchema.getDataChildByName(MonitoringModule.LEAF_NAME_STREAM_QNAME),
591 schemaNode.getQName().getLocalName());
592 if ((schemaNode.getDescription() != null) && !schemaNode.getDescription().equals("")) {
593 prepareLeafAndFillEntryBuilder(streamEntry,
594 listSchema.getDataChildByName(MonitoringModule.LEAF_DESCR_STREAM_QNAME),
595 schemaNode.getDescription());
597 prepareLeafAndFillEntryBuilder(streamEntry,
598 listSchema.getDataChildByName(MonitoringModule.LEAF_REPLAY_SUPP_STREAM_QNAME), true);
599 prepareLeafAndFillEntryBuilder(streamEntry,
600 listSchema.getDataChildByName(MonitoringModule.LEAF_START_TIME_STREAM_QNAME),
601 DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(OffsetDateTime.ofInstant(start, ZoneId.systemDefault())));
602 prepareListAndFillEntryBuilder(streamEntry,
603 (ListSchemaNode) listSchema.getDataChildByName(MonitoringModule.LIST_ACCESS_STREAM_QNAME), outputType,
607 final DataSchemaNode contStreamsSchema = ((ContainerSchemaNode) monitoringModule
608 .getDataChildByName(MonitoringModule.CONT_RESTCONF_STATE_QNAME))
609 .getDataChildByName(MonitoringModule.CONT_STREAMS_QNAME);
611 .containerBuilder((ContainerSchemaNode) contStreamsSchema).withChild(Builders
612 .mapBuilder((ListSchemaNode) streamListSchema).withChild(streamEntry.build()).build())
615 return streamEntry.build();