Add southbound utils.
authorSam Hague <shague@redhat.com>
Fri, 9 Oct 2015 18:57:28 +0000 (14:57 -0400)
committerSam Hague <shague@redhat.com>
Fri, 9 Oct 2015 19:08:09 +0000 (19:08 +0000)
This commit is copying the duplicated integration test code
for manipulating the southbound into a utils bundle. This
code is duplicated in the netvirt-it, setvirtsfc-it and southbound-it.
We will slowly migrate them to use this new utils bundle.

Change-Id: If3197fe3bcf50c12faff70cd01426b695686dd83
Signed-off-by: Sam Hague <shague@redhat.com>
utils/southbound-utils/pom.xml [new file with mode: 0644]
utils/southbound-utils/src/main/java/org/opendaylight/ovsdb/utils/southbound/utils/SouthboundUtils.java [new file with mode: 0644]
utils/southbound-utils/src/test/java/SouthboundUtilsTest.java [new file with mode: 0644]

diff --git a/utils/southbound-utils/pom.xml b/utils/southbound-utils/pom.xml
new file mode 100644 (file)
index 0000000..c9541ec
--- /dev/null
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.opendaylight.mdsal</groupId>
+    <artifactId>binding-parent</artifactId>
+    <version>0.8.0-SNAPSHOT</version>
+    <relativePath/>
+  </parent>
+
+  <groupId>org.opendaylight.ovsdb</groupId>
+  <artifactId>utils.southbound-utils</artifactId>
+  <version>1.2.1-SNAPSHOT</version>
+  <packaging>bundle</packaging>
+
+  <dependencies>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-binding-api</artifactId>
+      <version>1.3.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>southbound-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>southbound-impl</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>utils.mdsal-utils</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-simple</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </build>
+
+</project>
\ No newline at end of file
diff --git a/utils/southbound-utils/src/main/java/org/opendaylight/ovsdb/utils/southbound/utils/SouthboundUtils.java b/utils/southbound-utils/src/main/java/org/opendaylight/ovsdb/utils/southbound/utils/SouthboundUtils.java
new file mode 100644 (file)
index 0000000..bcc8d8e
--- /dev/null
@@ -0,0 +1,269 @@
+/*
+ * 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;
+    }
+}
diff --git a/utils/southbound-utils/src/test/java/SouthboundUtilsTest.java b/utils/southbound-utils/src/test/java/SouthboundUtilsTest.java
new file mode 100644 (file)
index 0000000..149a619
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * 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
+ */
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+public class SouthboundUtilsTest {
+    @Test
+    public void testDefault() {
+        assertTrue(true);
+    }
+}