diff options
Diffstat (limited to 'framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/DefaultOvsdbClient.java')
-rw-r--r-- | framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/DefaultOvsdbClient.java | 341 |
1 files changed, 240 insertions, 101 deletions
diff --git a/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/DefaultOvsdbClient.java b/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/DefaultOvsdbClient.java index 0c64cc0e..3a84d000 100644 --- a/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/DefaultOvsdbClient.java +++ b/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/DefaultOvsdbClient.java @@ -15,19 +15,19 @@ */ 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 java.net.InetSocketAddress; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.ExecutionException; - import org.onlab.packet.IpAddress; +import org.onosproject.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; @@ -71,14 +71,17 @@ import org.onosproject.ovsdb.rfc.utils.MutationUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.fasterxml.jackson.databind.JsonNode; -import com.google.common.base.Function; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.SettableFuture; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; /** * An representation of an ovsdb client. @@ -168,9 +171,8 @@ public class DefaultOvsdbClient /** * Gets the ovsdb row store. * - * @param dbName the ovsdb database name + * @param dbName the ovsdb database name * @param tableName the ovsdb table name - * * @return ovsRowStore, empty if row store is find */ private OvsdbRowStore getRowStore(String dbName, String tableName) { @@ -184,9 +186,9 @@ public class DefaultOvsdbClient /** * Gets the ovsdb row. * - * @param dbName the ovsdb database name + * @param dbName the ovsdb database name * @param tableName the ovsdb table name - * @param uuid the key of the row + * @param uuid the key of the row * @return row, empty if row is find */ @Override @@ -394,7 +396,7 @@ public class DefaultOvsdbClient port.setName(portName); if (portUuid == null) { insertConfig(OvsdbConstant.PORT, "_uuid", OvsdbConstant.BRIDGE, - "ports", bridgeUuid, port.getRow()); + "ports", bridgeUuid, port.getRow()); } else { updateConfig(OvsdbConstant.PORT, "_uuid", portUuid, port.getRow()); } @@ -414,7 +416,7 @@ public class DefaultOvsdbClient if (portUuid != null) { log.info("Port {} delete", portName); deleteConfig(OvsdbConstant.PORT, "_uuid", portUuid, - OvsdbConstant.BRIDGE, "ports"); + OvsdbConstant.BRIDGE, "ports"); } } @@ -455,8 +457,8 @@ public class DefaultOvsdbClient bridge.setName(bridgeName); bridgeUuid = insertConfig(OvsdbConstant.BRIDGE, "_uuid", - OvsdbConstant.DATABASENAME, "bridges", - ovsUuid, bridge.getRow()); + OvsdbConstant.DATABASENAME, "bridges", + ovsUuid, bridge.getRow()); if (bridgeUuid != null) { Port port = (Port) TableGenerator.createTable(dbSchema, @@ -466,7 +468,7 @@ public class DefaultOvsdbClient port.setName(bridgeName); insertConfig(OvsdbConstant.PORT, "_uuid", "Bridge", "ports", bridgeUuid, - port.getRow()); + port.getRow()); } } @@ -475,51 +477,92 @@ public class DefaultOvsdbClient updateConfig(OvsdbConstant.BRIDGE, "_uuid", bridgeUuid, bridge.getRow()); } - setController(bridgeUuid); + setControllerAuto(bridgeUuid); log.info("Create bridge success"); } /** - * Sets the Controller. + * 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 setController(String bridgeUuid) { - String controllerUuid = null; - String iPAddress = IpAddress.valueOf(((InetSocketAddress) channel - .localAddress()) - .getAddress() - .getHostAddress()) - .toString(); + 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)); + } - String target = "tcp:" + iPAddress + ":" + OvsdbConstant.OFPORT; - log.debug("controller IP {}: port {}", iPAddress, OvsdbConstant.OFPORT); + @Override + public void setControllersWithUUID(UUID bridgeUuid, List<ControllerInfo> controllers) { DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME); - Controller controller = (Controller) TableGenerator - .createTable(dbSchema, OvsdbTable.CONTROLLER); - - if (controller != null) { - controller.setTarget(target); - controllerUuid = getControllerUuid(OvsdbConstant.CONTROLLER, target); - if (controllerUuid == null) { + 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; + } - insertConfig(OvsdbConstant.CONTROLLER, "_uuid", - OvsdbConstant.BRIDGE, "controller", bridgeUuid, - controller.getRow()); + 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; + } - Bridge bridge = (Bridge) TableGenerator - .createTable(dbSchema, OvsdbTable.BRIDGE); - Set<UUID> controllerUuids = new HashSet<>(); - controllerUuids.add(UUID.uuid(controllerUuid)); - bridge.setController(controllerUuids); - updateConfig(OvsdbConstant.CONTROLLER, "_uuid", bridgeUuid, bridge.getRow()); + 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 @@ -530,7 +573,7 @@ public class DefaultOvsdbClient return; } deleteConfig(OvsdbConstant.BRIDGE, "_uuid", bridgeUUID, - OvsdbConstant.DATABASENAME, "bridges"); + OvsdbConstant.DATABASENAME, "bridges"); } @Override @@ -554,7 +597,7 @@ public class DefaultOvsdbClient if (portUuid == null) { portUuid = insertConfig(OvsdbConstant.PORT, "_uuid", OvsdbConstant.BRIDGE, - "ports", bridgeUuid, port.getRow()); + "ports", bridgeUuid, port.getRow()); } else { updateConfig(OvsdbConstant.PORT, "_uuid", portUuid, port.getRow()); } @@ -595,7 +638,7 @@ public class DefaultOvsdbClient options.put("remote_ip", dstIp.toString()); tunInterface.setOptions(options); updateConfig(OvsdbConstant.INTERFACE, "_uuid", interfaceUuid, - tunInterface.getRow()); + tunInterface.getRow()); log.info("Tunnel added success", tunInterface); } @@ -619,7 +662,7 @@ public class DefaultOvsdbClient if (portUUID != null) { log.info("Delete tunnel"); deleteConfig(OvsdbConstant.PORT, "_uuid", portUUID, - OvsdbConstant.BRIDGE, "ports"); + OvsdbConstant.BRIDGE, "ports"); } return; @@ -628,16 +671,15 @@ public class DefaultOvsdbClient /** * Delete transact config. * - * @param childTableName child table name - * @param childColumnName child column name - * @param childUuid child row uuid - * @param parentTableName parent table name + * @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) { + String childUuid, String parentTableName, + String parentColumnName) { DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME); TableSchema childTableSchema = dbSchema.getTableSchema(childTableName); @@ -672,14 +714,13 @@ public class DefaultOvsdbClient /** * Update transact config. * - * @param tableName table name + * @param tableName table name * @param columnName column name - * @param uuid uuid - * @param row the config data - * + * @param uuid uuid + * @param row the config data */ private void updateConfig(String tableName, String columnName, String uuid, - Row row) { + Row row) { DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME); TableSchema tableSchema = dbSchema.getTableSchema(tableName); @@ -698,18 +739,17 @@ public class DefaultOvsdbClient /** * Insert transact config. * - * @param childTableName child table name - * @param childColumnName child column name - * @param parentTableName parent table name + * @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 - * + * @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) { + String parentTableName, String parentColumnName, + String parentUuid, Row row) { DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME); TableSchema tableSchema = dbSchema.getTableSchema(childTableName); @@ -741,7 +781,7 @@ public class DefaultOvsdbClient if (childTableName.equalsIgnoreCase(OvsdbConstant.PORT)) { log.info("Handle port insert"); Insert intfInsert = handlePortInsertTable(OvsdbConstant.INTERFACE, - row); + row); if (intfInsert != null) { operations.add(intfInsert); @@ -772,8 +812,7 @@ public class DefaultOvsdbClient * Handles port insert. * * @param tableName ovsdb table interface - * @param portRow row of port - * + * @param portRow row of port * @return insert, empty if null */ private Insert handlePortInsertTable(String tableName, Row portRow) { @@ -801,8 +840,7 @@ public class DefaultOvsdbClient * Gets tunnel name. * * @param tunnelType - * @param dstIp the remote ip address - * + * @param dstIp the remote ip address * @return tunnel name */ private String getTunnelName(String tunnelType, IpAddress dstIp) { @@ -821,7 +859,7 @@ public class DefaultOvsdbClient Function<JsonNode, DatabaseSchema> rowFunction = new Function<JsonNode, DatabaseSchema>() { @Override public DatabaseSchema apply(JsonNode input) { - log.info("Get ovsdb database schema", dbName); + log.info("Get ovsdb database schema {}", dbName); DatabaseSchema dbSchema = FromJsonUtil .jsonNodeToDbSchema(dbName, input); if (dbSchema == null) { @@ -877,21 +915,17 @@ public class DefaultOvsdbClient } DatabaseSchema dbSchema = schema.get(dbName); if (dbSchema != null) { - Function<List<JsonNode>, List<OperationResult>> rowFunction = - new Function<List<JsonNode>, List<OperationResult>>() { - @Override - public List<OperationResult> apply(List<JsonNode> input) { - log.info("Get ovsdb operation result"); - List<OperationResult> result = FromJsonUtil - .jsonNodeToOperationResult(input, operations); - - if (result == null) { - log.debug("The operation result is null"); - return null; - } - return result; + 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); } @@ -972,7 +1006,7 @@ public class DefaultOvsdbClient } - @SuppressWarnings({ "rawtypes", "unchecked" }) + @SuppressWarnings({"rawtypes", "unchecked"}) @Override public void processResult(JsonNode response) { log.debug("Handle result"); @@ -1042,6 +1076,105 @@ public class DefaultOvsdbClient } @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); @@ -1185,4 +1318,10 @@ public class DefaultOvsdbClient } return ifaceid; } + + @Override + public void disconnect() { + channel.disconnect(); + this.agent.removeConnectedNode(nodeId); + } } |