Bug 6325 - upgrade draft11 to draft15 - added timestamp & etag 15/43115/9
authorJakub Toth <jatoth@cisco.com>
Thu, 4 Aug 2016 13:26:41 +0000 (09:26 -0400)
committerJakub Toth <jatoth@cisco.com>
Mon, 15 Aug 2016 15:21:29 +0000 (15:21 +0000)
  *fixed read of data from datastore

Change-Id: I629c909ba05f93f4d662199a86637e966cb6d8e1
Signed-off-by: Jakub Toth <jatoth@cisco.com>
restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/RestConnectorProvider.java
restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/common/wrapper/services/Draft15ServicesWrapperImpl.java
restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/restful/services/api/RestconfDataService.java
restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/restful/services/impl/RestconfDataServiceImpl.java
restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/restful/transaction/TransactionVarsWrapper.java
restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/restful/utils/DeleteDataTransactionUtil.java
restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/restful/utils/PatchDataTransactionUtil.java
restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/restful/utils/PostDataTransactionUtil.java
restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/restful/utils/PutDataTransactionUtil.java
restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/restful/utils/ReadDataTransactionUtil.java
restconf/sal-rest-connector/src/test/java/org/opendaylight/restconf/restful/utils/DeleteDataTransactionUtilTest.java

index dedea9b0a6cd15d3edfdea6e08d9d8462da27f6d..7c7ae377e17b9ed85020ad46e6b429a9e1e02868 100644 (file)
@@ -41,12 +41,11 @@ public class RestConnectorProvider implements Provider, RestConnector, AutoClose
 
     private static final Logger LOG = LoggerFactory.getLogger(RestConnectorProvider.class);
 
-    private final TransactionChainListener transactionListener = new TransactionChainListener() {
+    public static final TransactionChainListener transactionListener = new TransactionChainListener() {
         @Override
         public void onTransactionChainFailed(final TransactionChain<?, ?> chain,
                 final AsyncTransaction<?, ?> transaction, final Throwable cause) {
             LOG.warn("TransactionChain({}) {} FAILED!", chain, transaction.getIdentifier(), cause);
-            chain.close();
             resetTransactionChainForAdapaters(chain);
             throw new RestconfDocumentedException("TransactionChain(" + chain + ") not committed correctly", cause);
         }
@@ -58,8 +57,8 @@ public class RestConnectorProvider implements Provider, RestConnector, AutoClose
     };
 
     private ListenerRegistration<SchemaContextListener> listenerRegistration;
-    private DOMDataBroker dataBroker;
-    private DOMTransactionChain transactionChain;
+    private static DOMDataBroker dataBroker;
+    private static DOMTransactionChain transactionChain;
 
     @Override
     public void onSessionInitiated(final ProviderSession session) {
@@ -73,11 +72,11 @@ public class RestConnectorProvider implements Provider, RestConnector, AutoClose
         final DOMMountPointServiceHandler domMountPointServiceHandler = new DOMMountPointServiceHandler(
                 session.getService(DOMMountPointService.class));
 
-        this.dataBroker = session.getService(DOMDataBroker.class);
-        final DOMDataBrokerHandler brokerHandler = new DOMDataBrokerHandler(this.dataBroker);
+        dataBroker = session.getService(DOMDataBroker.class);
+        final DOMDataBrokerHandler brokerHandler = new DOMDataBrokerHandler(dataBroker);
 
-        this.transactionChain = this.dataBroker.createTransactionChain(this.transactionListener);
-        final TransactionChainHandler transactionChainHandler = new TransactionChainHandler(this.transactionChain);
+        transactionChain = dataBroker.createTransactionChain(transactionListener);
+        final TransactionChainHandler transactionChainHandler = new TransactionChainHandler(transactionChain);
 
         final DOMRpcService rpcService = session.getService(DOMRpcService.class);
         final RpcServiceHandler rpcServiceHandler = new RpcServiceHandler(rpcService);
@@ -93,10 +92,10 @@ public class RestConnectorProvider implements Provider, RestConnector, AutoClose
      * @param chain
      *            - old {@link TransactionChain}
      */
-    private void resetTransactionChainForAdapaters(final TransactionChain<?, ?> chain) {
-        LOG.trace("Resetting TransactionChain({}) to {}", chain, this.transactionChain);
-        this.transactionChain = Preconditions.checkNotNull(this.dataBroker)
-                .createTransactionChain(this.transactionListener);
+    public static void resetTransactionChainForAdapaters(final TransactionChain<?, ?> chain) {
+        LOG.trace("Resetting TransactionChain({}) to {}", chain, transactionChain);
+        chain.close();
+        transactionChain = Preconditions.checkNotNull(dataBroker).createTransactionChain(transactionListener);
     }
 
     @Override
@@ -109,8 +108,8 @@ public class RestConnectorProvider implements Provider, RestConnector, AutoClose
         if (this.listenerRegistration != null) {
             this.listenerRegistration.close();
         }
-        if (this.transactionChain != null) {
-            this.transactionChain.close();
+        if (transactionChain != null) {
+            transactionChain.close();
         }
     }
 }
index 713bea1b5f5b5f33bfea56204801d70926da5602..507914b6cb2dde1cee23a86d21f6dddbcbc4f28b 100644 (file)
@@ -102,7 +102,7 @@ public class Draft15ServicesWrapperImpl implements Draft15BaseServicesWrapper, D
     }
 
     @Override
-    public NormalizedNodeContext readData(final String identifier, final UriInfo uriInfo) {
+    public Response readData(final String identifier, final UriInfo uriInfo) {
         return this.delegRestconfDataService.readData(identifier, uriInfo);
     }
 
index 12bbf9f78ef1a15bd73af99217d8b94e0331e36d..f1f3b7e348f7ae07b87b9c074a709b5e73b68de8 100644 (file)
@@ -47,7 +47,7 @@ public interface RestconfDataService {
     @Path("/data/{identifier:.+}")
     @Produces({ Draft15.MediaTypes.DATA + RestconfConstants.JSON, Draft15.MediaTypes.DATA, MediaType.APPLICATION_JSON,
             MediaType.APPLICATION_XML, MediaType.TEXT_XML })
-    NormalizedNodeContext readData(@Encoded @PathParam("identifier") String identifier,
+    Response readData(@Encoded @PathParam("identifier") String identifier,
             @Context UriInfo uriInfo);
 
     /**
index a6187f5fa39f022513afaddf85a232315791db74..95645334cbfacc1d6a2876d86bc9c9158fb707ad 100644 (file)
@@ -9,16 +9,20 @@ package org.opendaylight.restconf.restful.services.impl;
 
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
+import java.text.SimpleDateFormat;
+import java.util.TimeZone;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
 import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
+import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
 import org.opendaylight.netconf.sal.restconf.impl.InstanceIdentifierContext;
 import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext;
 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.restconf.RestConnectorProvider;
 import org.opendaylight.restconf.common.references.SchemaContextRef;
 import org.opendaylight.restconf.handlers.SchemaContextHandler;
 import org.opendaylight.restconf.handlers.TransactionChainHandler;
@@ -53,25 +57,36 @@ public class RestconfDataServiceImpl implements RestconfDataService {
     }
 
     @Override
-    public NormalizedNodeContext readData(final String identifier, final UriInfo uriInfo) {
+    public Response readData(final String identifier, final UriInfo uriInfo) {
         Preconditions.checkNotNull(identifier);
         final SchemaContextRef schemaContextRef = new SchemaContextRef(this.schemaContextHandler.get());
 
-        final InstanceIdentifierContext<?> instanceIdentifier = ParserIdentifier.toInstanceIdentifier(identifier, schemaContextRef.get());
+        final InstanceIdentifierContext<?> instanceIdentifier = ParserIdentifier.toInstanceIdentifier(identifier,
+                schemaContextRef.get());
         final DOMMountPoint mountPoint = instanceIdentifier.getMountPoint();
         final String value = uriInfo.getQueryParameters().getFirst(RestconfDataServiceConstant.CONTENT);
 
-        DOMDataReadWriteTransaction transaction = null;
+        DOMTransactionChain transaction = null;
         if (mountPoint == null) {
-            transaction = this.transactionChainHandler.get().newReadWriteTransaction();
+            transaction = this.transactionChainHandler.get();
         } else {
             transaction = transactionOfMountPoint(mountPoint);
         }
         final TransactionVarsWrapper transactionNode = new TransactionVarsWrapper(instanceIdentifier, mountPoint,
                 transaction);
         final NormalizedNode<?, ?> node = ReadDataTransactionUtil.readData(value, transactionNode);
-
-        return new NormalizedNodeContext(instanceIdentifier, node);
+        final SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
+        dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
+        final String etag = '"' + node.getNodeType().getModule().getFormattedRevision()
+                + node.getNodeType().getLocalName() + '"';
+        Response resp = null;
+        if ((value == null) || value.contains(RestconfDataServiceConstant.ReadData.CONFIG)) {
+            resp = Response.status(200).entity(new NormalizedNodeContext(instanceIdentifier, node)).header("ETag", etag)
+                    .header("Last-Modified", dateFormatGmt.toString()).build();
+        } else {
+            resp = Response.status(200).entity(new NormalizedNodeContext(instanceIdentifier, node)).build();
+        }
+        return resp;
     }
 
     @Override
@@ -87,10 +102,10 @@ public class RestconfDataServiceImpl implements RestconfDataService {
         PutDataTransactionUtil.validateListKeysEqualityInPayloadAndUri(payload);
 
         final DOMMountPoint mountPoint = payload.getInstanceIdentifierContext().getMountPoint();
-        DOMDataReadWriteTransaction transaction = null;
+        DOMTransactionChain transaction = null;
         SchemaContextRef ref = null;
         if (mountPoint == null) {
-            transaction = this.transactionChainHandler.get().newReadWriteTransaction();
+            transaction = this.transactionChainHandler.get();
             ref = new SchemaContextRef(this.schemaContextHandler.get());
         } else {
             transaction = transactionOfMountPoint(mountPoint);
@@ -112,10 +127,10 @@ public class RestconfDataServiceImpl implements RestconfDataService {
         Preconditions.checkNotNull(payload);
 
         final DOMMountPoint mountPoint = payload.getInstanceIdentifierContext().getMountPoint();
-        DOMDataReadWriteTransaction transaction = null;
+        DOMTransactionChain transaction = null;
         SchemaContextRef ref = null;
         if (mountPoint == null) {
-            transaction = this.transactionChainHandler.get().newReadWriteTransaction();
+            transaction = this.transactionChainHandler.get();
             ref = new SchemaContextRef(this.schemaContextHandler.get());
         } else {
             transaction = transactionOfMountPoint(mountPoint);
@@ -133,9 +148,9 @@ public class RestconfDataServiceImpl implements RestconfDataService {
                 schemaContextRef.get());
 
         final DOMMountPoint mountPoint = instanceIdentifier.getMountPoint();
-        final DOMDataReadWriteTransaction transaction;
+        final DOMTransactionChain transaction;
         if (mountPoint == null) {
-            transaction = this.transactionChainHandler.get().newReadWriteTransaction();
+            transaction = this.transactionChainHandler.get();
         } else {
             transaction = transactionOfMountPoint(mountPoint);
         }
@@ -156,10 +171,10 @@ public class RestconfDataServiceImpl implements RestconfDataService {
         Preconditions.checkNotNull(context);
         final DOMMountPoint mountPoint = context.getInstanceIdentifierContext().getMountPoint();
 
-        final DOMDataReadWriteTransaction transaction;
+        final DOMTransactionChain transaction;
         final SchemaContextRef ref;
         if (mountPoint == null) {
-            transaction = this.transactionChainHandler.get().newReadWriteTransaction();
+            transaction = this.transactionChainHandler.get();
             ref = new SchemaContextRef(this.schemaContextHandler.get());
         } else {
             transaction = transactionOfMountPoint(mountPoint);
@@ -178,10 +193,10 @@ public class RestconfDataServiceImpl implements RestconfDataService {
      * @param mountPoint
      * @return {@link DOMDataReadWriteTransaction}
      */
-    private static DOMDataReadWriteTransaction transactionOfMountPoint(final DOMMountPoint mountPoint) {
+    private static DOMTransactionChain transactionOfMountPoint(final DOMMountPoint mountPoint) {
         final Optional<DOMDataBroker> domDataBrokerService = mountPoint.getService(DOMDataBroker.class);
         if (domDataBrokerService.isPresent()) {
-            return domDataBrokerService.get().newReadWriteTransaction();
+            return domDataBrokerService.get().createTransactionChain(RestConnectorProvider.transactionListener);
         } else {
             final String errMsg = "DOM data broker service isn't available for mount point "
                     + mountPoint.getIdentifier();
index 1789d30933d98d992258066d5ecde44971068b50..23b3875f86540adae724b28699049c2ec6074329 100644 (file)
@@ -8,8 +8,8 @@
 package org.opendaylight.restconf.restful.transaction;
 
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
 import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
+import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
 import org.opendaylight.netconf.sal.restconf.impl.InstanceIdentifierContext;
 
 /**
@@ -21,7 +21,7 @@ public final class TransactionVarsWrapper {
     private final InstanceIdentifierContext<?> instanceIdentifier;
     private final DOMMountPoint mountPoint;
     private LogicalDatastoreType configuration = null;
-    private final DOMDataReadWriteTransaction transaction;
+    private final DOMTransactionChain transactionChain;
 
     /**
      * Set base type of variables, which ones we need for transaction.
@@ -32,15 +32,15 @@ public final class TransactionVarsWrapper {
      *            - {@link InstanceIdentifierContext} of data for transaction
      * @param mountPoint
      *            - mount point if is present
-     * @param transaction
-     *            - {@link DOMDataReadWriteTransaction} transaction for
-     *            operations
+     * @param transactionChain
+     *            - transaction chain for creating specific type of transaction
+     *            in specific operation
      */
     public TransactionVarsWrapper(final InstanceIdentifierContext<?> instanceIdentifier, final DOMMountPoint mountPoint,
-            final DOMDataReadWriteTransaction transaction) {
+            final DOMTransactionChain transactionChain) {
         this.instanceIdentifier = instanceIdentifier;
         this.mountPoint = mountPoint;
-        this.transaction = transaction;
+        this.transactionChain = transactionChain;
     }
 
     /**
@@ -82,11 +82,12 @@ public final class TransactionVarsWrapper {
     }
 
     /**
-     * Get specific type of transaction
+     * Get transaction chain for creating specific transaction for specific
+     * operation
      *
-     * @return specific type transaction
+     * @return transaction chain
      */
-    public DOMDataReadWriteTransaction getTransaction() {
-        return this.transaction;
+    public DOMTransactionChain getTransactionChain() {
+        return this.transactionChain;
     }
 }
index 53c19c5fe96fce213f6a983f777b5c43733ea8d9..15d1f1c95d43326dd641a22497576cc2c99de7de 100644 (file)
@@ -34,7 +34,8 @@ public final class DeleteDataTransactionUtil {
      */
     public static Response deleteData(final TransactionVarsWrapper transactionNode) {
         final CheckedFuture<Void, TransactionCommitFailedException> future = submitData(
-                transactionNode.getTransaction(), transactionNode.getInstanceIdentifier().getInstanceIdentifier());
+                transactionNode.getTransactionChain().newReadWriteTransaction(),
+                transactionNode.getInstanceIdentifier().getInstanceIdentifier());
         final ResponseFactory response = new ResponseFactory();
         FutureCallbackTx.addCallback(future, RestconfDataServiceConstant.DeleteData.DELETE_TX_TYPE, response);
         return response.build();
index 09cdf6a6e2284ef6bbe5f7cb6ef2601c8da321db..0b350a7667c4608c648ffedfd856813328f5a3c6 100644 (file)
@@ -26,6 +26,7 @@ import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
 import org.opendaylight.netconf.sal.restconf.impl.RestconfError;
 import org.opendaylight.netconf.sal.restconf.impl.RestconfError.ErrorTag;
 import org.opendaylight.netconf.sal.restconf.impl.RestconfError.ErrorType;
+import org.opendaylight.restconf.RestConnectorProvider;
 import org.opendaylight.restconf.common.references.SchemaContextRef;
 import org.opendaylight.restconf.restful.transaction.TransactionVarsWrapper;
 import org.opendaylight.restconf.restful.utils.RestconfDataServiceConstant.PatchData;
@@ -56,6 +57,7 @@ public final class PatchDataTransactionUtil {
                                                final SchemaContextRef schemaContextRef) {
         final List<PATCHStatusEntity> editCollection = new ArrayList<>();
         int errorCounter = 0;
+        final DOMDataReadWriteTransaction tx = transactionNode.getTransactionChain().newReadWriteTransaction();
 
         for (final PATCHEntity patchEntity : context.getData()) {
             final PATCHEditOperation operation = PATCHEditOperation.valueOf(patchEntity.getOperation().toUpperCase());
@@ -65,8 +67,7 @@ public final class PatchDataTransactionUtil {
                     if (errorCounter == 0) {
                         try {
                             createDataWithinTransaction(LogicalDatastoreType.CONFIGURATION,
-                                    patchEntity.getTargetNode(), patchEntity.getNode(),
-                                    transactionNode.getTransaction(), schemaContextRef);
+                                    patchEntity.getTargetNode(), patchEntity.getNode(), tx, schemaContextRef);
                             editCollection.add(new PATCHStatusEntity(patchEntity.getEditId(), true, null));
                         } catch (final RestconfDocumentedException e) {
                             editCollection.add(new PATCHStatusEntity(patchEntity.getEditId(),
@@ -78,8 +79,8 @@ public final class PatchDataTransactionUtil {
                 case DELETE:
                     if (errorCounter == 0) {
                         try {
-                            deleteDataWithinTransaction(LogicalDatastoreType.CONFIGURATION,
-                                    patchEntity.getTargetNode(), transactionNode.getTransaction());
+                            deleteDataWithinTransaction(LogicalDatastoreType.CONFIGURATION, patchEntity.getTargetNode(),
+                                    tx);
                             editCollection.add(new PATCHStatusEntity(patchEntity.getEditId(), true, null));
                         } catch (final RestconfDocumentedException e) {
                             editCollection.add(new PATCHStatusEntity(patchEntity.getEditId(),
@@ -92,8 +93,7 @@ public final class PatchDataTransactionUtil {
                     if (errorCounter == 0) {
                         try {
                             mergeDataWithinTransaction(LogicalDatastoreType.CONFIGURATION,
-                                    patchEntity.getTargetNode(), patchEntity.getNode(), transactionNode.getTransaction(),
-                                    schemaContextRef);
+                                    patchEntity.getTargetNode(), patchEntity.getNode(), tx, schemaContextRef);
                             editCollection.add(new PATCHStatusEntity(patchEntity.getEditId(), true, null));
                         } catch (final RestconfDocumentedException e) {
                             editCollection.add(new PATCHStatusEntity(patchEntity.getEditId(),
@@ -106,8 +106,7 @@ public final class PatchDataTransactionUtil {
                     if (errorCounter == 0) {
                         try {
                             replaceDataWithinTransaction(LogicalDatastoreType.CONFIGURATION,
-                                    patchEntity.getTargetNode(), patchEntity.getNode(), schemaContextRef,
-                                    transactionNode.getTransaction());
+                                    patchEntity.getTargetNode(), patchEntity.getNode(), schemaContextRef, tx);
                             editCollection.add(new PATCHStatusEntity(patchEntity.getEditId(), true, null));
                         } catch (final RestconfDocumentedException e) {
                             editCollection.add(new PATCHStatusEntity(patchEntity.getEditId(),
@@ -119,8 +118,8 @@ public final class PatchDataTransactionUtil {
                 case REMOVE:
                     if (errorCounter == 0) {
                         try {
-                            removeDataWithinTransaction(LogicalDatastoreType.CONFIGURATION,
-                                    patchEntity.getTargetNode(), transactionNode.getTransaction());
+                            removeDataWithinTransaction(LogicalDatastoreType.CONFIGURATION, patchEntity.getTargetNode(),
+                                    tx);
                             editCollection.add(new PATCHStatusEntity(patchEntity.getEditId(), true, null));
                         } catch (final RestconfDocumentedException e) {
                             editCollection.add(new PATCHStatusEntity(patchEntity.getEditId(),
@@ -141,8 +140,7 @@ public final class PatchDataTransactionUtil {
         // if no errors then submit transaction, otherwise cancel
         if (errorCounter == 0) {
             final ResponseFactory response = new ResponseFactory();
-            final CheckedFuture<Void, TransactionCommitFailedException> future = transactionNode
-                    .getTransaction().submit();
+            final CheckedFuture<Void, TransactionCommitFailedException> future = tx.submit();
 
             try {
                 FutureCallbackTx.addCallback(future, PatchData.PATCH_TX_TYPE, response);
@@ -154,7 +152,8 @@ public final class PatchDataTransactionUtil {
 
             return new PATCHStatusContext(context.getPatchId(), ImmutableList.copyOf(editCollection), true, null);
         } else {
-            transactionNode.getTransaction().cancel();
+            tx.cancel();
+            RestConnectorProvider.resetTransactionChainForAdapaters(transactionNode.getTransactionChain());
             return new PATCHStatusContext(context.getPatchId(), ImmutableList.copyOf(editCollection), false, null);
         }
     }
index 778acd9734df942d004e55a8c8c67c37ec4966a9..bc464069e0832dd36bd7d351a7f2ea4aec3d8d86 100644 (file)
@@ -89,7 +89,7 @@ public final class PostDataTransactionUtil {
     private static CheckedFuture<Void, TransactionCommitFailedException> submitData(final YangInstanceIdentifier path,
             final NormalizedNode<?, ?> data, final TransactionVarsWrapper transactionNode,
             final SchemaContext schemaContext) {
-        final DOMDataReadWriteTransaction transaction = transactionNode.getTransaction();
+        final DOMDataReadWriteTransaction transaction = transactionNode.getTransactionChain().newReadWriteTransaction();
         final NormalizedNode<?, ?> node = ImmutableNodes.fromInstanceId(schemaContext, path);
         transaction.put(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(node.getIdentifier()), node);
         TransactionUtil.ensureParentsByMerge(path, schemaContext, transaction);
index d0302cfcd3488e32ffc91d9e6b847e4edf4363d6..8db0b433f40507cce4d20c9aa48c018575a19b9a 100644 (file)
@@ -139,7 +139,7 @@ public final class PutDataTransactionUtil {
         final ResponseFactory responseFactory = new ResponseFactory(
                 ReadDataTransactionUtil.readData(RestconfDataServiceConstant.ReadData.CONFIG, transactionNode));
         final CheckedFuture<Void, TransactionCommitFailedException> submitData = submitData(path, schemaCtxRef.get(),
-                transactionNode.getTransaction(), payload.getData());
+                transactionNode.getTransactionChain().newWriteOnlyTransaction(), payload.getData());
         FutureCallbackTx.addCallback(submitData, RestconfDataServiceConstant.PutData.PUT_TX_TYPE, responseFactory);
         return responseFactory.build();
     }
index 425f23bf702ed4c313c9791698669ac45c2b8d20..5f0d995b00c54b5970789d501cd5196b88589b34 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.restconf.restful.utils;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.CheckedFuture;
+import java.util.Collection;
 import javax.annotation.Nonnull;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
@@ -18,6 +19,7 @@ import org.opendaylight.netconf.sal.restconf.impl.RestconfError.ErrorTag;
 import org.opendaylight.netconf.sal.restconf.impl.RestconfError.ErrorType;
 import org.opendaylight.restconf.restful.transaction.TransactionVarsWrapper;
 import org.opendaylight.yangtools.yang.common.QNameModule;
+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.AugmentationNode;
@@ -30,7 +32,9 @@ 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.impl.schema.Builders;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+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.model.api.RpcDefinition;
 
@@ -90,7 +94,7 @@ public final class ReadDataTransactionUtil {
     private static NormalizedNode<?, ?> readDataViaTransaction(final TransactionVarsWrapper transactionNode) {
         if (transactionNode.getLogicalDatastoreType() != null) {
             final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> listenableFuture = transactionNode
-                    .getTransaction().read(transactionNode.getLogicalDatastoreType(),
+                    .getTransactionChain().newReadOnlyTransaction().read(transactionNode.getLogicalDatastoreType(),
                             transactionNode.getInstanceIdentifier().getInstanceIdentifier());
             final NormalizedNodeFactory dataFactory = new NormalizedNodeFactory();
             FutureCallbackTx.addCallback(listenableFuture, RestconfDataServiceConstant.ReadData.READ_TYPE_TX,
@@ -118,7 +122,7 @@ public final class ReadDataTransactionUtil {
         final NormalizedNode<?, ?> configDataNode = readDataViaTransaction(transactionNode);
 
         // if no data exists
-        if (stateDataNode == null && configDataNode == null) {
+        if ((stateDataNode == null) && (configDataNode == null)) {
             throw new RestconfDocumentedException(
                     "Request could not be completed because the relevant data model content does not exist",
                     ErrorType.PROTOCOL,
@@ -209,21 +213,50 @@ public final class ReadDataTransactionUtil {
      */
     private static NormalizedNode<?, ?> prepareData(final NormalizedNode<?, ?> configDataNode,
             final NormalizedNode<?, ?> stateDataNode) {
-        final MapNode immutableStateData = ImmutableNodes.mapNodeBuilder(stateDataNode.getNodeType())
+
+        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())
+            final MapNode immutableConfigData = ImmutableNodes.mapNodeBuilder(configDataNode.getNodeType())
                 .addChild((MapEntryNode) configDataNode).build();
-
-        final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder = ImmutableNodes
+            final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder = ImmutableNodes
                 .mapEntryBuilder();
-        mapEntryBuilder.withNodeIdentifier((NodeIdentifierWithPredicates) configDataNode.getIdentifier());
+            mapEntryBuilder.withNodeIdentifier((NodeIdentifierWithPredicates) configDataNode.getIdentifier());
 
-        // MAP CONFIG DATA
-        mapDataNode(immutableConfigData, mapEntryBuilder);
-        // MAP STATE DATA
-        mapDataNode(immutableStateData, mapEntryBuilder);
+            // MAP CONFIG DATA
+            mapDataNode(immutableConfigData, mapEntryBuilder);
+            // MAP STATE DATA
+            mapDataNode(immutableStateData, mapEntryBuilder);
+            return ImmutableNodes.mapNodeBuilder(configDataNode.getNodeType()).addChild(mapEntryBuilder.build()).build();
+        } 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 ImmutableNodes.mapNodeBuilder(configDataNode.getNodeType()).addChild(mapEntryBuilder.build()).build();
+            return containerBuilder.build();
+        } else {
+            throw new RestconfDocumentedException("Bad type of node.");
+        }
+    }
+
+    /**
+     * Map data to builder
+     *
+     * @param containerBuilder
+     *            - builder for mapping data
+     * @param childs
+     *            - childs of data (container)
+     */
+    private static void mapCont(final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> containerBuilder,
+            final Collection<DataContainerChild<? extends PathArgument, ?>> childs) {
+        for (final DataContainerChild<? extends PathArgument, ?> child : childs) {
+            containerBuilder.addChild(child);
+        }
     }
 
     /**
index f867ab1d1a2eef09765f229139e42d7759be5e57..f38923d9522b00e73f1c27cc0f6385cb511d3dd0 100644 (file)
@@ -10,7 +10,6 @@ package org.opendaylight.restconf.restful.utils;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
-
 import com.google.common.util.concurrent.Futures;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
@@ -21,6 +20,7 @@ import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
+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.netconf.sal.restconf.impl.RestconfError.ErrorTag;
@@ -29,14 +29,19 @@ import org.opendaylight.restconf.restful.transaction.TransactionVarsWrapper;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 
 public class DeleteDataTransactionUtilTest {
-    @Mock DOMDataReadWriteTransaction transaction;
-    @Mock InstanceIdentifierContext<?> context;
+    @Mock
+    private DOMTransactionChain transactionChain;
+    @Mock
+    private InstanceIdentifierContext<?> context;
+    @Mock
+    private DOMDataReadWriteTransaction readWrite;
 
     @Before
     public void init() throws Exception {
         MockitoAnnotations.initMocks(this);
-        Mockito.when(this.transaction.submit()).thenReturn(Futures.immediateCheckedFuture(null));
-        Mockito.when(context.getInstanceIdentifier()).thenReturn(YangInstanceIdentifier.EMPTY);
+        Mockito.when(this.transactionChain.newReadWriteTransaction()).thenReturn(this.readWrite);
+        Mockito.when(this.readWrite.submit()).thenReturn(Futures.immediateCheckedFuture(null));
+        Mockito.when(this.context.getInstanceIdentifier()).thenReturn(YangInstanceIdentifier.EMPTY);
     }
 
     /**
@@ -45,12 +50,13 @@ public class DeleteDataTransactionUtilTest {
     @Test
     public void deleteData() throws Exception {
         // assert that data to delete exists
-        Mockito.when(this.transaction.exists(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.EMPTY))
+        Mockito.when(this.transactionChain.newReadWriteTransaction().exists(LogicalDatastoreType.CONFIGURATION,
+                YangInstanceIdentifier.EMPTY))
                 .thenReturn(Futures.immediateCheckedFuture(Boolean.TRUE));
 
         // test
         final Response response = DeleteDataTransactionUtil.deleteData(
-                new TransactionVarsWrapper(this.context, null, this.transaction));
+                new TransactionVarsWrapper(this.context, null, this.transactionChain));
 
         // assert success
         assertEquals("Not expected response received", Status.OK.getStatusCode(), response.getStatus());
@@ -62,12 +68,13 @@ public class DeleteDataTransactionUtilTest {
     @Test
     public void deleteDataNegativeTest() throws Exception {
         // assert that data to delete does NOT exist
-        Mockito.when(this.transaction.exists(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.EMPTY))
+        Mockito.when(this.transactionChain.newReadWriteTransaction().exists(LogicalDatastoreType.CONFIGURATION,
+                YangInstanceIdentifier.EMPTY))
                 .thenReturn(Futures.immediateCheckedFuture(Boolean.FALSE));
 
         // test and assert error
         try {
-            DeleteDataTransactionUtil.deleteData(new TransactionVarsWrapper(this.context, null, this.transaction));
+            DeleteDataTransactionUtil.deleteData(new TransactionVarsWrapper(this.context, null, this.transactionChain));
             fail("Delete operation should fail due to missing data");
         } catch (final RestconfDocumentedException e) {
             assertEquals(ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());