aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject')
-rw-r--r--framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/DefaultEventSubject.java126
-rw-r--r--framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/EventSubject.java22
-rw-r--r--framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbBridge.java88
-rw-r--r--framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbBridgeName.java72
-rw-r--r--framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbClientService.java301
-rw-r--r--framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbConstant.java68
-rw-r--r--framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbController.java79
-rw-r--r--framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbDatapathId.java69
-rw-r--r--framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbEvent.java74
-rw-r--r--framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbEventListener.java28
-rw-r--r--framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbEventSubject.java75
-rw-r--r--framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbIfaceId.java69
-rw-r--r--framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbNodeId.java83
-rw-r--r--framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbNodeListener.java36
-rw-r--r--framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPort.java86
-rw-r--r--framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPortName.java71
-rw-r--r--framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPortNumber.java69
-rw-r--r--framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPortType.java71
-rw-r--r--framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbRowStore.java69
-rw-r--r--framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbStore.java71
-rw-r--r--framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbTableStore.java67
-rw-r--r--framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbTunnel.java126
-rw-r--r--framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbTunnelName.java70
-rw-r--r--framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/DefaultOvsdbClient.java1503
-rw-r--r--framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/OvsdbAgent.java42
-rw-r--r--framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/OvsdbProviderService.java81
-rw-r--r--framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/package-info.java20
-rw-r--r--framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/package-info.java20
28 files changed, 3556 insertions, 0 deletions
diff --git a/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/DefaultEventSubject.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/DefaultEventSubject.java
new file mode 100644
index 00000000..5d9134b4
--- /dev/null
+++ b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/DefaultEventSubject.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.controller;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+import java.util.Set;
+
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+
+/**
+ * This class is default event subject that implements OvsdbEventSubject.
+ */
+public class DefaultEventSubject implements OvsdbEventSubject {
+ private final MacAddress mac;
+ private final Set<IpAddress> ips;
+ private final OvsdbPortName portname;
+ private final OvsdbPortNumber portnumber;
+ private final OvsdbDatapathId dpid;
+ private final OvsdbPortType portType;
+ private final OvsdbIfaceId ifaceid;
+
+ /**
+ * Creates an end-station event subject using the supplied information.
+ *
+ * @param mac host MAC address
+ * @param ips host MAC ips
+ * @param portname port name
+ * @param portnumber port number
+ * @param dpid ovs dpid
+ * @param portType port type
+ * @param ifaceid vm ifaceid
+ */
+ public DefaultEventSubject(MacAddress mac, Set<IpAddress> ips,
+ OvsdbPortName portname, OvsdbPortNumber portnumber, OvsdbDatapathId dpid,
+ OvsdbPortType portType, OvsdbIfaceId ifaceid) {
+ super();
+ this.mac = mac;
+ this.ips = ips;
+ this.portname = portname;
+ this.portnumber = portnumber;
+ this.dpid = dpid;
+ this.portType = portType;
+ this.ifaceid = ifaceid;
+ }
+
+ @Override
+ public MacAddress hwAddress() {
+ return mac;
+ }
+
+ @Override
+ public Set<IpAddress> ipAddress() {
+ return ips;
+ }
+
+ @Override
+ public OvsdbPortName portName() {
+ return portname;
+ }
+
+ @Override
+ public OvsdbPortNumber portNumber() {
+ return portnumber;
+ }
+
+ @Override
+ public OvsdbPortType portType() {
+ return portType;
+ }
+
+ @Override
+ public OvsdbDatapathId dpid() {
+ return dpid;
+ }
+
+ @Override
+ public OvsdbIfaceId ifaceid() {
+ return ifaceid;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mac, portname, portnumber, dpid, portType, ifaceid);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof DefaultEventSubject) {
+ final DefaultEventSubject other = (DefaultEventSubject) obj;
+ return Objects.equals(this.mac, other.mac)
+ && Objects.equals(this.portname, other.portname)
+ && Objects.equals(this.portnumber, other.portnumber)
+ && Objects.equals(this.dpid, other.dpid)
+ && Objects.equals(this.portType, other.portType)
+ && Objects.equals(this.ifaceid, other.ifaceid);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this).add("mac", mac).add("portname", portname)
+ .add("portnumber", portnumber).add("portType", portType)
+ .add("ipAddresses", ips).add("dpid", dpid).add("ifaceid", ifaceid)
+ .toString();
+ }
+}
diff --git a/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/EventSubject.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/EventSubject.java
new file mode 100644
index 00000000..d8aaef65
--- /dev/null
+++ b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/EventSubject.java
@@ -0,0 +1,22 @@
+/*
+ * 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;
+
+/**
+ * Representation for an entity that carries important information for a listener.
+ */
+public interface EventSubject {
+}
diff --git a/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbBridge.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbBridge.java
new file mode 100644
index 00000000..18c59e14
--- /dev/null
+++ b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbBridge.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.controller;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Objects;
+
+/**
+ * The class representing an ovsdb bridge.
+ * This class is immutable.
+ */
+public final class OvsdbBridge {
+
+ private final OvsdbBridgeName bridgeName;
+ private final OvsdbDatapathId datapathId;
+
+ /**
+ * Constructor from an OvsdbBridgeName bridgeName and an OvsdbDatapathId
+ * datapathId.
+ *
+ * @param bridgeName the bridgeName to use
+ * @param datapathId the datapathId to use
+ */
+ public OvsdbBridge(OvsdbBridgeName bridgeName, OvsdbDatapathId datapathId) {
+ checkNotNull(bridgeName, "bridgeName is not null");
+ checkNotNull(datapathId, "datapathId is not null");
+ this.bridgeName = bridgeName;
+ this.datapathId = datapathId;
+ }
+
+ /**
+ * Gets the bridge name of bridge.
+ *
+ * @return the bridge name of bridge
+ */
+ public OvsdbBridgeName bridgeName() {
+ return bridgeName;
+ }
+
+ /**
+ * Gets the datapathId of bridge.
+ *
+ * @return datapathId the datapathId to use
+ */
+ public OvsdbDatapathId datapathId() {
+ return datapathId;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(bridgeName, datapathId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof OvsdbBridge) {
+ final OvsdbBridge otherOvsdbBridge = (OvsdbBridge) obj;
+ return Objects.equals(this.bridgeName, otherOvsdbBridge.bridgeName)
+ && Objects.equals(this.datapathId,
+ otherOvsdbBridge.datapathId);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this).add("bridgeName", bridgeName.value())
+ .add("datapathId", datapathId.value()).toString();
+ }
+}
diff --git a/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbBridgeName.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbBridgeName.java
new file mode 100644
index 00000000..759ec499
--- /dev/null
+++ b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbBridgeName.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.controller;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Objects;
+
+/**
+ * The class representing a bridge name.
+ * This class is immutable.
+ */
+public final class OvsdbBridgeName {
+
+ private final String value;
+
+ /**
+ * Constructor from a String.
+ *
+ * @param value the bridge name to use
+ */
+ public OvsdbBridgeName(String value) {
+ checkNotNull(value, "value is not null");
+ this.value = value;
+ }
+
+ /**
+ * Gets the value of bridge name.
+ *
+ * @return the value of the bridge name
+ */
+ public String value() {
+ return value;
+ }
+
+ @Override
+ public int hashCode() {
+ return value.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof OvsdbBridgeName) {
+ final OvsdbBridgeName otherBridgeName = (OvsdbBridgeName) obj;
+ return Objects.equals(this.value, otherBridgeName.value);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this).add("value", value).toString();
+ }
+
+}
diff --git a/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbClientService.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbClientService.java
new file mode 100644
index 00000000..a35fa6cf
--- /dev/null
+++ b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbClientService.java
@@ -0,0 +1,301 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.controller;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+import org.onlab.packet.IpAddress;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.behaviour.ControllerInfo;
+import org.onosproject.ovsdb.rfc.jsonrpc.OvsdbRPC;
+import org.onosproject.ovsdb.rfc.message.OperationResult;
+import org.onosproject.ovsdb.rfc.message.TableUpdates;
+import org.onosproject.ovsdb.rfc.notation.Row;
+import org.onosproject.ovsdb.rfc.notation.UUID;
+import org.onosproject.ovsdb.rfc.operations.Operation;
+import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Represents to provider facing side of a node.
+ */
+public interface OvsdbClientService extends OvsdbRPC {
+ /**
+ * Gets the node identifier.
+ *
+ * @return node identifier
+ */
+ OvsdbNodeId nodeId();
+
+ /**
+ * Creates the configuration for tunnel.
+ *
+ * @param srcIp source IP address
+ * @param dstIp destination IP address
+ */
+ @Deprecated
+ void createTunnel(IpAddress srcIp, IpAddress dstIp);
+
+ /**
+ * Creates a tunnel port with given options.
+ *
+ * @param bridgeName bridge name
+ * @param portName port name
+ * @param tunnelType tunnel type
+ * @param options tunnel options
+ * @return true if tunnel creation is successful, false otherwise
+ */
+ boolean createTunnel(String bridgeName, String portName, String tunnelType, Map<String, String> options);
+
+ /**
+ * Drops the configuration for tunnel.
+ *
+ * @param srcIp source IP address
+ * @param dstIp destination IP address
+ */
+ void dropTunnel(IpAddress srcIp, IpAddress dstIp);
+
+ /**
+ * Gets tunnels of node.
+ *
+ * @return set of tunnels; empty if no tunnel is find
+ */
+ Set<OvsdbTunnel> getTunnels();
+
+ /**
+ * Creates a bridge.
+ *
+ * @param bridgeName bridge name
+ */
+ void createBridge(String bridgeName);
+
+ /**
+ * Creates a bridge.
+ *
+ * @param bridgeName bridge name
+ * @param dpid data path id
+ * @param exPortName external port name
+ */
+ void createBridge(String bridgeName, String dpid, String exPortName);
+
+ /**
+ * Creates a bridge with given name and dpid.
+ * Sets the bridge's controller with given controllers.
+ *
+ * @param bridgeName bridge name
+ * @param dpid data path id
+ * @param controllers controllers
+ * @return true if bridge creation is successful, false otherwise
+ */
+ boolean createBridge(String bridgeName, String dpid, List<ControllerInfo> controllers);
+
+ /**
+ * Drops a bridge.
+ *
+ * @param bridgeName bridge name
+ */
+ void dropBridge(String bridgeName);
+
+ /**
+ * Gets bridges of node.
+ *
+ * @return set of bridges; empty if no bridge is find
+ */
+ Set<OvsdbBridge> getBridges();
+
+ /**
+ * Gets controllers of node.
+ *
+ * @param openflowDeviceId target device id
+ * @return set of controllers; empty if no controller is find
+ */
+ Set<ControllerInfo> getControllers(DeviceId openflowDeviceId);
+
+ /**
+ * Sets the Controllers for the specified bridge.
+ * <p>
+ * This method will replace the existing controller list with the new controller
+ * list.
+ *
+ * @param bridgeUuid bridge uuid
+ * @param controllers list of controllers
+ */
+ void setControllersWithUUID(UUID bridgeUuid, List<ControllerInfo> controllers);
+
+ /**
+ * Sets the Controllers for the specified device.
+ * <p>
+ * This method will replace the existing controller list with the new controller
+ * list.
+ *
+ * @param deviceId device id (likely Openflow device)
+ * @param controllers list of controllers
+ */
+ void setControllersWithDeviceId(DeviceId deviceId, List<ControllerInfo> controllers);
+
+ /**
+ * Creates a port.
+ *
+ * @param bridgeName bridge name
+ * @param portName port name
+ */
+ void createPort(String bridgeName, String portName);
+
+ /**
+ * Drops a port.
+ *
+ * @param bridgeName bridge name
+ * @param portName port name
+ */
+ void dropPort(String bridgeName, String portName);
+
+ /**
+ * Gets ports of bridge.
+ *
+ * @return set of ports; empty if no ports is find
+ */
+ Set<OvsdbPort> getPorts();
+
+ /**
+ * Checks if the node is still connected.
+ *
+ * @return true if the node is still connected
+ */
+ boolean isConnected();
+
+ /**
+ * Gets the Bridge uuid.
+ *
+ * @param bridgeName bridge name
+ * @return bridge uuid, empty if no uuid is find
+ */
+ String getBridgeUuid(String bridgeName);
+
+ /**
+ * Gets the Port uuid.
+ *
+ * @param portName port name
+ * @param bridgeUuid bridge uuid
+ * @return port uuid, empty if no uuid is find
+ */
+ String getPortUuid(String portName, String bridgeUuid);
+
+ /**
+ * Gets the Interface uuid.
+ *
+ * @param portUuid port uuid
+ * @param portName port name
+ * @return interface uuid, empty if no uuid is find
+ */
+ String getInterfaceUuid(String portUuid, String portName);
+
+ /**
+ * Gets the Controller uuid.
+ *
+ * @param controllerName controller name
+ * @param controllerTarget controller target
+ * @return controller uuid, empty if no uuid is find
+ */
+ String getControllerUuid(String controllerName, String controllerTarget);
+
+ /**
+ * Gets the OVS uuid.
+ *
+ * @param dbName database name
+ * @return ovs uuid, empty if no uuid is find
+ */
+ String getOvsUuid(String dbName);
+
+ /**
+ * Gets the OVSDB database schema.
+ *
+ * @param dbName database name
+ * @return database schema
+ */
+ ListenableFuture<DatabaseSchema> getOvsdbSchema(String dbName);
+
+ /**
+ * Gets the OVSDB table updates.
+ *
+ * @param dbName database name
+ * @param id random uuid
+ * @return table updates
+ */
+ ListenableFuture<TableUpdates> monitorTables(String dbName, String id);
+
+ /**
+ * Gets the OVSDB config operation result.
+ *
+ * @param dbName database name
+ * @param operations the list of operations
+ * @return operation results
+ */
+ ListenableFuture<List<OperationResult>> transactConfig(String dbName,
+ List<Operation> operations);
+
+ /**
+ * Gets the OVSDB database schema from local.
+ *
+ * @param dbName database name
+ * @return database schema
+ */
+ DatabaseSchema getDatabaseSchema(String dbName);
+
+ /**
+ * Gets the OVSDB row from local OVSDB store.
+ *
+ * @param dbName database name
+ * @param tableName table name
+ * @param uuid row uuid
+ * @return row OVSDB row
+ */
+ Row getRow(String dbName, String tableName, String uuid);
+
+ /**
+ * Removes the OVSDB row from local OVSDB store.
+ *
+ * @param dbName database name
+ * @param tableName table name
+ * @param uuid row uuid
+ */
+ void removeRow(String dbName, String tableName, String uuid);
+
+ /**
+ * Updates the local OVSDB store.
+ *
+ * @param dbName database name
+ * @param tableName table name
+ * @param uuid row uuid
+ * @param row OVSDB row
+ */
+ void updateOvsdbStore(String dbName, String tableName, String uuid, Row row);
+
+ /**
+ * Gets OVSDB local ports.
+ *
+ * @param ifaceids the ifaceid that needed
+ * @return OVSDB ports
+ */
+ Set<OvsdbPort> getLocalPorts(Iterable<String> ifaceids);
+
+ /**
+ * Disconnects the OVSDB server.
+ */
+ void disconnect();
+}
diff --git a/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbConstant.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbConstant.java
new file mode 100644
index 00000000..e91c928a
--- /dev/null
+++ b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbConstant.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.controller;
+
+/**
+ * Ovsdb related constants.
+ */
+public final class OvsdbConstant {
+
+ /**
+ * Default constructor.
+ *
+ * The constructor is private to prevent creating an instance of this
+ * utility class.
+ */
+ private OvsdbConstant() {
+ }
+
+ /** Ovsdb database Open_vSwitch. */
+ public static final String DATABASENAME = "Open_vSwitch";
+
+ /** Ovsdb table Bridge. */
+ public static final String BRIDGE = "Bridge";
+
+ /** Ovsdb table Interface. */
+ public static final String INTERFACE = "Interface";
+
+ /** Ovsdb table Controller. */
+ public static final String CONTROLLER = "Controller";
+
+ /** Ovsdb table Port. */
+ public static final String PORT = "Port";
+
+ /** Ovsdb bridge name. */
+ public static final String INTEGRATION_BRIDGE = "br-int";
+
+ /** Ovsdb vxlan tunnel type. */
+ public static final String TYPEVXLAN = "vxlan";
+
+ /** Openflow version. */
+ public static final String OPENFLOW13 = "OpenFlow13";
+
+ /** Ovsdb external_id_interface_id.. */
+ public static final String EXTERNAL_ID_INTERFACE_ID = "iface-id";
+
+ /** Ovsdb external_id_vm_mac. */
+ public static final String EXTERNAL_ID_VM_MAC = "attached-mac";
+
+ /** Openflow port. */
+ public static final int OFPORT = 6653;
+
+ /** Ovsdb port. */
+ public static final int OVSDBPORT = 6640;
+
+}
diff --git a/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbController.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbController.java
new file mode 100644
index 00000000..f22a5787
--- /dev/null
+++ b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbController.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.controller;
+
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.TpPort;
+
+import java.util.List;
+
+/**
+ * Abstraction of an ovsdb controller. Serves as an one stop shop for obtaining
+ * OvsdbNode and (un)register listeners on ovsdb events and ovsdb node events.
+ */
+public interface OvsdbController {
+
+ /**
+ * Adds Node Event Listener.
+ *
+ * @param listener node listener
+ */
+ void addNodeListener(OvsdbNodeListener listener);
+
+ /**
+ * Removes Node Event Listener.
+ *
+ * @param listener node listener
+ */
+ void removeNodeListener(OvsdbNodeListener listener);
+
+ /**
+ * Adds ovsdb event listener.
+ *
+ * @param listener event listener
+ */
+ void addOvsdbEventListener(OvsdbEventListener listener);
+
+ /**
+ * Removes ovsdb event listener.
+ *
+ * @param listener event listener
+ */
+ void removeOvsdbEventListener(OvsdbEventListener listener);
+
+ /**
+ * Gets all the nodes information.
+ *
+ * @return the list of node id
+ */
+ List<OvsdbNodeId> getNodeIds();
+
+ /**
+ * Gets an ovsdb client by node identifier.
+ *
+ * @param nodeId node identifier
+ * @return OvsdbClient ovsdb node information
+ */
+ OvsdbClientService getOvsdbClient(OvsdbNodeId nodeId);
+
+ /**
+ * Connect to the ovsdb server with given ip address and port number.
+ *
+ * @param ip ip address
+ * @param port port number
+ */
+ void connect(IpAddress ip, TpPort port);
+}
diff --git a/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbDatapathId.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbDatapathId.java
new file mode 100644
index 00000000..02989afa
--- /dev/null
+++ b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbDatapathId.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.controller;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+import java.util.Objects;
+
+/**
+ * The class representing a datapathid.
+ * This class is immutable.
+ */
+public final class OvsdbDatapathId {
+ private final String value;
+
+ /**
+ * Constructor from a String.
+ *
+ * @param value the datapathid to use
+ */
+ public OvsdbDatapathId(String value) {
+ checkNotNull(value, "value is not null");
+ this.value = value;
+ }
+
+ /**
+ * Gets the value of datapathid.
+ *
+ * @return the value of datapathid
+ */
+ public String value() {
+ return value;
+ }
+
+ @Override
+ public int hashCode() {
+ return value.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof OvsdbDatapathId) {
+ final OvsdbDatapathId otherDatapathId = (OvsdbDatapathId) obj;
+ return Objects.equals(this.value, otherDatapathId.value);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this).add("value", value).toString();
+ }
+}
diff --git a/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbEvent.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbEvent.java
new file mode 100644
index 00000000..f68b3c8a
--- /dev/null
+++ b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbEvent.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.controller;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * The abstract event of ovsdb.
+ */
+public final class OvsdbEvent<S> {
+
+ public enum Type {
+ /**
+ * Signifies that a new ovs port update has been detected.
+ */
+ PORT_ADDED,
+ /**
+ * Signifies that a ovs port has been removed.
+ */
+ PORT_REMOVED
+ }
+
+ private final Type type;
+ private final S subject;
+
+ /**
+ * Creates an event of a given type and for the specified event subject.
+ *
+ * @param type event type
+ * @param subject event subject
+ */
+ public OvsdbEvent(Type type, S subject) {
+ this.type = type;
+ this.subject = subject;
+ }
+
+ /**
+ * Returns the type of event.
+ *
+ * @return event type
+ */
+ public Type type() {
+ return type;
+ }
+
+ /**
+ * Returns the subject of event.
+ *
+ * @return subject to which this event pertains
+ */
+ public S subject() {
+ return subject;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this).add("type", type())
+ .add("subject", subject()).toString();
+ }
+
+}
diff --git a/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbEventListener.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbEventListener.java
new file mode 100644
index 00000000..b7bf2b55
--- /dev/null
+++ b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbEventListener.java
@@ -0,0 +1,28 @@
+/*
+ * 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;
+
+/**
+ * Allows for providers interested in ovsdb events to be notified.
+ */
+public interface OvsdbEventListener {
+ /**
+ * Handles the ovsdb event.
+ *
+ * @param event ovsdb event
+ */
+ void handle(OvsdbEvent<EventSubject> event);
+}
diff --git a/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbEventSubject.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbEventSubject.java
new file mode 100644
index 00000000..226a26e6
--- /dev/null
+++ b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbEventSubject.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.controller;
+
+import java.util.Set;
+
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+
+/**
+ * Represents for an entity that carry important information for listener.
+ */
+public interface OvsdbEventSubject extends EventSubject {
+ /**
+ * Returns the MAC address associated with this host (NIC).
+ *
+ * @return the MAC address of this host
+ */
+ MacAddress hwAddress();
+
+ /**
+ * Returns the IP address associated with this host's MAC.
+ *
+ * @return host IP address
+ */
+ Set<IpAddress> ipAddress();
+
+ /**
+ * Returns the Port name associated with the host.
+ *
+ * @return port name
+ */
+ OvsdbPortName portName();
+
+ /**
+ * Returns the Port number associated with the host.
+ *
+ * @return port number
+ */
+ OvsdbPortNumber portNumber();
+
+ /**
+ * Returns the Port type associated with the host.
+ *
+ * @return port type
+ */
+ OvsdbPortType portType();
+
+ /**
+ * Returns the Ovs dpid associated with the host.
+ *
+ * @return Ovs dpid
+ */
+ OvsdbDatapathId dpid();
+
+ /**
+ * Returns the vm ifaceid associated with the host.
+ *
+ * @return vm ifaceid
+ */
+ OvsdbIfaceId ifaceid();
+}
diff --git a/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbIfaceId.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbIfaceId.java
new file mode 100644
index 00000000..bf724fa4
--- /dev/null
+++ b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbIfaceId.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.controller;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+import java.util.Objects;
+
+/**
+ * The class representing an ifaceid.
+ * This class is immutable.
+ */
+public class OvsdbIfaceId {
+ private final String value;
+
+ /**
+ * Constructor from a String.
+ *
+ * @param value the ifaceid to use
+ */
+ public OvsdbIfaceId(String value) {
+ checkNotNull(value, "value is not null");
+ this.value = value;
+ }
+
+ /**
+ * Gets the value of ifaceid.
+ *
+ * @return the value of ifaceid
+ */
+ public String value() {
+ return value;
+ }
+
+ @Override
+ public int hashCode() {
+ return value.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof OvsdbIfaceId) {
+ final OvsdbIfaceId otherIfaceId = (OvsdbIfaceId) obj;
+ return Objects.equals(this.value, otherIfaceId.value);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this).add("value", value).toString();
+ }
+}
diff --git a/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbNodeId.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbNodeId.java
new file mode 100644
index 00000000..60146c85
--- /dev/null
+++ b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbNodeId.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.controller;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Objects;
+
+import org.onlab.packet.IpAddress;
+
+/**
+ * The class representing a nodeId of node which using ovsdb connection.
+ * This class is immutable.
+ */
+public final class OvsdbNodeId {
+ private static final String SCHEME = "ovsdb";
+ private final String nodeId;
+ private final String ipAddress;
+
+ /**
+ * Creates a new node identifier from an IpAddress ipAddress, a long port.
+ *
+ * @param ipAddress node IP address
+ * @param port node port
+ */
+ public OvsdbNodeId(IpAddress ipAddress, long port) {
+ checkNotNull(ipAddress, "ipAddress is not null");
+ this.ipAddress = ipAddress.toString();
+ this.nodeId = ipAddress.toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return nodeId.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof OvsdbNodeId)) {
+ return false;
+ }
+
+ OvsdbNodeId otherNodeId = (OvsdbNodeId) other;
+
+ return Objects.equals(otherNodeId.nodeId, this.nodeId);
+ }
+
+ @Override
+ public String toString() {
+ return SCHEME + ":" + nodeId;
+ }
+
+ /**
+ * Gets the value of the NodeId.
+ *
+ * @return the value of the NodeId.
+ */
+ public String nodeId() {
+ return SCHEME + ":" + nodeId;
+ }
+
+ /**
+ * Get the IP address of the node.
+ *
+ * @return the IP address of the node
+ */
+ public String getIpAddress() {
+ return ipAddress;
+ }
+}
diff --git a/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbNodeListener.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbNodeListener.java
new file mode 100644
index 00000000..ca732ef9
--- /dev/null
+++ b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbNodeListener.java
@@ -0,0 +1,36 @@
+/*
+ * 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;
+
+/**
+ * Allows for providers interested in node events to be notified.
+ */
+public interface OvsdbNodeListener {
+
+ /**
+ * Notifies that the node was added.
+ *
+ * @param nodeId the node where the event occurred
+ */
+ void nodeAdded(OvsdbNodeId nodeId);
+
+ /**
+ * Notifies that the node was removed.
+ *
+ * @param nodeId the node where the event occurred
+ */
+ void nodeRemoved(OvsdbNodeId nodeId);
+}
diff --git a/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPort.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPort.java
new file mode 100644
index 00000000..deea42d7
--- /dev/null
+++ b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPort.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.controller;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Objects;
+
+/**
+ * The class representing a ovsdb port. This class is immutable.
+ */
+public final class OvsdbPort {
+
+ private final OvsdbPortNumber portNumber;
+ private final OvsdbPortName portName;
+
+ /**
+ * Constructor from OvsdbPortNumber portNumber, OvsdbPortName portName.
+ *
+ * @param portNumber the portNumber to use
+ * @param portName the portName to use
+ */
+ public OvsdbPort(OvsdbPortNumber portNumber, OvsdbPortName portName) {
+ checkNotNull(portNumber, "portNumber is not null");
+ checkNotNull(portName, "portName is not null");
+ this.portNumber = portNumber;
+ this.portName = portName;
+ }
+
+ /**
+ * Gets the port number of port.
+ *
+ * @return the port number of port
+ */
+ public OvsdbPortNumber portNumber() {
+ return portNumber;
+ }
+
+ /**
+ * Gets the port name of port.
+ *
+ * @return the port name of port
+ */
+ public OvsdbPortName portName() {
+ return portName;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(portNumber, portName);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof OvsdbPort) {
+ final OvsdbPort otherOvsdbPort = (OvsdbPort) obj;
+ return Objects.equals(this.portNumber, otherOvsdbPort.portNumber)
+ && Objects.equals(this.portName, otherOvsdbPort.portName);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("portNumber", String.valueOf(portNumber.value()))
+ .add("portName", portName.value()).toString();
+ }
+}
diff --git a/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPortName.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPortName.java
new file mode 100644
index 00000000..7d40e99f
--- /dev/null
+++ b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPortName.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.controller;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Objects;
+
+/**
+ * The class representing a port number.
+ * This class is immutable.
+ */
+public final class OvsdbPortName {
+
+ private final String value;
+
+ /**
+ * Constructor from a String.
+ *
+ * @param value the port name to use
+ */
+ public OvsdbPortName(String value) {
+ checkNotNull(value, "value is not null");
+ this.value = value;
+ }
+
+ /**
+ * Gets the value of port name.
+ *
+ * @return the value of port name
+ */
+ public String value() {
+ return value;
+ }
+
+ @Override
+ public int hashCode() {
+ return value.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof OvsdbPortName) {
+ final OvsdbPortName otherOvsdbPortName = (OvsdbPortName) obj;
+ return Objects.equals(this.value, otherOvsdbPortName.value);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this).add("value", value).toString();
+ }
+}
diff --git a/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPortNumber.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPortNumber.java
new file mode 100644
index 00000000..86fc887a
--- /dev/null
+++ b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPortNumber.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.controller;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+/**
+ * The class representing a port number.
+ * This class is immutable.
+ */
+public final class OvsdbPortNumber {
+
+ private final long value;
+
+ /**
+ * Constructor from a long value.
+ *
+ * @param value the port number to use
+ */
+ public OvsdbPortNumber(long value) {
+ this.value = value;
+ }
+
+ /**
+ * Gets the value of port number.
+ *
+ * @return the value of port number
+ */
+ public long value() {
+ return value;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(value);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof OvsdbPortNumber) {
+ final OvsdbPortNumber ovsdbPortNumber = (OvsdbPortNumber) obj;
+ return Objects.equals(this.value, ovsdbPortNumber.value);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this).add("value", value).toString();
+ }
+}
diff --git a/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPortType.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPortType.java
new file mode 100644
index 00000000..fb7cdb00
--- /dev/null
+++ b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPortType.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.controller;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Objects;
+
+/**
+ * The class representing a port type.
+ * This class is immutable.
+ */
+public class OvsdbPortType {
+
+ private final String value;
+
+ /**
+ * Constructor from a String.
+ *
+ * @param value the port type to use
+ */
+ public OvsdbPortType(String value) {
+ checkNotNull(value, "value is not null");
+ this.value = value;
+ }
+
+ /**
+ * Gets the value of port type.
+ *
+ * @return the value of port type
+ */
+ public String value() {
+ return value;
+ }
+
+ @Override
+ public int hashCode() {
+ return value.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof OvsdbPortType) {
+ final OvsdbPortType otherOvsdbPortType = (OvsdbPortType) obj;
+ return Objects.equals(this.value, otherOvsdbPortType.value);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this).add("value", value).toString();
+ }
+}
diff --git a/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbRowStore.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbRowStore.java
new file mode 100644
index 00000000..bec0e2e9
--- /dev/null
+++ b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbRowStore.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.controller;
+
+import java.util.concurrent.ConcurrentMap;
+
+import org.onosproject.ovsdb.rfc.notation.Row;
+
+import com.google.common.collect.Maps;
+
+/**
+ * The class representing a table data.
+ */
+public class OvsdbRowStore {
+
+ private final ConcurrentMap<String, Row> rowStore = Maps.newConcurrentMap();
+
+ /**
+ * Gets the row.
+ *
+ * @param uuid the key of the rowStore
+ * @return row the row of the rowStore
+ */
+ public Row getRow(String uuid) {
+ return rowStore.get(uuid);
+ }
+
+ /**
+ * Inserts a row to rowStore.
+ *
+ * @param uuid key of the row
+ * @param row a row of the table
+ */
+ public void insertRow(String uuid, Row row) {
+ rowStore.put(uuid, row);
+ }
+
+ /**
+ * Deletes a row to rowStore.
+ *
+ * @param uuid key of the row
+ */
+ public void deleteRow(String uuid) {
+ rowStore.remove(uuid);
+ }
+
+ /**
+ * Gets the rowStore.
+ *
+ * @return rowStore
+ */
+ public ConcurrentMap<String, Row> getRowStore() {
+ return rowStore;
+ }
+
+}
diff --git a/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbStore.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbStore.java
new file mode 100644
index 00000000..56704908
--- /dev/null
+++ b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbStore.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.controller;
+
+import java.util.concurrent.ConcurrentMap;
+
+import com.google.common.collect.Maps;
+
+/**
+ * The cache for local ovsdb database.
+ */
+public class OvsdbStore {
+
+ private final ConcurrentMap<String, OvsdbTableStore> ovsdbStore = Maps.newConcurrentMap();
+
+ /**
+ * Gets the OvsdbTableStore.
+ *
+ * @param dbName ovsdb database name
+ * @return tableStore OvsdbTableStore
+ */
+ public OvsdbTableStore getOvsdbTableStore(String dbName) {
+ OvsdbTableStore tableStore = ovsdbStore.get(dbName);
+ if (tableStore == null) {
+ return null;
+ }
+ return tableStore;
+ }
+
+ /**
+ * Create or Update a value to ovsdbStore.
+ *
+ * @param dbName ovsdb database name
+ * @param tableStore a database tableStore.
+ */
+ public void createOrUpdateOvsdbStore(String dbName, OvsdbTableStore tableStore) {
+ ovsdbStore.put(dbName, tableStore);
+ }
+
+ /**
+ * Drops a value to rowStore.
+ *
+ * @param dbName ovsdb database name
+ */
+ public void dropOvsdbStore(String dbName) {
+ ovsdbStore.remove(dbName);
+ }
+
+ /**
+ * Gets the ovsdbStore.
+ *
+ * @return ovsdbStore
+ */
+ public ConcurrentMap<String, OvsdbTableStore> getOvsdbStore() {
+ return ovsdbStore;
+ }
+
+}
diff --git a/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbTableStore.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbTableStore.java
new file mode 100644
index 00000000..72b64f32
--- /dev/null
+++ b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbTableStore.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.controller;
+
+import java.util.concurrent.ConcurrentMap;
+
+import com.google.common.collect.Maps;
+
+/**
+ * The class representing a database data.
+ */
+public class OvsdbTableStore {
+
+ private final ConcurrentMap<String, OvsdbRowStore> tableStore = Maps.newConcurrentMap();
+
+ /**
+ * Gets the ovsdbRowStore.
+ *
+ * @param tableName an ovsdb table name
+ * @return OvsdbRowStore the data of table
+ */
+ public OvsdbRowStore getRows(String tableName) {
+ return tableStore.get(tableName);
+ }
+
+ /**
+ * Creates or updates a value to tableStore.
+ *
+ * @param tableName key of tableName
+ * @param rowStore a row of table
+ */
+ public void createOrUpdateTable(String tableName, OvsdbRowStore rowStore) {
+ tableStore.put(tableName, rowStore);
+ }
+
+ /**
+ * Drops a value to table data.
+ *
+ * @param tableName key of tableName
+ */
+ public void dropTable(String tableName) {
+ tableStore.remove(tableName);
+ }
+
+ /**
+ * Gets tableStore.
+ *
+ * @return tableStore
+ */
+ public ConcurrentMap<String, OvsdbRowStore> getTableStore() {
+ return tableStore;
+ }
+
+}
diff --git a/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbTunnel.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbTunnel.java
new file mode 100644
index 00000000..8c857da4
--- /dev/null
+++ b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbTunnel.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.controller;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Objects;
+
+import org.onlab.packet.IpAddress;
+
+/**
+ * The class representing an ovsdb tunnel.
+ * This class is immutable.
+ */
+public final class OvsdbTunnel {
+
+ private final IpAddress localIp;
+ private final IpAddress remoteIp;
+
+ public enum Type {
+ VXLAN, GRE
+ }
+
+ private final Type tunnelType;
+ private final OvsdbTunnelName tunnelName;
+
+ /**
+ * Constructor from an IpAddress localIp, IpAddress remoteIp Type tunnelType,
+ * OvsdbTunnelName tunnelName.
+ *
+ * @param localIp the localIp to use
+ * @param remoteIp the remoteIp to use
+ * @param tunnelType the tunnelType to use
+ * @param tunnelName the tunnelName to use
+ */
+ public OvsdbTunnel(IpAddress localIp, IpAddress remoteIp, Type tunnelType,
+ OvsdbTunnelName tunnelName) {
+ checkNotNull(localIp, "portName is not null");
+ checkNotNull(remoteIp, "portName is not null");
+ checkNotNull(tunnelName, "portName is not null");
+ this.localIp = localIp;
+ this.remoteIp = remoteIp;
+ this.tunnelType = tunnelType;
+ this.tunnelName = tunnelName;
+ }
+
+ /**
+ * Gets the local IP of tunnel.
+ *
+ * @return the local IP of tunnel
+ */
+ public IpAddress localIp() {
+ return localIp;
+ }
+
+ /**
+ * Gets the remote IP of tunnel.
+ *
+ * @return the remote IP of tunnel
+ */
+ public IpAddress remoteIp() {
+ return remoteIp;
+ }
+
+ /**
+ * Gets the tunnel type of tunnel.
+ *
+ * @return the tunnel type of tunnel
+ */
+ public Type tunnelType() {
+ return tunnelType;
+ }
+
+ /**
+ * Gets the tunnel name of tunnel.
+ *
+ * @return the tunnel name of tunnel
+ */
+ public OvsdbTunnelName tunnelName() {
+ return tunnelName;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(localIp, remoteIp, tunnelType, tunnelName);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof OvsdbTunnel) {
+ final OvsdbTunnel otherOvsdbTunnel = (OvsdbTunnel) obj;
+ return Objects.equals(this.localIp, otherOvsdbTunnel.localIp)
+ && Objects.equals(this.remoteIp, otherOvsdbTunnel.remoteIp)
+ && Objects.equals(this.tunnelType,
+ otherOvsdbTunnel.tunnelType)
+ && Objects.equals(this.tunnelName,
+ otherOvsdbTunnel.tunnelName);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this).add("localIp", localIp.toString())
+ .add("remoteIp", remoteIp.toString())
+ .add("tunnelType", tunnelType).add("tunnelName", tunnelName)
+ .toString();
+ }
+}
diff --git a/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbTunnelName.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbTunnelName.java
new file mode 100644
index 00000000..490d640b
--- /dev/null
+++ b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbTunnelName.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.controller;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Objects;
+
+/**
+ * The class representing a tunnel name.
+ * This class is immutable.
+ */
+public final class OvsdbTunnelName {
+ private final String value;
+
+ /**
+ * Constructor from a String.
+ *
+ * @param value the tunnel name to use
+ */
+ public OvsdbTunnelName(String value) {
+ checkNotNull(value, "value is not null");
+ this.value = value;
+ }
+
+ /**
+ * Gets the value of tunnel name.
+ *
+ * @return the value of tunnel name
+ */
+ public String value() {
+ return value;
+ }
+
+ @Override
+ public int hashCode() {
+ return value.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof OvsdbTunnelName) {
+ final OvsdbTunnelName otherOvsdbTunnelName = (OvsdbTunnelName) obj;
+ return Objects.equals(this.value, otherOvsdbTunnelName.value);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this).add("value", value).toString();
+ }
+}
diff --git a/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/DefaultOvsdbClient.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/DefaultOvsdbClient.java
new file mode 100644
index 00000000..8a661ab9
--- /dev/null
+++ b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/DefaultOvsdbClient.java
@@ -0,0 +1,1503 @@
+/*
+ * 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 com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.SettableFuture;
+
+import io.netty.channel.Channel;
+
+import org.onlab.packet.IpAddress;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.behaviour.ControllerInfo;
+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.exception.BridgeCreateException;
+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.OvsdbMap;
+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 java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+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 java.util.concurrent.atomic.AtomicReference;
+import java.util.stream.Collectors;
+
+/**
+ * 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 store if no rows exist in the table
+ */
+ private OvsdbRowStore getRowStore(String dbName, String tableName) {
+ OvsdbTableStore tableStore = getTableStore(dbName);
+ if (tableStore == null) {
+ return null;
+ }
+
+ OvsdbRowStore rowStore = tableStore.getRows(tableName);
+ if (rowStore == null) {
+ rowStore = new OvsdbRowStore();
+ }
+ return rowStore;
+ }
+
+ /**
+ * 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 {
+ String message = BridgeCreateException.createMessage(ovsUuid);
+ throw new BridgeCreateException(message);
+ }
+
+ } else {
+ log.info("Update a bridge");
+ updateConfig(OvsdbConstant.BRIDGE, "_uuid", bridgeUuid, bridge.getRow());
+ }
+
+ setControllerAuto(bridgeUuid);
+ log.info("Create bridge success");
+ }
+
+ @Override
+ public void createBridge(String bridgeName, String dpid, String exPortName) {
+ 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);
+ if (dpid != null) {
+ Map<String, String> options = new HashMap<>();
+ options.put("datapath-id", dpid);
+ bridge.setOtherConfig(options);
+ }
+ 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 {
+ String message = BridgeCreateException.createMessage(ovsUuid);
+ throw new BridgeCreateException(message);
+ }
+
+ } else {
+ log.info("Update a bridge");
+ updateConfig(OvsdbConstant.BRIDGE, "_uuid", bridgeUuid, bridge.getRow());
+ }
+ // Create external port
+ if (exPortName != null) {
+ createPort(bridgeName, exPortName);
+ }
+
+ setControllerAuto(bridgeUuid);
+ log.info("Create bridge success");
+ }
+
+ @Override
+ public boolean createBridge(String bridgeName, String dpid, List<ControllerInfo> controllers) {
+
+ DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
+ String ovsUuid = getOvsUuid(OvsdbConstant.DATABASENAME);
+
+ if (dbSchema == null || ovsUuid == null) {
+ log.warn("Couldn't find database Open_vSwitch");
+ return false;
+ }
+
+ String bridgeUuid = getBridgeUuid(bridgeName);
+ if (bridgeUuid != null) {
+ log.warn("Bridge {} is already exist", bridgeName);
+ // remove existing one and re-create?
+ return false;
+ }
+
+ Bridge bridge = (Bridge) TableGenerator.createTable(dbSchema, OvsdbTable.BRIDGE);
+ bridge.setName(bridgeName);
+
+ Set<String> failMode = new HashSet<>(Arrays.asList("secure"));
+ bridge.setFailMode(failMode);
+
+ Set<String> protocols = new HashSet<>(Arrays.asList(OvsdbConstant.OPENFLOW13));
+ bridge.setProtocols(protocols);
+
+ Map<String, String> options = new HashMap<>();
+ options.put("datapath-id", dpid);
+ bridge.setOtherConfig(options);
+
+ bridgeUuid = insertConfig(OvsdbConstant.BRIDGE, "_uuid",
+ OvsdbConstant.DATABASENAME, "bridges",
+ ovsUuid, bridge.getRow());
+
+ if (bridgeUuid != null) {
+ createPort(bridgeName, bridgeName);
+ } else {
+ log.warn("Failed to create bridge {} on {}", bridgeName, nodeId.toString());
+ return false;
+ }
+
+ setControllersWithUUID(UUID.uuid(bridgeUuid), controllers);
+ return true;
+ }
+
+ /**
+ * Sets the bridge's controller automatically.
+ * <p/>
+ * The connection is a TCP connection to the local ONOS instance's IP
+ * and the default OpenFlow port.
+ *
+ * @param bridgeUuid bridge uuid
+ */
+ private void setControllerAuto(String bridgeUuid) {
+ IpAddress ipAddress = IpAddress.valueOf(((InetSocketAddress) channel.localAddress()).getAddress());
+ ControllerInfo controllerInfo = new ControllerInfo(ipAddress, OvsdbConstant.OFPORT, "tcp");
+ log.debug("Automatically setting controller for bridge {} to {}",
+ bridgeUuid, controllerInfo.target());
+ setControllersWithUUID(UUID.uuid(bridgeUuid), ImmutableList.of(controllerInfo));
+ }
+
+ @Override
+ public void setControllersWithUUID(UUID bridgeUuid, List<ControllerInfo> controllers) {
+
+ DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
+ if (dbSchema == null) {
+ log.debug("There is no schema");
+ return;
+ }
+ List<Controller> oldControllers = getControllers(bridgeUuid);
+ if (oldControllers == null) {
+ log.warn("There are no controllers");
+ return;
+ }
+
+ Set<UUID> newControllerUuids = new HashSet<>();
+
+ Set<ControllerInfo> newControllers = new HashSet<>(controllers);
+ List<Controller> removeControllers = new ArrayList<>();
+ oldControllers.forEach(controller -> {
+ ControllerInfo controllerInfo = new ControllerInfo((String) controller.getTargetColumn().data());
+ if (newControllers.contains(controllerInfo)) {
+ newControllers.remove(controllerInfo);
+ newControllerUuids.add(controller.getRow().uuid());
+ } else {
+ removeControllers.add(controller);
+ }
+ });
+ OvsdbRowStore controllerRowStore = getRowStore(OvsdbConstant.DATABASENAME,
+ OvsdbConstant.CONTROLLER);
+ if (controllerRowStore == null) {
+ log.debug("There is no controller table");
+ return;
+ }
+
+ removeControllers.forEach(c -> deleteConfig(OvsdbConstant.CONTROLLER, "_uuid", c.getRow().uuid().value(),
+ OvsdbConstant.BRIDGE, "controller"));
+
+ newControllers.stream().map(c -> {
+ Controller controller = (Controller) TableGenerator
+ .createTable(dbSchema, OvsdbTable.CONTROLLER);
+ controller.setTarget(c.target());
+ return controller;
+ }).forEach(c -> {
+ String uuid = insertConfig(OvsdbConstant.CONTROLLER, "_uuid",
+ OvsdbConstant.BRIDGE, "controller", bridgeUuid.value(),
+ c.getRow());
+ newControllerUuids.add(UUID.uuid(uuid));
+
+ });
+
+ OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
+ OvsdbConstant.BRIDGE);
+ if (rowStore == null) {
+ log.debug("There is no bridge table");
+ return;
+ }
+
+ Row bridgeRow = rowStore.getRow(bridgeUuid.value());
+ Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, bridgeRow, OvsdbTable.BRIDGE);
+ bridge.setController(OvsdbSet.ovsdbSet(newControllerUuids));
+ updateConfig(OvsdbConstant.BRIDGE, "_uuid", bridgeUuid.value(), bridge.getRow());
+ }
+
+ @Override
+ public void setControllersWithDeviceId(DeviceId deviceId, List<ControllerInfo> controllers) {
+ setControllersWithUUID(getBridgeUUID(deviceId), controllers);
+ }
+
+ @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 boolean createTunnel(String bridgeName, String portName, String tunnelType, Map<String, String> options) {
+
+ String bridgeUuid = getBridgeUuid(bridgeName);
+ if (bridgeUuid == null) {
+ log.warn("Couldn't find bridge {} in {}", bridgeName, nodeId.getIpAddress());
+ return false;
+ }
+
+ if (getPortUuid(portName, bridgeUuid) != null) {
+ log.warn("Port {} already exists", portName);
+ // remove existing one and re-create?
+ return false;
+ }
+
+ ArrayList<Operation> operations = Lists.newArrayList();
+ DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
+
+ // insert a new port to the port table
+ Port port = (Port) TableGenerator.createTable(dbSchema, OvsdbTable.PORT);
+ port.setName(portName);
+ Insert portInsert = new Insert(dbSchema.getTableSchema("Port"), "Port", port.getRow());
+ portInsert.getRow().put("interfaces", UUID.uuid("Interface"));
+ operations.add(portInsert);
+
+ // update the bridge table
+ Condition condition = ConditionUtil.equals("_uuid", UUID.uuid(bridgeUuid));
+ Mutation mutation = MutationUtil.insert("ports", UUID.uuid("Port"));
+ List<Condition> conditions = new ArrayList<>(Arrays.asList(condition));
+ List<Mutation> mutations = new ArrayList<>(Arrays.asList(mutation));
+ operations.add(new Mutate(dbSchema.getTableSchema("Bridge"), conditions, mutations));
+
+ // insert a tunnel interface
+ Interface intf = (Interface) TableGenerator.createTable(dbSchema, OvsdbTable.INTERFACE);
+ intf.setName(portName);
+ intf.setType(tunnelType);
+ intf.setOptions(options);
+ Insert intfInsert = new Insert(dbSchema.getTableSchema("Interface"), "Interface", intf.getRow());
+ operations.add(intfInsert);
+
+ transactConfig(OvsdbConstant.DATABASENAME, operations);
+ return true;
+ }
+
+ @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 = (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<ControllerInfo> getControllers(DeviceId openflowDeviceId) {
+ UUID bridgeUuid = getBridgeUUID(openflowDeviceId);
+ if (bridgeUuid == null) {
+ log.warn("bad bridge Uuid");
+ return null;
+ }
+ List<Controller> controllers = getControllers(bridgeUuid);
+ if (controllers == null) {
+ log.warn("bad list of controllers");
+ return null;
+ }
+ return controllers.stream().
+ map(controller -> new ControllerInfo(
+ (String) controller.getTargetColumn()
+ .data())).collect(Collectors.toSet());
+ }
+
+ private List<Controller> getControllers(UUID bridgeUuid) {
+ DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
+ if (dbSchema == null) {
+ return null;
+ }
+ OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
+ OvsdbConstant.BRIDGE);
+ if (rowStore == null) {
+ log.debug("There is no bridge table");
+ return null;
+ }
+
+ Row bridgeRow = rowStore.getRow(bridgeUuid.value());
+ Bridge bridge = (Bridge) TableGenerator.
+ getTable(dbSchema, bridgeRow, OvsdbTable.BRIDGE);
+
+ //FIXME remove log
+ log.warn("type of controller column", bridge.getControllerColumn()
+ .data().getClass());
+ Set<UUID> controllerUuids = (Set<UUID>) ((OvsdbSet) bridge
+ .getControllerColumn().data()).set();
+// Set<String> controllerUuidStrings = (Set<String>) bridge.getControllerColumn().data();
+
+ OvsdbRowStore controllerRowStore = getRowStore(OvsdbConstant.DATABASENAME,
+ OvsdbConstant.CONTROLLER);
+ if (controllerRowStore == null) {
+ log.debug("There is no controller table");
+ return null;
+ }
+
+ List<Controller> ovsdbControllers = new ArrayList<>();
+ ConcurrentMap<String, Row> controllerTableRows = controllerRowStore.getRowStore();
+ controllerTableRows.forEach((key, row) -> {
+ if (!controllerUuids.contains(UUID.uuid(key))) {
+ return;
+ }
+ Controller controller = (Controller) TableGenerator
+ .getTable(dbSchema, row, OvsdbTable.CONTROLLER);
+ ovsdbControllers.add(controller);
+ });
+ return ovsdbControllers;
+ }
+
+
+ private UUID getBridgeUUID(DeviceId openflowDeviceId) {
+ DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
+ if (dbSchema == null) {
+ return null;
+ }
+ OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
+ OvsdbConstant.BRIDGE);
+ if (rowStore == null) {
+ log.debug("There is no bridge table");
+ return null;
+ }
+
+ ConcurrentMap<String, Row> bridgeTableRows = rowStore.getRowStore();
+ final AtomicReference<UUID> uuid = new AtomicReference<>();
+ for (Map.Entry<String, Row> entry : bridgeTableRows.entrySet()) {
+ Bridge b = (Bridge) TableGenerator.getTable(dbSchema,
+ entry.getValue(),
+ OvsdbTable.BRIDGE);
+ if (matchesDpid(b, openflowDeviceId)) {
+ uuid.set(UUID.uuid(entry.getKey()));
+ break;
+ }
+ }
+ if (uuid.get() == null) {
+ log.debug("There is no bridge for {}", openflowDeviceId);
+ }
+ return uuid.get();
+
+ }
+
+ private static boolean matchesDpid(Bridge b, DeviceId deviceId) {
+ String ofDpid = deviceId.toString().replace("of:", "");
+ Set ofDeviceIds = ((OvsdbSet) b.getDatapathIdColumn().data()).set();
+ //TODO Set<String>
+ return ofDeviceIds.contains(ofDpid);
+ }
+
+ @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());
+ }
+
+ @Override
+ public Set<OvsdbPort> getLocalPorts(Iterable<String> ifaceids) {
+ 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);
+ DatabaseSchema dbSchema = getDatabaseSchema(OvsdbConstant.DATABASENAME);
+ Interface intf = (Interface) TableGenerator
+ .getTable(dbSchema, row, OvsdbTable.INTERFACE);
+ if (intf == null || getIfaceid(intf) == null) {
+ continue;
+ }
+ String portName = intf.getName();
+ Set<String> ifaceidSet = Sets.newHashSet(ifaceids);
+ if (portName.startsWith("vxlan")
+ || !ifaceidSet.contains(getIfaceid(intf))) {
+ continue;
+ }
+ long ofPort = getOfPort(intf);
+ if ((ofPort < 0) || (portName == null)) {
+ continue;
+ }
+
+ OvsdbPort ovsdbPort = new OvsdbPort(new OvsdbPortNumber(ofPort),
+ new OvsdbPortName(portName));
+ if (ovsdbPort != null) {
+ ovsdbPorts.add(ovsdbPort);
+ }
+ }
+ return ovsdbPorts;
+ }
+
+ private String getIfaceid(Interface intf) {
+ OvsdbMap ovsdbMap = (OvsdbMap) intf.getExternalIdsColumn().data();
+ @SuppressWarnings("unchecked")
+ Map<String, String> externalIds = ovsdbMap.map();
+ if (externalIds.isEmpty()) {
+ log.warn("The external_ids is null");
+ return null;
+ }
+ String ifaceid = externalIds
+ .get(OvsdbConstant.EXTERNAL_ID_INTERFACE_ID);
+ if (ifaceid == null) {
+ log.warn("The ifaceid is null");
+ return null;
+ }
+ return ifaceid;
+ }
+
+ @Override
+ public void disconnect() {
+ channel.disconnect();
+ this.agent.removeConnectedNode(nodeId);
+ }
+}
diff --git a/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/OvsdbAgent.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/OvsdbAgent.java
new file mode 100644
index 00000000..70ffae8b
--- /dev/null
+++ b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/OvsdbAgent.java
@@ -0,0 +1,42 @@
+/*
+ * 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 org.onosproject.ovsdb.controller.OvsdbNodeId;
+import org.onosproject.ovsdb.controller.OvsdbClientService;
+
+/**
+ * Responsible for keeping track of the current set of nodes connected to the
+ * system.
+ */
+public interface OvsdbAgent {
+ /**
+ * Add a node that has just connected to the system.
+ *
+ * @param nodeId the nodeId to add
+ * @param ovsdbClient the actual node object.
+ */
+ void addConnectedNode(OvsdbNodeId nodeId, OvsdbClientService ovsdbClient);
+
+ /**
+ * Clear all state in controller node maps for a node that has disconnected
+ * from the local controller. Also release control for that node from the
+ * global repository. Notify node listeners.
+ *
+ * @param nodeId the node id to be removed.
+ */
+ void removeConnectedNode(OvsdbNodeId nodeId);
+}
diff --git a/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/OvsdbProviderService.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/OvsdbProviderService.java
new file mode 100644
index 00000000..48f58d02
--- /dev/null
+++ b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/OvsdbProviderService.java
@@ -0,0 +1,81 @@
+/*
+ * 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 org.onosproject.ovsdb.rfc.jsonrpc.Callback;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+/**
+ * Represents the driver side of an ovsdb node. This interface should never be
+ * exposed to consumers.
+ */
+public interface OvsdbProviderService {
+ /**
+ * Sets the ovsdb agent to be used. This method can only be called once.
+ *
+ * @param agent the agent to set.
+ */
+ void setAgent(OvsdbAgent agent);
+
+ /**
+ * Sets the associated Netty channel for this node.
+ *
+ * @param channel the Netty channel
+ */
+ void setChannel(Channel channel);
+
+ /**
+ * Announces to the ovsdb agent that this node has added.
+ */
+ void nodeAdded();
+
+ /**
+ * Announces to the ovsdb agent that this node has removed.
+ */
+ void nodeRemoved();
+
+ /**
+ * Sets whether the node is connected.
+ *
+ * @param connected whether the node is connected
+ */
+ void setConnection(boolean connected);
+
+ /**
+ * Processes result from ovsdb.
+ *
+ * @param response JsonNode response from ovsdb
+ */
+ void processResult(JsonNode response);
+
+ /**
+ * processes request from ovsdb.
+ *
+ * @param request JsonNode request from ovsdb
+ */
+ void processRequest(JsonNode request);
+
+ /**
+ * Sets call back.
+ *
+ * @param monitorCallback the callback to set
+ */
+ void setCallback(Callback monitorCallback);
+
+}
diff --git a/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/package-info.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/package-info.java
new file mode 100644
index 00000000..b14afdfb
--- /dev/null
+++ b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * Ovsdb controller node driver API.
+ */
+package org.onosproject.ovsdb.controller.driver; \ No newline at end of file
diff --git a/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/package-info.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/package-info.java
new file mode 100644
index 00000000..d6fb434c
--- /dev/null
+++ b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * Ovsdb controller API.
+ */
+package org.onosproject.ovsdb.controller; \ No newline at end of file