NETCONF-514: Use exists instead of read for PUT 88/68988/1
authorTom Pantelis <tompantelis@gmail.com>
Mon, 26 Feb 2018 19:19:01 +0000 (14:19 -0500)
committerJakub Toth <jakub.toth@pantheon.tech>
Fri, 2 Mar 2018 06:52:58 +0000 (07:52 +0100)
The PUT operation needs to check if the path already exists
in order to return the proper response code according to the RFC
however calling exists instead of read is more efficient on the
back end.

Change-Id: Ibd7e99324c6a151aae91083e0c90bdf877161dee
Signed-off-by: Tom Pantelis <tompantelis@gmail.com>
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/ResponseFactory.java
restconf/sal-rest-connector/src/test/java/org/opendaylight/restconf/restful/services/impl/RestconfDataServiceImplTest.java
restconf/sal-rest-connector/src/test/java/org/opendaylight/restconf/restful/utils/PutDataTransactionUtilTest.java

index 0c880cd99fcc7bc78a4be72ec86fb6b3a91df27c..51bb39f6e4786c3287ca074647c23af8d8c38c06 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.restconf.restful.utils;
 
 import com.google.common.util.concurrent.CheckedFuture;
 import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
@@ -37,7 +38,7 @@ public final class DeleteDataTransactionUtil {
         final CheckedFuture<Void, TransactionCommitFailedException> future = submitData(
                 transactionNode.getTransactionChain(), transactionNode.getTransactionChain().newReadWriteTransaction(),
                 transactionNode.getInstanceIdentifier().getInstanceIdentifier());
-        final ResponseFactory response = new ResponseFactory();
+        final ResponseFactory response = new ResponseFactory(Status.OK);
         FutureCallbackTx.addCallback(future, RestconfDataServiceConstant.DeleteData.DELETE_TX_TYPE, response);
         return response.build();
     }
index 09107d3db88fceda3383ea4076ba65bd76f2c71c..2c7087eeedf76b34ad56e91fdbd59ff7a000202c 100644 (file)
@@ -13,6 +13,7 @@ import com.google.common.collect.Lists;
 import com.google.common.util.concurrent.CheckedFuture;
 import java.util.ArrayList;
 import java.util.List;
+import javax.ws.rs.core.Response.Status;
 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.common.api.data.TransactionCommitFailedException;
@@ -131,7 +132,7 @@ public final class PatchDataTransactionUtil {
 
         // if no errors then submit transaction, otherwise cancel
         if (noError) {
-            final ResponseFactory response = new ResponseFactory();
+            final ResponseFactory response = new ResponseFactory(Status.OK);
             final CheckedFuture<Void, TransactionCommitFailedException> future = tx.submit();
 
             try {
@@ -309,4 +310,4 @@ public final class PatchDataTransactionUtil {
                     "Data already exists", ErrorType.PROTOCOL, ErrorTag.DATA_EXISTS, path);
         }
     }
-}
\ No newline at end of file
+}
index 33e8bbb16922dbb2a88cbbfaeb9b10c3c316ec28..42225da32aa0fc219aef3771e36db38235cc732f 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.restconf.restful.utils;
 import com.google.common.util.concurrent.CheckedFuture;
 import java.net.URI;
 import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
 import javax.ws.rs.core.UriBuilder;
 import javax.ws.rs.core.UriInfo;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
@@ -73,7 +74,7 @@ public final class PostDataTransactionUtil {
                 payload.getInstanceIdentifierContext().getInstanceIdentifier(), payload.getData(),
                 transactionNode, schemaContextRef.get(), insert, point);
         final URI location = PostDataTransactionUtil.resolveLocation(uriInfo, transactionNode, schemaContextRef);
-        final ResponseFactory dataFactory = new ResponseFactory(null, location);
+        final ResponseFactory dataFactory = new ResponseFactory(Status.CREATED).location(location);
         FutureCallbackTx.addCallback(future, RestconfDataServiceConstant.PostData.POST_TX_TYPE, dataFactory);
         return dataFactory.build();
     }
@@ -112,7 +113,7 @@ public final class PostDataTransactionUtil {
                                 PutDataTransactionUtil.readList(path.getParent(), schemaContext, domTransactionChain,
                                         schemaNode);
                         final OrderedMapNode readList = (OrderedMapNode) readData;
-                        if ((readList == null) || readList.getValue().isEmpty()) {
+                        if (readList == null || readList.getValue().isEmpty()) {
                             makePost(path, data, schemaContext, domTransactionChain, newReadWriteTransaction);
                             return newReadWriteTransaction.submit();
                         } else {
@@ -129,7 +130,7 @@ public final class PostDataTransactionUtil {
                                         .readList(path.getParent(), schemaContext, domTransactionChain, schemaNode);
 
                         final OrderedLeafSetNode<?> readLeafList = (OrderedLeafSetNode<?>) readData;
-                        if ((readLeafList == null) || readLeafList.getValue().isEmpty()) {
+                        if (readLeafList == null || readLeafList.getValue().isEmpty()) {
                             makePost(path, data, schemaContext, domTransactionChain, newReadWriteTransaction);
                             return newReadWriteTransaction.submit();
                         } else {
@@ -150,7 +151,7 @@ public final class PostDataTransactionUtil {
                                 PutDataTransactionUtil.readList(path.getParent(), schemaContext, domTransactionChain,
                                         schemaNode);
                         final OrderedMapNode readList = (OrderedMapNode) readData;
-                        if ((readList == null) || readList.getValue().isEmpty()) {
+                        if (readList == null || readList.getValue().isEmpty()) {
                             makePost(path, data, schemaContext, domTransactionChain, newReadWriteTransaction);
                             return newReadWriteTransaction.submit();
                         } else {
@@ -164,7 +165,7 @@ public final class PostDataTransactionUtil {
                                         schemaNode);
 
                         final OrderedLeafSetNode<?> readLeafList = (OrderedLeafSetNode<?>) readData;
-                        if ((readLeafList == null) || readLeafList.getValue().isEmpty()) {
+                        if (readLeafList == null || readLeafList.getValue().isEmpty()) {
                             makePost(path, data, schemaContext, domTransactionChain, newReadWriteTransaction);
                             return newReadWriteTransaction.submit();
                         } else {
@@ -179,7 +180,7 @@ public final class PostDataTransactionUtil {
                                 PutDataTransactionUtil.readList(path.getParent(), schemaContext, domTransactionChain,
                                         schemaNode);
                         final OrderedMapNode readList = (OrderedMapNode) readData;
-                        if ((readList == null) || readList.getValue().isEmpty()) {
+                        if (readList == null || readList.getValue().isEmpty()) {
                             makePost(path, data, schemaContext, domTransactionChain, newReadWriteTransaction);
                             return newReadWriteTransaction.submit();
                         } else {
@@ -193,7 +194,7 @@ public final class PostDataTransactionUtil {
                                         schemaNode);
 
                         final OrderedLeafSetNode<?> readLeafList = (OrderedLeafSetNode<?>) readData;
-                        if ((readLeafList == null) || readLeafList.getValue().isEmpty()) {
+                        if (readLeafList == null || readLeafList.getValue().isEmpty()) {
                             makePost(path, data, schemaContext, domTransactionChain, newReadWriteTransaction);
                             return newReadWriteTransaction.submit();
                         } else {
index 3feab015633f4e1be6a6f9aa8d88ff435e3bb9a7..77d7873b7b1bce036f4ad1734da292f7eb73c19b 100644 (file)
@@ -12,7 +12,9 @@ import com.google.common.util.concurrent.CheckedFuture;
 import java.util.List;
 import java.util.Map;
 import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
 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.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
@@ -61,9 +63,9 @@ public final class PutDataTransactionUtil {
      *             input data
      */
     public static void validInputData(final SchemaNode schemaNode, final NormalizedNodeContext payload) {
-        if ((schemaNode != null) && (payload.getData() == null)) {
+        if (schemaNode != null && payload.getData() == null) {
             throw new RestconfDocumentedException("Input is required.", ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE);
-        } else if ((schemaNode == null) && (payload.getData() != null)) {
+        } else if (schemaNode == null && payload.getData() != null) {
             throw new RestconfDocumentedException("No input expected.", ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE);
         }
     }
@@ -108,7 +110,7 @@ public final class PutDataTransactionUtil {
         final NormalizedNode<?, ?> data = payload.getData();
         if (schemaNode instanceof ListSchemaNode) {
             final List<QName> keyDefinitions = ((ListSchemaNode) schemaNode).getKeyDefinition();
-            if ((lastPathArgument instanceof NodeIdentifierWithPredicates) && (data instanceof MapEntryNode)) {
+            if (lastPathArgument instanceof NodeIdentifierWithPredicates && data instanceof MapEntryNode) {
                 final Map<QName, Object> uriKeyValues = ((NodeIdentifierWithPredicates) lastPathArgument)
                         .getKeyValues();
                 isEqualUriAndPayloadKeyValues(uriKeyValues, (MapEntryNode) data, keyDefinitions);
@@ -153,10 +155,19 @@ public final class PutDataTransactionUtil {
     public static Response putData(final NormalizedNodeContext payload, final SchemaContextRef schemaCtxRef,
                                final TransactionVarsWrapper transactionNode, final String insert, final String point) {
         final YangInstanceIdentifier path = payload.getInstanceIdentifierContext().getInstanceIdentifier();
-        final ResponseFactory responseFactory = new ResponseFactory(
-                ReadDataTransactionUtil.readData(RestconfDataServiceConstant.ReadData.CONFIG, transactionNode));
-        final CheckedFuture<Void, TransactionCommitFailedException> submitData = submitData(path, schemaCtxRef.get(),
-                transactionNode.getTransactionChain(), payload.getData(), insert, point);
+        final SchemaContext schemaContext = schemaCtxRef.get();
+
+        final DOMDataReadWriteTransaction readWriteTransaction =
+                transactionNode.getTransactionChain().newReadWriteTransaction();
+
+        final CheckedFuture<Boolean, ReadFailedException> existsFuture =
+                readWriteTransaction.exists(LogicalDatastoreType.CONFIGURATION, path);
+        final FutureDataFactory<Boolean> existsResponse = new FutureDataFactory<>();
+        FutureCallbackTx.addCallback(existsFuture, RestconfDataServiceConstant.PutData.PUT_TX_TYPE, existsResponse);
+
+        final ResponseFactory responseFactory = new ResponseFactory(existsResponse.result ? Status.OK : Status.CREATED);
+        final CheckedFuture<Void, TransactionCommitFailedException> submitData = submitData(path, schemaContext,
+                transactionNode.getTransactionChain(), readWriteTransaction, payload.getData(), insert, point);
         FutureCallbackTx.addCallback(submitData, RestconfDataServiceConstant.PutData.PUT_TX_TYPE, responseFactory);
         return responseFactory.build();
     }
@@ -180,10 +191,10 @@ public final class PutDataTransactionUtil {
      */
     private static CheckedFuture<Void, TransactionCommitFailedException> submitData(final YangInstanceIdentifier path,
             final SchemaContext schemaContext, final DOMTransactionChain domTransactionChain,
+            final DOMDataReadWriteTransaction readWriteTransaction,
             final NormalizedNode<?, ?> data, final String insert, final String point) {
-        final DOMDataReadWriteTransaction newReadWriteTransaction = domTransactionChain.newReadWriteTransaction();
         if (insert == null) {
-            return makePut(path, schemaContext, newReadWriteTransaction, data);
+            return makePut(path, schemaContext, readWriteTransaction, data);
         } else {
             final DataSchemaNode schemaNode = checkListAndOrderedType(schemaContext, path);
             switch (insert) {
@@ -192,57 +203,57 @@ public final class PutDataTransactionUtil {
                         final NormalizedNode<?, ?> readData =
                                 readList(path, schemaContext, domTransactionChain, schemaNode);
                         final OrderedMapNode readList = (OrderedMapNode) readData;
-                        if ((readList == null) || readList.getValue().isEmpty()) {
-                            return makePut(path, schemaContext, newReadWriteTransaction, data);
+                        if (readList == null || readList.getValue().isEmpty()) {
+                            return makePut(path, schemaContext, readWriteTransaction, data);
                         } else {
-                            newReadWriteTransaction.delete(LogicalDatastoreType.CONFIGURATION, path.getParent());
-                            simplePut(LogicalDatastoreType.CONFIGURATION, path, newReadWriteTransaction,
+                            readWriteTransaction.delete(LogicalDatastoreType.CONFIGURATION, path.getParent());
+                            simplePut(LogicalDatastoreType.CONFIGURATION, path, readWriteTransaction,
                                     schemaContext, data);
-                            listPut(LogicalDatastoreType.CONFIGURATION, path.getParent(), newReadWriteTransaction,
+                            listPut(LogicalDatastoreType.CONFIGURATION, path.getParent(), readWriteTransaction,
                                     schemaContext, readList);
-                            return newReadWriteTransaction.submit();
+                            return readWriteTransaction.submit();
                         }
                     } else {
                         final NormalizedNode<?, ?> readData =
                                 readList(path, schemaContext, domTransactionChain, schemaNode);
 
                         final OrderedLeafSetNode<?> readLeafList = (OrderedLeafSetNode<?>) readData;
-                        if ((readLeafList == null) || readLeafList.getValue().isEmpty()) {
-                            return makePut(path, schemaContext, newReadWriteTransaction, data);
+                        if (readLeafList == null || readLeafList.getValue().isEmpty()) {
+                            return makePut(path, schemaContext, readWriteTransaction, data);
                         } else {
-                            newReadWriteTransaction.delete(LogicalDatastoreType.CONFIGURATION, path.getParent());
-                            simplePut(LogicalDatastoreType.CONFIGURATION, path, newReadWriteTransaction,
+                            readWriteTransaction.delete(LogicalDatastoreType.CONFIGURATION, path.getParent());
+                            simplePut(LogicalDatastoreType.CONFIGURATION, path, readWriteTransaction,
                                     schemaContext, data);
-                            listPut(LogicalDatastoreType.CONFIGURATION, path.getParent(), newReadWriteTransaction,
+                            listPut(LogicalDatastoreType.CONFIGURATION, path.getParent(), readWriteTransaction,
                                     schemaContext, readLeafList);
-                            return newReadWriteTransaction.submit();
+                            return readWriteTransaction.submit();
                         }
                     }
                 case "last":
-                    return makePut(path, schemaContext, newReadWriteTransaction, data);
+                    return makePut(path, schemaContext, readWriteTransaction, data);
                 case "before":
                     if (schemaNode instanceof ListSchemaNode) {
                         final NormalizedNode<?, ?> readData =
                                 readList(path, schemaContext, domTransactionChain, schemaNode);
                         final OrderedMapNode readList = (OrderedMapNode) readData;
-                        if ((readList == null) || readList.getValue().isEmpty()) {
-                            return makePut(path, schemaContext, newReadWriteTransaction, data);
+                        if (readList == null || readList.getValue().isEmpty()) {
+                            return makePut(path, schemaContext, readWriteTransaction, data);
                         } else {
-                            insertWithPointListPut(newReadWriteTransaction, LogicalDatastoreType.CONFIGURATION, path,
+                            insertWithPointListPut(readWriteTransaction, LogicalDatastoreType.CONFIGURATION, path,
                                     data, schemaContext, point, readList, true);
-                            return newReadWriteTransaction.submit();
+                            return readWriteTransaction.submit();
                         }
                     } else {
                         final NormalizedNode<?, ?> readData =
                                 readList(path, schemaContext, domTransactionChain, schemaNode);
 
                         final OrderedLeafSetNode<?> readLeafList = (OrderedLeafSetNode<?>) readData;
-                        if ((readLeafList == null) || readLeafList.getValue().isEmpty()) {
-                            return makePut(path, schemaContext, newReadWriteTransaction, data);
+                        if (readLeafList == null || readLeafList.getValue().isEmpty()) {
+                            return makePut(path, schemaContext, readWriteTransaction, data);
                         } else {
-                            insertWithPointLeafListPut(newReadWriteTransaction, LogicalDatastoreType.CONFIGURATION,
+                            insertWithPointLeafListPut(readWriteTransaction, LogicalDatastoreType.CONFIGURATION,
                                     path, data, schemaContext, point, readLeafList, true);
-                            return newReadWriteTransaction.submit();
+                            return readWriteTransaction.submit();
                         }
                     }
                 case "after":
@@ -250,24 +261,24 @@ public final class PutDataTransactionUtil {
                         final NormalizedNode<?, ?> readData =
                                 readList(path, schemaContext, domTransactionChain, schemaNode);
                         final OrderedMapNode readList = (OrderedMapNode) readData;
-                        if ((readList == null) || readList.getValue().isEmpty()) {
-                            return makePut(path, schemaContext, newReadWriteTransaction, data);
+                        if (readList == null || readList.getValue().isEmpty()) {
+                            return makePut(path, schemaContext, readWriteTransaction, data);
                         } else {
-                            insertWithPointListPut(newReadWriteTransaction, LogicalDatastoreType.CONFIGURATION,
+                            insertWithPointListPut(readWriteTransaction, LogicalDatastoreType.CONFIGURATION,
                                     path, data, schemaContext, point, readList, false);
-                            return newReadWriteTransaction.submit();
+                            return readWriteTransaction.submit();
                         }
                     } else {
                         final NormalizedNode<?, ?> readData =
                                 readList(path, schemaContext, domTransactionChain, schemaNode);
 
                         final OrderedLeafSetNode<?> readLeafList = (OrderedLeafSetNode<?>) readData;
-                        if ((readLeafList == null) || readLeafList.getValue().isEmpty()) {
-                            return makePut(path, schemaContext, newReadWriteTransaction, data);
+                        if (readLeafList == null || readLeafList.getValue().isEmpty()) {
+                            return makePut(path, schemaContext, readWriteTransaction, data);
                         } else {
-                            insertWithPointLeafListPut(newReadWriteTransaction, LogicalDatastoreType.CONFIGURATION,
+                            insertWithPointLeafListPut(readWriteTransaction, LogicalDatastoreType.CONFIGURATION,
                                     path, data, schemaContext, point, readLeafList, true);
-                            return newReadWriteTransaction.submit();
+                            return readWriteTransaction.submit();
                         }
                     }
                 default:
index 1c165322966100f0e9c2660cd7ef9e21e7e80ed9..5e5578c82760dcd287cfc9bb32e8567eedeb600a 100644 (file)
@@ -12,25 +12,18 @@ import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.ResponseBuilder;
 import javax.ws.rs.core.Response.Status;
 import org.apache.commons.lang3.builder.Builder;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 final class ResponseFactory extends FutureDataFactory<Void> implements Builder<Response> {
 
     private ResponseBuilder responseBuilder;
 
-    ResponseFactory(final NormalizedNode<?, ?> readData) {
-        final Status status = prepareStatus(readData);
+    ResponseFactory(final Status status) {
         this.responseBuilder = Response.status(status);
     }
 
-    ResponseFactory(final NormalizedNode<?, ?> readData, final URI location) {
-        final Status status = prepareStatus(readData);
-        this.responseBuilder = Response.status(status);
-        this.responseBuilder.location(location);
-    }
-
-    ResponseFactory() {
-        this.responseBuilder = Response.status(Status.OK);
+    ResponseFactory location(final URI location) {
+        responseBuilder.location(location);
+        return this;
     }
 
     @Override
@@ -40,8 +33,4 @@ final class ResponseFactory extends FutureDataFactory<Void> implements Builder<R
         }
         return this.responseBuilder.build();
     }
-
-    private static Status prepareStatus(final NormalizedNode<?, ?> readData) {
-        return readData != null ? Status.OK : Status.CREATED;
-    }
 }
index 93babcbceb5b836b73f50ceed922ee610571a000..734683c7c99c91fbd9ba52b49e2f5bc4e83881ec 100644 (file)
@@ -322,9 +322,9 @@ public class RestconfDataServiceImplTest {
                 new InstanceIdentifierContext<>(this.iidBase, this.schemaNode, null, this.contextRef.get());
         final NormalizedNodeContext payload = new NormalizedNodeContext(iidContext, this.buildBaseCont);
 
-        doReturn(Futures.immediateCheckedFuture(Optional.of(this.buildBaseCont))).when(this.read)
-                .read(LogicalDatastoreType.CONFIGURATION, this.iidBase);
-        doNothing().when(this.write).put(LogicalDatastoreType.CONFIGURATION, this.iidBase, payload.getData());
+        doReturn(Futures.immediateCheckedFuture(Boolean.TRUE)).when(this.readWrite)
+                .exists(LogicalDatastoreType.CONFIGURATION, this.iidBase);
+        doNothing().when(this.readWrite).put(LogicalDatastoreType.CONFIGURATION, this.iidBase, payload.getData());
         doReturn(Futures.immediateCheckedFuture(null)).when(this.readWrite).submit();
         final Response response = this.dataService.putData(null, payload, this.uriInfo);
         assertNotNull(response);
@@ -342,9 +342,9 @@ public class RestconfDataServiceImplTest {
                 new InstanceIdentifierContext<>(this.iidBase, this.schemaNode, mountPoint, this.contextRef.get());
         final NormalizedNodeContext payload = new NormalizedNodeContext(iidContext, this.buildBaseCont);
 
-        doReturn(Futures.immediateCheckedFuture(Optional.of(this.buildBaseCont))).when(this.read)
-                .read(LogicalDatastoreType.CONFIGURATION, this.iidBase);
-        doNothing().when(this.write).put(LogicalDatastoreType.CONFIGURATION, this.iidBase, payload.getData());
+        doReturn(Futures.immediateCheckedFuture(Boolean.TRUE)).when(this.readWrite)
+                .exists(LogicalDatastoreType.CONFIGURATION, this.iidBase);
+        doNothing().when(this.readWrite).put(LogicalDatastoreType.CONFIGURATION, this.iidBase, payload.getData());
         doReturn(Futures.immediateCheckedFuture(null)).when(this.readWrite).submit();
         final Response response = this.dataService.putData(null, payload, this.uriInfo);
         assertNotNull(response);
index 885d38ada5517f87252f829b3041fb32d2c49e7b..fe3375e362a3de2681e0e91c28d1cad0ed9f8541 100644 (file)
@@ -12,7 +12,6 @@ import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.verify;
 
-import com.google.common.base.Optional;
 import com.google.common.util.concurrent.Futures;
 import org.junit.Before;
 import org.junit.Test;
@@ -208,16 +207,16 @@ public class PutDataTransactionUtilTest {
         doReturn(this.readWrite).when(this.transactionChain).newReadWriteTransaction();
         doReturn(this.read).when(this.transactionChain).newReadOnlyTransaction();
         doReturn(this.write).when(this.transactionChain).newWriteOnlyTransaction();
-        doReturn(Futures.immediateCheckedFuture(Optional.absent()))
-                .when(this.read).read(LogicalDatastoreType.CONFIGURATION, this.iid2);
-        doNothing().when(this.write).put(LogicalDatastoreType.CONFIGURATION,
+        doReturn(Futures.immediateCheckedFuture(Boolean.FALSE))
+                .when(this.readWrite).exists(LogicalDatastoreType.CONFIGURATION, this.iid2);
+        doNothing().when(this.readWrite).put(LogicalDatastoreType.CONFIGURATION,
                 payload.getInstanceIdentifierContext().getInstanceIdentifier(), payload.getData());
         doReturn(Futures.immediateCheckedFuture(null)).when(this.readWrite).submit();
 
         PutDataTransactionUtil.putData(payload, this.refSchemaCtx,
                 new TransactionVarsWrapper(payload.getInstanceIdentifierContext(), null, this.transactionChain), null,
                 null);
-        verify(this.read).read(LogicalDatastoreType.CONFIGURATION,
+        verify(this.readWrite).exists(LogicalDatastoreType.CONFIGURATION,
                 payload.getInstanceIdentifierContext().getInstanceIdentifier());
         verify(this.readWrite).put(LogicalDatastoreType.CONFIGURATION,
                 payload.getInstanceIdentifierContext().getInstanceIdentifier(), payload.getData());
@@ -232,16 +231,16 @@ public class PutDataTransactionUtilTest {
         doReturn(this.readWrite).when(this.transactionChain).newReadWriteTransaction();
         doReturn(this.read).when(this.transactionChain).newReadOnlyTransaction();
         doReturn(this.write).when(this.transactionChain).newWriteOnlyTransaction();
-        doReturn(Futures.immediateCheckedFuture(Optional.absent()))
-                .when(this.read).read(LogicalDatastoreType.CONFIGURATION, this.iid);
-        doNothing().when(this.write).put(LogicalDatastoreType.CONFIGURATION,
+        doReturn(Futures.immediateCheckedFuture(Boolean.FALSE))
+                .when(this.readWrite).exists(LogicalDatastoreType.CONFIGURATION, this.iid);
+        doNothing().when(this.readWrite).put(LogicalDatastoreType.CONFIGURATION,
                 payload.getInstanceIdentifierContext().getInstanceIdentifier(), payload.getData());
         doReturn(Futures.immediateCheckedFuture(null)).when(this.readWrite).submit();
 
         PutDataTransactionUtil.putData(payload, this.refSchemaCtx,
                 new TransactionVarsWrapper(payload.getInstanceIdentifierContext(), null, this.transactionChain), null,
                 null);
-        verify(this.read).read(LogicalDatastoreType.CONFIGURATION,
+        verify(this.readWrite).exists(LogicalDatastoreType.CONFIGURATION,
                 payload.getInstanceIdentifierContext().getInstanceIdentifier());
         verify(this.readWrite).put(LogicalDatastoreType.CONFIGURATION,
                 payload.getInstanceIdentifierContext().getInstanceIdentifier(), payload.getData());
@@ -256,15 +255,15 @@ public class PutDataTransactionUtilTest {
         doReturn(this.readWrite).when(this.transactionChain).newReadWriteTransaction();
         doReturn(this.read).when(this.transactionChain).newReadOnlyTransaction();
         doReturn(this.write).when(this.transactionChain).newWriteOnlyTransaction();
-        doReturn(Futures.immediateCheckedFuture(Optional.absent()))
-                .when(this.read).read(LogicalDatastoreType.CONFIGURATION, this.iid2);
-        doNothing().when(this.write).put(LogicalDatastoreType.CONFIGURATION,
+        doReturn(Futures.immediateCheckedFuture(Boolean.FALSE))
+                .when(this.readWrite).exists(LogicalDatastoreType.CONFIGURATION, this.iid2);
+        doNothing().when(this.readWrite).put(LogicalDatastoreType.CONFIGURATION,
                 payload.getInstanceIdentifierContext().getInstanceIdentifier(), payload.getData());
         doReturn(Futures.immediateCheckedFuture(null)).when(this.readWrite).submit();
         PutDataTransactionUtil.putData(payload, this.refSchemaCtx,
                 new TransactionVarsWrapper(payload.getInstanceIdentifierContext(), null, this.transactionChain), null,
                 null);
-        verify(this.read).read(LogicalDatastoreType.CONFIGURATION, this.iid2);
+        verify(this.readWrite).exists(LogicalDatastoreType.CONFIGURATION, this.iid2);
         verify(this.readWrite).put(LogicalDatastoreType.CONFIGURATION, this.iid2, payload.getData());
     }