ONOS-2708
Add implementation of getting ovsdb ports or bridges in the ovsdb node.

Change-Id: If31af08ccb90a29bc800a79f332dae2bc497b105
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());

+    }

+}