Fix AtomixConsistentMap::computeIf behavior to throw a ConcurrentModificationException when update races are detected

Change-Id: I6d2ab6b9864649e89156660949160261c511058a
diff --git a/core/store/primitives/src/main/java/org/onosproject/store/primitives/resources/impl/AtomixConsistentMap.java b/core/store/primitives/src/main/java/org/onosproject/store/primitives/resources/impl/AtomixConsistentMap.java
index 837e5ac..8bab853 100644
--- a/core/store/primitives/src/main/java/org/onosproject/store/primitives/resources/impl/AtomixConsistentMap.java
+++ b/core/store/primitives/src/main/java/org/onosproject/store/primitives/resources/impl/AtomixConsistentMap.java
@@ -35,6 +35,7 @@
 import java.util.function.Predicate;
 
 import org.onlab.util.Match;
+import org.onlab.util.Tools;
 import org.onosproject.store.primitives.TransactionId;
 import org.onosproject.store.primitives.resources.impl.AtomixConsistentMapCommands.Clear;
 import org.onosproject.store.primitives.resources.impl.AtomixConsistentMapCommands.ContainsKey;
@@ -53,6 +54,7 @@
 import org.onosproject.store.primitives.resources.impl.AtomixConsistentMapCommands.UpdateAndGet;
 import org.onosproject.store.primitives.resources.impl.AtomixConsistentMapCommands.Values;
 import org.onosproject.store.service.AsyncConsistentMap;
+import org.onosproject.store.service.ConsistentMapException;
 import org.onosproject.store.service.MapEvent;
 import org.onosproject.store.service.MapEventListener;
 import org.onosproject.store.service.MapTransaction;
@@ -245,11 +247,18 @@
             Match<byte[]> valueMatch = r1 == null ? Match.NULL : Match.ANY;
             Match<Long> versionMatch = r1 == null ? Match.ANY : Match.ifValue(r1.version());
             return client.submit(new UpdateAndGet(key,
-                    computedValue.get(),
-                    valueMatch,
-                    versionMatch))
-                    .whenComplete((r, e) -> throwIfLocked(r.status()))
-                    .thenApply(v -> v.newValue());
+                                                  computedValue.get(),
+                                                  valueMatch,
+                                                  versionMatch))
+                         .whenComplete((r, e) -> throwIfLocked(r.status()))
+                         .thenCompose(r -> {
+                             if (r.status() == MapEntryUpdateResult.Status.PRECONDITION_FAILED ||
+                                     r.status() == MapEntryUpdateResult.Status.WRITE_LOCK) {
+                                 return Tools.exceptionalFuture(new ConsistentMapException.ConcurrentModification());
+                             }
+                             return CompletableFuture.completedFuture(r);
+                         })
+                         .thenApply(v -> v.newValue());
         });
     }