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;
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;
16 import java.util.Optional;
18 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
19 import org.opendaylight.restconf.nb.rfc8040.Rfc8040.IetfYangLibrary;
20 import org.opendaylight.restconf.nb.rfc8040.Rfc8040.MonitoringModule;
21 import org.opendaylight.restconf.nb.rfc8040.Rfc8040.MonitoringModule.QueryParams;
22 import org.opendaylight.restconf.nb.rfc8040.utils.parser.ParserIdentifier;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev160621.module.list.Module.ConformanceType;
24 import org.opendaylight.yangtools.yang.common.QName;
25 import org.opendaylight.yangtools.yang.common.Revision;
26 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
27 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
28 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
29 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
30 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
31 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
32 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
33 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
34 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
35 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
36 import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
37 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
38 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
39 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
40 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.ListNodeBuilder;
41 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
42 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
43 import org.opendaylight.yangtools.yang.model.api.Deviation;
44 import org.opendaylight.yangtools.yang.model.api.FeatureDefinition;
45 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
46 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
47 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
48 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
49 import org.opendaylight.yangtools.yang.model.api.Module;
50 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
51 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
52 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
55 * Util class for mapping nodes.
58 public final class RestconfMappingNodeUtil {
60 private RestconfMappingNodeUtil() {
61 throw new UnsupportedOperationException("Util class");
65 * Map data from modules to {@link NormalizedNode}.
69 * @param ietfYangLibraryModule
70 * ietf-yang-library module
74 * module-set-id of actual set
75 * @return mapped data as {@link NormalizedNode}
77 public static NormalizedNode<NodeIdentifier, Collection<DataContainerChild<? extends PathArgument, ?>>>
78 mapModulesByIetfYangLibraryYang(final Set<Module> modules, final Module ietfYangLibraryModule,
79 final SchemaContext context, final String moduleSetId) {
80 final DataSchemaNode modulesStateSch =
81 ietfYangLibraryModule.getDataChildByName(IetfYangLibrary.MODUELS_STATE_CONT_QNAME);
82 final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> modulesStateBuilder =
83 Builders.containerBuilder((ContainerSchemaNode) modulesStateSch);
85 final DataSchemaNode moduleSetIdSch =
86 ((ContainerSchemaNode) modulesStateSch).getDataChildByName(IetfYangLibrary.MODULE_SET_ID_LEAF_QNAME);
88 .withChild(Builders.leafBuilder((LeafSchemaNode) moduleSetIdSch).withValue(moduleSetId).build());
90 final DataSchemaNode moduleSch = findNodeInGroupings(IetfYangLibrary.MODULE_QNAME_LIST, ietfYangLibraryModule);
91 final CollectionNodeBuilder<MapEntryNode, OrderedMapNode> mapBuilder =
92 Builders.orderedMapBuilder((ListSchemaNode) moduleSch);
93 for (final Module module : context.getModules()) {
94 fillMapByModules(mapBuilder, moduleSch, false, module, ietfYangLibraryModule, context);
96 return modulesStateBuilder.withChild(mapBuilder.build()).build();
100 * Map data by the specific module or submodule.
103 * ordered list builder for children
105 * schema of list for entryMapBuilder
107 * true if module is specified as submodule, false otherwise
109 * specific module or submodule
110 * @param ietfYangLibraryModule
111 * ietf-yang-library module
115 private static void fillMapByModules(final CollectionNodeBuilder<MapEntryNode, OrderedMapNode> mapBuilder,
116 final DataSchemaNode moduleSch, final boolean isSubmodule, final Module module,
117 final Module ietfYangLibraryModule, final SchemaContext context) {
118 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder =
119 Builders.mapEntryBuilder((ListSchemaNode) moduleSch);
120 addCommonLeafs(module, mapEntryBuilder, ietfYangLibraryModule);
121 addChildOfModuleBySpecificModuleInternal(
122 IetfYangLibrary.SPECIFIC_MODULE_SCHEMA_LEAF_QNAME, mapEntryBuilder, IetfYangLibrary.BASE_URI_OF_SCHEMA
123 + module.getName() + "/"
124 + module.getQNameModule().getRevision().map(Revision::toString).orElse(null),
125 ietfYangLibraryModule);
127 addChildOfModuleBySpecificModuleOfListChild(IetfYangLibrary.SPECIFIC_MODULE_NAMESPACE_LEAF_QNAME,
128 mapEntryBuilder, module.getNamespace().toString(), ietfYangLibraryModule);
130 // features - not mandatory
131 if (module.getFeatures() != null && !module.getFeatures().isEmpty()) {
132 addFeatureLeafList(IetfYangLibrary.SPECIFIC_MODULE_FEATURE_LEAF_LIST_QNAME, mapEntryBuilder,
133 module.getFeatures(), ietfYangLibraryModule);
135 // deviations - not mandatory
136 if (module.getDeviations() != null && !module.getDeviations().isEmpty()) {
137 addDeviationList(module, mapEntryBuilder, ietfYangLibraryModule, context);
138 addChildOfModuleBySpecificModuleOfListChild(IetfYangLibrary.SPECIFIC_MODULE_CONFORMANCE_LEAF_QNAME,
139 mapEntryBuilder, ConformanceType.Implement.getName(), ietfYangLibraryModule);
141 addChildOfModuleBySpecificModuleOfListChild(IetfYangLibrary.SPECIFIC_MODULE_CONFORMANCE_LEAF_QNAME,
142 mapEntryBuilder, ConformanceType.Import.getName(), ietfYangLibraryModule);
144 // submodules - not mandatory
145 if (module.getSubmodules() != null && !module.getSubmodules().isEmpty()) {
146 addSubmodules(module, mapEntryBuilder, ietfYangLibraryModule, context);
149 mapBuilder.withChild(mapEntryBuilder.build());
153 * Mapping submodules of specific module.
156 * module with submodules
157 * @param mapEntryBuilder
158 * mapEntryBuilder of parent for mapping children
159 * @param ietfYangLibraryModule
160 * ietf-yang-library module
164 private static void addSubmodules(final Module module,
165 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder,
166 final Module ietfYangLibraryModule, final SchemaContext context) {
167 final DataSchemaNode listSubm = findSchemaInListOfModulesSchema(
168 IetfYangLibrary.SPECIFIC_MODULE_SUBMODULE_LIST_QNAME, ietfYangLibraryModule);
169 final CollectionNodeBuilder<MapEntryNode, OrderedMapNode> mapBuilder =
170 Builders.orderedMapBuilder((ListSchemaNode) listSubm);
171 for (final Module submodule : module.getSubmodules()) {
172 fillMapByModules(mapBuilder, listSubm, true, submodule, ietfYangLibraryModule, context);
174 mapEntryBuilder.withChild(mapBuilder.build());
178 * Mapping deviations of specific module.
181 * module with deviations
182 * @param mapEntryBuilder
183 * mapEntryBuilder of parent for mapping children
184 * @param ietfYangLibraryModule
185 * ietf-yang-library module
189 private static void addDeviationList(final Module module,
190 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder,
191 final Module ietfYangLibraryModule, final SchemaContext context) {
192 final DataSchemaNode deviationsSchema = findSchemaInListOfModulesSchema(
193 IetfYangLibrary.SPECIFIC_MODULE_DEVIATION_LIST_QNAME, ietfYangLibraryModule);
194 final CollectionNodeBuilder<MapEntryNode, MapNode> deviations =
195 Builders.mapBuilder((ListSchemaNode) deviationsSchema);
196 for (final Deviation deviation : module.getDeviations()) {
197 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> deviationEntryNode =
198 Builders.mapEntryBuilder((ListSchemaNode) deviationsSchema);
199 final QName lastComponent = deviation.getTargetPath().getLastComponent();
200 addChildOfModuleBySpecificModule(IetfYangLibrary.SPECIFIC_MODULE_NAME_LEAF_QNAME, deviationEntryNode,
201 context.findModule(lastComponent.getModule()).get().getName(),
202 ietfYangLibraryModule);
203 addChildOfModuleBySpecificModule(IetfYangLibrary.SPECIFIC_MODULE_REVISION_LEAF_QNAME, deviationEntryNode,
204 lastComponent.getRevision(), ietfYangLibraryModule);
205 deviations.withChild(deviationEntryNode.build());
207 mapEntryBuilder.withChild(deviations.build());
211 * Mapping features of specific module.
213 * @param qnameOfFeaturesLeafList
214 * qname of feature leaf-list in ietf-yang-library module
215 * @param mapEntryBuilder
216 * mapEntryBuilder of parent for mapping children
218 * features of specific module
219 * @param ietfYangLibraryModule
220 * ieat-yang-library module
222 private static void addFeatureLeafList(final QName qnameOfFeaturesLeafList,
223 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder,
224 final Set<FeatureDefinition> features, final Module ietfYangLibraryModule) {
225 final DataSchemaNode schemaNode =
226 findSchemaInListOfModulesSchema(qnameOfFeaturesLeafList, ietfYangLibraryModule);
227 final ListNodeBuilder<Object, LeafSetEntryNode<Object>> leafSetBuilder =
228 Builders.leafSetBuilder((LeafListSchemaNode) schemaNode);
229 for (final FeatureDefinition feature : features) {
230 leafSetBuilder.withChild(Builders.leafSetEntryBuilder((LeafListSchemaNode) schemaNode)
231 .withValue(feature.getQName().getLocalName()).build());
233 mapEntryBuilder.withChild(leafSetBuilder.build());
237 * Mapping common leafs (grouping common-leafs in ietf-yang-library) of
241 * specific module for getting name and revision
242 * @param mapEntryBuilder
243 * mapEntryBuilder of parent for mapping children
244 * @param ietfYangLibraryModule
245 * ietf-yang-library module
247 private static void addCommonLeafs(final Module module,
248 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder,
249 final Module ietfYangLibraryModule) {
250 addChildOfModuleBySpecificModuleInternal(IetfYangLibrary.SPECIFIC_MODULE_NAME_LEAF_QNAME, mapEntryBuilder,
251 module.getName(), ietfYangLibraryModule);
252 addChildOfModuleBySpecificModuleInternal(IetfYangLibrary.SPECIFIC_MODULE_REVISION_LEAF_QNAME, mapEntryBuilder,
253 module.getQNameModule().getRevision().map(Revision::toString).orElse(""), ietfYangLibraryModule);
257 * Mapping data child of grouping module-list by ietf-yang-library.
259 * @param specificQName
260 * qname of leaf in module-list grouping
261 * @param mapEntryBuilder
262 * mapEntryBuilder of parent for mapping children
265 * @param ietfYangLibraryModule
266 * ietf-yang-library module
268 private static void addChildOfModuleBySpecificModuleOfListChild(final QName specificQName,
269 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder,
270 final Object value, final Module ietfYangLibraryModule) {
271 final DataSchemaNode leafSch = findSchemaInListOfModulesSchema(specificQName, ietfYangLibraryModule);
272 mapEntryBuilder.withChild(Builders.leafBuilder((LeafSchemaNode) leafSch).withValue(value).build());
276 * Find specific schema in gourping module-lsit.
278 * @param specificQName
280 * @param ietfYangLibraryModule
281 * ietf-yang-library module
282 * @return schemaNode of specific child
284 private static DataSchemaNode findSchemaInListOfModulesSchema(final QName specificQName,
285 final Module ietfYangLibraryModule) {
286 for (final GroupingDefinition groupingDefinition : ietfYangLibraryModule.getGroupings()) {
287 if (groupingDefinition.getQName().equals(IetfYangLibrary.GROUPING_MODULE_LIST_QNAME)) {
288 final DataSchemaNode dataChildByName =
289 groupingDefinition.getDataChildByName(IetfYangLibrary.MODULE_QNAME_LIST);
290 return ((ListSchemaNode) dataChildByName).getDataChildByName(specificQName);
293 throw new RestconfDocumentedException(specificQName.getLocalName() + " doesn't exist.");
297 * Mapping data child of internal groupings in module-list grouping.
299 * @param specifiLeafQName
300 * qnmae of leaf for mapping
301 * @param mapEntryBuilder
302 * mapEntryBuilder of parent for mapping children
305 * @param ietfYangLibraryModule
306 * ietf-yang-library module
308 private static void addChildOfModuleBySpecificModuleInternal(final QName specifiLeafQName,
309 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder,
310 final Object value, final Module ietfYangLibraryModule) {
311 final DataSchemaNode nameLeaf = findNodeInInternGroupings(specifiLeafQName, ietfYangLibraryModule);
312 mapEntryBuilder.withChild(Builders.leafBuilder((LeafSchemaNode) nameLeaf).withValue(value).build());
316 * Find schema node of leaf by qname in internal groupings of module-list.
319 * @param qnameOfSchema
321 * @param ietfYangLibraryModule
322 * ietf-yang-library module
323 * @return schema node of specific leaf
325 private static DataSchemaNode findNodeInInternGroupings(final QName qnameOfSchema,
326 final Module ietfYangLibraryModule) {
327 for (final GroupingDefinition groupingDefinition : ietfYangLibraryModule.getGroupings()) {
328 if (groupingDefinition.getQName().equals(IetfYangLibrary.GROUPING_MODULE_LIST_QNAME)) {
329 for (final GroupingDefinition internalGrouping : groupingDefinition.getGroupings()) {
330 if (internalGrouping.getDataChildByName(qnameOfSchema) != null) {
331 return internalGrouping.getDataChildByName(qnameOfSchema);
336 throw new RestconfDocumentedException(qnameOfSchema.getLocalName() + " doesn't exist.");
340 * Mapping childrens of list-module.
342 * @param specifiLeafQName
344 * @param mapEntryBuilder
345 * maptEntryBuilder of parent for mapping children
348 * @param ietfYangLibraryModule
349 * ietf-yang-library module
351 private static void addChildOfModuleBySpecificModule(final QName specifiLeafQName,
352 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder,
353 final Object value, final Module ietfYangLibraryModule) {
354 final DataSchemaNode nameLeaf = findNodeInGroupings(specifiLeafQName, ietfYangLibraryModule);
355 mapEntryBuilder.withChild(Builders.leafBuilder((LeafSchemaNode) nameLeaf).withValue(value).build());
359 * Find schema of specific leaf in list-module grouping.
361 * @param qnameOfSchema
363 * @param ietfYangLibraryModule
364 * ietf-yang-library module
365 * @return schemaNode of specific leaf
367 private static DataSchemaNode findNodeInGroupings(final QName qnameOfSchema, final Module ietfYangLibraryModule) {
368 for (final GroupingDefinition groupingDefinition : ietfYangLibraryModule.getGroupings()) {
369 if (groupingDefinition.getDataChildByName(qnameOfSchema) != null) {
370 return groupingDefinition.getDataChildByName(qnameOfSchema);
373 throw new RestconfDocumentedException(qnameOfSchema.getLocalName() + " doesn't exist.");
377 * Map capabilites by ietf-restconf-monitoring.
379 * @param monitoringModule
380 * ietf-restconf-monitoring module
381 * @return mapped capabilites
383 public static NormalizedNode<NodeIdentifier, Collection<DataContainerChild<? extends PathArgument, ?>>>
384 mapCapabilites(final Module monitoringModule) {
385 final DataSchemaNode restconfState =
386 monitoringModule.getDataChildByName(MonitoringModule.CONT_RESTCONF_STATE_QNAME);
387 final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> restStateContBuilder =
388 Builders.containerBuilder((ContainerSchemaNode) restconfState);
389 final DataSchemaNode capabilitesContSchema =
390 getChildOfCont((ContainerSchemaNode) restconfState, MonitoringModule.CONT_CAPABILITES_QNAME);
391 final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> capabilitesContBuilder =
392 Builders.containerBuilder((ContainerSchemaNode) capabilitesContSchema);
393 final DataSchemaNode leafListCapa = getChildOfCont((ContainerSchemaNode) capabilitesContSchema,
394 MonitoringModule.LEAF_LIST_CAPABILITY_QNAME);
395 final ListNodeBuilder<Object, LeafSetEntryNode<Object>> leafListCapaBuilder =
396 Builders.orderedLeafSetBuilder((LeafListSchemaNode) leafListCapa);
397 fillLeafListCapa(leafListCapaBuilder, (LeafListSchemaNode) leafListCapa);
399 return restStateContBuilder.withChild(capabilitesContBuilder.withChild(leafListCapaBuilder.build()).build())
404 * Map data to leaf-list.
407 * builder of parent for children
408 * @param leafListSchema
411 @SuppressWarnings({ "unchecked", "rawtypes" })
412 private static void fillLeafListCapa(final ListNodeBuilder builder, final LeafListSchemaNode leafListSchema) {
413 builder.withChild(leafListEntryBuild(leafListSchema, QueryParams.DEPTH));
414 builder.withChild(leafListEntryBuild(leafListSchema, QueryParams.FIELDS));
415 builder.withChild(leafListEntryBuild(leafListSchema, QueryParams.FILTER));
416 builder.withChild(leafListEntryBuild(leafListSchema, QueryParams.REPLAY));
417 builder.withChild(leafListEntryBuild(leafListSchema, QueryParams.WITH_DEFAULTS));
421 * Map value to leaf list entry node.
423 * @param leafListSchema
424 * leaf list schema of leaf list entry
426 * value of leaf entry
429 @SuppressWarnings("rawtypes")
430 private static LeafSetEntryNode leafListEntryBuild(final LeafListSchemaNode leafListSchema, final String value) {
431 return Builders.leafSetEntryBuilder(leafListSchema).withValue(value).build();
435 * Find specific schema node by qname in parent {@link ContainerSchemaNode}.
440 * specific qname of child
441 * @return schema node of child by qname
443 private static DataSchemaNode getChildOfCont(final ContainerSchemaNode parent, final QName childQName) {
444 for (final DataSchemaNode child : parent.getChildNodes()) {
445 if (child.getQName().equals(childQName)) {
449 throw new RestconfDocumentedException(
450 childQName.getLocalName() + " doesn't exist in container " + MonitoringModule.CONT_RESTCONF_STATE_NAME);
454 * Map data of yang notification to normalized node according to
455 * ietf-restconf-monitoring.
458 * qname of notification from listener
459 * @param notifications
460 * list of notifications for find schema of notification by
463 * start-time query parameter of notification
465 * output type of notification
467 * location of registered listener for sending data of
469 * @param monitoringModule
470 * ietf-restconf-monitoring module
472 * true if data of parent -
473 * ietf-restconf-monitoring:restconf-state/streams - exist in DS
474 * @return mapped data of notification - map entry node if parent exists,
475 * container streams with list and map entry node if not
477 @SuppressWarnings("rawtypes")
478 public static NormalizedNode mapYangNotificationStreamByIetfRestconfMonitoring(final QName notifiQName,
479 final Set<NotificationDefinition> notifications, final Instant start, final String outputType,
480 final URI uri, final Module monitoringModule, final boolean existParent) {
481 for (final NotificationDefinition notificationDefinition : notifications) {
482 if (notificationDefinition.getQName().equals(notifiQName)) {
483 final DataSchemaNode streamListSchema = ((ContainerSchemaNode) ((ContainerSchemaNode) monitoringModule
484 .getDataChildByName(MonitoringModule.CONT_RESTCONF_STATE_QNAME))
485 .getDataChildByName(MonitoringModule.CONT_STREAMS_QNAME))
486 .getDataChildByName(MonitoringModule.LIST_STREAM_QNAME);
487 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> streamEntry =
488 Builders.mapEntryBuilder((ListSchemaNode) streamListSchema);
490 final ListSchemaNode listSchema = (ListSchemaNode) streamListSchema;
491 prepareLeafAndFillEntryBuilder(streamEntry,
492 listSchema.getDataChildByName(MonitoringModule.LEAF_NAME_STREAM_QNAME),
493 notificationDefinition.getQName().getLocalName());
495 final Optional<String> optDesc = notificationDefinition.getDescription();
496 if (optDesc.isPresent()) {
497 prepareLeafAndFillEntryBuilder(streamEntry,
498 listSchema.getDataChildByName(MonitoringModule.LEAF_DESCR_STREAM_QNAME), optDesc.get());
500 prepareLeafAndFillEntryBuilder(streamEntry,
501 listSchema.getDataChildByName(MonitoringModule.LEAF_REPLAY_SUPP_STREAM_QNAME), true);
503 prepareLeafAndFillEntryBuilder(streamEntry,
504 listSchema.getDataChildByName(MonitoringModule.LEAF_START_TIME_STREAM_QNAME),
505 DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(OffsetDateTime.ofInstant(start,
506 ZoneId.systemDefault())));
508 prepareListAndFillEntryBuilder(streamEntry,
509 (ListSchemaNode) listSchema.getDataChildByName(MonitoringModule.LIST_ACCESS_STREAM_QNAME),
513 final DataSchemaNode contStreamsSchema = ((ContainerSchemaNode) monitoringModule
514 .getDataChildByName(MonitoringModule.CONT_RESTCONF_STATE_QNAME))
515 .getDataChildByName(MonitoringModule.CONT_STREAMS_QNAME);
516 return Builders.containerBuilder((ContainerSchemaNode) contStreamsSchema).withChild(Builders
517 .mapBuilder((ListSchemaNode) streamListSchema).withChild(streamEntry.build()).build())
520 return streamEntry.build();
524 throw new RestconfDocumentedException(notifiQName + " doesn't exist in any modul");
527 private static void prepareListAndFillEntryBuilder(
528 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> streamEntry,
529 final ListSchemaNode listSchemaNode, final String outputType, final URI uriToWebsocketServer) {
530 final CollectionNodeBuilder<MapEntryNode, MapNode> accessListBuilder = Builders.mapBuilder(listSchemaNode);
531 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entryAccessList =
532 Builders.mapEntryBuilder(listSchemaNode);
533 prepareLeafAndFillEntryBuilder(entryAccessList,
534 listSchemaNode.getDataChildByName(MonitoringModule.LEAF_ENCODING_ACCESS_QNAME), outputType);
535 prepareLeafAndFillEntryBuilder(entryAccessList,
536 listSchemaNode.getDataChildByName(MonitoringModule.LEAF_LOCATION_ACCESS_QNAME),
537 uriToWebsocketServer.toString());
538 streamEntry.withChild(accessListBuilder.withChild(entryAccessList.build()).build());
542 * Prepare leaf and fill entry builder.
544 * @param streamEntry Stream entry
545 * @param leafSchema Leaf schema
548 private static void prepareLeafAndFillEntryBuilder(
549 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> streamEntry,
550 final DataSchemaNode leafSchema, final Object value) {
551 streamEntry.withChild(Builders.leafBuilder((LeafSchemaNode) leafSchema).withValue(value).build());
555 * Map data of data change notification to normalized node according to
556 * ietf-restconf-monitoring.
559 * path of data to listen on
561 * start-time query parameter of notification
563 * output type of notification
565 * location of registered listener for sending data of
567 * @param monitoringModule
568 * ietf-restconf-monitoring module
570 * true if data of parent -
571 * ietf-restconf-monitoring:restconf-state/streams - exist in DS
572 * @param schemaContext
573 * schemaContext for parsing instance identifier to get schema
575 * @return mapped data of notification - map entry node if parent exists,
576 * container streams with list and map entry node if not
578 @SuppressWarnings("rawtypes")
579 public static NormalizedNode mapDataChangeNotificationStreamByIetfRestconfMonitoring(
580 final YangInstanceIdentifier path, final Instant start, final String outputType, final URI uri,
581 final Module monitoringModule, final boolean existParent, final SchemaContext schemaContext) {
582 final SchemaNode schemaNode = ParserIdentifier
583 .toInstanceIdentifier(ParserIdentifier.stringFromYangInstanceIdentifier(path, schemaContext),
584 schemaContext, Optional.empty())
586 final DataSchemaNode streamListSchema = ((ContainerSchemaNode) ((ContainerSchemaNode) monitoringModule
587 .getDataChildByName(MonitoringModule.CONT_RESTCONF_STATE_QNAME))
588 .getDataChildByName(MonitoringModule.CONT_STREAMS_QNAME))
589 .getDataChildByName(MonitoringModule.LIST_STREAM_QNAME);
590 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> streamEntry =
591 Builders.mapEntryBuilder((ListSchemaNode) streamListSchema);
593 final ListSchemaNode listSchema = (ListSchemaNode) streamListSchema;
594 prepareLeafAndFillEntryBuilder(streamEntry,
595 listSchema.getDataChildByName(MonitoringModule.LEAF_NAME_STREAM_QNAME),
596 schemaNode.getQName().getLocalName());
598 final Optional<String> optDesc = schemaNode.getDescription();
599 if (optDesc.isPresent()) {
600 prepareLeafAndFillEntryBuilder(streamEntry,
601 listSchema.getDataChildByName(MonitoringModule.LEAF_DESCR_STREAM_QNAME), optDesc.get());
603 prepareLeafAndFillEntryBuilder(streamEntry,
604 listSchema.getDataChildByName(MonitoringModule.LEAF_REPLAY_SUPP_STREAM_QNAME), true);
605 prepareLeafAndFillEntryBuilder(streamEntry,
606 listSchema.getDataChildByName(MonitoringModule.LEAF_START_TIME_STREAM_QNAME),
607 DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(OffsetDateTime.ofInstant(start, ZoneId.systemDefault())));
608 prepareListAndFillEntryBuilder(streamEntry,
609 (ListSchemaNode) listSchema.getDataChildByName(MonitoringModule.LIST_ACCESS_STREAM_QNAME), outputType,
613 final DataSchemaNode contStreamsSchema = ((ContainerSchemaNode) monitoringModule
614 .getDataChildByName(MonitoringModule.CONT_RESTCONF_STATE_QNAME))
615 .getDataChildByName(MonitoringModule.CONT_STREAMS_QNAME);
617 .containerBuilder((ContainerSchemaNode) contStreamsSchema).withChild(Builders
618 .mapBuilder((ListSchemaNode) streamListSchema).withChild(streamEntry.build()).build())
621 return streamEntry.build();