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.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+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;
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.ListNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeAttrBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
import org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree;
* set tagged for {@link WriterParameters}
* @return {@link WriterParameters}
*/
- @Nonnull
- public static WriterParameters parseUriParameters(@Nonnull final InstanceIdentifierContext<?> identifier,
- @Nullable final UriInfo uriInfo, final boolean tagged) {
+ public static @NonNull WriterParameters parseUriParameters(final @NonNull InstanceIdentifierContext<?> identifier,
+ final @Nullable UriInfo uriInfo, final boolean tagged) {
return parseParams(identifier, uriInfo, tagged);
}
* URI info
* @return {@link WriterParameters}
*/
- @Nonnull
- public static WriterParameters parseUriParameters(@Nonnull final InstanceIdentifierContext<?> identifier,
- @Nullable final UriInfo uriInfo) {
+ public static @NonNull WriterParameters parseUriParameters(final @NonNull InstanceIdentifierContext<?> identifier,
+ final @Nullable UriInfo uriInfo) {
return parseParams(identifier, uriInfo, false);
}
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,
* schema context
* @return {@link NormalizedNode}
*/
- @Nullable
- public static NormalizedNode<?, ?> readData(@Nonnull final String valueOfContent,
- @Nonnull final TransactionVarsWrapper transactionNode, final SchemaContext schemaContext) {
+ public static @Nullable NormalizedNode<?, ?> readData(final @NonNull String valueOfContent,
+ final @NonNull TransactionVarsWrapper transactionNode, final SchemaContext schemaContext) {
return readData(valueOfContent, transactionNode, null, schemaContext);
}
* schema context
* @return {@link NormalizedNode}
*/
- @Nullable
- public static NormalizedNode<?, ?> readData(@Nonnull final String valueOfContent,
- @Nonnull final TransactionVarsWrapper transactionNode, final String withDefa, final SchemaContext ctx) {
+ public static @Nullable NormalizedNode<?, ?> readData(final @NonNull String valueOfContent,
+ final @NonNull TransactionVarsWrapper transactionNode, final String withDefa, final SchemaContext ctx) {
switch (valueOfContent) {
case RestconfDataServiceConstant.ReadData.CONFIG:
transactionNode.setLogicalDatastoreType(LogicalDatastoreType.CONFIGURATION);
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()) {
final List<NotificationListenerAdapter> 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(
((ListSchemaNode) childSchema).getKeyDefinition());
builder.withChild(childBuilder.build());
} else if (child instanceof LeafNode) {
- final String defaultVal = ((LeafSchemaNode) childSchema).getDefault();
- final String nodeVal = ((LeafNode<String>) child).getValue();
+ final Object defaultVal = ((LeafSchemaNode) childSchema).getType().getDefaultValue().orElse(null);
+ final Object nodeVal = child.getValue();
final NormalizedNodeAttrBuilder<NodeIdentifier, Object, LeafNode<Object>> leafBuilder =
Builders.leafBuilder((LeafSchemaNode) childSchema);
if (keys.contains(child.getNodeType())) {
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());
}
((ListSchemaNode) childSchema).getKeyDefinition());
builder.withChild(childBuilder.build());
} else if (child instanceof LeafNode) {
- final String defaultVal = ((LeafSchemaNode) childSchema).getDefault();
- final String nodeVal = ((LeafNode<String>) child).getValue();
+ final Object defaultVal = ((LeafSchemaNode) childSchema).getType().getDefaultValue().orElse(null);
+ final Object nodeVal = child.getValue();
final NormalizedNodeAttrBuilder<NodeIdentifier, Object, LeafNode<Object>> 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());
}
* {@link TransactionVarsWrapper} - wrapper for variables
* @return {@link NormalizedNode}
*/
- @Nullable
- private static NormalizedNode<?, ?> readDataViaTransaction(
- @Nonnull final TransactionVarsWrapper transactionNode) {
+ private static @Nullable NormalizedNode<?, ?> readDataViaTransaction(
+ final @NonNull TransactionVarsWrapper transactionNode) {
final NormalizedNodeFactory dataFactory = new NormalizedNodeFactory();
- try (DOMDataReadOnlyTransaction tx = transactionNode.getTransactionChain().newReadOnlyTransaction()) {
- final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> listenableFuture = tx.read(
+ try (DOMDataTreeReadTransaction tx = transactionNode.getTransactionChain().newReadOnlyTransaction()) {
+ final FluentFuture<Optional<NormalizedNode<?, ?>>> listenableFuture = tx.read(
transactionNode.getLogicalDatastoreType(),
transactionNode.getInstanceIdentifier().getInstanceIdentifier());
FutureCallbackTx.addCallback(listenableFuture, RestconfDataServiceConstant.ReadData.READ_TYPE_TX,
* schema context
* @return {@link NormalizedNode}
*/
- @Nullable
- private static NormalizedNode<?, ?> readAllData(@Nonnull final TransactionVarsWrapper transactionNode,
+ private static @Nullable NormalizedNode<?, ?> readAllData(final @NonNull TransactionVarsWrapper transactionNode,
final String withDefa, final SchemaContext ctx) {
// PREPARE STATE DATA NODE
transactionNode.setLogicalDatastoreType(LogicalDatastoreType.OPERATIONAL);
}
// if no data exists
- if ((stateDataNode == null) && (configDataNode == null)) {
+ if (stateDataNode == null && configDataNode == null) {
return null;
}
}
// 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
* data node of config data
* @return {@link NormalizedNode}
*/
- @Nonnull
- private static NormalizedNode<?, ?> mapNode(@Nonnull final NormalizedNode<?, ?> stateDataNode,
- @Nonnull final NormalizedNode<?, ?> configDataNode) {
- validPossibilityOfMergeNodes(stateDataNode, configDataNode);
+ private static @NonNull NormalizedNode<?, ?> mergeStateAndConfigData(
+ final @NonNull NormalizedNode<?, ?> stateDataNode, final @NonNull NormalizedNode<?, ?> configDataNode) {
+ validateNodeMerge(stateDataNode, configDataNode);
if (configDataNode instanceof RpcDefinition) {
return prepareRpcData(configDataNode, stateDataNode);
} else {
}
/**
- * 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(final @NonNull NormalizedNode<?, ?> stateDataNode,
+ final @NonNull 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.");
}
}
* data node of state data
* @return {@link NormalizedNode}
*/
- @Nonnull
- private static NormalizedNode<?, ?> prepareRpcData(@Nonnull final NormalizedNode<?, ?> configDataNode,
- @Nonnull final NormalizedNode<?, ?> stateDataNode) {
+ private static @NonNull NormalizedNode<?, ?> prepareRpcData(final @NonNull NormalizedNode<?, ?> configDataNode,
+ final @NonNull NormalizedNode<?, ?> stateDataNode) {
final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder = ImmutableNodes
.mapEntryBuilder();
mapEntryBuilder.withNodeIdentifier((NodeIdentifierWithPredicates) configDataNode.getIdentifier());
* @param mapEntryBuilder
* builder for mapping data
*/
- private static void mapRpcDataNode(@Nonnull final NormalizedNode<?, ?> dataNode,
- @Nonnull final DataContainerNodeBuilder<
- NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder) {
+ private static void mapRpcDataNode(final @NonNull NormalizedNode<?, ?> dataNode,
+ final @NonNull DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder) {
((ContainerNode) dataNode).getValue().forEach(mapEntryBuilder::addChild);
}
* data node of state data
* @return {@link NormalizedNode}
*/
- @Nonnull
- private static NormalizedNode<?, ?> prepareData(@Nonnull final NormalizedNode<?, ?> configDataNode,
- @Nonnull final NormalizedNode<?, ?> stateDataNode) {
- if (configDataNode instanceof MapNode) {
+ @SuppressWarnings("unchecked")
+ private static @NonNull NormalizedNode<?, ?> prepareData(final @NonNull NormalizedNode<?, ?> configDataNode,
+ final @NonNull NormalizedNode<?, ?> stateDataNode) {
+ if (configDataNode instanceof OrderedMapNode) {
+ final CollectionNodeBuilder<MapEntryNode, OrderedMapNode> 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<MapEntryNode, MapNode> builder = ImmutableNodes
.mapNodeBuilder().withNodeIdentifier(((MapNode) configDataNode).getIdentifier());
return builder.build();
} else if (configDataNode instanceof LeafNode) {
return ImmutableNodes.leafNode(configDataNode.getNodeType(), configDataNode.getValue());
+ } else if (configDataNode instanceof OrderedLeafSetNode) {
+ final ListNodeBuilder<Object, LeafSetEntryNode<Object>> builder = Builders
+ .orderedLeafSetBuilder().withNodeIdentifier(((OrderedLeafSetNode<?>) configDataNode).getIdentifier());
+
+ mapValueToBuilder(((OrderedLeafSetNode<Object>) configDataNode).getValue(),
+ ((OrderedLeafSetNode<Object>) stateDataNode).getValue(), builder);
+ return builder.build();
+ } else if (configDataNode instanceof LeafSetNode) {
+ final ListNodeBuilder<Object, LeafSetEntryNode<Object>> builder = Builders
+ .leafSetBuilder().withNodeIdentifier(((LeafSetNode<?>) configDataNode).getIdentifier());
+
+ mapValueToBuilder(((LeafSetNode<Object>) configDataNode).getValue(),
+ ((LeafSetNode<Object>) stateDataNode).getValue(), builder);
+ return builder.build();
+ } else if (configDataNode instanceof UnkeyedListNode) {
+ final CollectionNodeBuilder<UnkeyedListEntryNode, UnkeyedListNode> builder = Builders
+ .unkeyedListBuilder().withNodeIdentifier(((UnkeyedListNode) configDataNode).getIdentifier());
+
+ mapValueToBuilder(((UnkeyedListNode) configDataNode).getValue(),
+ ((UnkeyedListNode) stateDataNode).getValue(), builder);
+ return builder.build();
+ } else if (configDataNode instanceof UnkeyedListEntryNode) {
+ final DataContainerNodeAttrBuilder<NodeIdentifier, UnkeyedListEntryNode> 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());
}
}
* builder
*/
private static <T extends NormalizedNode<? extends PathArgument, ?>> void mapValueToBuilder(
- @Nonnull final Collection<T> configData,
- @Nonnull final Collection<T> stateData,
- @Nonnull final NormalizedNodeContainerBuilder<?, PathArgument, T, ?> builder) {
+ final @NonNull Collection<T> configData, final @NonNull Collection<T> stateData,
+ final @NonNull NormalizedNodeContainerBuilder<?, PathArgument, T, ?> builder) {
final Map<PathArgument, T> configMap = configData.stream().collect(
Collectors.toMap(NormalizedNode::getIdentifier, Function.identity()));
final Map<PathArgument, T> stateMap = stateData.stream().collect(
* - builder
*/
private static <T extends NormalizedNode<? extends PathArgument, ?>> void mapDataToBuilder(
- @Nonnull final Map<PathArgument, T> configMap,
- @Nonnull final Map<PathArgument, T> stateMap,
- @Nonnull final NormalizedNodeContainerBuilder<?, PathArgument, T, ?> builder) {
+ final @NonNull Map<PathArgument, T> configMap, final @NonNull Map<PathArgument, T> stateMap,
+ final @NonNull NormalizedNodeContainerBuilder<?, PathArgument, T, ?> builder) {
configMap.entrySet().stream().filter(x -> !stateMap.containsKey(x.getKey())).forEach(
y -> builder.addChild(y.getValue()));
stateMap.entrySet().stream().filter(x -> !configMap.containsKey(x.getKey())).forEach(
*/
@SuppressWarnings("unchecked")
private static <T extends NormalizedNode<? extends PathArgument, ?>> void mergeDataToBuilder(
- @Nonnull final Map<PathArgument, T> configMap,
- @Nonnull final Map<PathArgument, T> stateMap,
- @Nonnull final NormalizedNodeContainerBuilder<?, PathArgument, T, ?> builder) {
+ final @NonNull Map<PathArgument, T> configMap, final @NonNull Map<PathArgument, T> stateMap,
+ final @NonNull NormalizedNodeContainerBuilder<?, PathArgument, T, ?> builder) {
// it is enough to process only config data because operational contains the same data
configMap.entrySet().stream().filter(x -> stateMap.containsKey(x.getKey())).forEach(
y -> builder.addChild((T) prepareData(y.getValue(), stateMap.get(y.getKey()))));