X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=restconf%2Fsal-rest-connector%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Frestconf%2Futils%2Fmapping%2FRestconfMappingNodeUtil.java;h=a0cbaaab742b1972f6dc7859e26be2b8016454d7;hb=159f2a9cfd97531452c174cede9a4f3ab1262935;hp=939f3ac7550ec3c6b7fb96a87c8ecc4b01cd979f;hpb=990f1c0d249e9f27e192cf6c1300e516ace81087;p=netconf.git diff --git a/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/utils/mapping/RestconfMappingNodeUtil.java b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/utils/mapping/RestconfMappingNodeUtil.java index 939f3ac755..a0cbaaab74 100644 --- a/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/utils/mapping/RestconfMappingNodeUtil.java +++ b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/utils/mapping/RestconfMappingNodeUtil.java @@ -7,26 +7,45 @@ */ package org.opendaylight.restconf.utils.mapping; -import com.google.common.base.Preconditions; +import java.net.URI; +import java.text.SimpleDateFormat; import java.util.Collection; +import java.util.Date; import java.util.Set; -import org.opendaylight.restconf.Draft11; -import org.opendaylight.restconf.utils.RestconfConstants; -import org.opendaylight.restconf.utils.schema.context.RestconfSchemaUtil; +import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException; +import org.opendaylight.restconf.Rfc8040.IetfYangLibrary; +import org.opendaylight.restconf.Rfc8040.MonitoringModule; +import org.opendaylight.restconf.Rfc8040.MonitoringModule.QueryParams; +import org.opendaylight.restconf.utils.parser.ParserIdentifier; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev160621.module.list.Module.ConformanceType; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; +import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild; import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode; import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; import org.opendaylight.yangtools.yang.data.api.schema.MapNode; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode; import org.opendaylight.yangtools.yang.data.impl.schema.Builders; import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder; import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder; import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.ListNodeBuilder; +import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.Deviation; import org.opendaylight.yangtools.yang.model.api.FeatureDefinition; +import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.NotificationDefinition; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.api.SchemaNode; /** * Util class for mapping nodes @@ -39,127 +58,557 @@ public final class RestconfMappingNodeUtil { } /** - * Mapping {@link Module} from {@link Set} of {@link Module} to - * {@link ListSchemaNode} of {@link Module} list. + * Map data from modules to {@link NormalizedNode} * - * @param restconfModule - * - restconf module * @param modules - * - all modules - * @return {@link MapNode} - */ - public static MapNode restconfMappingNode(final Module restconfModule, final Set modules) { - final DataSchemaNode modulListSchemaNode = RestconfSchemaUtil.getRestconfSchemaNode(restconfModule, - Draft11.RestconfModule.MODULE_LIST_SCHEMA_NODE); - Preconditions.checkState(modulListSchemaNode instanceof ListSchemaNode); - - final CollectionNodeBuilder listModuleBuilder = Builders - .mapBuilder((ListSchemaNode) modulListSchemaNode); - for (final Module module : modules) { - listModuleBuilder.withChild(toModuleEntryNode(module, modulListSchemaNode)); + * - modules for mapping + * @param ietfYangLibraryModule + * - ietf-yang-library module + * @param context + * - schema context + * @param moduleSetId + * - module-set-id of actual set + * @return mapped data as {@link NormalizedNode} + */ + public static NormalizedNode>> + mapModulesByIetfYangLibraryYang(final Set modules, final Module ietfYangLibraryModule, + final SchemaContext context, final String moduleSetId) { + final DataSchemaNode modulesStateSch = + ietfYangLibraryModule.getDataChildByName(IetfYangLibrary.MODUELS_STATE_CONT_QNAME); + final DataContainerNodeAttrBuilder modulesStateBuilder = + Builders.containerBuilder((ContainerSchemaNode) modulesStateSch); + + final DataSchemaNode moduleSetIdSch = + ((ContainerSchemaNode) modulesStateSch).getDataChildByName(IetfYangLibrary.MODULE_SET_ID_LEAF_QNAME); + modulesStateBuilder + .withChild(Builders.leafBuilder((LeafSchemaNode) moduleSetIdSch).withValue(moduleSetId).build()); + + final DataSchemaNode moduleSch = findNodeInGroupings(IetfYangLibrary.MODULE_QNAME_LIST, ietfYangLibraryModule); + final CollectionNodeBuilder mapBuilder = + Builders.orderedMapBuilder((ListSchemaNode) moduleSch); + for (final Module module : context.getModules()) { + fillMapByModules(mapBuilder, moduleSch, false, module, ietfYangLibraryModule, context); } - return listModuleBuilder.build(); + return modulesStateBuilder.withChild(mapBuilder.build()).build(); } /** - * Mapping {@link MapEntryNode} entries of {@link Module} to - * {@link ListSchemaNode}. + * Map data by the specific module or submodule * + * @param mapBuilder + * - ordered list builder for children + * @param moduleSch + * - schema of list for entryMapBuilder + * @param isSubmodule + * - true if module is specified as submodule, false otherwise * @param module - * - module for mapping - * @param modulListSchemaNode - * - mapped {@link DataSchemaNode} - * @return {@link MapEntryNode} - */ - private static MapEntryNode toModuleEntryNode(final Module module, final DataSchemaNode modulListSchemaNode) { - final ListSchemaNode listSchemaNode = (ListSchemaNode) modulListSchemaNode; - final Collection childListSchemaNode = listSchemaNode.getChildNodes(); - final DataContainerNodeAttrBuilder moduleNodeValues = Builders - .mapEntryBuilder(listSchemaNode); - - // MODULE NAME SCHEMA NODE - fillListWithLeaf(listSchemaNode, moduleNodeValues, RestconfMappingNodeConstants.NAME, module.getName()); - - // MODULE REVISION SCHEMA NODE - fillListWithLeaf(listSchemaNode, moduleNodeValues, RestconfMappingNodeConstants.REVISION, - RestconfConstants.REVISION_FORMAT.format(module.getRevision())); - - // MODULE NAMESPACE SCHEMA NODE - fillListWithLeaf(listSchemaNode, moduleNodeValues, RestconfMappingNodeConstants.NAMESPACE, - module.getNamespace().toString()); - - // MODULE FEATURES SCHEMA NODES - final DataSchemaNode schemaNode = RestconfSchemaUtil.findSchemaNodeInCollection(childListSchemaNode, - RestconfMappingNodeConstants.FEATURE); - Preconditions.checkState(schemaNode instanceof LeafListSchemaNode); - final ListNodeBuilder> featureBuilder = Builders - .leafSetBuilder((LeafListSchemaNode) schemaNode); - for (final FeatureDefinition feature : module.getFeatures()) { - featureBuilder.withChild(Builders.leafSetEntryBuilder((LeafListSchemaNode) schemaNode) + * - specific module or submodule + * @param ietfYangLibraryModule + * - ietf-yang-library module + * @param context + * - schema context + */ + private static void fillMapByModules(final CollectionNodeBuilder mapBuilder, + final DataSchemaNode moduleSch, final boolean isSubmodule, final Module module, + final Module ietfYangLibraryModule, final SchemaContext context) { + final DataContainerNodeAttrBuilder mapEntryBuilder = + Builders.mapEntryBuilder((ListSchemaNode) moduleSch); + addCommonLeafs(module, mapEntryBuilder, ietfYangLibraryModule); + addChildOfModuleBySpecificModuleInternal( + IetfYangLibrary.SPECIFIC_MODULE_SCHEMA_LEAF_QNAME, mapEntryBuilder, IetfYangLibrary.BASE_URI_OF_SCHEMA + + module.getName() + "/" + new SimpleDateFormat("yyyy-MM-dd").format(module.getRevision()), + ietfYangLibraryModule); + if (!isSubmodule) { + addChildOfModuleBySpecificModuleOfListChild(IetfYangLibrary.SPECIFIC_MODULE_NAMESPACE_LEAF_QNAME, + mapEntryBuilder, module.getNamespace().toString(), ietfYangLibraryModule); + + // features - not mandatory + if ((module.getFeatures() != null) && !module.getFeatures().isEmpty()) { + addFeatureLeafList(IetfYangLibrary.SPECIFIC_MODULE_FEATURE_LEAF_LIST_QNAME, mapEntryBuilder, + module.getFeatures(), ietfYangLibraryModule); + } + // deviations - not mandatory + if ((module.getDeviations() != null) && !module.getDeviations().isEmpty()) { + addDeviationList(module, mapEntryBuilder, ietfYangLibraryModule, context); + addChildOfModuleBySpecificModuleOfListChild(IetfYangLibrary.SPECIFIC_MODULE_CONFORMANCE_LEAF_QNAME, + mapEntryBuilder, ConformanceType.Implement.getName(), ietfYangLibraryModule); + } else { + addChildOfModuleBySpecificModuleOfListChild(IetfYangLibrary.SPECIFIC_MODULE_CONFORMANCE_LEAF_QNAME, + mapEntryBuilder, ConformanceType.Import.getName(), ietfYangLibraryModule); + } + // submodules - not mandatory + if ((module.getSubmodules() != null) && !module.getSubmodules().isEmpty()) { + addSubmodules(module, mapEntryBuilder, ietfYangLibraryModule, context); + } + } + mapBuilder.withChild(mapEntryBuilder.build()); + } + + /** + * Mapping submodules of specific module + * + * @param module + * - module with submodules + * @param mapEntryBuilder + * - mapEntryBuilder of parent for mapping children + * @param ietfYangLibraryModule + * - ietf-yang-library module + * @param context + * - schema context + */ + private static void addSubmodules(final Module module, + final DataContainerNodeAttrBuilder mapEntryBuilder, + final Module ietfYangLibraryModule, final SchemaContext context) { + final DataSchemaNode listSubm = findSchemaInListOfModulesSchema( + IetfYangLibrary.SPECIFIC_MODULE_SUBMODULE_LIST_QNAME, ietfYangLibraryModule); + final CollectionNodeBuilder mapBuilder = + Builders.orderedMapBuilder((ListSchemaNode) listSubm); + for (final Module submodule : module.getSubmodules()) { + fillMapByModules(mapBuilder, listSubm, true, submodule, ietfYangLibraryModule, context); + } + mapEntryBuilder.withChild(mapBuilder.build()); + } + + /** + * Mapping deviations of specific module + * + * @param module + * - module with deviations + * @param mapEntryBuilder + * - mapEntryBuilder of parent for mapping children + * @param ietfYangLibraryModule + * - ietf-yang-library module + * @param context + * - schema context + */ + private static void addDeviationList(final Module module, + final DataContainerNodeAttrBuilder mapEntryBuilder, + final Module ietfYangLibraryModule, final SchemaContext context) { + final DataSchemaNode deviationsSchema = findSchemaInListOfModulesSchema( + IetfYangLibrary.SPECIFIC_MODULE_DEVIATION_LIST_QNAME, ietfYangLibraryModule); + final CollectionNodeBuilder deviations = + Builders.mapBuilder((ListSchemaNode) deviationsSchema); + for (final Deviation deviation : module.getDeviations()) { + final DataContainerNodeAttrBuilder deviationEntryNode = + Builders.mapEntryBuilder((ListSchemaNode) deviationsSchema); + final QName lastComponent = deviation.getTargetPath().getLastComponent(); + addChildOfModuleBySpecificModule(IetfYangLibrary.SPECIFIC_MODULE_NAME_LEAF_QNAME, deviationEntryNode, + context.findModuleByNamespaceAndRevision(lastComponent.getNamespace(), lastComponent.getRevision()) + .getName(), + ietfYangLibraryModule); + addChildOfModuleBySpecificModule(IetfYangLibrary.SPECIFIC_MODULE_REVISION_LEAF_QNAME, deviationEntryNode, + lastComponent.getRevision(), ietfYangLibraryModule); + deviations.withChild(deviationEntryNode.build()); + } + mapEntryBuilder.withChild(deviations.build()); + } + + /** + * Mapping features of specific module + * + * @param qnameOfFeaturesLeafList + * - qname of feature leaf-list in ietf-yang-library module + * @param mapEntryBuilder + * - mapEntryBuilder of parent for mapping children + * @param features + * - features of specific module + * @param ietfYangLibraryModule + * - ieat-yang-library module + */ + private static void addFeatureLeafList(final QName qnameOfFeaturesLeafList, + final DataContainerNodeAttrBuilder mapEntryBuilder, + final Set features, final Module ietfYangLibraryModule) { + final DataSchemaNode schemaNode = + findSchemaInListOfModulesSchema(qnameOfFeaturesLeafList, ietfYangLibraryModule); + final ListNodeBuilder> leafSetBuilder = + Builders.leafSetBuilder((LeafListSchemaNode) schemaNode); + for (final FeatureDefinition feature : features) { + leafSetBuilder.withChild(Builders.leafSetEntryBuilder((LeafListSchemaNode) schemaNode) .withValue(feature.getQName().getLocalName()).build()); } - moduleNodeValues.withChild(featureBuilder.build()); + mapEntryBuilder.withChild(leafSetBuilder.build()); + } - return moduleNodeValues.build(); + /** + * Mapping common leafs (grouping common-leafs in ietf-yang-library) of + * specific module + * + * @param module + * - specific module for getting name and revision + * @param mapEntryBuilder + * - mapEntryBuilder of parent for mapping children + * @param ietfYangLibraryModule + * - ietf-yang-library module + */ + private static void addCommonLeafs(final Module module, + final DataContainerNodeAttrBuilder mapEntryBuilder, + final Module ietfYangLibraryModule) { + addChildOfModuleBySpecificModuleInternal(IetfYangLibrary.SPECIFIC_MODULE_NAME_LEAF_QNAME, mapEntryBuilder, + module.getName(), ietfYangLibraryModule); + addChildOfModuleBySpecificModuleInternal(IetfYangLibrary.SPECIFIC_MODULE_REVISION_LEAF_QNAME, mapEntryBuilder, + new SimpleDateFormat("yyyy-MM-dd").format(module.getRevision()), ietfYangLibraryModule); } /** - * Mapping {@link MapEntryNode} stream entries of stream to - * {@link ListSchemaNode} + * Mapping data child of grouping module-list by ietf-yang-library * - * @param streamName - * - stream name - * @param streamListSchemaNode - * - mapped {@link DataSchemaNode} - * @return {@link MapEntryNode} + * @param specificQName + * - qname of leaf in module-list grouping + * @param mapEntryBuilder + * - mapEntryBuilder of parent for mapping children + * @param value + * - value of leaf + * @param ietfYangLibraryModule + * - ietf-yang-library module */ - public static MapEntryNode toStreamEntryNode(final String streamName, final DataSchemaNode streamListSchemaNode) { - Preconditions.checkState(streamListSchemaNode instanceof ListSchemaNode); - final ListSchemaNode listStreamSchemaNode = (ListSchemaNode) streamListSchemaNode; - final DataContainerNodeAttrBuilder streamNodeValues = Builders - .mapEntryBuilder(listStreamSchemaNode); + private static void addChildOfModuleBySpecificModuleOfListChild(final QName specificQName, + final DataContainerNodeAttrBuilder mapEntryBuilder, + final Object value, final Module ietfYangLibraryModule) { + final DataSchemaNode leafSch = findSchemaInListOfModulesSchema(specificQName, ietfYangLibraryModule); + mapEntryBuilder.withChild(Builders.leafBuilder((LeafSchemaNode) leafSch).withValue(value).build()); + } - // STREAM NAME - fillListWithLeaf(listStreamSchemaNode, streamNodeValues, RestconfMappingNodeConstants.NAME, streamName); + /** + * Find specific schema in gourping module-lsit + * + * @param specificQName + * - qname of schema + * @param ietfYangLibraryModule + * - ietf-yang-library module + * @return schemaNode of specific child + */ + private static DataSchemaNode findSchemaInListOfModulesSchema(final QName specificQName, + final Module ietfYangLibraryModule) { + for (final GroupingDefinition groupingDefinition : ietfYangLibraryModule.getGroupings()) { + if (groupingDefinition.getQName().equals(IetfYangLibrary.GROUPING_MODULE_LIST_QNAME)) { + final DataSchemaNode dataChildByName = + groupingDefinition.getDataChildByName(IetfYangLibrary.MODULE_QNAME_LIST); + return ((ListSchemaNode) dataChildByName).getDataChildByName(specificQName); + } + } + throw new RestconfDocumentedException(specificQName.getLocalName() + " doesn't exist."); + } - // STREAM DESCRIPTION - fillListWithLeaf(listStreamSchemaNode, streamNodeValues, RestconfMappingNodeConstants.DESCRIPTION, - RestconfMappingStreamConstants.DESCRIPTION); + /** + * Mapping data child of internal groupings in module-list grouping + * + * @param specifiLeafQName + * - qnmae of leaf for mapping + * @param mapEntryBuilder + * - mapEntryBuilder of parent for mapping children + * @param value + * - value of leaf + * @param ietfYangLibraryModule + * - ietf-yang-library module + */ + private static void addChildOfModuleBySpecificModuleInternal(final QName specifiLeafQName, + final DataContainerNodeAttrBuilder mapEntryBuilder, + final Object value, final Module ietfYangLibraryModule) { + final DataSchemaNode nameLeaf = findNodeInInternGroupings(specifiLeafQName, ietfYangLibraryModule); + mapEntryBuilder.withChild(Builders.leafBuilder((LeafSchemaNode) nameLeaf).withValue(value).build()); + } - // STREAM REPLAY_SUPPORT - fillListWithLeaf(listStreamSchemaNode, streamNodeValues, RestconfMappingNodeConstants.REPLAY_SUPPORT, - RestconfMappingStreamConstants.REPLAY_SUPPORT); + /** + * Find schema node of leaf by qname in internal groupings of module-list + * grouping + * + * @param qnameOfSchema + * - qname of leaf + * @param ietfYangLibraryModule + * - ietf-yang-library module + * @return schema node of specific leaf + */ + private static DataSchemaNode findNodeInInternGroupings(final QName qnameOfSchema, + final Module ietfYangLibraryModule) { + for (final GroupingDefinition groupingDefinition : ietfYangLibraryModule.getGroupings()) { + if (groupingDefinition.getQName().equals(IetfYangLibrary.GROUPING_MODULE_LIST_QNAME)) { + for (final GroupingDefinition internalGrouping : groupingDefinition.getGroupings()) { + if (internalGrouping.getDataChildByName(qnameOfSchema) != null) { + return internalGrouping.getDataChildByName(qnameOfSchema); + } + } + } + } + throw new RestconfDocumentedException(qnameOfSchema.getLocalName() + " doesn't exist."); + } - // STREAM REPLAY_LOG - fillListWithLeaf(listStreamSchemaNode, streamNodeValues, RestconfMappingNodeConstants.REPLAY_LOG, - RestconfMappingStreamConstants.REPLAY_LOG); + /** + * Mapping childrens of list-module + * + * @param specifiLeafQName + * - qname of leaf + * @param mapEntryBuilder + * - maptEntryBuilder of parent for mapping children + * @param value + * - valeu of leaf + * @param ietfYangLibraryModule + * - ietf-yang-library module + */ + private static void addChildOfModuleBySpecificModule(final QName specifiLeafQName, + final DataContainerNodeAttrBuilder mapEntryBuilder, + final Object value, final Module ietfYangLibraryModule) { + final DataSchemaNode nameLeaf = findNodeInGroupings(specifiLeafQName, ietfYangLibraryModule); + mapEntryBuilder.withChild(Builders.leafBuilder((LeafSchemaNode) nameLeaf).withValue(value).build()); + } + + /** + * Find schema of specific leaf in list-module grouping + * + * @param qnameOfSchema + * - qname of leaf + * @param ietfYangLibraryModule + * - ietf-yang-library module + * @return schemaNode of specific leaf + */ + private static DataSchemaNode findNodeInGroupings(final QName qnameOfSchema, final Module ietfYangLibraryModule) { + for (final GroupingDefinition groupingDefinition : ietfYangLibraryModule.getGroupings()) { + if (groupingDefinition.getDataChildByName(qnameOfSchema) != null) { + return groupingDefinition.getDataChildByName(qnameOfSchema); + } + } + throw new RestconfDocumentedException(qnameOfSchema.getLocalName() + " doesn't exist."); + } + + /** + * Map capabilites by ietf-restconf-monitoring + * + * @param monitoringModule + * - ietf-restconf-monitoring module + * @return mapped capabilites + */ + public static NormalizedNode>> + mapCapabilites(final Module monitoringModule) { + final DataSchemaNode restconfState = + monitoringModule.getDataChildByName(MonitoringModule.CONT_RESTCONF_STATE_QNAME); + final DataContainerNodeAttrBuilder restStateContBuilder = + Builders.containerBuilder((ContainerSchemaNode) restconfState); + final DataSchemaNode capabilitesContSchema = + getChildOfCont((ContainerSchemaNode) restconfState, MonitoringModule.CONT_CAPABILITES_QNAME); + final DataContainerNodeAttrBuilder capabilitesContBuilder = + Builders.containerBuilder((ContainerSchemaNode) capabilitesContSchema); + final DataSchemaNode leafListCapa = getChildOfCont((ContainerSchemaNode) capabilitesContSchema, + MonitoringModule.LEAF_LIST_CAPABILITY_QNAME); + final ListNodeBuilder> leafListCapaBuilder = + Builders.orderedLeafSetBuilder((LeafListSchemaNode) leafListCapa); + fillLeafListCapa(leafListCapaBuilder, (LeafListSchemaNode) leafListCapa); - // STREAM EVENTS - fillListWithLeaf(listStreamSchemaNode, streamNodeValues, RestconfMappingNodeConstants.EVENTS, - RestconfMappingStreamConstants.EVENTS); + return restStateContBuilder.withChild(capabilitesContBuilder.withChild(leafListCapaBuilder.build()).build()) + .build(); + } - return streamNodeValues.build(); + /** + * Map data to leaf-list + * + * @param builder + * - builder of parent for children + * @param leafListSchema + */ + @SuppressWarnings({ "unchecked", "rawtypes" }) + private static void fillLeafListCapa(final ListNodeBuilder builder, final LeafListSchemaNode leafListSchema) { + builder.withChild(leafListEntryBuild(leafListSchema, QueryParams.DEPTH)); + builder.withChild(leafListEntryBuild(leafListSchema, QueryParams.FIELDS)); + builder.withChild(leafListEntryBuild(leafListSchema, QueryParams.FILTER)); + builder.withChild(leafListEntryBuild(leafListSchema, QueryParams.REPLAY)); + builder.withChild(leafListEntryBuild(leafListSchema, QueryParams.WITH_DEFAULTS)); } /** - * Method for filling {@link ListSchemaNode} with {@link LeafSchemaNode} + * Map value to leaf list entry node * - * @param listStreamSchemaNode - * - {@link ListSchemaNode} - * @param streamNodeValues - * - filled {@link DataContainerNodeAttrBuilder} - * @param nameSchemaNode - * - name of mapped leaf + * @param leafListSchema + * - leaf list schema of leaf list entry * @param value - * - value for mapped node - */ - private static void fillListWithLeaf( - final ListSchemaNode listStreamSchemaNode, - final DataContainerNodeAttrBuilder streamNodeValues, - final String nameSchemaNode, final Object value) { - final DataSchemaNode schemaNode = RestconfSchemaUtil - .findSchemaNodeInCollection(listStreamSchemaNode.getChildNodes(), nameSchemaNode); - Preconditions.checkState(schemaNode instanceof LeafSchemaNode); - streamNodeValues.withChild(Builders.leafBuilder((LeafSchemaNode) schemaNode).withValue(value).build()); + * - value of leaf entry + * @return entry node + */ + @SuppressWarnings("rawtypes") + private static LeafSetEntryNode leafListEntryBuild(final LeafListSchemaNode leafListSchema, final String value) { + return Builders.leafSetEntryBuilder(leafListSchema).withValue(value).build(); + } + + /** + * Find specific schema node by qname in parent {@link ContainerSchemaNode} + * + * @param parent + * - schemaNode + * @param childQName + * - specific qname of child + * @return schema node of child by qname + */ + private static DataSchemaNode getChildOfCont(final ContainerSchemaNode parent, final QName childQName) { + for (final DataSchemaNode child : parent.getChildNodes()) { + if (child.getQName().equals(childQName)) { + return child; + } + } + throw new RestconfDocumentedException( + childQName.getLocalName() + " doesn't exist in container " + MonitoringModule.CONT_RESTCONF_STATE_NAME); + } + + /** + * Map data of yang notification to normalized node according to + * ietf-restconf-monitoring + * + * @param notifiQName + * - qname of notification from listener + * @param notifications + * - list of notifications for find schema of notification by + * notifiQName + * @param start + * - start-time query parameter of notification + * @param outputType + * - output type of notification + * @param uri + * - location of registered listener for sending data of + * notification + * @param monitoringModule + * - ietf-restconf-monitoring module + * @param existParent + * - true if data of parent - + * ietf-restconf-monitoring:restconf-state/streams - exist in DS + * @return mapped data of notification - map entry node if parent exists, + * container streams with list and map entry node if not + */ + @SuppressWarnings("rawtypes") + public static NormalizedNode mapYangNotificationStreamByIetfRestconfMonitoring(final QName notifiQName, + final Set notifications, final Date start, final String outputType, final URI uri, + final Module monitoringModule, final boolean existParent) { + for (final NotificationDefinition notificationDefinition : notifications) { + if (notificationDefinition.getQName().equals(notifiQName)) { + final DataSchemaNode streamListSchema = ((ContainerSchemaNode) ((ContainerSchemaNode) monitoringModule + .getDataChildByName(MonitoringModule.CONT_RESTCONF_STATE_QNAME)) + .getDataChildByName(MonitoringModule.CONT_STREAMS_QNAME)) + .getDataChildByName(MonitoringModule.LIST_STREAM_QNAME); + final DataContainerNodeAttrBuilder streamEntry = + Builders.mapEntryBuilder((ListSchemaNode) streamListSchema); + + final ListSchemaNode listSchema = ((ListSchemaNode) streamListSchema); + prepareLeafAndFillEntryBuilder(streamEntry, + listSchema.getDataChildByName(MonitoringModule.LEAF_NAME_STREAM_QNAME), + notificationDefinition.getQName().getLocalName()); + if ((notificationDefinition.getDescription() != null) + && !notificationDefinition.getDescription().equals("")) { + prepareLeafAndFillEntryBuilder(streamEntry, + listSchema.getDataChildByName(MonitoringModule.LEAF_DESCR_STREAM_QNAME), + notificationDefinition.getDescription()); + } + prepareLeafAndFillEntryBuilder(streamEntry, + listSchema.getDataChildByName(MonitoringModule.LEAF_REPLAY_SUPP_STREAM_QNAME), true); + if (start != null) { + prepareLeafAndFillEntryBuilder(streamEntry, + listSchema.getDataChildByName(MonitoringModule.LEAF_START_TIME_STREAM_QNAME), + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'XXX").format(start)); + } + prepareListAndFillEntryBuilder(streamEntry, + (ListSchemaNode) listSchema.getDataChildByName(MonitoringModule.LIST_ACCESS_STREAM_QNAME), + outputType, uri); + + if (!existParent) { + final DataSchemaNode contStreamsSchema = ((ContainerSchemaNode) monitoringModule + .getDataChildByName(MonitoringModule.CONT_RESTCONF_STATE_QNAME)) + .getDataChildByName(MonitoringModule.CONT_STREAMS_QNAME); + return Builders.containerBuilder((ContainerSchemaNode) contStreamsSchema).withChild(Builders + .mapBuilder((ListSchemaNode) streamListSchema).withChild(streamEntry.build()).build()) + .build(); + } + return streamEntry.build(); + } + } + + throw new RestconfDocumentedException(notifiQName + " doesn't exist in any modul"); + } + + private static void prepareListAndFillEntryBuilder( + final DataContainerNodeAttrBuilder streamEntry, + final ListSchemaNode listSchemaNode, final String outputType, final URI uriToWebsocketServer) { + final CollectionNodeBuilder accessListBuilder = Builders.mapBuilder(listSchemaNode); + final DataContainerNodeAttrBuilder entryAccessList = + Builders.mapEntryBuilder(listSchemaNode); + prepareLeafAndFillEntryBuilder(entryAccessList, + listSchemaNode.getDataChildByName(MonitoringModule.LEAF_ENCODING_ACCESS_QNAME), outputType); + prepareLeafAndFillEntryBuilder(entryAccessList, + listSchemaNode.getDataChildByName(MonitoringModule.LEAF_LOCATION_ACCESS_QNAME), + uriToWebsocketServer.toString()); + streamEntry.withChild(accessListBuilder.withChild(entryAccessList.build()).build()); + } + + /** + * @param streamEntry + * @param dataChildByName + * @param localName + */ + private static void prepareLeafAndFillEntryBuilder( + final DataContainerNodeAttrBuilder streamEntry, + final DataSchemaNode leafSchema, final Object value) { + streamEntry.withChild(Builders.leafBuilder((LeafSchemaNode) leafSchema).withValue(value).build()); + } + + /** + * Map data of data change notification to normalized node according to + * ietf-restconf-monitoring + * + * @param path + * - path of data to listen on + * @param start + * - start-time query parameter of notification + * @param outputType + * - output type of notification + * @param uri + * - location of registered listener for sending data of + * notification + * @param monitoringModule + * - ietf-restconf-monitoring module + * @param existParent + * - true if data of parent - + * ietf-restconf-monitoring:restconf-state/streams - exist in DS + * @param schemaContext + * - schemaContext for parsing instance identifier to get schema + * node of data + * @return mapped data of notification - map entry node if parent exists, + * container streams with list and map entry node if not + */ + @SuppressWarnings("rawtypes") + public static NormalizedNode mapDataChangeNotificationStreamByIetfRestconfMonitoring( + final YangInstanceIdentifier path, final Date start, final String outputType, final URI uri, + final Module monitoringModule, final boolean existParent, final SchemaContext schemaContext) { + final SchemaNode schemaNode = ParserIdentifier + .toInstanceIdentifier(ParserIdentifier.stringFromYangInstanceIdentifier(path, schemaContext), + schemaContext, null) + .getSchemaNode(); + final DataSchemaNode streamListSchema = ((ContainerSchemaNode) ((ContainerSchemaNode) monitoringModule + .getDataChildByName(MonitoringModule.CONT_RESTCONF_STATE_QNAME)) + .getDataChildByName(MonitoringModule.CONT_STREAMS_QNAME)) + .getDataChildByName(MonitoringModule.LIST_STREAM_QNAME); + final DataContainerNodeAttrBuilder streamEntry = + Builders.mapEntryBuilder((ListSchemaNode) streamListSchema); + + final ListSchemaNode listSchema = ((ListSchemaNode) streamListSchema); + prepareLeafAndFillEntryBuilder(streamEntry, + listSchema.getDataChildByName(MonitoringModule.LEAF_NAME_STREAM_QNAME), + schemaNode.getQName().getLocalName()); + if ((schemaNode.getDescription() != null) && !schemaNode.getDescription().equals("")) { + prepareLeafAndFillEntryBuilder(streamEntry, + listSchema.getDataChildByName(MonitoringModule.LEAF_DESCR_STREAM_QNAME), + schemaNode.getDescription()); + } + prepareLeafAndFillEntryBuilder(streamEntry, + listSchema.getDataChildByName(MonitoringModule.LEAF_REPLAY_SUPP_STREAM_QNAME), true); + prepareLeafAndFillEntryBuilder(streamEntry, + listSchema.getDataChildByName(MonitoringModule.LEAF_START_TIME_STREAM_QNAME), + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'XXX").format(start)); + prepareListAndFillEntryBuilder(streamEntry, + (ListSchemaNode) listSchema.getDataChildByName(MonitoringModule.LIST_ACCESS_STREAM_QNAME), outputType, + uri); + + if (!existParent) { + final DataSchemaNode contStreamsSchema = ((ContainerSchemaNode) monitoringModule + .getDataChildByName(MonitoringModule.CONT_RESTCONF_STATE_QNAME)) + .getDataChildByName(MonitoringModule.CONT_STREAMS_QNAME); + return Builders + .containerBuilder((ContainerSchemaNode) contStreamsSchema).withChild(Builders + .mapBuilder((ListSchemaNode) streamListSchema).withChild(streamEntry.build()).build()) + .build(); + } + return streamEntry.build(); } }