<ovsdb.library.version>1.0.0-SNAPSHOT</ovsdb.library.version>
<ovsdb.plugin.version>1.0.0-SNAPSHOT</ovsdb.plugin.version>
<ovsdb.northbound.version>0.6.0-SNAPSHOT</ovsdb.northbound.version>
+ <schema.Open_vSwitch.version>1.0.0-SNAPSHOT</schema.Open_vSwitch.version>
+ <schema.hardware_vtep.version>1.0.0-SNAPSHOT</schema.hardware_vtep.version>
</properties>
<dependencies>
<artifactId>ovsdb_northbound</artifactId>
<version>${ovsdb.northbound.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.ovsdb</groupId>
+ <artifactId>ovsdb_schema.Open_vSwitch</artifactId>
+ <version>${schema.Open_vSwitch.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.ovsdb</groupId>
+ <artifactId>ovsdb_schema.hardware_vtep</artifactId>
+ <version>${schema.hardware_vtep.version}</version>
+ </dependency>
+
<!-- Add Pax Exam -->
<dependency>
<groupId>org.ops4j.pax.exam</groupId>
<reuseForks>false</reuseForks>
<parallel>none</parallel>
<threadCount>1</threadCount>
+ <!-- Including just the Library integration tests till Plugin migration is done -->
+ <!-- TODO remove this includes section once the plugin migration is complete -->
+ <includes>
+ <include>**/*LibraryIT*</include>
+ </includes>
</configuration>
</execution>
</executions>
package org.opendaylight.ovsdb.integrationtest;
-import org.ops4j.pax.exam.Option;
-import org.ops4j.pax.exam.options.DefaultCompositeOption;
-
import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
import static org.ops4j.pax.exam.CoreOptions.systemPackages;
import static org.ops4j.pax.exam.CoreOptions.systemProperty;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.options.DefaultCompositeOption;
+
public class ConfigurationBundles {
);
}
+ public static Option ovsdbDefaultSchemaBundles() {
+ return new DefaultCompositeOption(
+ mavenBundle("org.opendaylight.ovsdb", "ovsdb_schema.Open_vSwitch").versionAsInProject(),
+ mavenBundle("org.opendaylight.ovsdb", "ovsdb_schema.hardware_vtep").versionAsInProject()
+ );
+ }
+
}
*/
package org.opendaylight.ovsdb.integrationtest;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
+import java.net.InetAddress;
import java.util.Properties;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
-import org.opendaylight.controller.sal.connection.ConnectionConstants;
-import org.opendaylight.controller.sal.core.Node;
import org.opendaylight.controller.sal.utils.ServiceHelper;
-import org.opendaylight.ovsdb.plugin.IConnectionServiceInternal;
+import org.opendaylight.ovsdb.lib.OvsdbClient;
+import org.opendaylight.ovsdb.lib.OvsdbConnection;
+import org.opendaylight.ovsdb.lib.OvsdbConnectionListener;
public abstract class OvsdbIntegrationTestBase {
private final static String identifier = "TEST";
+ private final static String SERVER_IPADDRESS = "ovsdbserver.ipaddress";
+ private final static String SERVER_PORT = "ovsdbserver.port";
+ private final static String CONNECTION_TYPE = "ovsdbserver.connection";
+ private final static String CONNECTION_TYPE_ACTIVE = "active";
+ private final static String CONNECTION_TYPE_PASSIVE = "passive";
+
+ private final static String DEFAULT_SERVER_PORT = "6640";
+
+ /**
+ * Represents the Open Vswitch Schema
+ */
+ public final static String OPEN_VSWITCH_SCHEMA = "Open_vSwitch";
+ public final static String HARDWARE_VTEP = "hardware_vtep";
+
+ public Properties loadProperties() {
+ Properties props = new Properties(System.getProperties());
+ return props;
+ }
+
+ public OvsdbClient getTestConnection() throws IOException, InterruptedException, ExecutionException, TimeoutException {
+ Properties props = loadProperties();
+ String addressStr = props.getProperty(SERVER_IPADDRESS);
+ String portStr = props.getProperty(SERVER_PORT, DEFAULT_SERVER_PORT);
+ String connectionType = props.getProperty(CONNECTION_TYPE, "active");
+
+ // If the connection type is active, controller connects to the ovsdb-server
+ if (connectionType.equalsIgnoreCase(CONNECTION_TYPE_ACTIVE)) {
+ if (addressStr == null) {
+ fail(usage());
+ }
+
+ InetAddress address;
+ try {
+ address = InetAddress.getByName(addressStr);
+ } catch (Exception e) {
+ System.out.println("Unable to resolve " + addressStr);
+ e.printStackTrace();
+ return null;
+ }
+
+ Integer port;
+ try {
+ port = Integer.parseInt(portStr);
+ } catch (NumberFormatException e) {
+ System.out.println("Invalid port number : " + portStr);
+ e.printStackTrace();
+ return null;
+ }
+
+ OvsdbConnection connection = (OvsdbConnection)ServiceHelper.getGlobalInstance(OvsdbConnection.class, this);
+ return connection.connect(address, port);
+ } else if (connectionType.equalsIgnoreCase(CONNECTION_TYPE_PASSIVE)) {
+ ExecutorService executor = Executors.newFixedThreadPool(1);
+ Future<OvsdbClient> passiveConnection = executor.submit(new PassiveListener());
+ return passiveConnection.get(60, TimeUnit.SECONDS);
+ }
+ fail("Connection parameter ("+CONNECTION_TYPE+") must be either active or passive");
+ return null;
+ }
+
+ private String usage() {
+ return "Integration Test needs a valid connection configuration as follows :\n" +
+ "active connection : mvn -Pintegrationtest -Dovsdbserver.ipaddress=x.x.x.x -Dovsdbserver.port=yyyy verify\n"+
+ "passive connection : mvn -Pintegrationtest -Dovsdbserver.connection=passive verify\n";
+ }
+
+ public class PassiveListener implements Callable<OvsdbClient>, OvsdbConnectionListener {
+ OvsdbClient client = null;
+ @Override
+ public OvsdbClient call() throws Exception {
+ OvsdbConnection connection = (OvsdbConnection)ServiceHelper.getGlobalInstance(OvsdbConnection.class, this);
+ connection.registerForPassiveConnection(this);
+ while (client == null) {
+ Thread.sleep(500);
+ }
+ return client;
+ }
+
+ @Override
+ public void connected(OvsdbClient client) {
+ this.client = client;
+ }
- public Node getTestConnection() throws IOException {
- IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class,
- this);
- Map<ConnectionConstants, String> params = new HashMap<ConnectionConstants, String>();
- Properties props = System.getProperties();
- params.put(ConnectionConstants.ADDRESS,
- props.getProperty("ovsdbserver.ipaddress"));
- params.put(ConnectionConstants.PORT,
- props.getProperty("ovsdbserver.port", "6640"));
-
- Node node = connectionService.connect(identifier, params);
- if (node == null) {
- throw new IOException("Failed to connect to the ovsdb server");
+ @Override
+ public void disconnected(OvsdbClient client) {
+ assertEquals(this.client.getConnectionInfo(), client.getConnectionInfo());
+ this.client = null;
}
- return node;
}
}
--- /dev/null
+/*
+ * Copyright (c) 2014 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
+ *
+ * Authors : Madhu Venugopal
+ */
+package org.opendaylight.ovsdb.integrationtest.library;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+import static org.opendaylight.ovsdb.lib.operations.Operations.op;
+import static org.ops4j.pax.exam.CoreOptions.junitBundles;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.propagateSystemProperty;
+import static org.ops4j.pax.exam.CoreOptions.systemProperty;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+
+import javax.inject.Inject;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.opendaylight.ovsdb.integrationtest.ConfigurationBundles;
+import org.opendaylight.ovsdb.integrationtest.OvsdbIntegrationTestBase;
+import org.opendaylight.ovsdb.lib.OvsdbClient;
+import org.opendaylight.ovsdb.lib.notation.Mutator;
+import org.opendaylight.ovsdb.lib.notation.UUID;
+import org.opendaylight.ovsdb.lib.operations.OperationResult;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.schema.openvswitch.Bridge;
+import org.opendaylight.ovsdb.schema.openvswitch.OpenVSwitch;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.util.PathUtils;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Sets;
+import com.google.common.util.concurrent.ListenableFuture;
+
+@RunWith(PaxExam.class)
+public class OvsdbLibraryIT extends OvsdbIntegrationTestBase {
+ private Logger log = LoggerFactory.getLogger(OvsdbLibraryIT.class);
+ @Inject
+ private BundleContext bc;
+ private OvsdbClient client = null;
+
+ @Configuration
+ public Option[] config() {
+ return options(
+ //
+ systemProperty("logback.configurationFile").value(
+ "file:" + PathUtils.getBaseDir()
+ + "/src/test/resources/logback.xml"
+ ),
+ // To start OSGi console for inspection remotely
+ systemProperty("osgi.console").value("2401"),
+
+ propagateSystemProperty("ovsdbserver.ipaddress"),
+ propagateSystemProperty("ovsdbserver.port"),
+
+ ConfigurationBundles.controllerBundles(),
+ ConfigurationBundles.ovsdbLibraryBundles(),
+ ConfigurationBundles.ovsdbDefaultSchemaBundles(),
+ junitBundles()
+ );
+ }
+
+ private String stateToString(int state) {
+ switch (state) {
+ case Bundle.ACTIVE:
+ return "ACTIVE";
+ case Bundle.INSTALLED:
+ return "INSTALLED";
+ case Bundle.RESOLVED:
+ return "RESOLVED";
+ case Bundle.UNINSTALLED:
+ return "UNINSTALLED";
+ default:
+ return "Not CONVERTED";
+ }
+ }
+
+ @Before
+ public void areWeReady() throws InterruptedException {
+ assertNotNull(bc);
+ boolean debugit = false;
+ Bundle b[] = bc.getBundles();
+ for (Bundle element : b) {
+ int state = element.getState();
+ if (state != Bundle.ACTIVE && state != Bundle.RESOLVED) {
+ log.info("Bundle:" + element.getSymbolicName() + " state:"
+ + stateToString(state));
+ debugit = true;
+ }
+ }
+ if (debugit) {
+ log.debug("Do some debugging because some bundle is unresolved");
+ }
+
+ // Assert if true, if false we are good to go!
+ assertFalse(debugit);
+ try {
+ client = getTestConnection();
+ } catch (Exception e) {
+ fail("Exception : "+e.getMessage());
+ }
+ }
+
+ public boolean isSchemaSupported(String schema) throws ExecutionException, InterruptedException {
+ ListenableFuture<List<String>> databases = client.getDatabases();
+ List<String> dbNames = databases.get();
+ assertNotNull(dbNames);
+ if (dbNames.contains(schema)) return true;
+ return false;
+ }
+
+ static String testBridgeName = "br_test";
+ static UUID testBridgeUuid = null;
+ private void createTypedBridge() throws IOException, InterruptedException, ExecutionException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+ Bridge bridge = client.createTypedRowWrapper(Bridge.class);
+ bridge.setName(testBridgeName);
+ bridge.setStatus(ImmutableMap.of("key","value"));
+ bridge.setFloodVlans(Sets.newHashSet(34));
+
+ OpenVSwitch openVSwitch = client.createTypedRowWrapper(OpenVSwitch.class);
+ openVSwitch.setBridges(Sets.newHashSet(new UUID(testBridgeName)));
+
+ int insertOperationIndex = 0;
+
+ TransactionBuilder transactionBuilder = client.transactBuilder()
+ .add(op.insert(bridge.getSchema())
+ .withId(testBridgeName)
+ .value(bridge.getNameColumn()))
+ .add(op.update(bridge.getSchema())
+ .set(bridge.getStatusColumn())
+ .set(bridge.getFloodVlansColumn())
+ .where(bridge.getNameColumn().getSchema().opEqual(bridge.getName()))
+ .and(bridge.getNameColumn().getSchema().opEqual(bridge.getName())).build())
+ .add(op.mutate(openVSwitch.getSchema())
+ .addMutation(openVSwitch.getBridgesColumn().getSchema(), Mutator.INSERT,
+ openVSwitch.getBridgesColumn().getData()));
+
+ ListenableFuture<List<OperationResult>> results = transactionBuilder.execute();
+ List<OperationResult> operationResults = results.get();
+ assertFalse(operationResults.isEmpty());
+ // Check if Results matches the number of operations in transaction
+ assertEquals(transactionBuilder.getOperations().size(), operationResults.size());
+ System.out.println("Insert & Update operation results = " + operationResults);
+ for (OperationResult result : operationResults) {
+ assertNull(result.getError());
+ }
+ testBridgeUuid = operationResults.get(insertOperationIndex).getUuid();
+ assertNotNull(testBridgeUuid);
+ }
+
+ @Test
+ public void tableTest() throws Exception {
+ assertNotNull("Invalid Client. Check connection params", client);
+ Thread.sleep(3000); // Wait for a few seconds to get the Schema exchange done
+ if (isSchemaSupported(OPEN_VSWITCH_SCHEMA)) {
+ DatabaseSchema dbSchema = client.getSchema(OPEN_VSWITCH_SCHEMA, true).get();
+ assertNotNull(dbSchema);
+ System.out.println(OPEN_VSWITCH_SCHEMA + " schema in "+ client.getConnectionInfo() +
+ " with Tables : " + dbSchema.getTables());
+
+ // A simple Typed Test to make sure a Typed wrapper bundle can coexist in an OSGi environment
+ createTypedBridge();
+ }
+
+ if (isSchemaSupported(HARDWARE_VTEP)) {
+ DatabaseSchema dbSchema = client.getSchema(HARDWARE_VTEP, true).get();
+ assertNotNull(dbSchema);
+ System.out.println(HARDWARE_VTEP + " schema in "+ client.getConnectionInfo() +
+ " with Tables : " + dbSchema.getTables());
+ }
+ }
+
+ @After
+ public void tearDown() throws InterruptedException, ExecutionException {
+ Bridge bridge = client.getTypedRowWrapper(Bridge.class, null);
+ OpenVSwitch openVSwitch = client.getTypedRowWrapper(OpenVSwitch.class, null);
+
+ ListenableFuture<List<OperationResult>> results = client.transactBuilder()
+ .add(op.delete(bridge.getSchema())
+ .where(bridge.getNameColumn().getSchema().opEqual(testBridgeName))
+ .build())
+ .add(op.mutate(openVSwitch.getSchema())
+ .addMutation(openVSwitch.getBridgesColumn().getSchema(), Mutator.DELETE, Sets.newHashSet(testBridgeUuid)))
+ .add(op.commit(true))
+ .execute();
+
+ List<OperationResult> operationResults = results.get();
+ System.out.println("Delete operation results = " + operationResults);
+ }
+}
package org.opendaylight.ovsdb.integrationtest.northbound;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.google.common.collect.Lists;
-import com.sun.jersey.api.client.Client;
-import com.sun.jersey.api.client.ClientResponse;
-import com.sun.jersey.api.client.WebResource;
-import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeNotNull;
+import static org.ops4j.pax.exam.CoreOptions.junitBundles;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.propagateSystemProperty;
+import static org.ops4j.pax.exam.CoreOptions.systemProperty;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-
import org.junit.runners.Parameterized;
import org.opendaylight.controller.sal.core.Node;
import org.opendaylight.controller.usermanager.IUserManager;
import org.opendaylight.ovsdb.integrationtest.ConfigurationBundles;
import org.opendaylight.ovsdb.integrationtest.OvsdbIntegrationTestBase;
+import org.opendaylight.ovsdb.lib.OvsdbClient;
import org.ops4j.pax.exam.Configuration;
import org.ops4j.pax.exam.Option;
import org.ops4j.pax.exam.junit.PaxExamParameterized;
import org.slf4j.LoggerFactory;
import org.yaml.snakeyaml.Yaml;
-import javax.inject.Inject;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.List;
-import java.util.Map;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.ops4j.pax.exam.CoreOptions.junitBundles;
-import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
-import static org.ops4j.pax.exam.CoreOptions.options;
-import static org.ops4j.pax.exam.CoreOptions.propagateSystemProperty;
-import static org.ops4j.pax.exam.CoreOptions.systemProperty;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.Lists;
+import com.sun.jersey.api.client.Client;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.WebResource;
+import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
@RunWith(PaxExamParameterized.class)
@ExamReactorStrategy(PerClass.class)
@Inject
private BundleContext bc;
private Node node = null;
+ private OvsdbClient client = null;
private IUserManager userManager;
@Parameterized.Parameters(name = "ApiTest{index}:{0}")
@Test
public void testApi() {
System.out.println("Running " + fTestCase + "...\n");
+ /*
+ * TODO : Remove this assumeNotNull once the new library migration is completed.
+ */
+ assumeNotNull(node);
Client client = Client.create();
client.addFilter(new HTTPBasicAuthFilter(USERNAME , PASSWORD));
String uri = BASE_URI + fPath;
assertTrue(this.userManager != null);
try {
- node = getTestConnection();
- } catch (IOException e) {
- e.printStackTrace();
+ client = getTestConnection();
+ } catch (Exception e) {
+ fail("Exception : "+e.getMessage());
}
// Wait before making a REST call to avoid overloading Tomcat
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeNotNull;
import static org.ops4j.pax.exam.CoreOptions.junitBundles;
import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
import static org.ops4j.pax.exam.CoreOptions.options;
import static org.ops4j.pax.exam.CoreOptions.propagateSystemProperty;
import static org.ops4j.pax.exam.CoreOptions.systemProperty;
-import java.io.IOException;
import java.util.List;
import javax.inject.Inject;
import org.opendaylight.controller.sal.utils.ServiceHelper;
import org.opendaylight.ovsdb.integrationtest.ConfigurationBundles;
import org.opendaylight.ovsdb.integrationtest.OvsdbIntegrationTestBase;
+import org.opendaylight.ovsdb.lib.OvsdbClient;
import org.opendaylight.ovsdb.plugin.OVSDBConfigService;
import org.ops4j.pax.exam.Configuration;
import org.ops4j.pax.exam.Option;
private BundleContext bc;
private OVSDBConfigService ovsdbConfigService = null;
private Node node = null;
+ private OvsdbClient client = null;
// Configure the OSGi container
@Configuration
// Assert if true, if false we are good to go!
assertFalse(debugit);
try {
- node = getTestConnection();
- } catch (IOException e) {
- e.printStackTrace();
+ client = getTestConnection();
+ } catch (Exception e) {
+ fail("Exception : "+e.getMessage());
}
this.ovsdbConfigService = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
}
@Test
public void tableTest() throws Exception {
- assertNotNull("Invalid Node. Check connection params", node);
+ assertNotNull("Invalid Node. Check connection params", client);
Thread.sleep(3000); // Wait for a few seconds to get the Schema exchange done
+ /*
+ * TODO : Remove the assumeNotNull once the Plugin is migrated to the new lib
+ */
+ assumeNotNull(node);
List<String> tables = ovsdbConfigService.getTables(node);
System.out.println("Tables = "+tables);
assertNotNull(tables);
<modules>
<module>library</module>
<module>schemas/Open_vSwitch</module>
+ <module>schemas/hardware_vtep</module>
<module>plugin</module>
<module>northbound</module>
<module>neutron</module>
import junit.framework.Assert;
import org.junit.After;
+import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.ovsdb.lib.OvsdbClient;
break;
}
}
- Assert.assertTrue(HARDWARE_VTEP_SCHEMA+" schema is not supported by the switch", hasHardwareVTepSchema);
+ Assume.assumeTrue(hasHardwareVTepSchema);
}
@Before