diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/BridgeConfig.java b/core/api/src/main/java/org/onosproject/net/behaviour/BridgeConfig.java
index e0ff0e7..96397ea 100644
--- a/core/api/src/main/java/org/onosproject/net/behaviour/BridgeConfig.java
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/BridgeConfig.java
@@ -1,69 +1,78 @@
-/*
- * 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.net.behaviour;
-
-import java.util.Collection;
-
-import org.onosproject.net.device.PortDescription;
-import org.onosproject.net.driver.HandlerBehaviour;
-
-/**
- * Behaviour for handling various drivers for bridge configurations.
- */
-public interface BridgeConfig extends HandlerBehaviour {
-
-    /**
-     * Add a bridge.
-     *
-     * @param bridgeName bridge name
-     */
-    void addBridge(BridgeName bridgeName);
-
-    /**
-     * Remove a bridge.
-     *
-     * @param bridgeName bridge name
-     */
-    void deleteBridge(BridgeName bridgeName);
-
-    /**
-     * Remove a bridge.
-     *
-     * @return bridge collection
-     */
-    Collection<BridgeDescription> getBridges();
-
-    /**
-     * Add a logical/virtual port.
-     *
-     * @param port port number
-     */
-    void addPort(PortDescription port);
-
-    /**
-     * Delete a logical/virtual port.
-     *
-     * @param port port number
-     */
-    void deletePort(PortDescription port);
-
-    /**
-     * Delete a logical/virtual port.
-     *
-     * @return collection of port
-     */
-    Collection<PortDescription> getPorts();
-}
+/*
+ * 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.net.behaviour;
+
+import java.util.Collection;
+import java.util.Set;
+
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.PortDescription;
+import org.onosproject.net.driver.HandlerBehaviour;
+
+/**
+ * Behaviour for handling various drivers for bridge configurations.
+ */
+public interface BridgeConfig extends HandlerBehaviour {
+
+    /**
+     * Add a bridge.
+     *
+     * @param bridgeName bridge name
+     */
+    void addBridge(BridgeName bridgeName);
+
+    /**
+     * Remove a bridge.
+     *
+     * @param bridgeName bridge name
+     */
+    void deleteBridge(BridgeName bridgeName);
+
+    /**
+     * Remove a bridge.
+     *
+     * @return bridge collection
+     */
+    Collection<BridgeDescription> getBridges();
+
+    /**
+     * Add a logical/virtual port.
+     *
+     * @param port port number
+     */
+    void addPort(PortDescription port);
+
+    /**
+     * Delete a logical/virtual port.
+     *
+     * @param port port number
+     */
+    void deletePort(PortDescription port);
+
+    /**
+     * Delete a logical/virtual port.
+     *
+     * @return collection of port
+     */
+    Collection<PortDescription> getPorts();
+
+    /**
+     * Get a collection of port.
+     *
+     * @return portNumbers set of PortNumber
+     */
+    Set<PortNumber> getPortNumbers();
+}
diff --git a/drivers/src/main/java/org/onosproject/driver/ovsdb/OvsdbBridgeConfig.java b/drivers/src/main/java/org/onosproject/driver/ovsdb/OvsdbBridgeConfig.java
index 54f95a6..30c7526 100644
--- a/drivers/src/main/java/org/onosproject/driver/ovsdb/OvsdbBridgeConfig.java
+++ b/drivers/src/main/java/org/onosproject/driver/ovsdb/OvsdbBridgeConfig.java
@@ -1,136 +1,152 @@
-/*
- * 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.driver.ovsdb;
-
-import java.util.Collection;
-import java.util.Set;
-
-import org.onlab.packet.IpAddress;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.behaviour.BridgeConfig;
-import org.onosproject.net.behaviour.BridgeDescription;
-import org.onosproject.net.behaviour.BridgeName;
-import org.onosproject.net.behaviour.DefaultBridgeDescription;
-import org.onosproject.net.device.DefaultPortDescription;
-import org.onosproject.net.device.PortDescription;
-import org.onosproject.net.driver.AbstractHandlerBehaviour;
-import org.onosproject.net.driver.DriverHandler;
-import org.onosproject.ovsdb.controller.OvsdbBridge;
-import org.onosproject.ovsdb.controller.OvsdbClientService;
-import org.onosproject.ovsdb.controller.OvsdbController;
-import org.onosproject.ovsdb.controller.OvsdbNodeId;
-import org.onosproject.ovsdb.controller.OvsdbPort;
-
-import com.google.common.collect.Sets;
-
-/**
- * The implementation of BridageConfig.
- */
-public class OvsdbBridgeConfig extends AbstractHandlerBehaviour
-        implements BridgeConfig {
-
-    @Override
-    public void addBridge(BridgeName bridgeName) {
-        DriverHandler handler = handler();
-        OvsdbClientService ovsdbNode = getOvsdbNode(handler);
-        ovsdbNode.createBridge(bridgeName.name());
-    }
-
-    @Override
-    public void deleteBridge(BridgeName bridgeName) {
-        DriverHandler handler = handler();
-        OvsdbClientService ovsdbNode = getOvsdbNode(handler);
-        ovsdbNode.dropBridge(bridgeName.name());
-    }
-
-    @Override
-    public Collection<BridgeDescription> getBridges() {
-        DriverHandler handler = handler();
-        DeviceId deviceId = handler.data().deviceId();
-        OvsdbClientService ovsdbNode = getOvsdbNode(handler);
-        Set<OvsdbBridge> ovsdbSet = ovsdbNode.getBridges();
-        Collection<BridgeDescription> bridges = Sets.newHashSet();
-        ovsdbSet.forEach(o -> {
-            BridgeName bridgeName = BridgeName.bridgeName(o.bridgeName()
-                    .toString());
-            DeviceId ownDeviceId = DeviceId.deviceId(o.datapathId().toString());
-            BridgeDescription description = new DefaultBridgeDescription(
-                                                                         bridgeName,
-                                                                         deviceId,
-                                                                         ownDeviceId);
-            bridges.add(description);
-        });
-        return bridges;
-    }
-
-    @Override
-    public void addPort(PortDescription port) {
-        DriverHandler handler = handler();
-        OvsdbClientService ovsdbNode = getOvsdbNode(handler);
-        Set<OvsdbBridge> ovsdbSet = ovsdbNode.getBridges();
-        if (ovsdbSet != null && ovsdbSet.size() > 0) {
-            OvsdbBridge bridge = ovsdbSet.iterator().next();
-            ovsdbNode.createPort(bridge.bridgeName().toString(), port
-                    .portNumber().toString());
-        }
-    }
-
-    @Override
-    public void deletePort(PortDescription port) {
-        DriverHandler handler = handler();
-        OvsdbClientService ovsdbNode = getOvsdbNode(handler);
-        Set<OvsdbBridge> ovsdbSet = ovsdbNode.getBridges();
-        if (ovsdbSet != null && ovsdbSet.size() > 0) {
-            OvsdbBridge bridge = ovsdbSet.iterator().next();
-            ovsdbNode.dropPort(bridge.bridgeName().toString(), port
-                    .portNumber().toString());
-        }
-    }
-
-    @Override
-    public Collection<PortDescription> getPorts() {
-        DriverHandler handler = handler();
-        OvsdbClientService ovsdbNode = getOvsdbNode(handler);
-        Set<OvsdbPort> ovsdbSet = ovsdbNode.getPorts();
-        Collection<PortDescription> ports = Sets.newHashSet();
-        ovsdbSet.forEach(o -> {
-            PortNumber port = PortNumber.portNumber(o.portNumber().value());
-            PortDescription description = new DefaultPortDescription(port, true);
-            ports.add(description);
-        });
-        return ports;
-    }
-
-    // OvsdbNodeId(IP:port) is used in the adaptor while DeviceId(ovsdb:IP:port)
-    // is used in the core. So DeviceId need be changed to OvsdbNodeId.
-    private OvsdbNodeId changeDeviceIdToNodeId(DeviceId deviceId) {
-        int lastColon = deviceId.toString().lastIndexOf(":");
-        int fistColon = deviceId.toString().indexOf(":");
-        String ip = deviceId.toString().substring(fistColon + 1, lastColon);
-        String port = deviceId.toString().substring(lastColon + 1);
-        IpAddress ipAddress = IpAddress.valueOf(ip);
-        long portL = Long.valueOf(port).longValue();
-        return new OvsdbNodeId(ipAddress, portL);
-    }
-
-    private OvsdbClientService getOvsdbNode(DriverHandler handler) {
-        OvsdbController ovsController = handler.get(OvsdbController.class);
-        DeviceId deviceId = handler.data().deviceId();
-        OvsdbNodeId nodeId = changeDeviceIdToNodeId(deviceId);
-        return ovsController.getOvsdbClient(nodeId);
-    }
-}
+/*
+ * 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.driver.ovsdb;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.onlab.packet.IpAddress;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.behaviour.BridgeConfig;
+import org.onosproject.net.behaviour.BridgeDescription;
+import org.onosproject.net.behaviour.BridgeName;
+import org.onosproject.net.behaviour.DefaultBridgeDescription;
+import org.onosproject.net.device.DefaultPortDescription;
+import org.onosproject.net.device.PortDescription;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.ovsdb.controller.OvsdbBridge;
+import org.onosproject.ovsdb.controller.OvsdbClientService;
+import org.onosproject.ovsdb.controller.OvsdbController;
+import org.onosproject.ovsdb.controller.OvsdbNodeId;
+import org.onosproject.ovsdb.controller.OvsdbPort;
+
+import com.google.common.collect.Sets;
+
+/**
+ * The implementation of BridageConfig.
+ */
+public class OvsdbBridgeConfig extends AbstractHandlerBehaviour
+        implements BridgeConfig {
+
+    @Override
+    public void addBridge(BridgeName bridgeName) {
+        DriverHandler handler = handler();
+        OvsdbClientService clientService = getOvsdbClientService(handler);
+        clientService.createBridge(bridgeName.name());
+    }
+
+    @Override
+    public void deleteBridge(BridgeName bridgeName) {
+        DriverHandler handler = handler();
+        OvsdbClientService clientService = getOvsdbClientService(handler);
+        clientService.dropBridge(bridgeName.name());
+    }
+
+    @Override
+    public Collection<BridgeDescription> getBridges() {
+        DriverHandler handler = handler();
+        DeviceId deviceId = handler.data().deviceId();
+        OvsdbClientService clientService = getOvsdbClientService(handler);
+        Set<OvsdbBridge> ovsdbSet = clientService.getBridges();
+        Collection<BridgeDescription> bridges = Sets.newHashSet();
+        ovsdbSet.forEach(o -> {
+            BridgeName bridgeName = BridgeName
+                    .bridgeName(o.bridgeName().value());
+            DeviceId ownDeviceId = DeviceId.deviceId("of:" + o.datapathId().value());
+            BridgeDescription description = new DefaultBridgeDescription(bridgeName,
+                                                                         deviceId,
+                                                                         ownDeviceId);
+            bridges.add(description);
+        });
+        return bridges == null ? Collections.emptySet() : bridges;
+    }
+
+    @Override
+    public void addPort(PortDescription port) {
+        DriverHandler handler = handler();
+        OvsdbClientService clientService = getOvsdbClientService(handler);
+        Set<OvsdbBridge> ovsdbSet = clientService.getBridges();
+        if (ovsdbSet != null && ovsdbSet.size() > 0) {
+            OvsdbBridge bridge = ovsdbSet.iterator().next();
+            clientService.createPort(bridge.bridgeName().toString(), port
+                    .portNumber().toString());
+        }
+    }
+
+    @Override
+    public void deletePort(PortDescription port) {
+        DriverHandler handler = handler();
+        OvsdbClientService clientService = getOvsdbClientService(handler);
+        Set<OvsdbBridge> ovsdbSet = clientService.getBridges();
+        if (ovsdbSet != null && ovsdbSet.size() > 0) {
+            OvsdbBridge bridge = ovsdbSet.iterator().next();
+            clientService.dropPort(bridge.bridgeName().toString(), port
+                    .portNumber().toString());
+        }
+    }
+
+    @Override
+    public Collection<PortDescription> getPorts() {
+        DriverHandler handler = handler();
+        OvsdbClientService clientService = getOvsdbClientService(handler);
+        Set<OvsdbPort> ovsdbSet = clientService.getPorts();
+        Collection<PortDescription> ports = Sets.newHashSet();
+        ovsdbSet.forEach(o -> {
+            PortNumber port = PortNumber.portNumber(o.portNumber().value());
+            PortDescription description = new DefaultPortDescription(port, true);
+            ports.add(description);
+        });
+        return ports;
+    }
+
+    // OvsdbNodeId(IP:port) is used in the adaptor while DeviceId(ovsdb:IP:port)
+    // is used in the core. So DeviceId need be changed to OvsdbNodeId.
+    private OvsdbNodeId changeDeviceIdToNodeId(DeviceId deviceId) {
+        int lastColon = deviceId.toString().lastIndexOf(":");
+        int fistColon = deviceId.toString().indexOf(":");
+        String ip = deviceId.toString().substring(fistColon + 1, lastColon);
+        String port = deviceId.toString().substring(lastColon + 1);
+        IpAddress ipAddress = IpAddress.valueOf(ip);
+        long portL = Long.valueOf(port).longValue();
+        return new OvsdbNodeId(ipAddress, portL);
+    }
+
+    // Used for getting OvsdbClientService.
+    private OvsdbClientService getOvsdbClientService(DriverHandler handler) {
+        OvsdbController ovsController = handler.get(OvsdbController.class);
+        DeviceId deviceId = handler.data().deviceId();
+        OvsdbNodeId nodeId = changeDeviceIdToNodeId(deviceId);
+        return ovsController.getOvsdbClient(nodeId);
+    }
+
+    @Override
+    public Set<PortNumber> getPortNumbers() {
+        Set<PortNumber> ports = new HashSet<>();
+        DriverHandler handler = handler();
+        OvsdbClientService clientService = getOvsdbClientService(handler);
+        Set<OvsdbPort> ovsdbSet = clientService.getPorts();
+        ovsdbSet.forEach(o -> {
+            PortNumber port = PortNumber.portNumber(o.portNumber().value(),
+                                                    o.portName().value());
+            ports.add(port);
+        });
+        return ports;
+    }
+}
diff --git a/drivers/src/main/resources/onos-drivers.xml b/drivers/src/main/resources/onos-drivers.xml
index 0b4ab43..91741ce 100644
--- a/drivers/src/main/resources/onos-drivers.xml
+++ b/drivers/src/main/resources/onos-drivers.xml
@@ -1,119 +1,119 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  ~ 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.
-  -->
-<drivers>
-    <driver name="default"
-            manufacturer="ON.Lab" hwVersion="0.0.1" swVersion="0.0.1">
-        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
-                   impl="org.onosproject.driver.pipeline.DefaultSingleTablePipeline"/>
-        <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver"
-                   impl="org.onosproject.driver.handshaker.DefaultSwitchHandshaker"/>
-    </driver>
-    <driver name="ovs" extends="default"
-            manufacturer="Nicira, Inc\." hwVersion="Open vSwitch" swVersion="2\..*">
-        <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver"
-                   impl="org.onosproject.driver.handshaker.NiciraSwitchHandshaker"/>
-        <behaviour api="org.onosproject.net.behaviour.TunnelConfig"
-                   impl="org.onosproject.driver.ovsdb.OvsdbTunnelConfig"/>
-        <behaviour api="org.onosproject.net.behaviour.BridgeConfig"
-                   impl="org.onosproject.driver.ovsdb.OvsdbBridgeConfig"/>
-    </driver>
-    <driver name="ovs-corsa" extends="ovs"
-            manufacturer="Corsa" hwVersion="emulation" swVersion="0.0.0">
-        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
-                   impl="org.onosproject.driver.pipeline.OVSCorsaPipeline"/>
-    </driver>
-    <driver name="spring-open-cpqd" extends="default"
-            manufacturer="Stanford University, Ericsson Research and CPqD Research" 
-            hwVersion="OpenFlow 1.3 Reference Userspace Switch" swVersion=".*">
-        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
-                   impl="org.onosproject.driver.pipeline.SpringOpenTTP"/>
-    </driver>
-    <driver name="spring-open" extends="default"
-            manufacturer="Dell " hwVersion="OpenFlow switch HW ver. 1.0" 
-            swVersion="OpenFlow switch SW ver. 1.0 and 1.3">
-        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
-                   impl="org.onosproject.driver.pipeline.SpringOpenTTPDell"/>
-    </driver>
-    <driver name="linc-oe" extends="default"
-            manufacturer="FlowForwarding.org" hwVersion="Unknown" 
-            swVersion="LINC-OE OpenFlow Software Switch 1.1">
-        <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver"
-                   impl="org.onosproject.driver.handshaker.OFOpticalSwitchImplLINC13"/>
-    </driver>
-    <driver name="corsa"
-            manufacturer="Corsa" hwVersion="Corsa Element" swVersion="2.3.1">
-        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
-                   impl="org.onosproject.driver.pipeline.CorsaPipeline"/>
-        <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver"
-                   impl="org.onosproject.driver.handshaker.CorsaSwitchHandshaker"/>
-    </driver>
-    <driver name="ofdpa" extends="default"
-            manufacturer="Broadcom Corp." hwVersion="OF-DPA.*" swVersion="OF-DPA.*">
-        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
-                   impl="org.onosproject.driver.pipeline.OFDPA1Pipeline"/>
-    </driver>
-    <driver name="pmc-olt" extends="default"
-            manufacturer="Big Switch Networks" hwVersion="ivs 0.5" swVersion="ivs 0.5">
-        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
-                   impl="org.onosproject.driver.pipeline.OLTPipeline"/>
-    </driver>
-    <driver name="g.fast" extends="default"
-            manufacturer="TEST1" hwVersion="TEST2" swVersion="TEST3">
-        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
-                   impl="org.onosproject.driver.pipeline.OLTPipeline"/>
-    </driver>
-    <!--  The SoftRouter driver is meant to be used by any software/NPU based
-       ~  switch that wishes to implement a simple 2-table router. To use this
-       ~  driver, configure ONOS with the dpid of the device, or extend the
-       ~  driver declaration with the manufacturer/hwVersion/swVersion of the
-       ~  device (see 'noviflow' example).
-      -->
-    <driver name="softrouter" extends="default"
-            manufacturer="Various" hwVersion="various" swVersion="0.0.0">
-        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
-                   impl="org.onosproject.driver.pipeline.SoftRouterPipeline"/>
-    </driver>
-    <driver name="centec-V350" extends="default"
-            manufacturer=".*Centec.*" hwVersion=".*" swVersion="3.1.*">
-        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
-                   impl="org.onosproject.driver.pipeline.CentecV350Pipeline"/>
-    </driver>
-    <driver name="pica" extends="default"
-            manufacturer="Pica8, Inc." hwVersion=".*" swVersion="PicOS 2.6">
-        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
-                   impl="org.onosproject.driver.pipeline.PicaPipeline"/>
-    </driver>
-    <driver name="noviflow" extends="softrouter"
-            manufacturer="NoviFlow Inc" hwVersion="NS.*" swVersion="NW.*">
-    </driver>
-    <!--  Emulation of the ofdpa pipeline using a CPqD OF 1.3 software switch.
-       ~  To use this driver, configure ONOS with the dpid of the device.
-      -->
-    <driver name="ofdpa-cpqd" extends="default"
-            manufacturer="ONF"
-            hwVersion="OF1.3 Software Switch from CPqD" swVersion="for Group Chaining">
-        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
-                   impl="org.onosproject.driver.pipeline.CpqdOFDPA1Pipeline"/>
-    </driver>
-    <driver name="calient" extends="default"
-            manufacturer="calient inc" hwVersion="calient hardware"
-            swVersion="ocs switch">
-        <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver"
-                   impl="org.onosproject.driver.handshaker.CalientFiberSwitchHandshaker"/>
-    </driver>
-</drivers>
-
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+<drivers>
+    <driver name="default"
+            manufacturer="ON.Lab" hwVersion="0.0.1" swVersion="0.0.1">
+        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
+                   impl="org.onosproject.driver.pipeline.OpenVSwitchPipeline"/>
+        <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver"
+                   impl="org.onosproject.driver.handshaker.DefaultSwitchHandshaker"/>
+                   <behaviour api="org.onosproject.net.behaviour.TunnelConfig"
+                   impl="org.onosproject.driver.ovsdb.OvsdbTunnelConfig"/>
+                   <behaviour api="org.onosproject.net.behaviour.BridgeConfig"
+                   impl="org.onosproject.driver.ovsdb.OvsdbBridgeConfig"/>
+    </driver>
+    <driver name="ovs" extends="default"
+            manufacturer="Nicira, Inc\." hwVersion="Open vSwitch" swVersion="2\..*">
+        <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver"
+                   impl="org.onosproject.driver.handshaker.NiciraSwitchHandshaker"/>
+    </driver>
+    <driver name="ovs-corsa" extends="ovs"
+            manufacturer="Corsa" hwVersion="emulation" swVersion="0.0.0">
+        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
+                   impl="org.onosproject.driver.pipeline.OVSCorsaPipeline"/>
+    </driver>
+    <driver name="spring-open-cpqd" extends="default"
+            manufacturer="Stanford University, Ericsson Research and CPqD Research" 
+            hwVersion="OpenFlow 1.3 Reference Userspace Switch" swVersion=".*">
+        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
+                   impl="org.onosproject.driver.pipeline.SpringOpenTTP"/>
+    </driver>
+    <driver name="spring-open" extends="default"
+            manufacturer="Dell " hwVersion="OpenFlow switch HW ver. 1.0" 
+            swVersion="OpenFlow switch SW ver. 1.0 and 1.3">
+        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
+                   impl="org.onosproject.driver.pipeline.SpringOpenTTPDell"/>
+    </driver>
+    <driver name="linc-oe" extends="default"
+            manufacturer="FlowForwarding.org" hwVersion="Unknown" 
+            swVersion="LINC-OE OpenFlow Software Switch 1.1">
+        <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver"
+                   impl="org.onosproject.driver.handshaker.OFOpticalSwitchImplLINC13"/>
+    </driver>
+    <driver name="corsa"
+            manufacturer="Corsa" hwVersion="Corsa Element" swVersion="2.3.1">
+        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
+                   impl="org.onosproject.driver.pipeline.CorsaPipeline"/>
+        <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver"
+                   impl="org.onosproject.driver.handshaker.CorsaSwitchHandshaker"/>
+    </driver>
+    <driver name="ofdpa" extends="default"
+            manufacturer="Broadcom Corp." hwVersion="OF-DPA.*" swVersion="OF-DPA.*">
+        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
+                   impl="org.onosproject.driver.pipeline.OFDPA1Pipeline"/>
+    </driver>
+    <driver name="pmc-olt" extends="default"
+            manufacturer="Big Switch Networks" hwVersion="ivs 0.5" swVersion="ivs 0.5">
+        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
+                   impl="org.onosproject.driver.pipeline.OLTPipeline"/>
+    </driver>
+    <driver name="g.fast" extends="default"
+            manufacturer="TEST1" hwVersion="TEST2" swVersion="TEST3">
+        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
+                   impl="org.onosproject.driver.pipeline.OLTPipeline"/>
+    </driver>
+    <!--  The SoftRouter driver is meant to be used by any software/NPU based
+       ~  switch that wishes to implement a simple 2-table router. To use this
+       ~  driver, configure ONOS with the dpid of the device, or extend the
+       ~  driver declaration with the manufacturer/hwVersion/swVersion of the
+       ~  device (see 'noviflow' example).
+      -->
+    <driver name="softrouter" extends="default"
+            manufacturer="Various" hwVersion="various" swVersion="0.0.0">
+        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
+                   impl="org.onosproject.driver.pipeline.SoftRouterPipeline"/>
+    </driver>
+    <driver name="centec-V350" extends="default"
+            manufacturer=".*Centec.*" hwVersion=".*" swVersion="3.1.*">
+        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
+                   impl="org.onosproject.driver.pipeline.CentecV350Pipeline"/>
+    </driver>
+    <driver name="pica" extends="default"
+            manufacturer="Pica8, Inc." hwVersion=".*" swVersion="PicOS 2.6">
+        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
+                   impl="org.onosproject.driver.pipeline.PicaPipeline"/>
+    </driver>
+    <driver name="noviflow" extends="softrouter"
+            manufacturer="NoviFlow Inc" hwVersion="NS.*" swVersion="NW.*">
+    </driver>
+    <!--  Emulation of the ofdpa pipeline using a CPqD OF 1.3 software switch.
+       ~  To use this driver, configure ONOS with the dpid of the device.
+      -->
+    <driver name="ofdpa-cpqd" extends="default"
+            manufacturer="ONF"
+            hwVersion="OF1.3 Software Switch from CPqD" swVersion="for Group Chaining">
+        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
+                   impl="org.onosproject.driver.pipeline.CpqdOFDPA1Pipeline"/>
+    </driver>
+    <driver name="calient" extends="default"
+            manufacturer="calient inc" hwVersion="calient hardware"
+            swVersion="ocs switch">
+        <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver"
+                   impl="org.onosproject.driver.handshaker.CalientFiberSwitchHandshaker"/>
+    </driver>
+</drivers>
+
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
index 74f4539..7559715 100644
--- 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
@@ -1,1056 +1,1128 @@
-/*
- * 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.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) {
-        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()) {
-                Row row = ovsTableRows.get(uuid);
-                String tableName = row.tableName();
-                if (tableName.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 childUuid 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 childTableName child table name
-     * @param childColumnName child column name
-     * @param parentTableName parent table name
-     * @param parentColumnName parent column
-     * @param parentUuid parent uuid
-     * @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.name()).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);
-    }
-
-}
+/*
+ * 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.Iterator;
+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.OvsdbBridgeName;
+import org.onosproject.ovsdb.controller.OvsdbClientService;
+import org.onosproject.ovsdb.controller.OvsdbConstant;
+import org.onosproject.ovsdb.controller.OvsdbDatapathId;
+import org.onosproject.ovsdb.controller.OvsdbNodeId;
+import org.onosproject.ovsdb.controller.OvsdbPort;
+import org.onosproject.ovsdb.controller.OvsdbPortName;
+import org.onosproject.ovsdb.controller.OvsdbPortNumber;
+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.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<OvsdbTunnel> ovsdbTunnels = new HashSet<OvsdbTunnel>();
+
+    /**
+     * 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());
+                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());
+                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) {
+        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()) {
+                Row row = ovsTableRows.get(uuid);
+                String tableName = row.tableName();
+                if (tableName.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) {
+
+            Interface tunInterface = (Interface) TableGenerator
+                    .createTable(dbSchema, 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 childUuid 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 childTableName child table name
+     * @param childColumnName child column name
+     * @param parentTableName parent table name
+     * @param parentColumnName parent column
+     * @param parentUuid parent uuid
+     * @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.name()).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) {
+                return Futures.transform(input, rowFunction);
+            }
+            return null;
+        } 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() {
+        Set<OvsdbBridge> ovsdbBridges = new HashSet<OvsdbBridge>();
+        OvsdbTableStore tableStore = getTableStore(OvsdbConstant.DATABASENAME);
+        if (tableStore == null) {
+            return null;
+        }
+        OvsdbRowStore rowStore = tableStore.getRows(OvsdbConstant.BRIDGE);
+        if (rowStore == null) {
+            return null;
+        }
+        ConcurrentMap<String, Row> rows = rowStore.getRowStore();
+        for (String uuid : rows.keySet()) {
+            Row row = getRow(OvsdbConstant.DATABASENAME, OvsdbConstant.BRIDGE,
+                             uuid);
+            OvsdbBridge ovsdbBridge = getOvsdbBridge(row);
+            if (ovsdbBridge != null) {
+                ovsdbBridges.add(ovsdbBridge);
+            }
+        }
+        return ovsdbBridges;
+    }
+
+    @Override
+    public Set<OvsdbPort> getPorts() {
+        Set<OvsdbPort> ovsdbPorts = new HashSet<OvsdbPort>();
+        OvsdbTableStore tableStore = getTableStore(OvsdbConstant.DATABASENAME);
+        if (tableStore == null) {
+            return null;
+        }
+        OvsdbRowStore rowStore = tableStore.getRows(OvsdbConstant.INTERFACE);
+        if (rowStore == null) {
+            return null;
+        }
+        ConcurrentMap<String, Row> rows = rowStore.getRowStore();
+        for (String uuid : rows.keySet()) {
+            Row row = getRow(OvsdbConstant.DATABASENAME,
+                             OvsdbConstant.INTERFACE, uuid);
+            OvsdbPort ovsdbPort = getOvsdbPort(row);
+            if (ovsdbPort != null) {
+                ovsdbPorts.add(ovsdbPort);
+            }
+        }
+        return ovsdbPorts;
+    }
+
+    @Override
+    public DatabaseSchema getDatabaseSchema(String dbName) {
+        return schema.get(dbName);
+    }
+
+    //Gets ovsdb port.
+    private OvsdbPort getOvsdbPort(Row row) {
+        DatabaseSchema dbSchema = getDatabaseSchema(OvsdbConstant.DATABASENAME);
+        Interface intf = (Interface) TableGenerator
+                .getTable(dbSchema, row, OvsdbTable.INTERFACE);
+        if (intf == null) {
+            return null;
+        }
+        long ofPort = getOfPort(intf);
+        String portName = intf.getName();
+        if ((ofPort < 0) || (portName == null)) {
+            return null;
+        }
+
+        OvsdbPort ovsdbPort = new OvsdbPort(new OvsdbPortNumber(ofPort),
+                                            new OvsdbPortName(portName));
+        return ovsdbPort;
+    }
+
+    ////Gets ovsdb bridge.
+    private OvsdbBridge getOvsdbBridge(Row row) {
+        DatabaseSchema dbSchema = getDatabaseSchema(OvsdbConstant.DATABASENAME);
+        Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, row,
+                                                         OvsdbTable.BRIDGE);
+        if (bridge == null) {
+            return null;
+        }
+
+        OvsdbSet datapathIdSet = (OvsdbSet) bridge.getDatapathIdColumn().data();
+        @SuppressWarnings("unchecked")
+        Set<String> datapathIds = datapathIdSet.set();
+        if (datapathIds == null || datapathIds.size() == 0) {
+            return null;
+        }
+        String datapathId = (String) datapathIds.toArray()[0];
+        String bridgeName = bridge.getName();
+        if ((datapathId == null) || (bridgeName == null)) {
+            return null;
+        }
+
+        OvsdbBridge ovsdbBridge = new OvsdbBridge(new OvsdbBridgeName(bridgeName),
+                                                  new OvsdbDatapathId(datapathId));
+        return ovsdbBridge;
+    }
+
+    //Gets ofPort in the interface.
+    private long getOfPort(Interface intf) {
+        OvsdbSet ofPortSet = (OvsdbSet) intf.getOpenFlowPortColumn().data();
+        @SuppressWarnings("unchecked")
+        Set<Integer> ofPorts = ofPortSet.set();
+        while (ofPorts == null || ofPorts.size() <= 0) {
+            log.debug("The ofport is null in {}", intf.getName());
+            return -1;
+        }
+        // return (long) ofPorts.toArray()[0];
+        Iterator<Integer> it = ofPorts.iterator();
+        return Long.parseLong(it.next().toString());
+    }
+}
