import com.google.common.collect.Lists;
import com.google.common.collect.ObjectArrays;
import java.net.InetAddress;
+import java.net.NetworkInterface;
import java.net.UnknownHostException;
import java.util.ArrayList;
+import java.util.Enumeration;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicBoolean;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
-import org.opendaylight.ovsdb.openstack.netvirt.impl.*;
import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
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.PortNumber;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.*;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIds;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs;
+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.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.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
return true;
}
+ private String getLocalControllerHostIpAddress() {
+ String ipaddress = null;
+ try{
+ for (Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces();
+ ifaces.hasMoreElements();) {
+ NetworkInterface iface = (NetworkInterface) ifaces.nextElement();
+
+ for (Enumeration<InetAddress> inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements();) {
+ InetAddress inetAddr = (InetAddress) inetAddrs.nextElement();
+ if (!inetAddr.isLoopbackAddress()) {
+ if (inetAddr.isSiteLocalAddress()) {
+ ipaddress = inetAddr.getHostAddress();
+ break;
+ }
+ }
+ }
+ }
+ }catch (Exception e){
+ LOG.warn("Exception while fetching local host ip address ",e);
+ }
+ return ipaddress;
+ }
+
+ private String getControllerTarget(Node ovsdbNode) {
+ String target = null;
+ String ipAddr = null;
+ OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
+ ConnectionInfo connectionInfo = ovsdbNodeAugmentation.getConnectionInfo();
+ LOG.info("connectionInfo: {}", connectionInfo);
+ if (connectionInfo != null && connectionInfo.getLocalIp() != null) {
+ ipAddr = new String(connectionInfo.getLocalIp().getValue());
+ }
+ if (ipAddr == null) {
+ ipAddr = getLocalControllerHostIpAddress();
+ }
+
+ if (ipAddr != null) {
+ target = NetvirtITConstants.OPENFLOW_CONNECTION_PROTOCOL + ":"
+ + ipAddr + ":" + NetvirtITConstants.DEFAULT_OPENFLOW_PORT;
+ }
+
+ return target;
+ }
+
//@Ignore//
@Test
public void testAddDeleteOvsdbNode() throws InterruptedException {
ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
connectOvsdbNode(connectionInfo);
+ ControllerEntry controllerEntry;
+ for (int i = 0; i < 10; i++) {
+ Node ovsdbNode = getOvsdbNode(connectionInfo);
+ Assert.assertNotNull("ovsdb node not found", ovsdbNode);
+ String controllerTarget = getControllerTarget(ovsdbNode);
+ Assert.assertNotNull("Failed to get controller target", controllerTarget);
+ OvsdbBridgeAugmentation bridge = getBridge(connectionInfo, NetvirtITConstants.INTEGRATION_BRIDGE_NAME);
+ Assert.assertNotNull(bridge);
+ Assert.assertNotNull(bridge.getControllerEntry());
+ controllerEntry = bridge.getControllerEntry().iterator().next();
+ Assert.assertEquals(controllerTarget, controllerEntry.getTarget().getValue());
+ if (controllerEntry.isIsConnected()) {
+ Assert.assertTrue(controllerEntry.isIsConnected());
+ break;
+ }
+ Thread.sleep(1000);
+ }
+
+ Assert.assertTrue(deleteBridge(connectionInfo, NetvirtITConstants.INTEGRATION_BRIDGE_NAME));
+ Thread.sleep(1000);
Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
- //Assume.assumeTrue(disconnectOvsdbNode(connectionInfo));
}
@Ignore
public static final int CONNECTION_INIT_TIMEOUT = 10000;
public static final String DEFAULT_SERVER_IPADDRESS = "127.0.0.1";
public static final String DEFAULT_SERVER_PORT = "6640";
+ public static final String DEFAULT_OPENFLOW_PORT = "6653";
public static final String DEFAULT_SERVER_EXTRAS = "false";
public static final String BRIDGE_NAME = "brtest";
public static final String PORT_NAME = "porttest";
public static final String INTEGRATION_BRIDGE_NAME = "br-int";
+ public static final String OPENFLOW_CONNECTION_PROTOCOL = "tcp";
}
public static final String BRIDGE_URI_PREFIX = "bridge";
public static final String TP_URI_PREFIX = "terminationpoint";
public static final Integer DEFAULT_OVSDB_PORT = 6640;
+ public static final String DEFAULT_OPENFLOW_PORT = "6653";
+ public static final String OPENFLOW_CONNECTION_PROTOCOL = "tcp";
public static final String UUID = "uuid";
public static final ImmutableBiMap<Class<? extends OvsdbBridgeProtocolBase>,String> OVSDB_PROTOCOL_MAP
= new ImmutableBiMap.Builder<Class<? extends OvsdbBridgeProtocolBase>,String>()
return iid;
}
+ public static InstanceIdentifier<Node> createInstanceIdentifier(
+ OvsdbConnectionInstance client, Controller controller, String bridgeName) {
+ InstanceIdentifier<Node> iid;
+ if (controller.getExternalIdsColumn() != null
+ && controller.getExternalIdsColumn().getData() != null
+ && controller.getExternalIdsColumn().getData().containsKey(SouthboundConstants.IID_EXTERNAL_ID_KEY)) {
+ String iidString = controller.getExternalIdsColumn().getData().get(SouthboundConstants.IID_EXTERNAL_ID_KEY);
+ iid = (InstanceIdentifier<Node>) SouthboundUtil.deserializeInstanceIdentifier(iidString);
+ } else {
+ // TODO retrieve bridge name
+ String nodeString = client.getNodeKey().getNodeId().getValue()
+ + "/bridge/" + bridgeName;
+ NodeId nodeId = new NodeId(new Uri(nodeString));
+ NodeKey nodeKey = new NodeKey(nodeId);
+ iid = InstanceIdentifier.builder(NetworkTopology.class)
+ .child(Topology.class,new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID))
+ .child(Node.class,nodeKey)
+ .build();
+ }
+ return iid;
+ }
+
public static NodeId createManagedNodeId(InstanceIdentifier<Node> iid) {
NodeKey nodeKey = iid.firstKeyOf(Node.class, NodeKey.class);
return nodeKey.getNodeId();
return protocolList;
}
- public static List<ControllerEntry> createControllerEntries(Bridge bridge,Map<UUID,
- Controller> updatedControllerRows) {
- LOG.debug("Bridge: {}, updatedControllerRows: {}",bridge,updatedControllerRows);
- Set<UUID> controllerUUIDs = bridge.getControllerColumn().getData();
- List<ControllerEntry> controllerEntries = new ArrayList<ControllerEntry>();
+ /**
+ * Create the {@link ControllerEntry} list given an OVSDB {@link Bridge}
+ * and {@link Controller} rows.
+ *
+ * @param bridge the {@link Bridge} to update
+ * @param updatedControllerRows the list of {@link Controller} controllers with updates
+ * @return list of {@link ControllerEntry} entries
+ */
+ public static List<ControllerEntry> createControllerEntries(Bridge bridge,
+ Map<UUID, Controller> updatedControllerRows) {
+
+ LOG.debug("createControllerEntries Bridge: {}\n, updatedControllerRows: {}",
+ bridge, updatedControllerRows);
+ final Set<UUID> controllerUUIDs = bridge.getControllerColumn().getData();
+ final 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();
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid uuid =
- new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
- .ietf.yang.types.rev130715.Uuid(controller.getUuid().toString());
- controllerEntries.add(new ControllerEntryBuilder()
- .setTarget(new Uri(targetString))
- .setIsConnected(controller.getIsConnectedColumn().getData())
- .setControllerUuid(uuid).build());
- }
+ final Controller controller = updatedControllerRows.get(controllerUUID);
+ addControllerEntries(controllerEntries, controller);
}
- LOG.debug("controllerEntries: {}", controllerEntries.toString());
+ LOG.debug("controllerEntries: {}", controllerEntries);
return controllerEntries;
}
+ /**
+ * Create the {@link ControllerEntry} list given an MDSAL {@link Node} bridge
+ * and {@link Controller} rows.
+ *
+ * @param bridgeNode the {@link Node} to update
+ * @param updatedControllerRows the list of {@link Controller} controllers with updates
+ * @return list of {@link ControllerEntry} entries
+ */
+ public static List<ControllerEntry> createControllerEntries(Node bridgeNode,
+ Map<UUID, Controller> updatedControllerRows) {
+
+ LOG.debug("createControllerEntries Bridge 2: {}\n, updatedControllerRows: {}",
+ bridgeNode, updatedControllerRows);
+ final List<ControllerEntry> controllerEntriesCreated = new ArrayList<ControllerEntry>();
+ final OvsdbBridgeAugmentation ovsdbBridgeAugmentation =
+ bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
+ if (ovsdbBridgeAugmentation == null) {
+ return controllerEntriesCreated;
+ }
+
+ final List<ControllerEntry> controllerEntries = ovsdbBridgeAugmentation.getControllerEntry();
+ for (ControllerEntry controllerEntry : controllerEntries) {
+ final Controller controller = updatedControllerRows.get(
+ new UUID(controllerEntry.getControllerUuid().getValue()));
+ addControllerEntries(controllerEntriesCreated, controller);
+ }
+ LOG.debug("controllerEntries: {}", controllerEntriesCreated);
+ return controllerEntriesCreated;
+ }
+
+ /**
+ * Add the OVSDB {@link Controller} updates to the MDSAL {@link ControllerEntry} list.
+ *
+ * @param controllerEntries the list of {@link ControllerEntry} to update
+ * @param controller the updated OVSDB {@link Controller}
+ */
+ public static void addControllerEntries(List<ControllerEntry> controllerEntries,
+ final Controller controller) {
+
+ if (controller != null && controller.getTargetColumn() != null) {
+ final String targetString = controller.getTargetColumn().getData();
+ final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid uuid =
+ new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
+ .ietf.yang.types.rev130715.Uuid(controller.getUuid().toString());
+
+ controllerEntries.add(new ControllerEntryBuilder()
+ .setTarget(new Uri(targetString))
+ .setIsConnected(controller.getIsConnectedColumn().getData())
+ .setControllerUuid(uuid).build());
+ }
+ }
+
public static Map<UUID, Controller> createOvsdbController(OvsdbBridgeAugmentation omn,DatabaseSchema dbSchema) {
List<ControllerEntry> controllerEntries = omn.getControllerEntry();
Map<UUID,Controller> controllerMap = new HashMap<UUID,Controller>();
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.util.concurrent.CheckedFuture;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.util.Enumeration;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+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.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAttributes;
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.OvsdbNodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException;
return Optional.absent();
}
}
+
+ public static <D extends org.opendaylight.yangtools.yang.binding.DataObject> Optional<D> readNode(
+ ReadWriteTransaction transaction, final InstanceIdentifier<D> connectionIid) {
+ Optional<D> node = Optional.absent();
+ try {
+ node = transaction.read(LogicalDatastoreType.OPERATIONAL, connectionIid).checkedGet();
+ } catch (final ReadFailedException e) {
+ LOG.warn("Read Operational/DS for Node failed! {}", connectionIid, e);
+ }
+ return node;
+ }
+
+ private static String getLocalControllerHostIpAddress() {
+ String ipaddress = null;
+ try {
+ for (Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces();
+ ifaces.hasMoreElements();) {
+ NetworkInterface iface = (NetworkInterface) ifaces.nextElement();
+
+ for (Enumeration<InetAddress> inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements();) {
+ InetAddress inetAddr = (InetAddress) inetAddrs.nextElement();
+ if (!inetAddr.isLoopbackAddress()) {
+ if (inetAddr.isSiteLocalAddress()) {
+ ipaddress = inetAddr.getHostAddress();
+ break;
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ LOG.warn("Exception while fetching local host ip address ",e);
+ }
+ return ipaddress;
+ }
+
+ public static String getControllerTarget(Node ovsdbNode) {
+ String target = null;
+ String ipAddr = null;
+ OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
+ ConnectionInfo connectionInfo = ovsdbNodeAugmentation.getConnectionInfo();
+ LOG.info("connectionInfo: {}", connectionInfo);
+ if (connectionInfo != null && connectionInfo.getLocalIp() != null) {
+ ipAddr = new String(connectionInfo.getLocalIp().getValue());
+ }
+ if (ipAddr == null) {
+ ipAddr = getLocalControllerHostIpAddress();
+ }
+
+ if (ipAddr != null) {
+ target = SouthboundConstants.OPENFLOW_CONNECTION_PROTOCOL + ":"
+ + ipAddr + ":" + SouthboundConstants.DEFAULT_OPENFLOW_PORT;
+ }
+
+ return target;
+ }
}
import org.apache.commons.lang3.math.NumberUtils;
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.error.SchemaVersionMismatchException;
import org.opendaylight.ovsdb.lib.message.TableUpdates;
import org.opendaylight.ovsdb.lib.notation.UUID;
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.IpAddress;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
private void updateBridge(ReadWriteTransaction transaction,
Bridge bridge) {
final InstanceIdentifier<Node> connectionIId = getOvsdbConnectionInstance().getInstanceIdentifier();
- Optional<Node> connection = readNode(transaction, connectionIId);
+ Optional<Node> connection = SouthboundUtil.readNode(transaction, connectionIId);
if (connection.isPresent()) {
LOG.debug("Connection {} is present",connection);
return result;
}
- private Optional<Node> readNode(ReadWriteTransaction transaction,
- final InstanceIdentifier<Node> connectionIid) {
- Optional<Node> node = Optional.absent();
- try {
- node = transaction.read(LogicalDatastoreType.OPERATIONAL, connectionIid).checkedGet();
- } catch (final ReadFailedException e) {
- LOG.warn("Read Operational/DS for Node fail! {}", connectionIid, e);
- }
- return node;
- }
-
private Node buildConnectionNode(
Bridge bridge) {
//Update node with managed node reference
connectionNode.addAugmentation(OvsdbNodeAugmentation.class, ovsdbConnectionAugmentationBuilder.build());
- LOG.debug("Update node with bridge node ref {}",ovsdbConnectionAugmentationBuilder.toString());
+ LOG.debug("Update node with bridge node ref {}",
+ ovsdbConnectionAugmentationBuilder.getManagedNodeEntry().iterator().next());
return connectionNode.build();
}
bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
LOG.debug("Built with the intent to store bridge data {}",
- ovsdbBridgeAugmentationBuilder.toString());
+ ovsdbBridgeAugmentationBuilder.build());
return bridgeNodeBuilder.build();
}
*/
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;
import org.opendaylight.ovsdb.schema.openvswitch.Bridge;
import org.opendaylight.ovsdb.schema.openvswitch.Controller;
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<UUID, Controller> updatedControllerRows;
private Map<UUID, Bridge> updatedBridgeRows;
@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.
+ *
+ * <p>
+ * 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.
+ * </p>
+ *
+ * @param transaction the {@link ReadWriteTransaction}
+ * @param updatedControllerRows updated {@link Controller} rows
+ * @param updatedBridgeRows updated {@link Bridge} rows
+ */
+ private void updateController(ReadWriteTransaction transaction,
+ Map<UUID, Controller> updatedControllerRows,
+ Map<UUID, Bridge> updatedBridgeRows) {
+
+ for (Map.Entry<UUID, Bridge> bridgeEntry : updatedBridgeRows.entrySet()) {
+ final List<ControllerEntry> 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.
+ *
+ * <p>
+ * 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.
+ * </p>
+ *
+ * @param transaction the {@link ReadWriteTransaction}
+ * @param updatedControllerRows updated {@link Controller} rows
+
+ */
+ private void updateController(ReadWriteTransaction transaction,
+ Map<UUID, Controller> updatedControllerRows) {
+ Map<InstanceIdentifier<Node>, Node> bridgeNodes = getBridgeNodes(transaction);
+ for (Map.Entry<InstanceIdentifier<Node>, Node> bridgeNodeEntry : bridgeNodes.entrySet()) {
+ final List<ControllerEntry> controllerEntries =
+ SouthboundMapper.createControllerEntries(bridgeNodeEntry.getValue(), updatedControllerRows);
+
+ for (ControllerEntry controllerEntry : controllerEntries) {
+ final InstanceIdentifier<Node> bridgeIid = bridgeNodeEntry.getKey();
+ InstanceIdentifier<ControllerEntry> 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<ControllerEntry> iid =
- SouthboundMapper.createInstanceIdentifier(getOvsdbConnectionInstance(), 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<InstanceIdentifier<Node>, Node> getBridgeNodes(ReadWriteTransaction transaction) {
+ Map<InstanceIdentifier<Node>, Node> bridgeNodes = new HashMap<>();
+ final InstanceIdentifier<Node> connectionIId = getOvsdbConnectionInstance().getInstanceIdentifier();
+ final Optional<Node> ovsdbNode = SouthboundUtil.readNode(transaction, connectionIId);
+ if (ovsdbNode.isPresent()) {
+ OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.get().getAugmentation(OvsdbNodeAugmentation.class);
+ if (ovsdbNodeAugmentation != null) {
+ final List<ManagedNodeEntry> managedNodeEntries = ovsdbNodeAugmentation.getManagedNodeEntry();
+ for (ManagedNodeEntry managedNodeEntry : managedNodeEntries) {
+ final InstanceIdentifier<Node> bridgeIid =
+ (InstanceIdentifier<Node>) managedNodeEntry.getBridgeRef().getValue();
+ @SuppressWarnings("unchecked")
+ final Optional<Node> 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<ControllerEntry> 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<Node> bridgeIid = InstanceIdentifier.builder(NetworkTopology.class)
+ .child(Topology.class,new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID))
+ .child(Node.class,nodeKey)
+ .build();
+
+ InstanceIdentifier<ControllerEntry> iid = bridgeIid
+ .augmentation(OvsdbBridgeAugmentation.class)
+ .child(ControllerEntry.class, controllerEntry.getKey());
+ return iid;
+ }
}
import org.opendaylight.ovsdb.southbound.SouthboundConstants;
import org.opendaylight.ovsdb.southbound.SouthboundMapper;
import org.opendaylight.ovsdb.southbound.SouthboundProvider;
+import org.opendaylight.ovsdb.southbound.SouthboundUtil;
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.PortNumber;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.collect.ImmutableBiMap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.ObjectArrays;
-
/**
* Integration tests for southbound-impl
*
public Option[] getLoggingOptions() {
Option[] options = new Option[] {
editConfigurationFilePut(SouthboundITConstants.ORG_OPS4J_PAX_LOGGING_CFG,
- "log4j.logger.org.opendaylight.ovsdb.southbound-impl",
- LogLevelOption.LogLevel.DEBUG.name())
+ //"log4j.logger.org.opendaylight.ovsdb.southbound-impl",
+ //LogLevelOption.LogLevel.DEBUG.name())
+ "log4j.logger.org.opendaylight.ovsdb",
+ LogLevelOption.LogLevel.TRACE.name())
};
options = ObjectArrays.concat(options, super.getLoggingOptions(), Option.class);
public void testOvsdbBridgeControllerInfo() throws InterruptedException {
ConnectionInfo connectionInfo = getConnectionInfo(addressStr,portStr);
Node ovsdbNode = connectOvsdbNode(connectionInfo);
- List<ControllerEntry> setControllerEntry = createControllerEntry();
- Uri setUri = new Uri(addressStr + ":" + portStr);
+ String controllerTarget = SouthboundUtil.getControllerTarget(ovsdbNode);
+ assertNotNull("Failed to get controller target", controllerTarget);
+ List<ControllerEntry> setControllerEntry = createControllerEntry(controllerTarget);
+ Uri setUri = new Uri(controllerTarget);
Assert.assertTrue(addBridge(connectionInfo, null, SouthboundITConstants.BRIDGE_NAME,null, true,
SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null,
setControllerEntry, null));
OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
- Assert.assertNotNull(bridge);
- Assert.assertNotNull(bridge.getControllerEntry());
+ Assert.assertNotNull("bridge was not found: " + SouthboundITConstants.BRIDGE_NAME, bridge);
+ Assert.assertNotNull("ControllerEntry was not found: " + setControllerEntry.iterator().next(),
+ bridge.getControllerEntry());
List<ControllerEntry> getControllerEntries = bridge.getControllerEntry();
for (ControllerEntry entry : getControllerEntries) {
if (entry.getTarget() != null) {
- Assert.assertEquals(entry.getTarget().toString(), setUri.toString());
+ Assert.assertEquals(setUri.toString(), entry.getTarget().toString());
}
}
+
Assert.assertTrue(deleteBridge(connectionInfo));
Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
}
- private List<ControllerEntry> createControllerEntry() {
+
+ private List<ControllerEntry> createControllerEntry(String controllerTarget) {
List<ControllerEntry> controllerEntriesList = new ArrayList<ControllerEntry>();
controllerEntriesList.add(new ControllerEntryBuilder()
- .setTarget(new Uri(addressStr + ":" + portStr))
+ .setTarget(new Uri(controllerTarget))
.build());
return controllerEntriesList;
}
+
private void setManagedBy(final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
final ConnectionInfo connectionInfo) {
InstanceIdentifier<Node> connectionNodePath = createInstanceIdentifier(connectionInfo);
public static final int CONNECTION_INIT_TIMEOUT = 10000;
public static final String DEFAULT_SERVER_IPADDRESS = "127.0.0.1";
public static final String DEFAULT_SERVER_PORT = "6640";
+ public static final String DEFAULT_OPENFLOW_PORT = "6653";
public static final String BRIDGE_NAME = "brtest";
+ public static final String OPENFLOW_CONNECTION_PROTOCOL = "tcp";
}