[ONOS-2162][ONOS-2259]-- OVSDB- The implementation of OvsdbProviderService
and OvsdbClientService.

Change-Id: I3e04d7c111adf16201f8ad7ec732eb81de05b960
diff --git a/ovsdb/api/pom.xml b/ovsdb/api/pom.xml
index 6520db4..3bb879b 100644
--- a/ovsdb/api/pom.xml
+++ b/ovsdb/api/pom.xml
@@ -31,6 +31,11 @@
             <artifactId>netty-transport-native-epoll</artifactId>
             <version>${netty4.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-ovsdb-rfc</artifactId>
+            <version>${project.version}</version>
+        </dependency>
     </dependencies>
 
 </project>
diff --git a/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbClientService.java b/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbClientService.java
index 08e3175..8bccd5c 100644
--- a/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbClientService.java
+++ b/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbClientService.java
@@ -15,14 +15,24 @@
  */
 package org.onosproject.ovsdb.controller;
 
+import java.util.List;
 import java.util.Set;
 
 import org.onlab.packet.IpAddress;
 
+import org.onosproject.ovsdb.rfc.jsonrpc.OvsdbRPC;
+import org.onosproject.ovsdb.rfc.message.OperationResult;
+import org.onosproject.ovsdb.rfc.message.TableUpdates;
+import org.onosproject.ovsdb.rfc.notation.Row;
+import org.onosproject.ovsdb.rfc.operations.Operation;
+import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
 /**
  * Represents to provider facing side of a node.
  */
-public interface OvsdbClientService {
+public interface OvsdbClientService extends OvsdbRPC {
     /**
      * Gets the node identifier.
      *
@@ -104,4 +114,111 @@
      */
     boolean isConnected();
 
+    /**
+     * Gets the Bridge uuid.
+     *
+     * @param bridgeName bridge name
+     * @return bridge uuid, empty if no uuid is find
+     */
+    String getBridgeUuid(String bridgeName);
+
+    /**
+     * Gets the Port uuid.
+     *
+     * @param portName port name
+     * @param bridgeUuid bridge uuid
+     * @return port uuid, empty if no uuid is find
+     */
+    String getPortUuid(String portName, String bridgeUuid);
+
+    /**
+     * Gets the Interface uuid.
+     *
+     * @param portUuid port uuid
+     * @param portName port name
+     * @return interface uuid, empty if no uuid is find
+     */
+    String getInterfaceUuid(String portUuid, String portName);
+
+    /**
+     * Gets the Controller uuid.
+     *
+     * @param controllerName controller name
+     * @param controllerTarget controller target
+     * @return controller uuid, empty if no uuid is find
+     */
+    String getControllerUuid(String controllerName, String controllerTarget);
+
+    /**
+     * Gets the Ovs uuid.
+     *
+     * @param dbName database name
+     * @return ovs uuid, empty if no uuid is find
+     */
+    String getOvsUuid(String dbName);
+
+    /**
+     * Gets the ovsdb database schema.
+     *
+     * @param dbName database name
+     * @return database schema
+     */
+    ListenableFuture<DatabaseSchema> getOvsdbSchema(String dbName);
+
+    /**
+     * Gets the ovsdb table updates.
+     *
+     * @param dbName database name
+     * @param id random uuid
+     * @return table updates
+     */
+    ListenableFuture<TableUpdates> monitorTables(String dbName, String id);
+
+    /**
+     * Gets the ovsdb config operation result.
+     *
+     * @param dbName database name
+     * @param operations the list of operations
+     * @return operation results
+     */
+    ListenableFuture<List<OperationResult>> transactConfig(String dbName,
+                                                           List<Operation> operations);
+
+    /**
+     * Gets the ovsdb database schema from local.
+     *
+     * @param  dbName database name
+     * @return database schema
+     */
+    DatabaseSchema getDatabaseSchema(String dbName);
+
+    /**
+     * Gets the ovsdb row from the local ovsdb store.
+     *
+     * @param dbName database name
+     * @param tableName table name
+     * @param uuid row uuid
+     * @return row ovsdb row
+     */
+    Row getRow(String dbName, String tableName, String uuid);
+
+    /**
+     * Removes the ovsdb row from the local ovsdb store.
+     *
+     * @param dbName database name
+     * @param tableName table name
+     * @param uuid row uuid
+     */
+    void removeRow(String dbName, String tableName, String uuid);
+
+    /**
+     * Update the local ovsdb store.
+     *
+     * @param dbName database name
+     * @param tableName table name
+     * @param uuid row uuid
+     * @param row ovsdb row
+     */
+    void updateOvsdbStore(String dbName, String tableName, String uuid, Row row);
+
 }
diff --git a/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbConstant.java b/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbConstant.java
new file mode 100644
index 0000000..c1133bb
--- /dev/null
+++ b/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbConstant.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.controller;
+
+/**
+ * Ovsdb related constants.
+ */
+public final class OvsdbConstant {
+
+    /**
+     * Default constructor.
+     *
+     * The constructor is private to prevent creating an instance of this
+     * utility class.
+     */
+    private OvsdbConstant() {
+    }
+
+    /** Ovsdb database Open_vSwitch. */
+    public static final String DATABASENAME = "Open_vSwitch";
+
+    /** Ovsdb table Bridge. */
+    public static final String BRIDGE = "Bridge";
+
+    /** Ovsdb table Interface. */
+    public static final String INTERFACE = "Interface";
+
+    /** Ovsdb table Controller. */
+    public static final String CONTROLLER = "Controller";
+
+    /** Ovsdb table Port. */
+    public static final String PORT = "Port";
+
+    /** Ovsdb bridge name. */
+    public static final String INTEGRATION_BRIDGE = "br-int";
+
+    /** Ovsdb vxlan tunnel type. */
+    public static final String TYPEVXLAN = "vxlan";
+
+    /** Openflow version. */
+    public static final String OPENFLOW13 = "OpenFlow13";
+
+    /** Ovsdb external_id_interface_id.. */
+    public static final String EXTERNAL_ID_INTERFACE_ID = "iface-id";
+
+    /** Ovsdb external_id_vm_mac. */
+    public static final String EXTERNAL_ID_VM_MAC = "attached-mac";
+
+    /** Openflow port. */
+    public static final int OFPORT = 6633;
+
+    /** Ovsdb port. */
+    public static final int OVSDBPORT = 6640;
+
+}
diff --git a/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbRowStore.java b/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbRowStore.java
new file mode 100644
index 0000000..bec0e2e
--- /dev/null
+++ b/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbRowStore.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.controller;
+
+import java.util.concurrent.ConcurrentMap;
+
+import org.onosproject.ovsdb.rfc.notation.Row;
+
+import com.google.common.collect.Maps;
+
+/**
+ * The class representing a table data.
+ */
+public class OvsdbRowStore {
+
+    private final ConcurrentMap<String, Row> rowStore = Maps.newConcurrentMap();
+
+    /**
+     * Gets the row.
+     *
+     * @param uuid the key of the rowStore
+     * @return row the row of the rowStore
+     */
+    public Row getRow(String uuid) {
+        return rowStore.get(uuid);
+    }
+
+    /**
+     * Inserts a row to rowStore.
+     *
+     * @param uuid key of the row
+     * @param row a row of the table
+     */
+    public void insertRow(String uuid, Row row) {
+        rowStore.put(uuid, row);
+    }
+
+    /**
+     * Deletes a row to rowStore.
+     *
+     * @param uuid key of the row
+     */
+    public void deleteRow(String uuid) {
+        rowStore.remove(uuid);
+    }
+
+    /**
+     * Gets the rowStore.
+     *
+     * @return rowStore
+     */
+    public ConcurrentMap<String, Row> getRowStore() {
+        return rowStore;
+    }
+
+}
diff --git a/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbStore.java b/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbStore.java
new file mode 100644
index 0000000..5670490
--- /dev/null
+++ b/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbStore.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.controller;
+
+import java.util.concurrent.ConcurrentMap;
+
+import com.google.common.collect.Maps;
+
+/**
+ * The cache for local ovsdb database.
+ */
+public class OvsdbStore {
+
+    private final ConcurrentMap<String, OvsdbTableStore> ovsdbStore = Maps.newConcurrentMap();
+
+    /**
+     * Gets the OvsdbTableStore.
+     *
+     * @param dbName ovsdb database name
+     * @return tableStore OvsdbTableStore
+     */
+    public OvsdbTableStore getOvsdbTableStore(String dbName) {
+        OvsdbTableStore tableStore = ovsdbStore.get(dbName);
+        if (tableStore == null) {
+            return null;
+        }
+        return tableStore;
+    }
+
+    /**
+     * Create or Update a value to ovsdbStore.
+     *
+     * @param dbName ovsdb database name
+     * @param tableStore a database tableStore.
+     */
+    public void createOrUpdateOvsdbStore(String dbName, OvsdbTableStore tableStore) {
+        ovsdbStore.put(dbName, tableStore);
+    }
+
+    /**
+     * Drops a value to rowStore.
+     *
+     * @param dbName ovsdb database name
+     */
+    public void dropOvsdbStore(String dbName) {
+        ovsdbStore.remove(dbName);
+    }
+
+    /**
+     * Gets the ovsdbStore.
+     *
+     * @return ovsdbStore
+     */
+    public ConcurrentMap<String, OvsdbTableStore> getOvsdbStore() {
+        return ovsdbStore;
+    }
+
+}
diff --git a/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbTableStore.java b/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbTableStore.java
new file mode 100644
index 0000000..1d9146e
--- /dev/null
+++ b/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbTableStore.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.controller;
+
+import java.util.concurrent.ConcurrentMap;
+
+import com.google.common.collect.Maps;
+
+/**
+ * The class representing a database data.
+ */
+public class OvsdbTableStore {
+
+    private final ConcurrentMap<String, OvsdbRowStore> tableStore = Maps.newConcurrentMap();
+
+    /**
+     * Gets the ovsdbRowStore.
+     *
+     * @param tableName a ovsdb table name
+     * @return OvsdbRowStore the data of the table
+     */
+    public OvsdbRowStore getRows(String tableName) {
+        return tableStore.get(tableName);
+    }
+
+    /**
+     * Create or update a value to tableStore.
+     *
+     * @param tableName key of the tableName
+     * @param rowStore a row of the table
+     */
+    public void createOrUpdateTable(String tableName, OvsdbRowStore rowStore) {
+        tableStore.put(tableName, rowStore);
+    }
+
+    /**
+     * Drops a value to table data.
+     *
+     * @param tableName key of the tableName
+     */
+    public void dropTable(String tableName) {
+        tableStore.remove(tableName);
+    }
+
+    /**
+     * Gets the tableStore.
+     *
+     * @return tableStore
+     */
+    public ConcurrentMap<String, OvsdbRowStore> getTableStore() {
+        return tableStore;
+    }
+
+}
diff --git a/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/DefaultOvsdbClient.java b/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/DefaultOvsdbClient.java
new file mode 100644
index 0000000..f1889ce
--- /dev/null
+++ b/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/DefaultOvsdbClient.java
@@ -0,0 +1,1065 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.controller.driver;
+
+import io.netty.channel.Channel;
+
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutionException;
+
+import org.onlab.packet.IpAddress;
+import org.onosproject.ovsdb.controller.OvsdbBridge;
+import org.onosproject.ovsdb.controller.OvsdbClientService;
+import org.onosproject.ovsdb.controller.OvsdbConstant;
+import org.onosproject.ovsdb.controller.OvsdbNodeId;
+import org.onosproject.ovsdb.controller.OvsdbPort;
+import org.onosproject.ovsdb.controller.OvsdbRowStore;
+import org.onosproject.ovsdb.controller.OvsdbStore;
+import org.onosproject.ovsdb.controller.OvsdbTableStore;
+import org.onosproject.ovsdb.controller.OvsdbTunnel;
+import org.onosproject.ovsdb.rfc.jsonrpc.Callback;
+import org.onosproject.ovsdb.rfc.message.OperationResult;
+import org.onosproject.ovsdb.rfc.message.TableUpdates;
+import org.onosproject.ovsdb.rfc.notation.Condition;
+import org.onosproject.ovsdb.rfc.notation.Mutation;
+import org.onosproject.ovsdb.rfc.notation.OvsdbSet;
+import org.onosproject.ovsdb.rfc.notation.Row;
+import org.onosproject.ovsdb.rfc.notation.UUID;
+import org.onosproject.ovsdb.rfc.operations.Delete;
+import org.onosproject.ovsdb.rfc.operations.Insert;
+import org.onosproject.ovsdb.rfc.operations.Mutate;
+import org.onosproject.ovsdb.rfc.operations.Operation;
+import org.onosproject.ovsdb.rfc.operations.Update;
+import org.onosproject.ovsdb.rfc.schema.ColumnSchema;
+import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
+import org.onosproject.ovsdb.rfc.schema.TableSchema;
+import org.onosproject.ovsdb.rfc.table.Bridge;
+import org.onosproject.ovsdb.rfc.table.Controller;
+import org.onosproject.ovsdb.rfc.table.Interface;
+import org.onosproject.ovsdb.rfc.table.OpenVSwitch;
+import org.onosproject.ovsdb.rfc.table.OvsdbTable;
+import org.onosproject.ovsdb.rfc.table.Port;
+import org.onosproject.ovsdb.rfc.table.TableGenerator;
+import org.onosproject.ovsdb.rfc.utils.ConditionUtil;
+import org.onosproject.ovsdb.rfc.utils.FromJsonUtil;
+import org.onosproject.ovsdb.rfc.utils.JsonRpcWriterUtil;
+import org.onosproject.ovsdb.rfc.utils.MutationUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.base.Function;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.SettableFuture;
+
+/**
+ * An representation of an ovsdb client.
+ */
+public class DefaultOvsdbClient
+        implements OvsdbProviderService, OvsdbClientService {
+
+    private final Logger log = LoggerFactory
+            .getLogger(DefaultOvsdbClient.class);
+
+    private Channel channel;
+
+    private OvsdbAgent agent;
+    private boolean connected;
+    private OvsdbNodeId nodeId;
+    private Callback monitorCallBack;
+
+    private OvsdbStore ovsdbStore = new OvsdbStore();
+
+    private final Map<String, String> requestMethod = Maps.newHashMap();
+    private final Map<String, SettableFuture<? extends Object>> requestResult = Maps
+            .newHashMap();
+
+    private final Map<String, DatabaseSchema> schema = Maps.newHashMap();
+    private final Set<OvsdbPort> ovsdbPorts = new HashSet<OvsdbPort>();
+    private final Set<OvsdbTunnel> ovsdbTunnels = new HashSet<OvsdbTunnel>();
+    private final Set<OvsdbBridge> ovsdbBridges = new HashSet<OvsdbBridge>();
+
+    /**
+     * Creates an OvsdbClient.
+     *
+     * @param nodeId ovsdb node id
+     */
+    public DefaultOvsdbClient(OvsdbNodeId nodeId) {
+        this.nodeId = nodeId;
+    }
+
+    @Override
+    public OvsdbNodeId nodeId() {
+        return nodeId;
+    }
+
+    @Override
+    public void setAgent(OvsdbAgent agent) {
+        if (this.agent == null) {
+            this.agent = agent;
+        }
+    }
+
+    @Override
+    public void setChannel(Channel channel) {
+        this.channel = channel;
+    }
+
+    @Override
+    public void setConnection(boolean connected) {
+        this.connected = connected;
+    }
+
+    @Override
+    public boolean isConnected() {
+        return this.connected;
+    }
+
+    @Override
+    public void nodeAdded() {
+        this.agent.addConnectedNode(nodeId, this);
+    }
+
+    @Override
+    public void nodeRemoved() {
+        this.agent.removeConnectedNode(nodeId);
+        channel.disconnect();
+    }
+
+    /**
+     * Gets the ovsdb table store.
+     *
+     * @param dbName the ovsdb database name
+     * @return ovsTableStore, empty if table store is find
+     */
+    private OvsdbTableStore getTableStore(String dbName) {
+        if (ovsdbStore == null) {
+            return null;
+        }
+        return ovsdbStore.getOvsdbTableStore(dbName);
+    }
+
+    /**
+     * Gets the ovsdb row store.
+     *
+     * @param dbName the ovsdb database name
+     * @param tableName the ovsdb table name
+     *
+     * @return ovsRowStore, empty if row store is find
+     */
+    private OvsdbRowStore getRowStore(String dbName, String tableName) {
+        OvsdbTableStore tableStore = getTableStore(dbName);
+        if (tableStore == null) {
+            return null;
+        }
+        return tableStore.getRows(tableName);
+    }
+
+    /**
+     * Gets the ovsdb row.
+     *
+     * @param dbName the ovsdb database name
+     * @param tableName the ovsdb table name
+     * @param uuid the key of the row
+     * @return row, empty if row is find
+     */
+    @Override
+    public Row getRow(String dbName, String tableName, String uuid) {
+        OvsdbTableStore tableStore = getTableStore(dbName);
+        if (tableStore == null) {
+            return null;
+        }
+        OvsdbRowStore rowStore = tableStore.getRows(tableName);
+        if (rowStore == null) {
+            return null;
+        }
+        return rowStore.getRow(uuid);
+    }
+
+    @Override
+    public void removeRow(String dbName, String tableName, String uuid) {
+        OvsdbTableStore tableStore = getTableStore(dbName);
+        if (tableStore == null) {
+            return;
+        }
+        OvsdbRowStore rowStore = tableStore.getRows(tableName);
+        if (rowStore == null) {
+            return;
+        }
+        rowStore.deleteRow(uuid);
+    }
+
+    @Override
+    public void updateOvsdbStore(String dbName, String tableName, String uuid,
+                                 Row row) {
+        OvsdbTableStore tableStore = ovsdbStore.getOvsdbTableStore(dbName);
+        if (tableStore == null) {
+            tableStore = new OvsdbTableStore();
+        }
+        OvsdbRowStore rowStore = tableStore.getRows(tableName);
+        if (rowStore == null) {
+            rowStore = new OvsdbRowStore();
+        }
+        rowStore.insertRow(uuid, row);
+        tableStore.createOrUpdateTable(tableName, rowStore);
+        ovsdbStore.createOrUpdateOvsdbStore(dbName, tableStore);
+    }
+
+    @Override
+    public String getPortUuid(String portName, String bridgeUuid) {
+        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
+
+        Row bridgeRow = getRow(OvsdbConstant.DATABASENAME,
+                               OvsdbConstant.BRIDGE, bridgeUuid);
+
+        Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, bridgeRow,
+                                                         OvsdbTable.BRIDGE);
+        if (bridge != null) {
+            OvsdbSet setPorts = (OvsdbSet) bridge.getPortsColumn().data();
+            @SuppressWarnings("unchecked")
+            Set<UUID> ports = setPorts.set();
+            if (ports == null || ports.size() == 0) {
+                log.warn("The port uuid is null");
+                return null;
+            }
+
+            for (UUID uuid : ports) {
+                Row portRow = getRow(OvsdbConstant.DATABASENAME,
+                                     OvsdbConstant.PORT, uuid.value());
+                if (portRow == null) {
+                    continue;
+                }
+                Port port = (Port) TableGenerator.getTable(dbSchema, portRow,
+                                                           OvsdbTable.PORT);
+                if (port != null && portName.equalsIgnoreCase(port.getName())) {
+                    return uuid.value();
+                }
+            }
+
+        }
+        return null;
+    }
+
+    @Override
+    public String getInterfaceUuid(String portUuid, String portName) {
+        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
+
+        Row portRow = getRow(OvsdbConstant.DATABASENAME, OvsdbConstant.PORT,
+                             portUuid);
+        Port port = (Port) TableGenerator.getTable(dbSchema, portRow,
+                                                   OvsdbTable.PORT);
+
+        if (port != null) {
+            OvsdbSet setInterfaces = (OvsdbSet) port.getInterfacesColumn().data();
+            @SuppressWarnings("unchecked")
+            Set<UUID> interfaces = setInterfaces.set();
+
+            if (interfaces == null || interfaces.size() == 0) {
+                log.warn("The interface uuid is null");
+                return null;
+            }
+
+            for (UUID uuid : interfaces) {
+                Row intfRow = getRow(OvsdbConstant.DATABASENAME,
+                                     OvsdbConstant.INTERFACE, uuid.value());
+                if (intfRow == null) {
+                    continue;
+                }
+                Interface intf = (Interface) TableGenerator
+                        .getTable(dbSchema, intfRow, OvsdbTable.INTERFACE);
+                if (intf != null && portName.equalsIgnoreCase(intf.getName())) {
+                    return uuid.value();
+                }
+            }
+
+        }
+
+        return null;
+    }
+
+    @Override
+    public String getBridgeUuid(String bridgeName) {
+        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
+
+        OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
+                                             OvsdbConstant.BRIDGE);
+        if (rowStore == null) {
+            log.debug("The bridge uuid is null");
+            return null;
+        }
+
+        ConcurrentMap<String, Row> bridgeTableRows = rowStore.getRowStore();
+        if (bridgeTableRows == null) {
+            log.debug("The bridge uuid is null");
+            return null;
+        }
+
+        for (String uuid : bridgeTableRows.keySet()) {
+            Bridge bridge = (Bridge) TableGenerator
+                    .getTable(dbSchema, bridgeTableRows.get(uuid),
+                              OvsdbTable.BRIDGE);
+
+            if (bridge.getName().equals(bridgeName)) {
+                return uuid;
+            }
+
+        }
+        return null;
+    }
+
+    @Override
+    public String getControllerUuid(String controllerName,
+                                    String controllerTarget) {
+        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
+        OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
+                                             OvsdbConstant.CONTROLLER);
+        if (rowStore == null) {
+            log.debug("The controller uuid is null");
+            return null;
+        }
+
+        ConcurrentMap<String, Row> controllerTableRows = rowStore.getRowStore();
+        if (controllerTableRows != null) {
+            for (String uuid : controllerTableRows.keySet()) {
+
+                Controller controller = (Controller) TableGenerator
+                        .getTable(dbSchema, controllerTableRows.get(uuid),
+                                  OvsdbTable.CONTROLLER);
+                String target = (String) controller.getTargetColumn().data();
+                if (target.equalsIgnoreCase(controllerTarget)) {
+                    return uuid;
+                }
+
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public String getOvsUuid(String dbName) {
+        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
+        OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
+                                             OvsdbConstant.DATABASENAME);
+        if (rowStore == null) {
+            log.debug("The bridge uuid is null");
+            return null;
+        }
+        ConcurrentMap<String, Row> ovsTableRows = rowStore.getRowStore();
+
+        if (ovsTableRows != null) {
+
+            for (String uuid : ovsTableRows.keySet()) {
+
+                OpenVSwitch ovs = (OpenVSwitch) TableGenerator
+                        .getTable(dbSchema, ovsTableRows.get(uuid),
+                                  OvsdbTable.OPENVSWITCH);
+
+                if (((TableSchema) ovs.getTbSchema()).name().equals(dbName)) {
+                    return uuid;
+                }
+            }
+
+        }
+
+        return null;
+    }
+
+    @Override
+    public void createPort(String bridgeName, String portName) {
+        String bridgeUuid = getBridgeUuid(bridgeName);
+        if (bridgeUuid == null) {
+            log.error("Can't find bridge {} in {}", bridgeName,
+                      nodeId.getIpAddress());
+            return;
+        }
+
+        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
+        String portUuid = getPortUuid(portName, bridgeUuid);
+
+        Port port = (Port) TableGenerator
+                .createTable(dbSchema, OvsdbTable.PORT);
+
+        port.setName(portName);
+        if (portUuid == null) {
+            insertConfig(OvsdbConstant.PORT, "_uuid", OvsdbConstant.BRIDGE,
+                      "ports", bridgeUuid, port.getRow());
+        } else {
+            updateConfig(OvsdbConstant.PORT, "_uuid", portUuid, port.getRow());
+        }
+
+        return;
+    }
+
+    @Override
+    public void dropPort(String bridgeName, String portName) {
+        String bridgeUuid = getBridgeUuid(bridgeName);
+        if (bridgeUuid == null) {
+            log.error("Could not find Bridge {} in {}", bridgeName, nodeId);
+            return;
+        }
+
+        String portUuid = getPortUuid(portName, bridgeUuid);
+        if (portUuid != null) {
+            log.info("Port {} delete", portName);
+            deleteConfig(OvsdbConstant.PORT, "_uuid", portUuid,
+                      OvsdbConstant.BRIDGE, "ports");
+        }
+    }
+
+    @Override
+    public void createBridge(String bridgeName) {
+        log.debug("create bridge {}", bridgeName);
+
+        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
+        if (dbSchema == null) {
+            log.warn("The schema is null");
+            return;
+        }
+
+        Bridge bridge = (Bridge) TableGenerator.createTable(dbSchema,
+                                                            OvsdbTable.BRIDGE);
+        if (bridge == null) {
+            log.debug("Can not create bridge");
+            return;
+        }
+
+        Set<String> failModes = new HashSet<>();
+        failModes.add("secure");
+        bridge.setFailMode(failModes);
+
+        Set<String> protocols = new HashSet<>();
+        protocols.add(OvsdbConstant.OPENFLOW13);
+        bridge.setProtocols(protocols);
+
+        String ovsUuid = getOvsUuid(OvsdbConstant.DATABASENAME);
+        if (ovsUuid == null) {
+            log.warn("The Open_vSwitch is null");
+            return;
+        }
+
+        String bridgeUuid = getBridgeUuid(bridgeName);
+        if (bridgeUuid == null) {
+            log.debug("Create a new bridge");
+
+            bridge.setName(bridgeName);
+            bridgeUuid = insertConfig(OvsdbConstant.BRIDGE, "_uuid",
+                                   OvsdbConstant.DATABASENAME, "bridges",
+                                   ovsUuid, bridge.getRow());
+
+            if (bridgeUuid != null) {
+                Port port = (Port) TableGenerator.createTable(dbSchema,
+                                                              OvsdbTable.PORT);
+                if (port != null) {
+                    log.debug("the port is not null");
+                    port.setName(bridgeName);
+
+                    insertConfig(OvsdbConstant.PORT, "_uuid", "Bridge", "ports", bridgeUuid,
+                              port.getRow());
+                }
+            }
+
+        } else {
+            log.info("Update a bridge");
+            updateConfig(OvsdbConstant.BRIDGE, "_uuid", bridgeUuid, bridge.getRow());
+        }
+
+        setController(bridgeUuid);
+        log.info("Create bridge success");
+    }
+
+    /**
+     * Sets the Controller.
+     *
+     * @param bridgeUuid bridge uuid
+     */
+    private void setController(String bridgeUuid) {
+        String controllerUuid = null;
+        String iPAddress = IpAddress.valueOf(((InetSocketAddress) channel
+                                                     .localAddress())
+                                                     .getAddress()
+                                                     .getHostAddress())
+                .toString();
+
+        String target = "tcp:" + iPAddress + ":" + OvsdbConstant.OFPORT;
+        log.debug("controller IP {}: port {}", iPAddress, OvsdbConstant.OFPORT);
+
+        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
+        Controller controller = (Controller) TableGenerator
+                .createTable(dbSchema, OvsdbTable.CONTROLLER);
+
+        if (controller != null) {
+            controller.setTarget(target);
+            controllerUuid = getControllerUuid(OvsdbConstant.CONTROLLER, target);
+            if (controllerUuid == null) {
+
+                insertConfig(OvsdbConstant.CONTROLLER, "_uuid",
+                          OvsdbConstant.BRIDGE, "controller", bridgeUuid,
+                          controller.getRow());
+
+            } else {
+
+                Bridge bridge = (Bridge) TableGenerator
+                        .createTable(dbSchema, OvsdbTable.BRIDGE);
+                Set<UUID> controllerUuids = new HashSet<>();
+                controllerUuids.add(UUID.uuid(controllerUuid));
+                bridge.setController(controllerUuids);
+                updateConfig(OvsdbConstant.CONTROLLER, "_uuid", bridgeUuid, bridge.getRow());
+
+            }
+        }
+
+    }
+
+    @Override
+    public void dropBridge(String bridgeName) {
+        String bridgeUUID = getBridgeUuid(bridgeName);
+        if (bridgeUUID == null) {
+            log.warn("Could not find bridge in node", nodeId.getIpAddress());
+            return;
+        }
+        deleteConfig(OvsdbConstant.BRIDGE, "_uuid", bridgeUUID,
+                  OvsdbConstant.DATABASENAME, "bridges");
+    }
+
+    @Override
+    public void createTunnel(IpAddress srcIp, IpAddress dstIp) {
+        String bridgeUuid = getBridgeUuid(OvsdbConstant.INTEGRATION_BRIDGE);
+        if (bridgeUuid == null) {
+            log.warn("Could not find bridge {} and Could not create tunnel. ",
+                     OvsdbConstant.INTEGRATION_BRIDGE);
+            return;
+        }
+
+        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
+        String portName = getTunnelName(OvsdbConstant.TYPEVXLAN, dstIp);
+        String portUuid = getPortUuid(portName, bridgeUuid);
+
+        Port port = (Port) TableGenerator
+                .createTable(dbSchema, OvsdbTable.PORT);
+        if (port != null) {
+            port.setName(portName);
+        }
+
+        if (portUuid == null) {
+            portUuid = insertConfig(OvsdbConstant.PORT, "_uuid", OvsdbConstant.BRIDGE,
+                      "ports", bridgeUuid, port.getRow());
+        } else {
+            updateConfig(OvsdbConstant.PORT, "_uuid", portUuid, port.getRow());
+        }
+
+        // When a tunnel is created, A row is inserted into port table and
+        // interface table of the ovsdb node.
+        // and the following step is to get the interface uuid from local store
+        // in controller node.
+        // but it need spend some time synchronising data between node and
+        // controller.
+        // so loop to judge if interfaceUUid is null is necessary.
+        String interfaceUuid = null;
+        for (int i = 0; i < 10; i++) {
+            interfaceUuid = getInterfaceUuid(portUuid, portName);
+            if (interfaceUuid == null) {
+                try {
+                    Thread.sleep(500);
+                } catch (InterruptedException e) {
+                    log.warn("Interrupted while waiting to get interfaceUuid");
+                    Thread.currentThread().interrupt();
+                }
+            } else {
+                break;
+            }
+        }
+
+        if (interfaceUuid != null) {
+            OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
+                                                 OvsdbConstant.INTERFACE);
+            if (rowStore == null) {
+                log.debug("The bridge uuid is null");
+                return;
+            }
+
+            ConcurrentMap<String, Row> intfTableRows = rowStore.getRowStore();
+            if (intfTableRows == null) {
+                log.debug("The bridge uuid is null");
+                return;
+            }
+
+            Interface tunInterface = (Interface) TableGenerator
+                    .getTable(dbSchema, intfTableRows.get(interfaceUuid),
+                              OvsdbTable.INTERFACE);
+            if (tunInterface != null) {
+
+                tunInterface.setType(OvsdbConstant.TYPEVXLAN);
+                Map<String, String> options = Maps.newHashMap();
+                options.put("key", "flow");
+                options.put("local_ip", srcIp.toString());
+                options.put("remote_ip", dstIp.toString());
+                tunInterface.setOptions(options);
+                updateConfig(OvsdbConstant.INTERFACE, "_uuid", interfaceUuid,
+                          tunInterface.getRow());
+                log.info("Tunnel added success", tunInterface);
+
+            }
+        }
+
+        return;
+    }
+
+    @Override
+    public void dropTunnel(IpAddress srcIp, IpAddress dstIp) {
+        String bridgeName = OvsdbConstant.INTEGRATION_BRIDGE;
+        String portName = getTunnelName(OvsdbConstant.TYPEVXLAN, dstIp);
+        String bridgeUuid = getBridgeUuid(OvsdbConstant.INTEGRATION_BRIDGE);
+        if (bridgeUuid == null) {
+            log.warn("Could not find bridge {} in {}", bridgeName,
+                     nodeId.getIpAddress());
+            return;
+        }
+
+        String portUUID = getPortUuid(portName, bridgeUuid);
+        if (portUUID != null) {
+            log.info("Delete tunnel");
+            deleteConfig(OvsdbConstant.PORT, "_uuid", portUUID,
+                      OvsdbConstant.BRIDGE, "ports");
+        }
+
+        return;
+    }
+
+    /**
+     * Delete transact config.
+     *
+     * @param childTableName child table name
+     * @param childColumnName child column name
+     * @param childRowUuid child row uuid
+     * @param parentTableName parent table name
+     * @param parentColumnName parent column
+     *
+     */
+    private void deleteConfig(String childTableName, String childColumnName,
+                           String childUuid, String parentTableName,
+                           String parentColumnName) {
+        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
+        TableSchema childTableSchema = dbSchema.getTableSchema(childTableName);
+
+        ArrayList<Operation> operations = Lists.newArrayList();
+        if (parentTableName != null && parentColumnName != null) {
+            TableSchema parentTableSchema = dbSchema
+                    .getTableSchema(parentTableName);
+            ColumnSchema parentColumnSchema = parentTableSchema
+                    .getColumnSchema(parentColumnName);
+            List<Mutation> mutations = Lists.newArrayList();
+            Mutation mutation = MutationUtil.delete(parentColumnSchema.name(),
+                                                    UUID.uuid(childUuid));
+            mutations.add(mutation);
+            List<Condition> conditions = Lists.newArrayList();
+            Condition condition = ConditionUtil.includes(parentColumnName,
+                                                         UUID.uuid(childUuid));
+            conditions.add(condition);
+            Mutate op = new Mutate(parentTableSchema, conditions, mutations);
+            operations.add(op);
+        }
+
+        List<Condition> conditions = Lists.newArrayList();
+        Condition condition = ConditionUtil.equals(childColumnName, UUID.uuid(childUuid));
+        conditions.add(condition);
+        Delete del = new Delete(childTableSchema, conditions);
+        operations.add(del);
+        transactConfig(OvsdbConstant.DATABASENAME, operations);
+
+        return;
+    }
+
+    /**
+     * Update transact config.
+     *
+     * @param tableName table name
+     * @param columnName column name
+     * @param uuid uuid
+     * @param row the config data
+     *
+     */
+    private void updateConfig(String tableName, String columnName, String uuid,
+                           Row row) {
+        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
+        TableSchema tableSchema = dbSchema.getTableSchema(tableName);
+
+        List<Condition> conditions = Lists.newArrayList();
+        Condition condition = ConditionUtil.equals(columnName, UUID.uuid(uuid));
+        conditions.add(condition);
+
+        Update update = new Update(tableSchema, row, conditions);
+
+        ArrayList<Operation> operations = Lists.newArrayList();
+        operations.add(update);
+
+        transactConfig(OvsdbConstant.DATABASENAME, operations);
+    }
+
+    /**
+     * Insert transact config.
+     *
+     * @param childTable child table name
+     * @param childColumnName child column name
+     * @param childRowUuid child row uuid
+     * @param parentTableName parent table name
+     * @param parentColumnName parent column
+     * @param row the config data
+     *
+     * @return uuid, empty if no uuid is find
+     */
+    private String insertConfig(String childtableName, String childColumnName,
+                             String parentTableName, String parentColumnName,
+                             String parentUuid, Row row) {
+        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
+        TableSchema tableSchema = dbSchema.getTableSchema(childtableName);
+
+        String namedUuid = childtableName;
+        Insert insert = new Insert(tableSchema, namedUuid, row);
+
+        ArrayList<Operation> operations = Lists.newArrayList();
+        operations.add(insert);
+
+        if (parentTableName != null && parentColumnName != null) {
+            TableSchema parentTableSchema = dbSchema
+                    .getTableSchema(parentTableName);
+            ColumnSchema parentColumnSchema = parentTableSchema
+                    .getColumnSchema(parentColumnName);
+
+            List<Mutation> mutations = Lists.newArrayList();
+            Mutation mutation = MutationUtil.insert(parentColumnSchema.name(),
+                                                    UUID.uuid(namedUuid));
+            mutations.add(mutation);
+
+            List<Condition> conditions = Lists.newArrayList();
+            Condition condition = ConditionUtil.equals("_uuid",
+                                                       UUID.uuid(parentUuid));
+            conditions.add(condition);
+
+            Mutate op = new Mutate(parentTableSchema, conditions, mutations);
+            operations.add(op);
+        }
+        if (childtableName.equalsIgnoreCase(OvsdbConstant.PORT)) {
+            log.info("Handle port insert");
+            Insert intfInsert = handlePortInsertTable(OvsdbConstant.INTERFACE,
+                                                    row);
+
+            if (intfInsert != null) {
+                operations.add(intfInsert);
+            }
+
+            Insert ins = (Insert) operations.get(0);
+            ins.getRow().put("interfaces",
+                             UUID.uuid(OvsdbConstant.INTERFACE));
+        }
+
+        List<OperationResult> results;
+        try {
+            results = transactConfig(OvsdbConstant.DATABASENAME, operations)
+                    .get();
+
+            return results.get(0).getUuid().value();
+        } catch (InterruptedException e) {
+            log.warn("Interrupted while waiting to get result");
+            Thread.currentThread().interrupt();
+        } catch (ExecutionException e) {
+            log.error("Exception thrown while to get result");
+        }
+
+        return null;
+    }
+
+    /**
+     * Handles port insert.
+     *
+     * @param tableName ovsdb table interface
+     * @param portRow row of port
+     *
+     * @return insert, empty if null
+     */
+    private Insert handlePortInsertTable(String tableName, Row portRow) {
+        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
+
+        TableSchema portTableSchema = dbSchema
+                .getTableSchema(OvsdbConstant.PORT);
+        ColumnSchema portColumnSchema = portTableSchema.getColumnSchema("name");
+
+        String portName = (String) portRow.getColumn(portColumnSchema).data();
+
+        Interface inf = (Interface) TableGenerator
+                .createTable(dbSchema, OvsdbTable.INTERFACE);
+
+        inf.setName(portName);
+
+        TableSchema intfTableSchema = dbSchema
+                .getTableSchema(OvsdbConstant.INTERFACE);
+        Insert insert = new Insert(intfTableSchema, OvsdbConstant.INTERFACE,
+                                   inf.getRow());
+        return insert;
+    }
+
+    /**
+     * Gets tunnel name.
+     *
+     * @param tunnelType
+     * @param dstIp the remote ip address
+     *
+     * @return tunnel name
+     */
+    private String getTunnelName(String tunnelType, IpAddress dstIp) {
+        return tunnelType + "-" + dstIp.toString();
+    }
+
+    @Override
+    public ListenableFuture<DatabaseSchema> getOvsdbSchema(String dbName) {
+        if (dbName == null) {
+            return null;
+        }
+        DatabaseSchema databaseSchema = schema.get(dbName);
+        if (databaseSchema == null) {
+            List<String> dbNames = new ArrayList<String>();
+            dbNames.add(dbName);
+            Function<JsonNode, DatabaseSchema> rowFunction = new Function<JsonNode, DatabaseSchema>() {
+                @Override
+                public DatabaseSchema apply(JsonNode input) {
+                    log.info("Get ovsdb database schema", dbName);
+                    DatabaseSchema dbSchema = FromJsonUtil
+                            .jsonNodeToDbSchema(dbName, input);
+                    if (dbSchema == null) {
+                        log.debug("Get ovsdb database schema error");
+                        return null;
+                    }
+                    schema.put(dbName, dbSchema);
+
+                    return dbSchema;
+                }
+            };
+
+            ListenableFuture<JsonNode> input = getSchema(dbNames);
+            if (input != null) {
+                try {
+                    log.info("input message: {}", input.get().toString());
+                } catch (InterruptedException e) {
+                    log.warn("Interrupted while waiting to get message");
+                    Thread.currentThread().interrupt();
+                } catch (ExecutionException e) {
+                    log.error("Exception thrown while to get message");
+                }
+            }
+            return Futures.transform(input, rowFunction);
+        } else {
+            return Futures.immediateFuture(databaseSchema);
+        }
+    }
+
+    @Override
+    public ListenableFuture<TableUpdates> monitorTables(String dbName, String id) {
+        if (dbName == null) {
+            return null;
+        }
+        DatabaseSchema dbSchema = schema.get(dbName);
+        if (dbSchema != null) {
+            Function<JsonNode, TableUpdates> rowFunction = new Function<JsonNode, TableUpdates>() {
+                @Override
+                public TableUpdates apply(JsonNode input) {
+                    log.info("Get table updates");
+                    TableUpdates updates = FromJsonUtil
+                            .jsonNodeToTableUpdates(input, dbSchema);
+                    if (updates == null) {
+                        log.debug("Get table updates error");
+                        return null;
+                    }
+                    return updates;
+                }
+            };
+            return Futures.transform(monitor(dbSchema, id), rowFunction);
+        }
+        return null;
+    }
+
+    @Override
+    public ListenableFuture<List<OperationResult>> transactConfig(String dbName,
+                                                                  List<Operation> operations) {
+        if (dbName == null) {
+            return null;
+        }
+        DatabaseSchema dbSchema = schema.get(dbName);
+        if (dbSchema != null) {
+            Function<List<JsonNode>, List<OperationResult>> rowFunction =
+                    new Function<List<JsonNode>, List<OperationResult>>() {
+                @Override
+                public List<OperationResult> apply(List<JsonNode> input) {
+                    log.info("Get ovsdb operation result");
+                    List<OperationResult> result = FromJsonUtil
+                            .jsonNodeToOperationResult(input, operations);
+
+                    if (result == null) {
+                        log.debug("The operation result is null");
+                        return null;
+                    }
+                    return result;
+                }
+            };
+            return Futures.transform(transact(dbSchema, operations),
+                                     rowFunction);
+        }
+        return null;
+    }
+
+    @Override
+    public ListenableFuture<JsonNode> getSchema(List<String> dbnames) {
+        String id = java.util.UUID.randomUUID().toString();
+        String getSchemaString = JsonRpcWriterUtil.getSchemaStr(id, dbnames);
+
+        SettableFuture<JsonNode> sf = SettableFuture.create();
+        requestResult.put(id, sf);
+        requestMethod.put(id, "getSchema");
+
+        channel.writeAndFlush(getSchemaString);
+        return sf;
+
+    }
+
+    @Override
+    public ListenableFuture<List<String>> echo() {
+        String id = java.util.UUID.randomUUID().toString();
+        String echoString = JsonRpcWriterUtil.echoStr(id);
+
+        SettableFuture<List<String>> sf = SettableFuture.create();
+        requestResult.put(id, sf);
+        requestMethod.put(id, "echo");
+
+        channel.writeAndFlush(echoString);
+        return sf;
+
+    }
+
+    @Override
+    public ListenableFuture<JsonNode> monitor(DatabaseSchema dbSchema,
+                                              String monitorId) {
+        String id = java.util.UUID.randomUUID().toString();
+        String monitorString = JsonRpcWriterUtil.monitorStr(id, monitorId,
+                                                            dbSchema);
+
+        SettableFuture<JsonNode> sf = SettableFuture.create();
+        requestResult.put(id, sf);
+        requestMethod.put(id, "monitor");
+
+        channel.writeAndFlush(monitorString);
+        return sf;
+
+    }
+
+    @Override
+    public ListenableFuture<List<String>> listDbs() {
+        String id = java.util.UUID.randomUUID().toString();
+        String listDbsString = JsonRpcWriterUtil.listDbsStr(id);
+
+        SettableFuture<List<String>> sf = SettableFuture.create();
+        requestResult.put(id, sf);
+        requestMethod.put(id, "listDbs");
+
+        channel.writeAndFlush(listDbsString);
+        return sf;
+
+    }
+
+    @Override
+    public ListenableFuture<List<JsonNode>> transact(DatabaseSchema dbSchema,
+                                                     List<Operation> operations) {
+        String id = java.util.UUID.randomUUID().toString();
+        String transactString = JsonRpcWriterUtil.transactStr(id, dbSchema,
+                                                              operations);
+
+        SettableFuture<List<JsonNode>> sf = SettableFuture.create();
+        requestResult.put(id, sf);
+        requestMethod.put(id, "transact");
+
+        channel.writeAndFlush(transactString);
+        return sf;
+
+    }
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    @Override
+    public void processResult(JsonNode response) {
+        log.debug("Handle result");
+        String requestId = response.get("id").asText();
+        SettableFuture sf = requestResult.get(requestId);
+        if (sf == null) {
+            log.debug("No such future to process");
+            return;
+        }
+        String methodName = requestMethod.get(requestId);
+
+        Object result;
+        result = FromJsonUtil.jsonResultParser(response, methodName);
+
+        sf.set(result);
+        return;
+    }
+
+    @Override
+    public void processRequest(JsonNode requestJson) {
+        log.debug("Handle request");
+        if (requestJson.get("method").asText().equalsIgnoreCase("echo")) {
+            log.debug("handle echo request");
+
+            String replyString = FromJsonUtil.getEchoRequestStr(requestJson);
+            channel.writeAndFlush(replyString);
+
+            return;
+        } else {
+            FromJsonUtil
+                    .jsonCallbackRequestParser(requestJson, monitorCallBack);
+            return;
+        }
+    }
+
+    @Override
+    public void setCallback(Callback monitorCallback) {
+        this.monitorCallBack = monitorCallback;
+    }
+
+    @Override
+    public Set<OvsdbTunnel> getTunnels() {
+        return ovsdbTunnels;
+    }
+
+    @Override
+    public Set<OvsdbBridge> getBridges() {
+        return ovsdbBridges;
+    }
+
+    @Override
+    public Set<OvsdbPort> getPorts() {
+        return ovsdbPorts;
+    }
+
+    @Override
+    public DatabaseSchema getDatabaseSchema(String dbName) {
+        return schema.get(dbName);
+    }
+
+}
diff --git a/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/OvsdbProviderService.java b/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/OvsdbProviderService.java
index a7c0840..48f58d0 100644
--- a/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/OvsdbProviderService.java
+++ b/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/OvsdbProviderService.java
@@ -17,6 +17,10 @@
 
 import io.netty.channel.Channel;
 
+import org.onosproject.ovsdb.rfc.jsonrpc.Callback;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
 /**
  * Represents the driver side of an ovsdb node. This interface should never be
  * exposed to consumers.
@@ -52,4 +56,26 @@
      * @param connected whether the node is connected
      */
     void setConnection(boolean connected);
+
+    /**
+     * Processes result from ovsdb.
+     *
+     * @param response JsonNode response from ovsdb
+     */
+    void processResult(JsonNode response);
+
+    /**
+     * processes request from ovsdb.
+     *
+     * @param request JsonNode request from ovsdb
+     */
+    void processRequest(JsonNode request);
+
+    /**
+     * Sets call back.
+     *
+     * @param monitorCallback the callback to set
+     */
+    void setCallback(Callback monitorCallback);
+
 }