X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=restconf%2Frestconf-nb-rfc8040%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Frestconf%2Fnb%2Frfc8040%2Frests%2Futils%2FReadDataTransactionUtil.java;h=e162181f30b473bb198c9b3aeb27809389e2a98c;hb=982e75ece2483e413befe3edd8fd90022a644f72;hp=b973d26e2f1c79083440b22314a0760821d335b6;hpb=824baf9fe14e31465c58f3842c4cb0aa88b34757;p=netconf.git diff --git a/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/utils/ReadDataTransactionUtil.java b/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/utils/ReadDataTransactionUtil.java index b973d26e2f..e162181f30 100644 --- a/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/utils/ReadDataTransactionUtil.java +++ b/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/utils/ReadDataTransactionUtil.java @@ -9,23 +9,24 @@ package org.opendaylight.restconf.nb.rfc8040.rests.utils; import static org.opendaylight.restconf.nb.rfc8040.rests.utils.RestconfStreamsConstants.STREAMS_PATH; import static org.opendaylight.restconf.nb.rfc8040.rests.utils.RestconfStreamsConstants.STREAM_PATH_PART; -import com.google.common.base.Optional; + +import com.google.common.collect.Iterables; import com.google.common.primitives.Ints; -import com.google.common.util.concurrent.CheckedFuture; +import com.google.common.util.concurrent.FluentFuture; import java.net.URI; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.function.Function; import java.util.stream.Collectors; import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.ws.rs.core.UriInfo; -import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; -import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; -import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction; -import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction; +import org.opendaylight.mdsal.common.api.LogicalDatastoreType; +import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction; +import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction; import org.opendaylight.restconf.common.context.InstanceIdentifierContext; import org.opendaylight.restconf.common.context.WriterParameters; import org.opendaylight.restconf.common.context.WriterParameters.WriterParametersBuilder; @@ -49,15 +50,21 @@ import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode; 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.LeafNode; +import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode; +import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode; 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.OrderedLeafSetNode; +import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode; +import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode; +import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode; import org.opendaylight.yangtools.yang.data.impl.schema.Builders; import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes; 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.DataContainerNodeBuilder; -import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeAttrBuilder; +import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.ListNodeBuilder; +import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeBuilder; import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder; import org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree; import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; @@ -169,9 +176,9 @@ public final class ReadDataTransactionUtil { if (!depth.get(0).equals(RestconfDataServiceConstant.ReadData.UNBOUNDED)) { final Integer value = Ints.tryParse(depth.get(0)); - if ((value == null) - || (!((value >= RestconfDataServiceConstant.ReadData.MIN_DEPTH) - && (value <= RestconfDataServiceConstant.ReadData.MAX_DEPTH)))) { + if (value == null + || !(value >= RestconfDataServiceConstant.ReadData.MIN_DEPTH + && value <= RestconfDataServiceConstant.ReadData.MAX_DEPTH)) { throw new RestconfDocumentedException( new RestconfError(RestconfError.ErrorType.PROTOCOL, RestconfError.ErrorTag.INVALID_VALUE, "Invalid depth parameter: " + depth, null, @@ -197,6 +204,7 @@ public final class ReadDataTransactionUtil { * @param transactionNode * {@link TransactionVarsWrapper} - wrapper for variables * @param schemaContext + * schema context * @return {@link NormalizedNode} */ @Nullable @@ -215,6 +223,7 @@ public final class ReadDataTransactionUtil { * @param withDefa * vaule of with-defaults parameter * @param ctx + * schema context * @return {@link NormalizedNode} */ @Nullable @@ -267,7 +276,7 @@ public final class ReadDataTransactionUtil { final SchemaContextRef schemaContextRef, final UriInfo uriInfo) { final SchemaContext schemaContext = schemaContextRef.get(); if (identifier.contains(STREAMS_PATH) && !identifier.contains(STREAM_PATH_PART)) { - final DOMDataReadWriteTransaction wTx = transactionNode.getTransactionChain().newReadWriteTransaction(); + final DOMDataTreeReadWriteTransaction wTx = transactionNode.getTransactionChain().newReadWriteTransaction(); final boolean exist = SubscribeToStreamUtil.checkExist(schemaContext, wTx); for (final NotificationDefinition notificationDefinition : schemaContextRef.get().getNotifications()) { @@ -277,9 +286,7 @@ public final class ReadDataTransactionUtil { final List notifiStreamJSON = CreateStreamUtil.createYangNotifiStream(notificationDefinition, schemaContextRef, NotificationOutputType.JSON.getName()); - notifiStreamJSON.addAll(notifiStreamXML); - - for (final NotificationListenerAdapter listener : notifiStreamJSON) { + for (final NotificationListenerAdapter listener : Iterables.concat(notifiStreamXML, notifiStreamJSON)) { final URI uri = SubscribeToStreamUtil.prepareUriByStreamName(uriInfo, listener.getStreamName()); final NormalizedNode mapToStreams = RestconfMappingNodeUtil.mapYangNotificationStreamByIetfRestconfMonitoring( @@ -313,12 +320,12 @@ public final class ReadDataTransactionUtil { final DataSchemaContextTree baseSchemaCtxTree = DataSchemaContextTree.from(ctx); final DataSchemaNode baseSchemaNode = baseSchemaCtxTree.getChild(path).getDataSchemaNode(); if (result instanceof ContainerNode) { - final DataContainerNodeAttrBuilder builder = + final DataContainerNodeBuilder builder = Builders.containerBuilder((ContainerSchemaNode) baseSchemaNode); buildCont(builder, (ContainerNode) result, baseSchemaCtxTree, path, trim); return builder.build(); } else { - final DataContainerNodeAttrBuilder builder = + final DataContainerNodeBuilder builder = Builders.mapEntryBuilder((ListSchemaNode) baseSchemaNode); buildMapEntryBuilder(builder, (MapEntryNode) result, baseSchemaCtxTree, path, trim, ((ListSchemaNode) baseSchemaNode).getKeyDefinition()); @@ -327,14 +334,14 @@ public final class ReadDataTransactionUtil { } private static void buildMapEntryBuilder( - final DataContainerNodeAttrBuilder builder, + final DataContainerNodeBuilder builder, final MapEntryNode result, final DataSchemaContextTree baseSchemaCtxTree, final YangInstanceIdentifier actualPath, final boolean trim, final List keys) { for (final DataContainerChild child : result.getValue()) { final YangInstanceIdentifier path = actualPath.node(child.getIdentifier()); final DataSchemaNode childSchema = baseSchemaCtxTree.getChild(path).getDataSchemaNode(); if (child instanceof ContainerNode) { - final DataContainerNodeAttrBuilder childBuilder = + final DataContainerNodeBuilder childBuilder = Builders.containerBuilder((ContainerSchemaNode) childSchema); buildCont(childBuilder, (ContainerNode) child, baseSchemaCtxTree, path, trim); builder.withChild(childBuilder.build()); @@ -345,21 +352,21 @@ public final class ReadDataTransactionUtil { ((ListSchemaNode) childSchema).getKeyDefinition()); builder.withChild(childBuilder.build()); } else if (child instanceof LeafNode) { - final String defaultVal = ((LeafSchemaNode) childSchema).getDefault(); - final String nodeVal = ((LeafNode) child).getValue(); - final NormalizedNodeAttrBuilder> leafBuilder = + final Object defaultVal = ((LeafSchemaNode) childSchema).getType().getDefaultValue().orElse(null); + final Object nodeVal = child.getValue(); + final NormalizedNodeBuilder> leafBuilder = Builders.leafBuilder((LeafSchemaNode) childSchema); if (keys.contains(child.getNodeType())) { leafBuilder.withValue(((LeafNode) child).getValue()); builder.withChild(leafBuilder.build()); } else { if (trim) { - if ((defaultVal == null) || !defaultVal.equals(nodeVal)) { + if (defaultVal == null || !defaultVal.equals(nodeVal)) { leafBuilder.withValue(((LeafNode) child).getValue()); builder.withChild(leafBuilder.build()); } } else { - if ((defaultVal != null) && defaultVal.equals(nodeVal)) { + if (defaultVal != null && defaultVal.equals(nodeVal)) { leafBuilder.withValue(((LeafNode) child).getValue()); builder.withChild(leafBuilder.build()); } @@ -375,21 +382,21 @@ public final class ReadDataTransactionUtil { for (final MapEntryNode mapEntryNode : result.getValue()) { final YangInstanceIdentifier actualNode = path.node(mapEntryNode.getIdentifier()); final DataSchemaNode childSchema = baseSchemaCtxTree.getChild(actualNode).getDataSchemaNode(); - final DataContainerNodeAttrBuilder mapEntryBuilder = + final DataContainerNodeBuilder mapEntryBuilder = Builders.mapEntryBuilder((ListSchemaNode) childSchema); buildMapEntryBuilder(mapEntryBuilder, mapEntryNode, baseSchemaCtxTree, actualNode, trim, keys); builder.withChild(mapEntryBuilder.build()); } } - private static void buildCont(final DataContainerNodeAttrBuilder builder, + private static void buildCont(final DataContainerNodeBuilder builder, final ContainerNode result, final DataSchemaContextTree baseSchemaCtxTree, final YangInstanceIdentifier actualPath, final boolean trim) { for (final DataContainerChild child : result.getValue()) { final YangInstanceIdentifier path = actualPath.node(child.getIdentifier()); final DataSchemaNode childSchema = baseSchemaCtxTree.getChild(path).getDataSchemaNode(); if (child instanceof ContainerNode) { - final DataContainerNodeAttrBuilder builderChild = + final DataContainerNodeBuilder builderChild = Builders.containerBuilder((ContainerSchemaNode) childSchema); buildCont(builderChild, result, baseSchemaCtxTree, actualPath, trim); builder.withChild(builderChild.build()); @@ -400,17 +407,17 @@ public final class ReadDataTransactionUtil { ((ListSchemaNode) childSchema).getKeyDefinition()); builder.withChild(childBuilder.build()); } else if (child instanceof LeafNode) { - final String defaultVal = ((LeafSchemaNode) childSchema).getDefault(); - final String nodeVal = ((LeafNode) child).getValue(); - final NormalizedNodeAttrBuilder> leafBuilder = + final Object defaultVal = ((LeafSchemaNode) childSchema).getType().getDefaultValue().orElse(null); + final Object nodeVal = child.getValue(); + final NormalizedNodeBuilder> leafBuilder = Builders.leafBuilder((LeafSchemaNode) childSchema); if (trim) { - if ((defaultVal == null) || !defaultVal.equals(nodeVal)) { + if (defaultVal == null || !defaultVal.equals(nodeVal)) { leafBuilder.withValue(((LeafNode) child).getValue()); builder.withChild(leafBuilder.build()); } } else { - if ((defaultVal != null) && defaultVal.equals(nodeVal)) { + if (defaultVal != null && defaultVal.equals(nodeVal)) { leafBuilder.withValue(((LeafNode) child).getValue()); builder.withChild(leafBuilder.build()); } @@ -432,8 +439,8 @@ public final class ReadDataTransactionUtil { private static NormalizedNode readDataViaTransaction( @Nonnull final TransactionVarsWrapper transactionNode) { final NormalizedNodeFactory dataFactory = new NormalizedNodeFactory(); - try (DOMDataReadOnlyTransaction tx = transactionNode.getTransactionChain().newReadOnlyTransaction()) { - final CheckedFuture>, ReadFailedException> listenableFuture = tx.read( + try (DOMDataTreeReadTransaction tx = transactionNode.getTransactionChain().newReadOnlyTransaction()) { + final FluentFuture>> listenableFuture = tx.read( transactionNode.getLogicalDatastoreType(), transactionNode.getInstanceIdentifier().getInstanceIdentifier()); FutureCallbackTx.addCallback(listenableFuture, RestconfDataServiceConstant.ReadData.READ_TYPE_TX, @@ -450,6 +457,7 @@ public final class ReadDataTransactionUtil { * @param withDefa * with-defaults parameter * @param ctx + * schema context * @return {@link NormalizedNode} */ @Nullable @@ -470,7 +478,7 @@ public final class ReadDataTransactionUtil { } // if no data exists - if ((stateDataNode == null) && (configDataNode == null)) { + if (stateDataNode == null && configDataNode == null) { return null; } @@ -485,11 +493,11 @@ public final class ReadDataTransactionUtil { } // merge data from config and state - return mapNode(stateDataNode, configDataNode); + return mergeStateAndConfigData(stateDataNode, configDataNode); } /** - * Map data by type of read node. + * Merge state and config data into a single NormalizedNode. * * @param stateDataNode * data node of state data @@ -498,9 +506,9 @@ public final class ReadDataTransactionUtil { * @return {@link NormalizedNode} */ @Nonnull - private static NormalizedNode mapNode(@Nonnull final NormalizedNode stateDataNode, - @Nonnull final NormalizedNode configDataNode) { - validPossibilityOfMergeNodes(stateDataNode, configDataNode); + private static NormalizedNode mergeStateAndConfigData(@Nonnull final NormalizedNode stateDataNode, + @Nonnull final NormalizedNode configDataNode) { + validateNodeMerge(stateDataNode, configDataNode); if (configDataNode instanceof RpcDefinition) { return prepareRpcData(configDataNode, stateDataNode); } else { @@ -509,19 +517,19 @@ public final class ReadDataTransactionUtil { } /** - * Valid of can be data merged together. + * Validates whether the two NormalizedNodes can be merged. * * @param stateDataNode * data node of state data * @param configDataNode * data node of config data */ - private static void validPossibilityOfMergeNodes(@Nonnull final NormalizedNode stateDataNode, - @Nonnull final NormalizedNode configDataNode) { + private static void validateNodeMerge(@Nonnull final NormalizedNode stateDataNode, + @Nonnull final NormalizedNode configDataNode) { final QNameModule moduleOfStateData = stateDataNode.getIdentifier().getNodeType().getModule(); final QNameModule moduleOfConfigData = configDataNode.getIdentifier().getNodeType().getModule(); - if (moduleOfStateData != moduleOfConfigData) { - throw new RestconfDocumentedException("It is not possible to merge "); + if (!moduleOfStateData.equals(moduleOfConfigData)) { + throw new RestconfDocumentedException("Unable to merge data from different modules."); } } @@ -572,10 +580,19 @@ public final class ReadDataTransactionUtil { * data node of state data * @return {@link NormalizedNode} */ + @SuppressWarnings("unchecked") @Nonnull private static NormalizedNode prepareData(@Nonnull final NormalizedNode configDataNode, @Nonnull final NormalizedNode stateDataNode) { - if (configDataNode instanceof MapNode) { + if (configDataNode instanceof OrderedMapNode) { + final CollectionNodeBuilder builder = Builders + .orderedMapBuilder().withNodeIdentifier(((MapNode) configDataNode).getIdentifier()); + + mapValueToBuilder( + ((OrderedMapNode) configDataNode).getValue(), ((OrderedMapNode) stateDataNode).getValue(), builder); + + return builder.build(); + } else if (configDataNode instanceof MapNode) { final CollectionNodeBuilder builder = ImmutableNodes .mapNodeBuilder().withNodeIdentifier(((MapNode) configDataNode).getIdentifier()); @@ -592,7 +609,7 @@ public final class ReadDataTransactionUtil { return builder.build(); } else if (configDataNode instanceof ContainerNode) { - final DataContainerNodeAttrBuilder builder = Builders + final DataContainerNodeBuilder builder = Builders .containerBuilder().withNodeIdentifier(((ContainerNode) configDataNode).getIdentifier()); mapValueToBuilder( @@ -617,8 +634,36 @@ public final class ReadDataTransactionUtil { return builder.build(); } else if (configDataNode instanceof LeafNode) { return ImmutableNodes.leafNode(configDataNode.getNodeType(), configDataNode.getValue()); + } else if (configDataNode instanceof OrderedLeafSetNode) { + final ListNodeBuilder> builder = Builders + .orderedLeafSetBuilder().withNodeIdentifier(((OrderedLeafSetNode) configDataNode).getIdentifier()); + + mapValueToBuilder(((OrderedLeafSetNode) configDataNode).getValue(), + ((OrderedLeafSetNode) stateDataNode).getValue(), builder); + return builder.build(); + } else if (configDataNode instanceof LeafSetNode) { + final ListNodeBuilder> builder = Builders + .leafSetBuilder().withNodeIdentifier(((LeafSetNode) configDataNode).getIdentifier()); + + mapValueToBuilder(((LeafSetNode) configDataNode).getValue(), + ((LeafSetNode) stateDataNode).getValue(), builder); + return builder.build(); + } else if (configDataNode instanceof UnkeyedListNode) { + final CollectionNodeBuilder builder = Builders + .unkeyedListBuilder().withNodeIdentifier(((UnkeyedListNode) configDataNode).getIdentifier()); + + mapValueToBuilder(((UnkeyedListNode) configDataNode).getValue(), + ((UnkeyedListNode) stateDataNode).getValue(), builder); + return builder.build(); + } else if (configDataNode instanceof UnkeyedListEntryNode) { + final DataContainerNodeBuilder builder = Builders + .unkeyedListEntryBuilder().withNodeIdentifier(((UnkeyedListEntryNode) configDataNode).getIdentifier()); + + mapValueToBuilder(((UnkeyedListEntryNode) configDataNode).getValue(), + ((UnkeyedListEntryNode) stateDataNode).getValue(), builder); + return builder.build(); } else { - throw new RestconfDocumentedException("Bad type of node."); + throw new RestconfDocumentedException("Unexpected node type: " + configDataNode.getClass().getName()); } }