Add controller to bridge 00/16700/5
authorEd Warnicke <eaw@cisco.com>
Sun, 15 Mar 2015 22:16:22 +0000 (17:16 -0500)
committerEd Warnicke <eaw@cisco.com>
Wed, 18 Mar 2015 18:27:35 +0000 (13:27 -0500)
You can now write controller info to a bridge and
read it back in the operational store when it comes
back from ovsdb.

Change-Id: I6f7b7b53201da053605fe965908a00785651e46e
Signed-off-by: Ed Warnicke <eaw@cisco.com>
southbound/southbound-api/src/main/yang/ovsdb.yang
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/SouthboundMapper.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/BridgeCreateCommand.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/transactions/md/OvsdbBridgeUpdateCommand.java

index b0178c8823c346ac7e26f189bc6a5747b3f75b05..a910d23006c7f3c5c7b12743b1f943a65baaf07d 100644 (file)
@@ -105,6 +105,15 @@ module ovsdb {
             }
         }
 
+        list controller-entry {
+            description "Bridge controller info";
+            key "target";
+            leaf target {
+                description "Uri telling bridge how to connect to controller";
+                type inet:uri;
+            }
+        }
+
         leaf datapath-id {
             description "Datapath-id of the bridge";
             type datapath-id;
index 10cd8b64afe42bcb5df7c5f418997ce220f63b3a..d873841c8a85a481bca7a88dbc54f6689378afc1 100644 (file)
@@ -12,13 +12,19 @@ import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.opendaylight.ovsdb.lib.OvsdbClient;
 import org.opendaylight.ovsdb.lib.OvsdbConnectionInfo;
+import org.opendaylight.ovsdb.lib.notation.UUID;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
 import org.opendaylight.ovsdb.schema.openvswitch.Bridge;
+import org.opendaylight.ovsdb.schema.openvswitch.Controller;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
@@ -30,6 +36,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.re
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolBase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntryBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryBuilder;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
@@ -217,10 +225,10 @@ public class SouthboundMapper {
         return datapath;
     }
 
-    public static Set<String> createOvsdbBridgeProtocols(OvsdbBridgeAugmentation omn) {
+    public static Set<String> createOvsdbBridgeProtocols(OvsdbBridgeAugmentation ovsdbBridgeNode) {
         Set<String> protocols = new HashSet<String>();
-        if(omn.getProtocolEntry() != null && omn.getProtocolEntry().size() > 0) {
-            for(ProtocolEntry protocol : omn.getProtocolEntry()) {
+        if(ovsdbBridgeNode.getProtocolEntry() != null && ovsdbBridgeNode.getProtocolEntry().size() > 0) {
+            for(ProtocolEntry protocol : ovsdbBridgeNode.getProtocolEntry()) {
                 if(SouthboundConstants.OVSDB_PROTOCOL_MAP.get(protocol.getProtocol()) != null) {
                     protocols.add(SouthboundConstants.OVSDB_PROTOCOL_MAP.get(protocol.getProtocol()));
                 } else {
@@ -244,4 +252,34 @@ public class SouthboundMapper {
         }
         return protocolList;
     }
+
+    public static List<ControllerEntry> createControllerEntries(Bridge bridge,Map<UUID,Controller> updatedControllerRows) {
+        LOG.info("Bridge: {}, updatedControllerRows: {}",bridge,updatedControllerRows);
+        Set<UUID> controllerUUIDs = bridge.getControllerColumn().getData();
+        List<ControllerEntry> controllerEntries = new ArrayList<ControllerEntry>();
+        for(UUID controllerUUID : controllerUUIDs ) {
+            Controller controller = updatedControllerRows.get(controllerUUID);
+            if(controller != null && controller.getTargetColumn() != null
+                    && controller.getTargetColumn() != null) {
+                String targetString = controller.getTargetColumn().getData();
+                controllerEntries.add(new ControllerEntryBuilder().setTarget(new Uri(targetString)).build());
+            }
+        }
+        return controllerEntries;
+    }
+
+    public static Map<UUID, Controller> createOvsdbController(OvsdbBridgeAugmentation omn,DatabaseSchema dbSchema) {
+        List<ControllerEntry> controllerEntries = omn.getControllerEntry();
+        Map<UUID,Controller> controllerMap = new HashMap<UUID,Controller>();
+        if(controllerEntries != null && !controllerEntries.isEmpty()) {
+            int index = 0;
+            for(ControllerEntry controllerEntry : controllerEntries) {
+                String controllerNamedUUID = "Controller_" + omn.getBridgeName().getValue() + index++;
+                Controller controller = TyperUtils.getTypedRowWrapper(dbSchema, Controller.class);
+                controller.setTarget(controllerEntry.getTarget().getValue());
+                controllerMap.put(new UUID(controllerNamedUUID), controller);
+            }
+        }
+        return controllerMap;
+    }
 }
index 68b0ae0e99e6fcf17e28c706cbe416ec632d1dc3..2838ef199577dcae2582ce09b7dfd5ee704e5e40 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.ovsdb.southbound.ovsdb.transact;
 import static org.opendaylight.ovsdb.lib.operations.Operations.op;
 
 import java.util.Map;
+import java.util.Map.Entry;
 
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
 import org.opendaylight.ovsdb.lib.notation.Mutator;
@@ -17,6 +18,7 @@ import org.opendaylight.ovsdb.lib.notation.UUID;
 import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
 import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
 import org.opendaylight.ovsdb.schema.openvswitch.Bridge;
+import org.opendaylight.ovsdb.schema.openvswitch.Controller;
 import org.opendaylight.ovsdb.schema.openvswitch.OpenVSwitch;
 import org.opendaylight.ovsdb.southbound.SouthboundMapper;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
@@ -52,11 +54,20 @@ public class BridgeCreateCommand implements TransactCommand {
                     && SouthboundMapper.createOvsdbBridgeProtocols(ovsdbManagedNode).size() > 0){
                 bridge.setProtocols(SouthboundMapper.createOvsdbBridgeProtocols(ovsdbManagedNode));
             }
-            transaction.add(op.insert(bridge).withId(namedUuid));
+            Map<UUID,Controller> controllerMap = SouthboundMapper.createOvsdbController(ovsdbManagedNode, transaction.getDatabaseSchema());
+            for(Entry<UUID,Controller >entry: controllerMap.entrySet()) {
+                transaction.add(op.insert(entry.getValue()).withId(entry.getKey().toString()));
+            }
+            if(!controllerMap.isEmpty()) {
+                bridge.setController(controllerMap.keySet());
+            }
+
+            String bridgeNamedUuid = "Bridge_" + ovsdbManagedNode.getBridgeName().getValue();
+            transaction.add(op.insert(bridge).withId(bridgeNamedUuid));
 
             // OpenVSwitchPart
             OpenVSwitch ovs = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), OpenVSwitch.class);
-            ovs.setBridges(Sets.newHashSet(new UUID(namedUuid)));
+            ovs.setBridges(Sets.newHashSet(new UUID(bridgeNamedUuid)));
             transaction.add(op.mutate(ovs).addMutation(ovs.getBridgesColumn().getSchema(),
                     Mutator.INSERT,
                     ovs.getBridgesColumn().getData())
index f994e08af484626c232caba7f9dd4f647197a5e0..745f8b32f224e3a2d0d367af25b26934c292e5b1 100644 (file)
@@ -3,16 +3,22 @@ package org.opendaylight.ovsdb.southbound.transactions.md;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
 
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.ovsdb.lib.message.TableUpdates;
+import org.opendaylight.ovsdb.lib.notation.UUID;
 import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
 import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
 import org.opendaylight.ovsdb.schema.openvswitch.Bridge;
+import org.opendaylight.ovsdb.schema.openvswitch.Controller;
 import org.opendaylight.ovsdb.southbound.OvsdbClientKey;
 import org.opendaylight.ovsdb.southbound.SouthboundMapper;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
@@ -22,6 +28,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.re
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentationBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntryBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagedNodeEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagedNodeEntryBuilder;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
@@ -43,8 +51,10 @@ public class OvsdbBridgeUpdateCommand extends AbstractTransactionCommand {
 
     @Override
     public void execute(ReadWriteTransaction transaction) {
-        Collection<Bridge> updatedRows = TyperUtils.extractRowsUpdated(Bridge.class, getUpdates(), getDbSchema()).values();
-        for(Bridge bridge : updatedRows) {
+        Map<UUID,Bridge> updatedBridgeRows = TyperUtils.extractRowsUpdated(Bridge.class, getUpdates(), getDbSchema());
+        Map<UUID,Controller> updatedControllerRows = TyperUtils.extractRowsUpdated(Controller.class, getUpdates(), getDbSchema());
+        for(Entry<UUID, Bridge> entry : updatedBridgeRows.entrySet()) {
+            Bridge bridge = entry.getValue();
             final InstanceIdentifier<Node> nodePath = getKey().toInstanceIndentifier();
             Optional<Node> node = Optional.absent();
             try{
@@ -68,13 +78,17 @@ public class OvsdbBridgeUpdateCommand extends AbstractTransactionCommand {
                         && SouthboundMapper.createMdsalProtocols(bridge).size() > 0) {
                     ovsdbManagedNodeBuilder.setProtocolEntry(SouthboundMapper.createMdsalProtocols(bridge));
                 }
+
+                if(!SouthboundMapper.createControllerEntries(bridge, updatedControllerRows).isEmpty()) {
+                    ovsdbManagedNodeBuilder.setControllerEntry(SouthboundMapper.createControllerEntries(bridge, updatedControllerRows));
+                }
                 ovsdbManagedNodeBuilder.setManagedBy(new OvsdbNodeRef(nodePath));
                 managedNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbManagedNodeBuilder.build());
 
                 InstanceIdentifier<Node> managedNodePath = SouthboundMapper.createInstanceIdentifier(manageNodeId);
 
                 LOG.debug("Store managed node augmentation data {}",ovsdbManagedNodeBuilder.toString());
-                transaction.put(LogicalDatastoreType.OPERATIONAL, managedNodePath, managedNodeBuilder.build());
+                transaction.merge(LogicalDatastoreType.OPERATIONAL, managedNodePath, managedNodeBuilder.build());
 
                 //Update node with managed node reference
                 NodeBuilder nodeBuilder = new NodeBuilder();
@@ -82,8 +96,8 @@ public class OvsdbBridgeUpdateCommand extends AbstractTransactionCommand {
 
                 OvsdbNodeAugmentationBuilder ovsdbNodeBuilder = new OvsdbNodeAugmentationBuilder();
                 List<ManagedNodeEntry> managedNodes = new ArrayList<ManagedNodeEntry>();
-                ManagedNodeEntry entry = new ManagedNodeEntryBuilder().setBridgeRef(new OvsdbBridgeRef(managedNodePath)).build();
-                managedNodes.add(entry);
+                ManagedNodeEntry managedNodeEntry = new ManagedNodeEntryBuilder().setBridgeRef(new OvsdbBridgeRef(managedNodePath)).build();
+                managedNodes.add(managedNodeEntry);
                 ovsdbNodeBuilder.setManagedNodeEntry(managedNodes);
 
                 nodeBuilder.addAugmentation(OvsdbNodeAugmentation.class, ovsdbNodeBuilder.build());