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;
10 import com.google.common.base.Optional;
12 import java.time.Instant;
13 import java.time.OffsetDateTime;
14 import java.time.ZoneId;
15 import java.time.format.DateTimeFormatter;
16 import java.util.Collection;
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.common.errors.RestconfDocumentedException;
22 import org.opendaylight.restconf.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.data.api.YangInstanceIdentifier;
26 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
27 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
28 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
29 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
30 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
31 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
32 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
33 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
34 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
35 import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
36 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
37 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
38 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
39 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.ListNodeBuilder;
40 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
41 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
42 import org.opendaylight.yangtools.yang.model.api.Deviation;
43 import org.opendaylight.yangtools.yang.model.api.FeatureDefinition;
44 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
45 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
46 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
47 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
48 import org.opendaylight.yangtools.yang.model.api.Module;
49 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
50 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
51 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
54 * Util class for mapping nodes.
57 public final class RestconfMappingNodeUtil {
59 private RestconfMappingNodeUtil() {
60 throw new UnsupportedOperationException("Util class");
64 * Map data from modules to {@link NormalizedNode}.
68 * @param ietfYangLibraryModule
69 * ietf-yang-library module
73 * module-set-id of actual set
74 * @return mapped data as {@link NormalizedNode}
76 public static NormalizedNode<NodeIdentifier, Collection<DataContainerChild<? extends PathArgument, ?>>>
77 mapModulesByIetfYangLibraryYang(final Set<Module> modules, final Module ietfYangLibraryModule,
78 final SchemaContext context, final String moduleSetId) {
79 final DataSchemaNode modulesStateSch =
80 ietfYangLibraryModule.getDataChildByName(IetfYangLibrary.MODUELS_STATE_CONT_QNAME);
81 final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> modulesStateBuilder =
82 Builders.containerBuilder((ContainerSchemaNode) modulesStateSch);
84 final DataSchemaNode moduleSetIdSch =
85 ((ContainerSchemaNode) modulesStateSch).getDataChildByName(IetfYangLibrary.MODULE_SET_ID_LEAF_QNAME);
87 .withChild(Builders.leafBuilder((LeafSchemaNode) moduleSetIdSch).withValue(moduleSetId).build());
89 final DataSchemaNode moduleSch = findNodeInGroupings(IetfYangLibrary.MODULE_QNAME_LIST, ietfYangLibraryModule);
90 final CollectionNodeBuilder<MapEntryNode, OrderedMapNode> mapBuilder =
91 Builders.orderedMapBuilder((ListSchemaNode) moduleSch);
92 for (final Module module : context.getModules()) {
93 fillMapByModules(mapBuilder, moduleSch, false, module, ietfYangLibraryModule, context);
95 return modulesStateBuilder.withChild(mapBuilder.build()).build();
99 * Map data by the specific module or submodule.
102 * ordered list builder for children
104 * schema of list for entryMapBuilder
106 * true if module is specified as submodule, false otherwise
108 * specific module or submodule
109 * @param ietfYangLibraryModule
110 * ietf-yang-library module
114 private static void fillMapByModules(final CollectionNodeBuilder<MapEntryNode, OrderedMapNode> mapBuilder,
115 final DataSchemaNode moduleSch, final boolean isSubmodule, final Module module,
116 final Module ietfYangLibraryModule, final SchemaContext context) {
117 final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder =
118 Builders.mapEntryBuilder((ListSchemaNode) moduleSch);
119 addCommonLeafs(module, mapEntryBuilder, ietfYangLibraryModule);
120 addChildOfModuleBySpecificModuleInternal(
121 IetfYangLibrary.SPECIFIC_MODULE_SCHEMA_LEAF_QNAME, mapEntryBuilder, IetfYangLibrary.BASE_URI_OF_SCHEMA
122 + module.getName() + "/" + module.getQNameModule().getFormattedRevision(),
123 ietfYangLibraryModule);
125 addChildOfModuleBySpecificModuleOfListChild(IetfYangLibrary.SPECIFIC_MODULE_NAMESPACE_LEAF_QNAME,
126 mapEntryBuilder, module.getNamespace().toString(), ietfYangLibraryModule);
128 // features - not mandatory
129 if ((module.getFeatures() != null) && !module.getFeatures().isEmpty()) {
130 addFeatureLeafList(IetfYangLibrary.SPECIFIC_MODULE_FEATURE_LEAF_LIST_QNAME, mapEntryBuilder,
131 module.getFeatures(), ietfYangLibraryModule);
133 // deviations - not mandatory
134 if ((module.getDeviations() != null) && !module.getDeviations().isEmpty()) {
135 addDeviationList(module, mapEntryBuilder, ietfYangLibraryModule, context);
136 addChildOfModuleBySpecificModuleOfListChild(IetfYangLibrary.SPECIFIC_MODULE_CONFORMANCE_LEAF_QNAME,
137 mapEntryBuilder, ConformanceType.Implement.getName(), ietfYangLibraryModule);
139 addChildOfModuleBySpecificModuleOfListChild(IetfYangLibrary.SPECIFIC_MODULE_CONFORMANCE_LEAF_QNAME,
140 mapEntryBuilder, ConformanceType.Import.getName(), ietfYangLibraryModule);
142 // submodules - not mandatory
143 if ((module.getSubmodules() != null) && !module.getSubmodules().isEmpty()) {
144 addSubmodules(module, mapEntryBuilder, ietfYangLibraryModule, context);
147 mapBuilder.withChild(mapEntryBuilder.build());
151 * Mapping submodules of specific module.
154 * module with submodules
155 * @param mapEntryBuilder
156 * mapEntryBuilder of parent for mapping children
157 * @param ietfYangLibraryModule
158 * ietf-yang-library module
162 private static void addSubmodules(final Module module,
163 final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder,
164 final Module ietfYangLibraryModule, final SchemaContext context) {
165 final DataSchemaNode listSubm = findSchemaInListOfModulesSchema(
166 IetfYangLibrary.SPECIFIC_MODULE_SUBMODULE_LIST_QNAME, ietfYangLibraryModule);
167 final CollectionNodeBuilder<MapEntryNode, OrderedMapNode> mapBuilder =
168 Builders.orderedMapBuilder((ListSchemaNode) listSubm);
169 for (final Module submodule : module.getSubmodules()) {
170 fillMapByModules(mapBuilder, listSubm, true, submodule, ietfYangLibraryModule, context);
172 mapEntryBuilder.withChild(mapBuilder.build());
176 * Mapping deviations of specific module.
179 * module with deviations
180 * @param mapEntryBuilder
181 * mapEntryBuilder of parent for mapping children
182 * @param ietfYangLibraryModule
183 * ietf-yang-library module
187 private static void addDeviationList(final Module module,
188 final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder,
189 final Module ietfYangLibraryModule, final SchemaContext context) {
190 final DataSchemaNode deviationsSchema = findSchemaInListOfModulesSchema(
191 IetfYangLibrary.SPECIFIC_MODULE_DEVIATION_LIST_QNAME, ietfYangLibraryModule);
192 final CollectionNodeBuilder<MapEntryNode, MapNode> deviations =
193 Builders.mapBuilder((ListSchemaNode) deviationsSchema);
194 for (final Deviation deviation : module.getDeviations()) {
195 final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> deviationEntryNode =
196 Builders.mapEntryBuilder((ListSchemaNode) deviationsSchema);
197 final QName lastComponent = deviation.getTargetPath().getLastComponent();
198 addChildOfModuleBySpecificModule(IetfYangLibrary.SPECIFIC_MODULE_NAME_LEAF_QNAME, deviationEntryNode,
199 context.findModuleByNamespaceAndRevision(lastComponent.getNamespace(), lastComponent.getRevision())
201 ietfYangLibraryModule);
202 addChildOfModuleBySpecificModule(IetfYangLibrary.SPECIFIC_MODULE_REVISION_LEAF_QNAME, deviationEntryNode,
203 lastComponent.getRevision(), ietfYangLibraryModule);
204 deviations.withChild(deviationEntryNode.build());
206 mapEntryBuilder.withChild(deviations.build());
210 * Mapping features of specific module.
212 * @param qnameOfFeaturesLeafList
213 * qname of feature leaf-list in ietf-yang-library module
214 * @param mapEntryBuilder
215 * mapEntryBuilder of parent for mapping children
217 * features of specific module
218 * @param ietfYangLibraryModule
219 * ieat-yang-library module
221 private static void addFeatureLeafList(final QName qnameOfFeaturesLeafList,
222 final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder,
223 final Set<FeatureDefinition> features, final Module ietfYangLibraryModule) {
224 final DataSchemaNode schemaNode =
225 findSchemaInListOfModulesSchema(qnameOfFeaturesLeafList, ietfYangLibraryModule);
226 final ListNodeBuilder<Object, LeafSetEntryNode<Object>> leafSetBuilder =
227 Builders.leafSetBuilder((LeafListSchemaNode) schemaNode);
228 for (final FeatureDefinition feature : features) {
229 leafSetBuilder.withChild(Builders.leafSetEntryBuilder((LeafListSchemaNode) schemaNode)
230 .withValue(feature.getQName().getLocalName()).build());
232 mapEntryBuilder.withChild(leafSetBuilder.build());
236 * Mapping common leafs (grouping common-leafs in ietf-yang-library) of
240 * specific module for getting name and revision
241 * @param mapEntryBuilder
242 * mapEntryBuilder of parent for mapping children
243 * @param ietfYangLibraryModule
244 * ietf-yang-library module
246 private static void addCommonLeafs(final Module module,
247 final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder,
248 final Module ietfYangLibraryModule) {
249 addChildOfModuleBySpecificModuleInternal(IetfYangLibrary.SPECIFIC_MODULE_NAME_LEAF_QNAME, mapEntryBuilder,
250 module.getName(), ietfYangLibraryModule);
251 addChildOfModuleBySpecificModuleInternal(IetfYangLibrary.SPECIFIC_MODULE_REVISION_LEAF_QNAME, mapEntryBuilder,
252 module.getQNameModule().getFormattedRevision(), ietfYangLibraryModule);
256 * Mapping data child of grouping module-list by ietf-yang-library.
258 * @param specificQName
259 * qname of leaf in module-list grouping
260 * @param mapEntryBuilder
261 * mapEntryBuilder of parent for mapping children
264 * @param ietfYangLibraryModule
265 * ietf-yang-library module
267 private static void addChildOfModuleBySpecificModuleOfListChild(final QName specificQName,
268 final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder,
269 final Object value, final Module ietfYangLibraryModule) {
270 final DataSchemaNode leafSch = findSchemaInListOfModulesSchema(specificQName, ietfYangLibraryModule);
271 mapEntryBuilder.withChild(Builders.leafBuilder((LeafSchemaNode) leafSch).withValue(value).build());
275 * Find specific schema in gourping module-lsit.
277 * @param specificQName
279 * @param ietfYangLibraryModule
280 * ietf-yang-library module
281 * @return schemaNode of specific child
283 private static DataSchemaNode findSchemaInListOfModulesSchema(final QName specificQName,
284 final Module ietfYangLibraryModule) {
285 for (final GroupingDefinition groupingDefinition : ietfYangLibraryModule.getGroupings()) {
286 if (groupingDefinition.getQName().equals(IetfYangLibrary.GROUPING_MODULE_LIST_QNAME)) {
287 final DataSchemaNode dataChildByName =
288 groupingDefinition.getDataChildByName(IetfYangLibrary.MODULE_QNAME_LIST);
289 return ((ListSchemaNode) dataChildByName).getDataChildByName(specificQName);
292 throw new RestconfDocumentedException(specificQName.getLocalName() + " doesn't exist.");
296 * Mapping data child of internal groupings in module-list grouping.
298 * @param specifiLeafQName
299 * qnmae of leaf for mapping
300 * @param mapEntryBuilder
301 * mapEntryBuilder of parent for mapping children
304 * @param ietfYangLibraryModule
305 * ietf-yang-library module
307 private static void addChildOfModuleBySpecificModuleInternal(final QName specifiLeafQName,
308 final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder,
309 final Object value, final Module ietfYangLibraryModule) {
310 final DataSchemaNode nameLeaf = findNodeInInternGroupings(specifiLeafQName, ietfYangLibraryModule);
311 mapEntryBuilder.withChild(Builders.leafBuilder((LeafSchemaNode) nameLeaf).withValue(value).build());
315 * Find schema node of leaf by qname in internal groupings of module-list.
318 * @param qnameOfSchema
320 * @param ietfYangLibraryModule
321 * ietf-yang-library module
322 * @return schema node of specific leaf
324 private static DataSchemaNode findNodeInInternGroupings(final QName qnameOfSchema,
325 final Module ietfYangLibraryModule) {
326 for (final GroupingDefinition groupingDefinition : ietfYangLibraryModule.getGroupings()) {
327 if (groupingDefinition.getQName().equals(IetfYangLibrary.GROUPING_MODULE_LIST_QNAME)) {
328 for (final GroupingDefinition internalGrouping : groupingDefinition.getGroupings()) {
329 if (internalGrouping.getDataChildByName(qnameOfSchema) != null) {
330 return internalGrouping.getDataChildByName(qnameOfSchema);
335 throw new RestconfDocumentedException(qnameOfSchema.getLocalName() + " doesn't exist.");
339 * Mapping childrens of list-module.
341 * @param specifiLeafQName
343 * @param mapEntryBuilder
344 * maptEntryBuilder of parent for mapping children
347 * @param ietfYangLibraryModule
348 * ietf-yang-library module
350 private static void addChildOfModuleBySpecificModule(final QName specifiLeafQName,
351 final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder,
352 final Object value, final Module ietfYangLibraryModule) {
353 final DataSchemaNode nameLeaf = findNodeInGroupings(specifiLeafQName, ietfYangLibraryModule);
354 mapEntryBuilder.withChild(Builders.leafBuilder((LeafSchemaNode) nameLeaf).withValue(value).build());
358 * Find schema of specific leaf in list-module grouping.
360 * @param qnameOfSchema
362 * @param ietfYangLibraryModule
363 * ietf-yang-library module
364 * @return schemaNode of specific leaf
366 private static DataSchemaNode findNodeInGroupings(final QName qnameOfSchema, final Module ietfYangLibraryModule) {
367 for (final GroupingDefinition groupingDefinition : ietfYangLibraryModule.getGroupings()) {
368 if (groupingDefinition.getDataChildByName(qnameOfSchema) != null) {
369 return groupingDefinition.getDataChildByName(qnameOfSchema);
372 throw new RestconfDocumentedException(qnameOfSchema.getLocalName() + " doesn't exist.");
376 * Map capabilites by ietf-restconf-monitoring.
378 * @param monitoringModule
379 * ietf-restconf-monitoring module
380 * @return mapped capabilites
382 public static NormalizedNode<NodeIdentifier, Collection<DataContainerChild<? extends PathArgument, ?>>>
383 mapCapabilites(final Module monitoringModule) {
384 final DataSchemaNode restconfState =
385 monitoringModule.getDataChildByName(MonitoringModule.CONT_RESTCONF_STATE_QNAME);
386 final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> restStateContBuilder =
387 Builders.containerBuilder((ContainerSchemaNode) restconfState);
388 final DataSchemaNode capabilitesContSchema =
389 getChildOfCont((ContainerSchemaNode) restconfState, MonitoringModule.CONT_CAPABILITES_QNAME);
390 final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> capabilitesContBuilder =
391 Builders.containerBuilder((ContainerSchemaNode) capabilitesContSchema);
392 final DataSchemaNode leafListCapa = getChildOfCont((ContainerSchemaNode) capabilitesContSchema,
393 MonitoringModule.LEAF_LIST_CAPABILITY_QNAME);
394 final ListNodeBuilder<Object, LeafSetEntryNode<Object>> leafListCapaBuilder =
395 Builders.orderedLeafSetBuilder((LeafListSchemaNode) leafListCapa);
396 fillLeafListCapa(leafListCapaBuilder, (LeafListSchemaNode) leafListCapa);
398 return restStateContBuilder.withChild(capabilitesContBuilder.withChild(leafListCapaBuilder.build()).build())
403 * Map data to leaf-list.
406 * builder of parent for children
407 * @param leafListSchema
410 @SuppressWarnings({ "unchecked", "rawtypes" })
411 private static void fillLeafListCapa(final ListNodeBuilder builder, final LeafListSchemaNode leafListSchema) {
412 builder.withChild(leafListEntryBuild(leafListSchema, QueryParams.DEPTH));
413 builder.withChild(leafListEntryBuild(leafListSchema, QueryParams.FIELDS));
414 builder.withChild(leafListEntryBuild(leafListSchema, QueryParams.FILTER));
415 builder.withChild(leafListEntryBuild(leafListSchema, QueryParams.REPLAY));
416 builder.withChild(leafListEntryBuild(leafListSchema, QueryParams.WITH_DEFAULTS));
420 * Map value to leaf list entry node.
422 * @param leafListSchema
423 * leaf list schema of leaf list entry
425 * value of leaf entry
428 @SuppressWarnings("rawtypes")
429 private static LeafSetEntryNode leafListEntryBuild(final LeafListSchemaNode leafListSchema, final String value) {
430 return Builders.leafSetEntryBuilder(leafListSchema).withValue(value).build();
434 * Find specific schema node by qname in parent {@link ContainerSchemaNode}.
439 * specific qname of child
440 * @return schema node of child by qname
442 private static DataSchemaNode getChildOfCont(final ContainerSchemaNode parent, final QName childQName) {
443 for (final DataSchemaNode child : parent.getChildNodes()) {
444 if (child.getQName().equals(childQName)) {
448 throw new RestconfDocumentedException(
449 childQName.getLocalName() + " doesn't exist in container " + MonitoringModule.CONT_RESTCONF_STATE_NAME);
453 * Map data of yang notification to normalized node according to
454 * ietf-restconf-monitoring.
457 * qname of notification from listener
458 * @param notifications
459 * list of notifications for find schema of notification by
462 * start-time query parameter of notification
464 * output type of notification
466 * location of registered listener for sending data of
468 * @param monitoringModule
469 * ietf-restconf-monitoring module
471 * true if data of parent -
472 * ietf-restconf-monitoring:restconf-state/streams - exist in DS
473 * @return mapped data of notification - map entry node if parent exists,
474 * container streams with list and map entry node if not
476 @SuppressWarnings("rawtypes")
477 public static NormalizedNode mapYangNotificationStreamByIetfRestconfMonitoring(final QName notifiQName,
478 final Set<NotificationDefinition> notifications, final Instant start, final String outputType,
479 final URI uri, final Module monitoringModule, final boolean existParent) {
480 for (final NotificationDefinition notificationDefinition : notifications) {
481 if (notificationDefinition.getQName().equals(notifiQName)) {
482 final DataSchemaNode streamListSchema = ((ContainerSchemaNode) ((ContainerSchemaNode) monitoringModule
483 .getDataChildByName(MonitoringModule.CONT_RESTCONF_STATE_QNAME))
484 .getDataChildByName(MonitoringModule.CONT_STREAMS_QNAME))
485 .getDataChildByName(MonitoringModule.LIST_STREAM_QNAME);
486 final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> streamEntry =
487 Builders.mapEntryBuilder((ListSchemaNode) streamListSchema);
489 final ListSchemaNode listSchema = ((ListSchemaNode) streamListSchema);
490 prepareLeafAndFillEntryBuilder(streamEntry,
491 listSchema.getDataChildByName(MonitoringModule.LEAF_NAME_STREAM_QNAME),
492 notificationDefinition.getQName().getLocalName());
493 if ((notificationDefinition.getDescription() != null)
494 && !notificationDefinition.getDescription().equals("")) {
495 prepareLeafAndFillEntryBuilder(streamEntry,
496 listSchema.getDataChildByName(MonitoringModule.LEAF_DESCR_STREAM_QNAME),
497 notificationDefinition.getDescription());
499 prepareLeafAndFillEntryBuilder(streamEntry,
500 listSchema.getDataChildByName(MonitoringModule.LEAF_REPLAY_SUPP_STREAM_QNAME), true);
502 prepareLeafAndFillEntryBuilder(streamEntry,
503 listSchema.getDataChildByName(MonitoringModule.LEAF_START_TIME_STREAM_QNAME),
504 DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(OffsetDateTime.ofInstant(start,
505 ZoneId.systemDefault())));
507 prepareListAndFillEntryBuilder(streamEntry,
508 (ListSchemaNode) listSchema.getDataChildByName(MonitoringModule.LIST_ACCESS_STREAM_QNAME),
512 final DataSchemaNode contStreamsSchema = ((ContainerSchemaNode) monitoringModule
513 .getDataChildByName(MonitoringModule.CONT_RESTCONF_STATE_QNAME))
514 .getDataChildByName(MonitoringModule.CONT_STREAMS_QNAME);
515 return Builders.containerBuilder((ContainerSchemaNode) contStreamsSchema).withChild(Builders
516 .mapBuilder((ListSchemaNode) streamListSchema).withChild(streamEntry.build()).build())
519 return streamEntry.build();
523 throw new RestconfDocumentedException(notifiQName + " doesn't exist in any modul");
526 private static void prepareListAndFillEntryBuilder(
527 final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> streamEntry,
528 final ListSchemaNode listSchemaNode, final String outputType, final URI uriToWebsocketServer) {
529 final CollectionNodeBuilder<MapEntryNode, MapNode> accessListBuilder = Builders.mapBuilder(listSchemaNode);
530 final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entryAccessList =
531 Builders.mapEntryBuilder(listSchemaNode);
532 prepareLeafAndFillEntryBuilder(entryAccessList,
533 listSchemaNode.getDataChildByName(MonitoringModule.LEAF_ENCODING_ACCESS_QNAME), outputType);
534 prepareLeafAndFillEntryBuilder(entryAccessList,
535 listSchemaNode.getDataChildByName(MonitoringModule.LEAF_LOCATION_ACCESS_QNAME),
536 uriToWebsocketServer.toString());
537 streamEntry.withChild(accessListBuilder.withChild(entryAccessList.build()).build());
541 * Prepare leaf and fill entry builder.
543 * @param streamEntry Stream entry
544 * @param leafSchema Leaf schema
547 private static void prepareLeafAndFillEntryBuilder(
548 final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> streamEntry,
549 final DataSchemaNode leafSchema, final Object value) {
550 streamEntry.withChild(Builders.leafBuilder((LeafSchemaNode) leafSchema).withValue(value).build());
554 * Map data of data change notification to normalized node according to
555 * ietf-restconf-monitoring.
558 * path of data to listen on
560 * start-time query parameter of notification
562 * output type of notification
564 * location of registered listener for sending data of
566 * @param monitoringModule
567 * ietf-restconf-monitoring module
569 * true if data of parent -
570 * ietf-restconf-monitoring:restconf-state/streams - exist in DS
571 * @param schemaContext
572 * schemaContext for parsing instance identifier to get schema
574 * @return mapped data of notification - map entry node if parent exists,
575 * container streams with list and map entry node if not
577 @SuppressWarnings("rawtypes")
578 public static NormalizedNode mapDataChangeNotificationStreamByIetfRestconfMonitoring(
579 final YangInstanceIdentifier path, final Instant start, final String outputType, final URI uri,
580 final Module monitoringModule, final boolean existParent, final SchemaContext schemaContext) {
581 final SchemaNode schemaNode = ParserIdentifier
582 .toInstanceIdentifier(ParserIdentifier.stringFromYangInstanceIdentifier(path, schemaContext),
583 schemaContext, Optional.absent())
585 final DataSchemaNode streamListSchema = ((ContainerSchemaNode) ((ContainerSchemaNode) monitoringModule
586 .getDataChildByName(MonitoringModule.CONT_RESTCONF_STATE_QNAME))
587 .getDataChildByName(MonitoringModule.CONT_STREAMS_QNAME))
588 .getDataChildByName(MonitoringModule.LIST_STREAM_QNAME);
589 final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> streamEntry =
590 Builders.mapEntryBuilder((ListSchemaNode) streamListSchema);
592 final ListSchemaNode listSchema = ((ListSchemaNode) streamListSchema);
593 prepareLeafAndFillEntryBuilder(streamEntry,
594 listSchema.getDataChildByName(MonitoringModule.LEAF_NAME_STREAM_QNAME),
595 schemaNode.getQName().getLocalName());
596 if ((schemaNode.getDescription() != null) && !schemaNode.getDescription().equals("")) {
597 prepareLeafAndFillEntryBuilder(streamEntry,
598 listSchema.getDataChildByName(MonitoringModule.LEAF_DESCR_STREAM_QNAME),
599 schemaNode.getDescription());
601 prepareLeafAndFillEntryBuilder(streamEntry,
602 listSchema.getDataChildByName(MonitoringModule.LEAF_REPLAY_SUPP_STREAM_QNAME), true);
603 prepareLeafAndFillEntryBuilder(streamEntry,
604 listSchema.getDataChildByName(MonitoringModule.LEAF_START_TIME_STREAM_QNAME),
605 DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(OffsetDateTime.ofInstant(start, ZoneId.systemDefault())));
606 prepareListAndFillEntryBuilder(streamEntry,
607 (ListSchemaNode) listSchema.getDataChildByName(MonitoringModule.LIST_ACCESS_STREAM_QNAME), outputType,
611 final DataSchemaNode contStreamsSchema = ((ContainerSchemaNode) monitoringModule
612 .getDataChildByName(MonitoringModule.CONT_RESTCONF_STATE_QNAME))
613 .getDataChildByName(MonitoringModule.CONT_STREAMS_QNAME);
615 .containerBuilder((ContainerSchemaNode) contStreamsSchema).withChild(Builders
616 .mapBuilder((ListSchemaNode) streamListSchema).withChild(streamEntry.build()).build())
619 return streamEntry.build();