import org.opendaylight.netconf.sal.restconf.impl.PATCHContext;
import org.opendaylight.netconf.sal.restconf.impl.PATCHStatusContext;
import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
+import org.opendaylight.netconf.sal.restconf.impl.RestconfError;
import org.opendaylight.restconf.RestConnectorProvider;
import org.opendaylight.restconf.common.references.SchemaContextRef;
import org.opendaylight.restconf.handlers.SchemaContextHandler;
final TransactionVarsWrapper transactionNode = new TransactionVarsWrapper(instanceIdentifier, mountPoint,
transaction);
final NormalizedNode<?, ?> node = ReadDataTransactionUtil.readData(value, transactionNode);
+ if (node == null) {
+ throw new RestconfDocumentedException(
+ "Request could not be completed because the relevant data model content does not exist",
+ RestconfError.ErrorType.PROTOCOL,
+ RestconfError.ErrorTag.DATA_MISSING);
+ }
final SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
final String etag = '"' + node.getNodeType().getModule().getFormattedRevision()
* @return {@link NormalizedNode}
*/
public static NormalizedNode<?, ?> readData(final String valueOfContent, final TransactionVarsWrapper transactionNode) {
+ final NormalizedNode<?, ?> data;
if (valueOfContent != null) {
switch (valueOfContent) {
case RestconfDataServiceConstant.ReadData.CONFIG:
transactionNode.setLogicalDatastoreType(LogicalDatastoreType.CONFIGURATION);
- return readDataViaTransaction(transactionNode);
+ data = readDataViaTransaction(transactionNode);
+ break;
case RestconfDataServiceConstant.ReadData.NONCONFIG:
transactionNode.setLogicalDatastoreType(LogicalDatastoreType.OPERATIONAL);
- return readDataViaTransaction(transactionNode);
+ data = readDataViaTransaction(transactionNode);
+ break;
case RestconfDataServiceConstant.ReadData.ALL:
- return readDataViaTransaction(transactionNode);
+ data = readAllData(transactionNode);
+ break;
default:
throw new RestconfDocumentedException("Bad querry parameter for content.", ErrorType.APPLICATION,
ErrorTag.INVALID_VALUE);
}
} else {
- return readDataViaTransaction(transactionNode);
+ data = readAllData(transactionNode);
}
+
+ return data;
}
/**
* @return {@link NormalizedNode}
*/
private static NormalizedNode<?, ?> readDataViaTransaction(final TransactionVarsWrapper transactionNode) {
- if (transactionNode.getLogicalDatastoreType() != null) {
final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> listenableFuture = transactionNode
.getTransactionChain().newReadOnlyTransaction().read(transactionNode.getLogicalDatastoreType(),
transactionNode.getInstanceIdentifier().getInstanceIdentifier());
FutureCallbackTx.addCallback(listenableFuture, RestconfDataServiceConstant.ReadData.READ_TYPE_TX,
dataFactory);
return dataFactory.build();
- } else {
- return readAllData(transactionNode);
- }
}
/**
// if no data exists
if ((stateDataNode == null) && (configDataNode == null)) {
- throw new RestconfDocumentedException(
- "Request could not be completed because the relevant data model content does not exist",
- ErrorType.PROTOCOL,
- ErrorTag.DATA_MISSING);
+ return null;
}
// return config data
* - data node of state data
* @param configDataNode
* - data node of config data
- * @param transactionNode
- * - {@link TransactionVarsWrapper} - wrapper for variables
* @return {@link NormalizedNode}
*/
private static NormalizedNode<?, ?> mapNode(final NormalizedNode<?, ?> stateDataNode,
final NormalizedNode<?, ?> stateDataNode) {
if (configDataNode instanceof MapNode) { // part for lists mapping
- final MapNode immutableStateData = ImmutableNodes.mapNodeBuilder(stateDataNode.getNodeType())
- .addChild((MapEntryNode) stateDataNode).build();
- final MapNode immutableConfigData = ImmutableNodes.mapNodeBuilder(configDataNode.getNodeType())
- .addChild((MapEntryNode) configDataNode).build();
final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder = ImmutableNodes
.mapEntryBuilder();
- mapEntryBuilder.withNodeIdentifier((NodeIdentifierWithPredicates) configDataNode.getIdentifier());
+ final NodeIdentifierWithPredicates node = ((MapNode) configDataNode).getValue().iterator().next().getIdentifier();
+ mapEntryBuilder.withNodeIdentifier(node);
// MAP CONFIG DATA
- mapDataNode(immutableConfigData, mapEntryBuilder);
+ mapDataNode((MapNode) configDataNode, mapEntryBuilder);
// MAP STATE DATA
- mapDataNode(immutableStateData, mapEntryBuilder);
+ mapDataNode((MapNode) stateDataNode, mapEntryBuilder);
return ImmutableNodes.mapNodeBuilder(configDataNode.getNodeType()).addChild(mapEntryBuilder.build()).build();
- } else if (configDataNode instanceof ContainerNode) { // part for
- // containers
- // mapping
+ } else if (configDataNode instanceof ContainerNode) { // part for containers mapping
final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> containerBuilder = Builders
.containerBuilder((ContainerNode) configDataNode);
+
// MAP CONFIG DATA
mapCont(containerBuilder, ((ContainerNode) configDataNode).getValue());
// MAP STATE DATA
mapCont(containerBuilder, ((ContainerNode) stateDataNode).getValue());
-
return containerBuilder.build();
} else {
throw new RestconfDocumentedException("Bad type of node.");
--- /dev/null
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.restconf.restful.utils;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.doReturn;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.Futures;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
+import org.opendaylight.netconf.sal.restconf.impl.InstanceIdentifierContext;
+import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
+import org.opendaylight.restconf.restful.transaction.TransactionVarsWrapper;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+
+public class ReadDataTransactionUtilTest {
+
+ private static final TestData data = new TestData();
+ private static final YangInstanceIdentifier.NodeIdentifier nodeIdentifier = new YangInstanceIdentifier
+ .NodeIdentifier(QName.create("ns", "2016-02-28", "container"));
+
+ private TransactionVarsWrapper wrapper;
+ @Mock
+ private DOMTransactionChain transactionChain;
+ @Mock
+ private InstanceIdentifierContext<?> context;
+ @Mock
+ private DOMDataReadOnlyTransaction read;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ doReturn(read).when(transactionChain).newReadOnlyTransaction();
+ wrapper = new TransactionVarsWrapper(this.context, null, this.transactionChain);
+ }
+
+ @Test
+ public void readDataConfigTest() {
+ doReturn(Futures.immediateCheckedFuture(Optional.of(data.data3))).when(read)
+ .read(LogicalDatastoreType.CONFIGURATION, data.path);
+ doReturn(data.path).when(context).getInstanceIdentifier();
+ final String valueOfContent = RestconfDataServiceConstant.ReadData.CONFIG;
+ final NormalizedNode<?, ?> normalizedNode = ReadDataTransactionUtil.readData(valueOfContent, wrapper);
+ assertEquals(data.data3, normalizedNode);
+ }
+
+ @Test
+ public void readAllHavingOnlyConfigTest() {
+ doReturn(Futures.immediateCheckedFuture(Optional.of(data.data3))).when(read)
+ .read(LogicalDatastoreType.CONFIGURATION, data.path);
+ doReturn(Futures.immediateCheckedFuture(Optional.absent())).when(read)
+ .read(LogicalDatastoreType.OPERATIONAL, data.path);
+ doReturn(data.path).when(context).getInstanceIdentifier();
+ final String valueOfContent = RestconfDataServiceConstant.ReadData.ALL;
+ final NormalizedNode<?, ?> normalizedNode = ReadDataTransactionUtil.readData(valueOfContent, wrapper);
+ assertEquals(data.data3, normalizedNode);
+ }
+
+ @Test
+ public void readAllHavingOnlyNonConfigTest() {
+ doReturn(Futures.immediateCheckedFuture(Optional.of(data.data2))).when(read)
+ .read(LogicalDatastoreType.OPERATIONAL, data.path2);
+ doReturn(Futures.immediateCheckedFuture(Optional.absent())).when(read)
+ .read(LogicalDatastoreType.CONFIGURATION, data.path2);
+ doReturn(data.path2).when(context).getInstanceIdentifier();
+ final String valueOfContent = RestconfDataServiceConstant.ReadData.ALL;
+ final NormalizedNode<?, ?> normalizedNode = ReadDataTransactionUtil.readData(valueOfContent, wrapper);
+ assertEquals(data.data2, normalizedNode);
+ }
+
+ @Test
+ public void readDataNonConfigTest() {
+ doReturn(Futures.immediateCheckedFuture(Optional.of(data.data2))).when(read)
+ .read(LogicalDatastoreType.OPERATIONAL, data.path2);
+ doReturn(data.path2).when(context).getInstanceIdentifier();
+ final String valueOfContent = RestconfDataServiceConstant.ReadData.NONCONFIG;
+ final NormalizedNode<?, ?> normalizedNode = ReadDataTransactionUtil.readData(valueOfContent, wrapper);
+ assertEquals(data.data2, normalizedNode);
+ }
+
+ @Test
+ public void readContainerDataAllTest() {
+ doReturn(Futures.immediateCheckedFuture(Optional.of(data.data3))).when(read)
+ .read(LogicalDatastoreType.CONFIGURATION, data.path);
+ doReturn(Futures.immediateCheckedFuture(Optional.of(data.data4))).when(read)
+ .read(LogicalDatastoreType.OPERATIONAL, data.path);
+ doReturn(data.path).when(context).getInstanceIdentifier();
+ final String valueOfContent = RestconfDataServiceConstant.ReadData.ALL;
+ final NormalizedNode<?, ?> normalizedNode = ReadDataTransactionUtil.readData(valueOfContent, wrapper);
+ final ContainerNode checkingData = Builders
+ .containerBuilder()
+ .withNodeIdentifier(nodeIdentifier)
+ .withChild(data.contentLeaf)
+ .withChild(data.contentLeaf2)
+ .build();
+ assertEquals(checkingData, normalizedNode);
+ }
+
+ @Test
+ public void readContainerDataConfigNoValueOfContentTest() {
+ doReturn(Futures.immediateCheckedFuture(Optional.of(data.data3))).when(read)
+ .read(LogicalDatastoreType.CONFIGURATION, data.path);
+ doReturn(Futures.immediateCheckedFuture(Optional.of(data.data4))).when(read)
+ .read(LogicalDatastoreType.OPERATIONAL, data.path);
+ doReturn(data.path).when(context).getInstanceIdentifier();
+ final NormalizedNode<?, ?> normalizedNode = ReadDataTransactionUtil.readData(null, wrapper);
+ final ContainerNode checkingData = Builders
+ .containerBuilder()
+ .withNodeIdentifier(nodeIdentifier)
+ .withChild(data.contentLeaf)
+ .withChild(data.contentLeaf2)
+ .build();
+ assertEquals(checkingData, normalizedNode);
+ }
+
+ @Test
+ public void readListDataAllTest() {
+ doReturn(Futures.immediateCheckedFuture(Optional.of(data.listData))).when(read)
+ .read(LogicalDatastoreType.OPERATIONAL, data.path3);
+ doReturn(Futures.immediateCheckedFuture(Optional.of(data.listData2))).when(read)
+ .read(LogicalDatastoreType.CONFIGURATION, data.path3);
+ doReturn(data.path3).when(context).getInstanceIdentifier();
+ final String valueOfContent = RestconfDataServiceConstant.ReadData.ALL;
+ final NormalizedNode<?, ?> normalizedNode = ReadDataTransactionUtil.readData(valueOfContent, wrapper);
+ final MapNode checkingData = Builders
+ .mapBuilder()
+ .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(QName.create("ns", "2016-02-28", "list")))
+ .withChild(data.checkData)
+ .build();
+ assertEquals(checkingData, normalizedNode);
+ }
+
+ @Test
+ public void readDataWrongPathOrNoContentTest() {
+ doReturn(Futures.immediateCheckedFuture(Optional.absent())).when(read)
+ .read(LogicalDatastoreType.CONFIGURATION, data.path2);
+ doReturn(data.path2).when(context).getInstanceIdentifier();
+ final String valueOfContent = RestconfDataServiceConstant.ReadData.CONFIG;
+ final NormalizedNode<?, ?> normalizedNode = ReadDataTransactionUtil.readData(valueOfContent, wrapper);
+ assertNull(normalizedNode);
+ }
+
+ @Test(expected = RestconfDocumentedException.class)
+ public void readDataFailTest() {
+ final String valueOfContent = RestconfDataServiceConstant.ReadData.READ_TYPE_TX;
+ final NormalizedNode<?, ?> normalizedNode = ReadDataTransactionUtil.readData(valueOfContent, null);
+ assertNull(normalizedNode);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.restful.utils;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+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.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+
+class TestData {
+
+ final YangInstanceIdentifier path;
+ final YangInstanceIdentifier path2;
+ final YangInstanceIdentifier path3;
+ final MapEntryNode data;
+ final MapEntryNode data2;
+ final ContainerNode data3;
+ final ContainerNode data4;
+ final MapNode listData;
+ final MapNode listData2;
+ final UnkeyedListEntryNode unkeyedListEntryNode;
+ final LeafNode contentLeaf;
+ final LeafNode contentLeaf2;
+ final MapEntryNode checkData;
+
+ TestData() {
+ final QName base = QName.create("ns", "2016-02-28", "base");
+ final QName listQname = QName.create(base, "list");
+ final QName listKeyQName = QName.create(base, "list-key");
+ final YangInstanceIdentifier.NodeIdentifierWithPredicates nodeWithKey =
+ new YangInstanceIdentifier.NodeIdentifierWithPredicates(listQname, listKeyQName, "keyValue");
+ final YangInstanceIdentifier.NodeIdentifierWithPredicates nodeWithKey2 =
+ new YangInstanceIdentifier.NodeIdentifierWithPredicates(listQname, listKeyQName, "keyValue2");
+ final LeafNode<Object> content = Builders.leafBuilder()
+ .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(QName.create(base, "leaf-content")))
+ .withValue("content")
+ .build();
+ final LeafNode<Object> content2 = Builders.leafBuilder()
+ .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(QName.create(base, "leaf-content-different")))
+ .withValue("content-different")
+ .build();
+ final DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> dataContainer = Builders.leafBuilder()
+ .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(QName.create(listQname, "identifier")))
+ .withValue("id")
+ .build();
+ unkeyedListEntryNode = Builders.unkeyedListEntryBuilder()
+ .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(QName.create(listQname, "list")))
+ .withChild(dataContainer)
+ .build();
+ data = Builders.mapEntryBuilder()
+ .withNodeIdentifier(nodeWithKey)
+ .withChild(content)
+ .build();
+ data2 = Builders.mapEntryBuilder()
+ .withNodeIdentifier(nodeWithKey)
+ .withChild(content2)
+ .build();
+ checkData = Builders.mapEntryBuilder()
+ .withNodeIdentifier(nodeWithKey)
+ .withChild(content2)
+ .withChild(content)
+ .build();
+ listData = Builders.mapBuilder()
+ .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(QName.create(listQname, "list")))
+ .withChild(data)
+ .build();
+ listData2 = Builders.mapBuilder()
+ .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(QName.create(listQname, "list")))
+ .withChild(data)
+ .withChild(data2)
+ .build();
+ path = YangInstanceIdentifier.builder()
+ .node(QName.create(base, "cont"))
+ .node(listQname)
+ .node(nodeWithKey)
+ .build();
+ path2 = YangInstanceIdentifier.builder()
+ .node(QName.create(base, "cont"))
+ .node(listQname)
+ .node(nodeWithKey2)
+ .build();
+ path3 = YangInstanceIdentifier.builder()
+ .node(QName.create(base, "cont"))
+ .node(listQname)
+ .build();
+ contentLeaf = Builders.leafBuilder()
+ .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(QName.create(base, "content")))
+ .withValue("test")
+ .build();
+ contentLeaf2 = Builders.leafBuilder()
+ .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(QName.create(base, "content2")))
+ .withValue("test2")
+ .build();
+ data3 = Builders.containerBuilder()
+ .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(QName.create(base, "container")))
+ .withChild(contentLeaf)
+ .build();
+ data4 = Builders.containerBuilder()
+ .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(QName.create(base, "container2")))
+ .withChild(contentLeaf2)
+ .build();
+ }
+}
\ No newline at end of file