[Falcon][ONOS-2696] support method "replace" in ConsistentMap and method "notNull" in Match

Change-Id: I7c7d4644f963e52297785c2f9a5f21eff8723e61
diff --git a/core/api/src/main/java/org/onosproject/store/service/AsyncConsistentMap.java b/core/api/src/main/java/org/onosproject/store/service/AsyncConsistentMap.java
index fee8cfa..5e54eec 100644
--- a/core/api/src/main/java/org/onosproject/store/service/AsyncConsistentMap.java
+++ b/core/api/src/main/java/org/onosproject/store/service/AsyncConsistentMap.java
@@ -245,6 +245,16 @@
     CompletableFuture<Boolean> remove(K key, long version);
 
     /**
+     * Replaces the entry for the specified key only if there is any value
+     * which associated with specified key.
+     *
+     * @param key key with which the specified value is associated
+     * @param value value expected to be associated with the specified key
+     * @return the previous value associated with the specified key or null
+     */
+    CompletableFuture<Versioned<V>> replace(K key, V value);
+
+    /**
      * Replaces the entry for the specified key only if currently mapped
      * to the specified value.
      *
diff --git a/core/api/src/main/java/org/onosproject/store/service/ConsistentMap.java b/core/api/src/main/java/org/onosproject/store/service/ConsistentMap.java
index 289da20..9a6d409 100644
--- a/core/api/src/main/java/org/onosproject/store/service/ConsistentMap.java
+++ b/core/api/src/main/java/org/onosproject/store/service/ConsistentMap.java
@@ -247,6 +247,16 @@
     boolean remove(K key, long version);
 
     /**
+     * Replaces the entry for the specified key only if there is any value
+     * which associated with specified key.
+     *
+     * @param key key with which the specified value is associated
+     * @param value value expected to be associated with the specified key
+     * @return the previous value associated with the specified key or null
+     */
+    Versioned<V> replace(K key, V value);
+
+    /**
      * Replaces the entry for the specified key only if currently mapped
      * to the specified value.
      *
diff --git a/core/api/src/test/java/org/onosproject/store/service/ConsistentMapAdapter.java b/core/api/src/test/java/org/onosproject/store/service/ConsistentMapAdapter.java
index d0c1adf..a7a6ce8 100644
--- a/core/api/src/test/java/org/onosproject/store/service/ConsistentMapAdapter.java
+++ b/core/api/src/test/java/org/onosproject/store/service/ConsistentMapAdapter.java
@@ -123,6 +123,11 @@
     }
 
     @Override
+    public Versioned<V> replace(K key, V value) {
+        return null;
+    }
+
+    @Override
     public boolean replace(K key, V oldValue, V newValue) {
         return false;
     }
diff --git a/core/api/src/test/java/org/onosproject/store/service/TestConsistentMap.java b/core/api/src/test/java/org/onosproject/store/service/TestConsistentMap.java
index 85d1a68a..57b36ab 100644
--- a/core/api/src/test/java/org/onosproject/store/service/TestConsistentMap.java
+++ b/core/api/src/test/java/org/onosproject/store/service/TestConsistentMap.java
@@ -198,6 +198,15 @@
     }
 
     @Override
+    public Versioned<V> replace(K key, V value) {
+        Versioned<V> result = version(map.replace(key, value));
+        if (map.get(key).equals(value)) {
+            notifyListeners(mapName, UPDATE, key, result);
+        }
+        return result;
+    }
+
+    @Override
     public boolean replace(K key, V oldValue, V newValue) {
         boolean replaced = map.replace(key, oldValue, newValue);
         if (replaced) {
diff --git a/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DefaultAsyncConsistentMap.java b/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DefaultAsyncConsistentMap.java
index cdbbd28..a7823a4 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DefaultAsyncConsistentMap.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DefaultAsyncConsistentMap.java
@@ -392,6 +392,16 @@
     }
 
     @Override
+    public CompletableFuture<Versioned<V>> replace(K key, V value) {
+        checkNotNull(key, ERROR_NULL_KEY);
+        checkNotNull(value, ERROR_NULL_VALUE);
+        final MeteringAgent.Context timer = monitor.startTimer(REPLACE);
+        return updateAndGet(key, Match.ifNotNull(), Match.any(), value)
+                .whenComplete((r, e) -> timer.stop(e))
+                .thenApply(v -> v.oldValue());
+    }
+
+    @Override
     public CompletableFuture<Boolean> replace(K key, V oldValue, V newValue) {
         checkNotNull(key, ERROR_NULL_KEY);
         checkNotNull(oldValue, ERROR_NULL_VALUE);
diff --git a/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DefaultConsistentMap.java b/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DefaultConsistentMap.java
index 6f7b548..7841c16 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DefaultConsistentMap.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DefaultConsistentMap.java
@@ -156,6 +156,11 @@
     }
 
     @Override
+    public Versioned<V> replace(K key, V value) {
+        return complete(asyncMap.replace(key, value));
+    }
+
+    @Override
     public boolean replace(K key, V oldValue, V newValue) {
         return complete(asyncMap.replace(key, oldValue, newValue));
     }