--- /dev/null
+/*
+ * Copyright (c) 2015 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.utils.southbound.utils;
+
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.UnknownHostException;
+import java.util.Enumeration;
+
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.ovsdb.southbound.SouthboundConstants;
+import org.opendaylight.ovsdb.southbound.SouthboundMapper;
+import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
+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.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.OvsdbBridgeName;
+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.node.attributes.ConnectionInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfoBuilder;
+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.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
+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;
+
+public class SouthboundUtils {
+ private static final Logger LOG = LoggerFactory.getLogger(SouthboundUtils.class);
+ private static final int OVSDB_UPDATE_TIMEOUT = 1000;
+ private static final String DEFAULT_OPENFLOW_PORT = "6653";
+ private static final String OPENFLOW_CONNECTION_PROTOCOL = "tcp";
+ private MdsalUtils mdsalUtils;
+
+ public SouthboundUtils(MdsalUtils mdsalUtils) {
+ this.mdsalUtils = mdsalUtils;
+ }
+
+ public NodeId createNodeId(IpAddress ip, PortNumber port) {
+ String uriString = SouthboundConstants.OVSDB_URI_PREFIX + "://"
+ + new String(ip.getValue()) + ":" + port.getValue();
+ Uri uri = new Uri(uriString);
+ return new NodeId(uri);
+ }
+
+ public Node createNode(ConnectionInfo key) {
+ NodeBuilder nodeBuilder = new NodeBuilder();
+ nodeBuilder.setNodeId(createNodeId(key.getRemoteIp(), key.getRemotePort()));
+ nodeBuilder.addAugmentation(OvsdbNodeAugmentation.class, createOvsdbAugmentation(key));
+ return nodeBuilder.build();
+ }
+
+ public OvsdbNodeAugmentation createOvsdbAugmentation(ConnectionInfo key) {
+ OvsdbNodeAugmentationBuilder ovsdbNodeBuilder = new OvsdbNodeAugmentationBuilder();
+ ovsdbNodeBuilder.setConnectionInfo(key);
+ return ovsdbNodeBuilder.build();
+ }
+
+ public InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key) {
+ return createInstanceIdentifier(key.getRemoteIp(), key.getRemotePort());
+ }
+
+ public InstanceIdentifier<Node> createInstanceIdentifier(IpAddress ip, PortNumber port) {
+ InstanceIdentifier<Node> path = InstanceIdentifier
+ .create(NetworkTopology.class)
+ .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID))
+ .child(Node.class,createNodeKey(ip,port));
+ LOG.debug("Created ovsdb path: {}",path);
+ return path;
+ }
+
+ public InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key,OvsdbBridgeName bridgeName) {
+ return SouthboundMapper.createInstanceIdentifier(createManagedNodeId(key, bridgeName));
+ }
+
+ public NodeKey createNodeKey(IpAddress ip, PortNumber port) {
+ return new NodeKey(createNodeId(ip, port));
+ }
+
+ public NodeId createManagedNodeId(ConnectionInfo key, OvsdbBridgeName bridgeName) {
+ return createManagedNodeId(key.getRemoteIp(), key.getRemotePort(), bridgeName);
+ }
+
+ public NodeId createManagedNodeId(IpAddress ip, PortNumber port, OvsdbBridgeName bridgeName) {
+ return new NodeId(createNodeId(ip,port).getValue()
+ + "/" + SouthboundConstants.BRIDGE_URI_PREFIX + "/" + bridgeName.getValue());
+ }
+
+ public ConnectionInfo getConnectionInfo(final String addressStr, final String portStr) {
+ InetAddress inetAddress = null;
+ try {
+ inetAddress = InetAddress.getByName(addressStr);
+ } catch (UnknownHostException e) {
+ LOG.warn("Could not allocate InetAddress");
+ }
+
+ IpAddress address = SouthboundMapper.createIpAddress(inetAddress);
+ PortNumber port = new PortNumber(Integer.parseInt(portStr));
+
+ LOG.info("connectionInfo: {}", new ConnectionInfoBuilder()
+ .setRemoteIp(address)
+ .setRemotePort(port)
+ .build());
+ return new ConnectionInfoBuilder()
+ .setRemoteIp(address)
+ .setRemotePort(port)
+ .build();
+ }
+
+ public String connectionInfoToString(final ConnectionInfo connectionInfo) {
+ return new String(connectionInfo.getRemoteIp().getValue()) + ":" + connectionInfo.getRemotePort().getValue();
+ }
+
+ public boolean addOvsdbNode(final ConnectionInfo connectionInfo) {
+ boolean result = mdsalUtils.put(LogicalDatastoreType.CONFIGURATION,
+ createInstanceIdentifier(connectionInfo),
+ createNode(connectionInfo));
+ try {
+ Thread.sleep(OVSDB_UPDATE_TIMEOUT);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ return result;
+ }
+
+ public Node getOvsdbNode(final ConnectionInfo connectionInfo) {
+ Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
+ createInstanceIdentifier(connectionInfo));
+ return node;
+ }
+
+ public boolean deleteOvsdbNode(final ConnectionInfo connectionInfo) {
+ boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
+ createInstanceIdentifier(connectionInfo));
+ try {
+ Thread.sleep(OVSDB_UPDATE_TIMEOUT);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ return result;
+ }
+
+ public Node connectOvsdbNode(final ConnectionInfo connectionInfo) {
+ addOvsdbNode(connectionInfo);
+ Node node = getOvsdbNode(connectionInfo);
+ LOG.info("Connected to {}", connectionInfoToString(connectionInfo));
+ return node;
+ }
+
+ public boolean disconnectOvsdbNode(final ConnectionInfo connectionInfo) {
+ deleteOvsdbNode(connectionInfo);
+ LOG.info("Disconnected from {}", connectionInfoToString(connectionInfo));
+ return true;
+ }
+
+ public 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 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 = OPENFLOW_CONNECTION_PROTOCOL + ":"
+ + ipAddr + ":" + DEFAULT_OPENFLOW_PORT;
+ }
+
+ return target;
+ }
+
+ /**
+ * Extract the <code>store</code> type data store contents for the particular bridge identified by
+ * <code>bridgeName</code>.
+ *
+ * @param connectionInfo address for the node
+ * @param bridgeName name of the bridge
+ * @param store defined by the <code>LogicalDatastoreType</code> enumeration
+ * @return <code>store</code> type data store contents
+ */
+ public OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName,
+ LogicalDatastoreType store) {
+ OvsdbBridgeAugmentation ovsdbBridgeAugmentation = null;
+ Node bridgeNode = getBridgeNode(connectionInfo, bridgeName, store);
+ if (bridgeNode != null) {
+ ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
+ }
+ return ovsdbBridgeAugmentation;
+ }
+
+ /**
+ * extract the <code>LogicalDataStoreType.OPERATIONAL</code> type data store contents for the particular bridge
+ * identified by <code>bridgeName</code>
+ *
+ * @param connectionInfo address for the node
+ * @param bridgeName name of the bridge
+ * @see <code>NetvirtIT.getBridge(ConnectionInfo, String, LogicalDatastoreType)</code>
+ * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
+ */
+ public OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName) {
+ return getBridge(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
+ }
+
+ /**
+ * Extract the node contents from <code>store</code> type data store for the
+ * bridge identified by <code>bridgeName</code>.
+ *
+ * @param connectionInfo address for the node
+ * @param bridgeName name of the bridge
+ * @param store defined by the <code>LogicalDatastoreType</code> enumeration
+ * @return <code>store</code> type data store contents
+ */
+ public Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store) {
+ InstanceIdentifier<Node> bridgeIid = createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
+ return mdsalUtils.read(store, bridgeIid);
+ }
+
+ public boolean deleteBridge(final ConnectionInfo connectionInfo, final String bridgeName) {
+
+ boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
+ createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName)));
+ try {
+ Thread.sleep(OVSDB_UPDATE_TIMEOUT);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ return result;
+ }
+}