X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=southbound%2Fsouthbound-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fovsdb%2Fsouthbound%2Ftransactions%2Fmd%2FOvsdbControllerUpdateCommand.java;h=94a1bc8b50ca135581017be7e1bcb3da48267221;hb=df0401056be4d7e24eb48c630a318e1a8fd23fea;hp=7173d6a9d03b18b3a0b6efc1913adfc285875319;hpb=ec4b7e7948159b78fe2149c8224f4fd9d688d2e7;p=ovsdb.git diff --git a/southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/transactions/md/OvsdbControllerUpdateCommand.java b/southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/transactions/md/OvsdbControllerUpdateCommand.java index 7173d6a9d..94a1bc8b5 100644 --- a/southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/transactions/md/OvsdbControllerUpdateCommand.java +++ b/southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/transactions/md/OvsdbControllerUpdateCommand.java @@ -7,6 +7,8 @@ */ package org.opendaylight.ovsdb.southbound.transactions.md; +import java.util.HashMap; +import java.util.List; import java.util.Map; import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction; @@ -17,20 +19,33 @@ 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.OvsdbConnectionInstance; +import org.opendaylight.ovsdb.southbound.SouthboundConstants; import org.opendaylight.ovsdb.southbound.SouthboundMapper; +import org.opendaylight.ovsdb.southbound.SouthboundUtil; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation; +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.ovsdb.bridge.attributes.ControllerEntry; +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.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; -public class OvsdbControllerUpdateCommand extends AbstractTransactionCommand { - - +import com.google.common.base.Optional; +public class OvsdbControllerUpdateCommand extends AbstractTransactionCommand { + private static final Logger LOG = LoggerFactory.getLogger(OvsdbControllerUpdateCommand.class); private Map updatedControllerRows; private Map updatedBridgeRows; - public OvsdbControllerUpdateCommand(OvsdbClientKey key, + public OvsdbControllerUpdateCommand(OvsdbConnectionInstance key, TableUpdates updates, DatabaseSchema dbSchema) { super(key, updates, dbSchema); updatedBridgeRows = TyperUtils.extractRowsUpdated(Bridge.class, getUpdates(), getDbSchema()); @@ -40,19 +55,138 @@ public class OvsdbControllerUpdateCommand extends AbstractTransactionCommand { @Override public void execute(ReadWriteTransaction transaction) { - for (Bridge bridge: updatedBridgeRows.values()) { - setController(transaction, bridge); + if (updatedControllerRows != null && !updatedControllerRows.isEmpty()) { + if (updatedBridgeRows != null && !updatedBridgeRows.isEmpty()) { + updateController(transaction, updatedControllerRows, updatedBridgeRows); + } else { + updateController(transaction, updatedControllerRows); + } + } + } + + /** + * Update the ControllerEntry values for the given {@link Bridge} list. + * + *

+ * Controller and Bridge are independent tables in the Open_vSwitch schema + * but the OVSDB yang model includes the Controller fields in the + * Bridge data. In some cases the OVSDB will send Bridge and Controller + * updates together and in other cases independently. This method here + * assumes the former. + *

+ * + * @param transaction the {@link ReadWriteTransaction} + * @param updatedControllerRows updated {@link Controller} rows + * @param updatedBridgeRows updated {@link Bridge} rows + */ + private void updateController(ReadWriteTransaction transaction, + Map updatedControllerRows, + Map updatedBridgeRows) { + + for (Map.Entry bridgeEntry : updatedBridgeRows.entrySet()) { + final List controllerEntries = + SouthboundMapper.createControllerEntries(bridgeEntry.getValue(), updatedControllerRows); + + for (ControllerEntry controllerEntry : controllerEntries) { + transaction.merge(LogicalDatastoreType.OPERATIONAL, + getControllerEntryIid(controllerEntry, bridgeEntry.getValue().getNameColumn().getData()), + controllerEntry); + } } + } + + /** + * Update the ControllerEntry values after finding the related {@Bridge} list. + * + *

+ * Controller and Bridge are independent tables in the Open_vSwitch schema + * but the OVSDB yang model includes the Controller fields in the + * Bridge data. In some cases the OVSDB will send Bridge and Controller + * updates together and in other cases independently. This method here + * assumes the latter. + *

+ * + * @param transaction the {@link ReadWriteTransaction} + * @param updatedControllerRows updated {@link Controller} rows + + */ + private void updateController(ReadWriteTransaction transaction, + Map updatedControllerRows) { + Map, Node> bridgeNodes = getBridgeNodes(transaction); + for (Map.Entry, Node> bridgeNodeEntry : bridgeNodes.entrySet()) { + final List controllerEntries = + SouthboundMapper.createControllerEntries(bridgeNodeEntry.getValue(), updatedControllerRows); + + for (ControllerEntry controllerEntry : controllerEntries) { + final InstanceIdentifier bridgeIid = bridgeNodeEntry.getKey(); + InstanceIdentifier iid = bridgeIid + .augmentation(OvsdbBridgeAugmentation.class) + .child(ControllerEntry.class, controllerEntry.getKey()); + transaction.merge(LogicalDatastoreType.OPERATIONAL, + iid, controllerEntry); + } + } } - private void setController(ReadWriteTransaction transaction, Bridge bridge) { - for (ControllerEntry controllerEntry: SouthboundMapper.createControllerEntries(bridge, updatedControllerRows)) { - InstanceIdentifier iid = SouthboundMapper.createInstanceIdentifier(getKey(), bridge) - .augmentation(OvsdbBridgeAugmentation.class) - .child(ControllerEntry.class,controllerEntry.getKey()); - transaction.put(LogicalDatastoreType.OPERATIONAL, iid, controllerEntry); + /** + * Find all the {@link Node} bridge nodes for the given connection. + * + * @param transaction the {@link ReadWriteTransaction} + * @return + */ + private Map, Node> getBridgeNodes(ReadWriteTransaction transaction) { + Map, Node> bridgeNodes = new HashMap<>(); + final InstanceIdentifier connectionIId = getOvsdbConnectionInstance().getInstanceIdentifier(); + final Optional ovsdbNode = SouthboundUtil.readNode(transaction, connectionIId); + if (ovsdbNode.isPresent()) { + OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.get().getAugmentation(OvsdbNodeAugmentation.class); + if (ovsdbNodeAugmentation != null) { + final List managedNodeEntries = ovsdbNodeAugmentation.getManagedNodeEntry(); + for (ManagedNodeEntry managedNodeEntry : managedNodeEntries) { + final InstanceIdentifier bridgeIid = + (InstanceIdentifier) managedNodeEntry.getBridgeRef().getValue(); + @SuppressWarnings("unchecked") + final Optional bridgeNode = SouthboundUtil.readNode(transaction, bridgeIid); + if (bridgeNode.isPresent()) { + bridgeNodes.put(bridgeIid, bridgeNode.get()); + } else { + LOG.warn("OVSDB bridge node was not found: {}", bridgeIid); + } + } + } else { + LOG.warn("OvsdbNodeAugmentation was not found: {}", connectionIId); + } + } else { + LOG.warn("OVSDB node was not found: {}", connectionIId); } + + return bridgeNodes; } + /** + * Create the {@link InstanceIdentifier} for the {@link ControllerEntry}. + * + * @param controllerEntry the {@link ControllerEntry} + * @param bridgeName the name of the bridge + * @return the {@link InstanceIdentifier} + */ + private InstanceIdentifier getControllerEntryIid( + ControllerEntry controllerEntry, String bridgeName) { + + OvsdbConnectionInstance client = getOvsdbConnectionInstance(); + String nodeString = client.getNodeKey().getNodeId().getValue() + + "/bridge/" + bridgeName; + NodeId nodeId = new NodeId(new Uri(nodeString)); + NodeKey nodeKey = new NodeKey(nodeId); + InstanceIdentifier bridgeIid = InstanceIdentifier.builder(NetworkTopology.class) + .child(Topology.class,new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID)) + .child(Node.class,nodeKey) + .build(); + + InstanceIdentifier iid = bridgeIid + .augmentation(OvsdbBridgeAugmentation.class) + .child(ControllerEntry.class, controllerEntry.getKey()); + return iid; + } }