BUG 7801: prevent OptimisticLockFailedExceptions in write-transactions.
[controller.git] / opendaylight / md-sal / samples / clustering-test-app / provider / src / main / java / org / opendaylight / controller / clustering / it / provider / impl / WriteTransactionsHandler.java
index fd47b7176b2411b2bb629d65c56c5a1bac7474af..664e7fd26fcb85f8fedbb2ae1f36c0fe2c2ea8ac 100644 (file)
@@ -26,6 +26,7 @@ import java.util.concurrent.TimeUnit;
 import javax.annotation.Nullable;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.OptimisticLockFailedException;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
@@ -127,17 +128,31 @@ public class WriteTransactionsHandler implements Runnable {
 
     private boolean ensureListExists(final SettableFuture<RpcResult<WriteTransactionsOutput>> settableFuture) {
 
+        final MapNode mapNode = ImmutableNodes.mapNodeBuilder(ID_INTS).build();
+
+        DOMDataWriteTransaction tx = txProvider.createTransaction();
+        // write only the top list
+        tx.merge(LogicalDatastoreType.CONFIGURATION, ID_INTS_YID, mapNode);
+        try {
+            tx.submit().checkedGet();
+        } catch (final OptimisticLockFailedException e) {
+            // when multiple write-transactions are executed concurrently we need to ignore this.
+            // If we get optimistic lock here it means id-ints already exists and we can continue.
+            LOG.debug("Got an optimistic lock when writing initial top level list element.", e);
+        } catch (final TransactionCommitFailedException e) {
+            LOG.warn("Unable to ensure IdInts list for id: {} exists.", id, e);
+            settableFuture.set(RpcResultBuilder.<WriteTransactionsOutput>failed()
+                    .withError(RpcError.ErrorType.APPLICATION, "Unexpected-exception", e).build());
+            return false;
+        }
+
         final MapEntryNode entry = ImmutableNodes.mapEntryBuilder(ID_INTS, ID, id)
                 .withChild(ImmutableNodes.mapNodeBuilder(ITEM).build())
                 .build();
-        final MapNode mapNode =
-                ImmutableNodes.mapNodeBuilder(ID_INTS)
-                        .withChild(entry)
-                        .build();
 
-        final DOMDataWriteTransaction tx = txProvider.createTransaction();
         idListWithKey = ID_INTS_YID.node(entry.getIdentifier());
-        tx.merge(LogicalDatastoreType.CONFIGURATION, ID_INTS_YID, mapNode);
+        tx = txProvider.createTransaction();
+        tx.merge(LogicalDatastoreType.CONFIGURATION, idListWithKey, entry);
 
         try {
             tx.submit().checkedGet();