Add sample accessing database service to Foo

Change-Id: I514c57a278dea368448d284eb5bf0d41bb0013e3
diff --git a/core/api/src/main/java/org/onlab/onos/store/service/WriteRequest.java b/core/api/src/main/java/org/onlab/onos/store/service/WriteRequest.java
index dcf22e9..fb736e5 100644
--- a/core/api/src/main/java/org/onlab/onos/store/service/WriteRequest.java
+++ b/core/api/src/main/java/org/onlab/onos/store/service/WriteRequest.java
@@ -1,6 +1,8 @@
 package org.onlab.onos.store.service;
 
 import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onlab.onos.store.service.WriteRequest.Type.*;
 
 import java.util.Objects;
 
@@ -11,8 +13,13 @@
  */
 public class WriteRequest {
 
+    public static final int ANY_VERSION = -1;
+
     private final String tableName;
     private final String key;
+
+    private final Type type;
+
     private final byte[] newValue;
     private final long previousVersion;
     private final byte[] oldValue;
@@ -23,22 +30,22 @@
      *
      * @param tableName name of the table
      * @param key       key in the table
-     * @param newValue  value to write
+     * @param newValue  value to write, must not be null
      * @return WriteRequest
      */
     public static WriteRequest put(String tableName, String key,
                                    byte[] newValue) {
-        return new WriteRequest(tableName, key, newValue, -1, null);
+        return new WriteRequest(PUT, tableName, key,
+                                checkNotNull(newValue), ANY_VERSION, null);
     }
 
-    // FIXME: Is there a special version value to realize putIfAbsent?
     /**
      * Creates a write request, which will
      * put the specified value to the table if the previous version matches.
      *
      * @param tableName name of the table
      * @param key       key in the table
-     * @param newValue  value to write
+     * @param newValue  value to write, must not be null
      * @param previousVersion previous version expected
      * @return WriteRequest
      */
@@ -46,37 +53,107 @@
                                                    byte[] newValue,
                                                    long previousVersion) {
         checkArgument(previousVersion >= 0);
-        return new WriteRequest(tableName, key, newValue, previousVersion, null);
+        return new WriteRequest(PUT_IF_VERSION, tableName, key,
+                                checkNotNull(newValue), previousVersion, null);
     }
 
-    // FIXME: What is the behavior of oldValue=null? putIfAbsent?
     /**
      * Creates a write request, which will
      * put the specified value to the table if the previous value matches.
      *
      * @param tableName name of the table
      * @param key       key in the table
-     * @param newValue  value to write
-     * @param oldValue  previous value expected
+     * @param newValue  value to write, must not be null
+     * @param oldValue  previous value expected, must not be null
      * @return WriteRequest
      */
     public static WriteRequest putIfValueMatches(String tableName, String key,
                                                  byte[] newValue,
                                                  byte[] oldValue) {
-        return new WriteRequest(tableName, key, newValue, -1, oldValue);
+        return new WriteRequest(PUT_IF_VALUE, tableName, key,
+                                checkNotNull(newValue), ANY_VERSION,
+                                checkNotNull(oldValue));
     }
 
-    // FIXME: How do we remove value? newValue=null?
+    /**
+     * Creates a write request, which will
+     * put the specified value to the table if the previous value does not exist.
+     *
+     * @param tableName name of the table
+     * @param key       key in the table
+     * @param newValue  value to write, must not be null
+     * @return WriteRequest
+     */
+    public static WriteRequest putIfAbsent(String tableName, String key,
+                                           byte[] newValue) {
+        return new WriteRequest(PUT_IF_ABSENT, tableName, key,
+                                checkNotNull(newValue), ANY_VERSION, null);
+    }
+
+    /**
+     * Creates a write request, which will
+     * remove the specified entry from the table regardless of the previous value.
+     *
+     * @param tableName name of the table
+     * @param key       key in the table
+     * @return WriteRequest
+     */
+    public static WriteRequest remove(String tableName, String key) {
+        return new WriteRequest(REMOVE, tableName, key,
+                                null, ANY_VERSION, null);
+    }
+
+    /**
+     * Creates a write request, which will
+     * remove the specified entry from the table if the previous version matches.
+     *
+     * @param tableName name of the table
+     * @param key       key in the table
+     * @param previousVersion previous version expected
+     * @return WriteRequest
+     */
+    public static WriteRequest remove(String tableName, String key,
+                                      long previousVersion) {
+        return new WriteRequest(REMOVE_IF_VALUE, tableName, key,
+                                null, previousVersion, null);
+    }
+
+    /**
+     * Creates a write request, which will
+     * remove the specified entry from the table if the previous value matches.
+     *
+     * @param tableName name of the table
+     * @param key       key in the table
+     * @param oldValue  previous value expected, must not be null
+     * @return WriteRequest
+     */
+    public static WriteRequest remove(String tableName, String key,
+                                      byte[] oldValue) {
+        return new WriteRequest(Type.REMOVE_IF_VALUE, tableName, key,
+                                null, ANY_VERSION, checkNotNull(oldValue));
+    }
+
+    public enum Type {
+        PUT,
+        PUT_IF_VERSION,
+        PUT_IF_VALUE,
+        PUT_IF_ABSENT,
+        REMOVE,
+        REMOVE_IF_VERSION,
+        REMOVE_IF_VALUE,
+    }
 
     // hidden constructor
-    protected WriteRequest(String tableName, String key, byte[] newValue, long previousVersion, byte[] oldValue) {
+    protected WriteRequest(Type type, String tableName, String key,
+                           byte[] newValue,
+                           long previousVersion, byte[] oldValue) {
 
-        checkArgument(tableName != null);
-        checkArgument(key != null);
-        checkArgument(newValue != null);
+        checkNotNull(tableName);
+        checkNotNull(key);
 
         this.tableName = tableName;
         this.key = key;
+        this.type = type;
         this.newValue = newValue;
         this.previousVersion = previousVersion;
         this.oldValue = oldValue;
@@ -90,6 +167,10 @@
         return key;
     }
 
+    public WriteRequest.Type type() {
+        return type;
+    }
+
     public byte[] newValue() {
         return newValue;
     }
@@ -105,6 +186,7 @@
     @Override
     public String toString() {
         return MoreObjects.toStringHelper(getClass())
+                .add("type", type)
                 .add("tableName", tableName)
                 .add("key", key)
                 .add("newValue", newValue)
@@ -113,9 +195,10 @@
                 .toString();
     }
 
+    // TODO: revisit hashCode, equals condition
     @Override
     public int hashCode() {
-        return Objects.hash(key, tableName, previousVersion);
+        return Objects.hash(type, key, tableName, previousVersion);
     }
 
     @Override
@@ -130,7 +213,8 @@
             return false;
         }
         WriteRequest other = (WriteRequest) obj;
-        return Objects.equals(this.key, other.key) &&
+        return Objects.equals(this.type, other.type) &&
+                Objects.equals(this.key, other.key) &&
                 Objects.equals(this.tableName, other.tableName) &&
                 Objects.equals(this.previousVersion, other.previousVersion);
     }