.vagrant
.DS_Store
.checkstyle
+.factorypath
yang-gen-config
yang-gen-sal
maven-metadata-local.xml
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.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalSwitchAttributes;
public class HwvtepSouthboundUtil {
private static final Logger LOG = LoggerFactory.getLogger(HwvtepSouthboundUtil.class);
+ private static final String SCHEMA_VERSION_MISMATCH =
+ "{} column for {} table is not supported by this version of the {} schema: {}";
private static InstanceIdentifierCodec instanceIdentifierCodec;
return String.valueOf(
connectionInfo.getRemoteIp().getValue()) + ":" + connectionInfo.getRemotePort().getValue();
}
+
+
+ public static void schemaMismatchLog(String column, String table, SchemaVersionMismatchException ex) {
+ LOG.debug(SCHEMA_VERSION_MISMATCH, column, table, "hw_vtep", ex.getMessage());
+ }
}
package org.opendaylight.ovsdb.hwvtepsouthbound.transact;
+import static org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundUtil.schemaMismatchLog;
import static org.opendaylight.ovsdb.lib.operations.Operations.op;
import java.util.Collection;
setTunnels(transaction, iid, physicalSwitch, physicalSwitchAugmentation,
operationalPhysicalSwitchOptional.isPresent());
} catch (SchemaVersionMismatchException e) {
- LOG.debug("tunnels table unsupported for this version of HWVTEP schema", e);
+ schemaMismatchLog("tunnels", "Physical_Switch", e);
}
if (!operationalPhysicalSwitchOptional.isPresent()) {
//create a physical switch
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
+ <configuration>
+ <excludes>
+ <exclude>**/HwvtepSouthboundIT.java</exclude>
+ </excludes>
+ </configuration>
</plugin>
<!-- Needed if you use versionAsInProject() -->
<plugin>
<includeTestSourceDirectory>true</includeTestSourceDirectory>
</configuration>
</plugin>
- <plugin>
- <artifactId>maven-failsafe-plugin</artifactId>
- <configuration>
- <excludes>
- <exclude>**/HwvtepSouthboundIT.java</exclude>
- </excludes>
- </configuration>
- </plugin>
</plugins>
</build>
<artifactId>schema.openvswitch</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>schema.hardwarevtep</artifactId>
+ <version>${project.version}</version>
+ </dependency>
</dependencies>
<!--
<!-- Test only (move to another feature) -->
<bundle>mvn:org.opendaylight.ovsdb/utils.servicehelper/{{VERSION}}</bundle>
<bundle>mvn:org.opendaylight.ovsdb/schema.openvswitch/{{VERSION}}</bundle>
+ <bundle>mvn:org.opendaylight.ovsdb/schema.hardwarevtep/{{VERSION}}</bundle>
<!-- Test only ends -->
<bundle start="true">mvn:com.fasterxml.jackson.core/jackson-annotations/{{VERSION}}</bundle>
<bundle start="true">mvn:com.fasterxml.jackson.core/jackson-core/{{VERSION}}</bundle>
if (transactInvokers == null) {
try {
transactInvokers = new HashMap<>();
- List<String> databases = getDatabases().get();
- for (String database : databases) {
- DatabaseSchema dbSchema = getSchema(database).get();
- if (dbSchema != null) {
- transactInvokers.put(dbSchema, new TransactInvokerImpl(this,dbSchema));
- }
+ DatabaseSchema dbSchema = getSchema(SouthboundConstants.OPEN_V_SWITCH).get();
+ if(dbSchema != null) {
+ transactInvokers.put(dbSchema, new TransactInvokerImpl(this,dbSchema));
}
} catch (InterruptedException | ExecutionException e) {
LOG.warn("Exception attempting to createTransactionInvokers {}", connectionInfo, e);
* @param cm The connection manager.
*/
OvsdbDataTreeChangeListener(DataBroker db, OvsdbConnectionManager cm) {
- LOG.info("Registering OvsdbNodeDataChangeListener");
this.cm = cm;
this.db = db;
InstanceIdentifier<Node> path = InstanceIdentifier
DataTreeIdentifier<Node> dataTreeIdentifier =
new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, path);
registration = db.registerDataTreeChangeListener(dataTreeIdentifier, this);
+ LOG.info("OVSDB topology listener has been registered.");
}
@Override
public void close() {
registration.close();
+ LOG.info("OVSDB topology listener has been closed.");
}
@Override
} else {
try {
InstanceIdentifier<Node> instanceIdentifier = change.getRootPath().getRootIdentifier();
- LOG.info("Connecting on key {} to {}", instanceIdentifier, ovsdbNode);
cm.connect(instanceIdentifier, ovsdbNode);
+ LOG.info("OVSDB node has been connected: {}",ovsdbNode);
} catch (UnknownHostException e) {
LOG.warn("Failed to connect to ovsdbNode", e);
}
ConnectionInfo key = ovsdbNode.getConnectionInfo();
InstanceIdentifier<Node> iid = cm.getInstanceIdentifier(key);
try {
- LOG.info("Disconnecting from {}", ovsdbNode);
cm.disconnect(ovsdbNode);
+ LOG.info("OVSDB node has been disconnected:{}", ovsdbNode);
cm.stopConnectionReconciliationIfActive(iid.firstIdentifierOf(Node.class), ovsdbNode);
} catch (UnknownHostException e) {
LOG.warn("Failed to disconnect ovsdbNode", e);
*/
package org.opendaylight.ovsdb.southbound;
+import static org.opendaylight.ovsdb.southbound.SouthboundUtil.schemaMismatchLog;
+
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import org.opendaylight.ovsdb.schema.openvswitch.Qos;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IetfInetUtil;
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.Ipv4Address;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
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;
try {
protocols = bridge.getProtocolsColumn().getData();
} catch (SchemaVersionMismatchException e) {
- // We don't care about the exception stack trace here
- LOG.warn("protocols not supported by this version of ovsdb", e);
+ schemaMismatchLog("protocols", "Bridge", e);
}
List<ProtocolEntry> protocolList = new ArrayList<>();
if (protocols != null && protocols.size() > 0) {
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.schema.DatabaseSchema;
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;
public class SouthboundUtil {
private static final Logger LOG = LoggerFactory.getLogger(SouthboundUtil.class);
+ private static final String SCHEMA_VERSION_MISMATCH =
+ "{} column for {} table is not supported by this version of the {} schema: {}";
private static InstanceIdentifierCodec instanceIdentifierCodec;
return String.valueOf(
connectionInfo.getRemoteIp().getValue()) + ":" + connectionInfo.getRemotePort().getValue();
}
+
+ public static void schemaMismatchLog(String column, String table, SchemaVersionMismatchException ex) {
+ LOG.debug(SCHEMA_VERSION_MISMATCH, column, table, SouthboundConstants.OPEN_V_SWITCH, ex.getMessage());
+ }
}
package org.opendaylight.ovsdb.southbound.ovsdb.transact;
import static org.opendaylight.ovsdb.lib.operations.Operations.op;
+import static org.opendaylight.ovsdb.southbound.SouthboundUtil.schemaMismatchLog;
import java.util.Collection;
import java.util.Map;
transaction.add(op.mutate(bridge).addMutation(bridge.getProtocolsColumn().getSchema(),
Mutator.DELETE,bridge.getProtocolsColumn().getData()));
} catch (SchemaVersionMismatchException e) {
- LOG.warn("protocol is not supported by this version of ovsdb", e);
+ schemaMismatchLog("protocols", "Bridge", e);
}
}
}
package org.opendaylight.ovsdb.southbound.ovsdb.transact;
import static org.opendaylight.ovsdb.lib.operations.Operations.op;
+import static org.opendaylight.ovsdb.southbound.SouthboundUtil.schemaMismatchLog;
import java.util.Collection;
import java.util.Map;
.where(bridge.getNameColumn().getSchema().opEqual(bridge.getNameColumn().getData()))
.build());
} catch (SchemaVersionMismatchException e) {
- // We don't care about the exception stack trace here
- LOG.warn("protocol not supported by this version of ovsdb: {}", e.getMessage());
+ schemaMismatchLog("protocols", "Bridge", e);
}
}
}
package org.opendaylight.ovsdb.southbound.ovsdb.transact;
import static org.opendaylight.ovsdb.lib.operations.Operations.op;
+import static org.opendaylight.ovsdb.southbound.SouthboundUtil.schemaMismatchLog;
import java.util.Collection;
import java.util.Collections;
}
}
} catch (SchemaVersionMismatchException e) {
- LOG.debug("lldp column for Interface Table unsupported for this version of ovsdb schema", e);
+ schemaMismatchLog("lldp", "Interface", e);
}
}
}
}
} catch (SchemaVersionMismatchException e) {
- LOG.debug("bfd column for Interface Table unsupported for this version of ovsdb schema", e);
+ schemaMismatchLog("bfd", "Interface", e);
}
}
package org.opendaylight.ovsdb.southbound.ovsdb.transact;
import static org.opendaylight.ovsdb.lib.operations.Operations.op;
+import static org.opendaylight.ovsdb.southbound.SouthboundUtil.schemaMismatchLog;
import java.util.Collection;
import java.util.HashMap;
}
}
} catch (SchemaVersionMismatchException e) {
- LOG.debug("lldp column for Interface Table unsupported for this version of ovsdb schema", e);
+ schemaMismatchLog("lldp", "Interface", e);
}
}
}
}
} catch (SchemaVersionMismatchException e) {
- LOG.debug("bfd column for Interface Table unsupported for this version of ovsdb schema", e);
+ schemaMismatchLog("bfd", "Interface", e);
}
}
import org.opendaylight.yangtools.yang.binding.Identifier;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
public class TransactUtils {
- private static final Logger LOG = LoggerFactory.getLogger(TransactUtils.class);
-
private static <T extends DataObject> Predicate<DataObjectModification<T>> hasDataBefore() {
return new Predicate<DataObjectModification<T>>() {
@Override
if (child.getIdentifier() instanceof InstanceIdentifier.IdentifiableItem) {
K key = (K) ((InstanceIdentifier.IdentifiableItem) child.getIdentifier()).getKey();
KeyedInstanceIdentifier<N, K> extendedPath = path.child(item, key);
- LOG.debug("Building a new child iid for {} with {} and key {}, resulting in {}",
- path, item, extendedPath);
return extendedPath;
} else {
InstanceIdentifier<N> extendedPath = path.child(item);
- LOG.debug("Building a new child iid for {} with {}, resulting in {}",
- path, item, extendedPath);
return extendedPath;
}
}
*/
package org.opendaylight.ovsdb.southbound.transactions.md;
+import static org.opendaylight.ovsdb.southbound.SouthboundUtil.schemaMismatchLog;
+
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
}
ovsdbNodeBuilder.setInterfaceTypeEntry(ifEntryList);
} catch (SchemaVersionMismatchException e) {
- // We don't care about the exception stack trace here
- LOG.debug("Iface types not supported by this version of ovsdb: {}", e.getMessage());
+ schemaMismatchLog("iface_types", SouthboundConstants.OPEN_V_SWITCH, e);
}
}
}
ovsdbNodeBuilder.setDatapathTypeEntry(dpEntryList);
} catch (SchemaVersionMismatchException e) {
- // We don't care about the exception stack trace here
- LOG.debug("Datapath types not supported by this version of ovsdb: {}", e.getMessage());
+ schemaMismatchLog("datapath_types", SouthboundConstants.OPEN_V_SWITCH, e);
}
}
package org.opendaylight.ovsdb.southbound.transactions.md;
+import static org.opendaylight.ovsdb.southbound.SouthboundUtil.schemaMismatchLog;
+
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.ArrayList;
}
}
} catch (SchemaVersionMismatchException e) {
- // We don't care about the exception stack trace here
- LOG.warn("protocol not supported by this version of ovsdb: {}", e.getMessage());
+ schemaMismatchLog("protocols", "Bridge", e);
}
return result;
}
}
}
} catch (SchemaVersionMismatchException e) {
- LOG.debug("auto_attach column for Bridge Table unsupported for this version of ovsdb schema. {}", e);
+ schemaMismatchLog("auto_attach", "Bridge", e);
}
}
package org.opendaylight.ovsdb.southbound.transactions.md;
+import static org.opendaylight.ovsdb.southbound.SouthboundUtil.schemaMismatchLog;
+
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
ovsdbTerminationPointBuilder.setInterfaceLldp(interfaceLldpList);
}
} catch (SchemaVersionMismatchException e) {
- // We don't care about the exception stack trace here
- LOG.debug("lldp column for Interface Table unsupported for this version of ovsdb schema. {}", e.getMessage());
+ schemaMismatchLog("lldp", "Interface", e);
}
}
ovsdbTerminationPointBuilder.setInterfaceBfdStatus(interfaceBfdStatusList);
}
} catch (SchemaVersionMismatchException e) {
- // We don't care about the exception stack trace here
- LOG.debug("bfd-status column for Interface Table unsupported for this version of ovsdb schema. {}", e.getMessage());
+ schemaMismatchLog("bfd", "Interface", e);
}
}
ovsdbTerminationPointBuilder.setInterfaceBfd(interfaceBfdList);
}
} catch (SchemaVersionMismatchException e) {
- // We don't care about the exception stack trace here
- LOG.debug("bfd column for Interface Table unsupported for this version of ovsdb schema. {}", e.getMessage());
+ schemaMismatchLog("bfd", "Interface", e);
+
}
}
transactInvokers = new HashMap();
MemberModifier.field(OvsdbConnectionInstance.class, "transactInvokers").set(ovsdbConnectionInstance , transactInvokers);
ovsdbConnectionInstance.createTransactInvokers();
- verify(ovsdbConnectionInstance, times(0)).getDatabases();
+ verify(ovsdbConnectionInstance, times(0)).getSchema(anyString());
//transactInvokers null case
MemberModifier.field(OvsdbConnectionInstance.class, "transactInvokers").set(ovsdbConnectionInstance , null);
- ListenableFuture<List<String>> listenableFuture = mock(ListenableFuture.class);
- List<String> databases = new ArrayList<>();
- databases.add("database1");
- databases.add("database2");
- doReturn(listenableFuture).when(ovsdbConnectionInstance).getDatabases();
- when(listenableFuture.get()).thenReturn(databases);
ListenableFuture<DatabaseSchema> listenableDbSchema = mock(ListenableFuture.class);
DatabaseSchema dbSchema= mock(DatabaseSchema.class);
- DatabaseSchema dbSchema1= mock(DatabaseSchema.class);
doReturn(listenableDbSchema).when(ovsdbConnectionInstance).getSchema(anyString());
- when(listenableDbSchema.get()).thenReturn(dbSchema).thenReturn(dbSchema1);
+ when(listenableDbSchema.get()).thenReturn(dbSchema);
ovsdbConnectionInstance.createTransactInvokers();
- verify(ovsdbConnectionInstance).getDatabases();
- verify(ovsdbConnectionInstance, times(2)).getSchema(anyString());
+ verify(ovsdbConnectionInstance).getSchema(anyString());
Map<DatabaseSchema,TransactInvoker> testTransactInvokers = Whitebox.getInternalState(ovsdbConnectionInstance, "transactInvokers");
- assertEquals("Error, size of the hashmap is incorrect", 2, testTransactInvokers.size());
+ assertEquals("Error, size of the hashmap is incorrect", 1, testTransactInvokers.size());
}
@SuppressWarnings("unchecked")
package org.opendaylight.ovsdb.utils.ovsdb.it.utils;
-import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
private static final Logger LOG = LoggerFactory.getLogger(DockerOvs.class);
private static final String DEFAULT_DOCKER_FILE = "docker-ovs-2.5.1.yml";
private static final String DOCKER_FILE_PATH = "META-INF/docker-compose-files/";
- //private static final String[] HELP_CMD = {"docker-compose", "--help"};
- //private static final String[] EXEC_CMD_PFX = {"sudo", "docker-compose", "-f"};
private static final int COMPOSE_FILE_IDX = 3;
private static final String DEFAULT_OVSDB_HOST = "127.0.0.1";
private static final String[] PS_CMD = {"sudo", "docker-compose", "ps"};
private static final String[] PS_CMD_NO_SUDO = {"docker-compose", "ps"};
- private String[] upCmd = {"sudo", "docker-compose", "-f", null, "up", "-d"};
+ private String[] upCmd = {"sudo", "docker-compose", "-f", null, "up", "-d", "--force-recreate"};
private String[] downCmd = {"sudo", "docker-compose", "-f", null, "stop"};
+ private String[] execCmd = {"sudo", "docker-compose", "-f", null, "exec", null};
+
private File tmpDockerComposeFile;
- private List<String> ovsdbPorts;
boolean isRunning;
private String envServerAddress;
private String envServerPort;
private String envDockerComposeFile;
private boolean runDocker;
+ class DockerComposeServiceInfo {
+ public String name;
+ public String port;
+ }
+ private List<DockerComposeServiceInfo> dockerComposeServices = new ArrayList<DockerComposeServiceInfo>();
+
/**
* Get the array of system properties as pax exam Option objects for use in pax exam
* unit tests with Configuration annotation.
tmpDockerComposeFile = createTempDockerComposeFile(yamlFileName);
buildDockerComposeCommands();
- ovsdbPorts = extractPortsFromYaml();
+ parseDockerComposeYaml();
isRunning = false;
//We run this for A LONG TIME since on the first run docker must download the
//image from docker hub. In experience it takes significantly less than this
//even when downloading the image. Once the image is downloaded this command
//runs like that <snaps fingers>
- runProcess(60000, upCmd);
+ ProcUtils.runProcess(60000, upCmd);
isRunning = true;
waitForOvsdbServers(10 * 1000);
}
private void buildDockerComposeCommands() throws IOException, InterruptedException {
upCmd[COMPOSE_FILE_IDX] = tmpDockerComposeFile.toString();
downCmd[COMPOSE_FILE_IDX] = tmpDockerComposeFile.toString();
+ execCmd[COMPOSE_FILE_IDX] = tmpDockerComposeFile.toString();
- if (0 == tryProcess(5000, PS_CMD_NO_SUDO)) {
+ if (0 == ProcUtils.tryProcess(5000, PS_CMD_NO_SUDO)) {
LOG.info("DockerOvs.buildDockerComposeCommands docker-compose does not require sudo");
String[] tmp;
tmp = Arrays.copyOfRange(upCmd, 1, upCmd.length);
upCmd = tmp;
tmp = Arrays.copyOfRange(downCmd, 1, downCmd.length);
downCmd = tmp;
- } else if (0 == tryProcess(5000, PS_CMD)) {
+ tmp = Arrays.copyOfRange(execCmd, 1, execCmd.length);
+ execCmd = tmp;
+ } else if (0 == ProcUtils.tryProcess(5000, PS_CMD)) {
LOG.info("DockerOvs.buildDockerComposeCommands docker-compose requires sudo");
} else {
Assert.fail("docker-compose does not seem to work with or without sudo");
}
}
+
/**
* Get the IP address of the n'th OVS.
* @param ovsNumber which OVS?
if (!runDocker) {
return envServerPort;
}
- return ovsdbPorts.get(ovsNumber);
+ return dockerComposeServices.get(ovsNumber).port;
}
/**
* @return number of running OVS nodes
*/
public int getNumOvsNodes() {
- return ovsdbPorts.size();
+ return dockerComposeServices.size();
+ }
+
+ public String[] getExecCmdPrefix(int numOvs) {
+ String[] res = new String[execCmd.length];
+ System.arraycopy(execCmd, 0, res, 0, execCmd.length);
+ res[res.length - 1] = dockerComposeServices.get(numOvs).name;
+ return res;
+ }
+
+ public void runInContainer(int waitFor, int numOvs, String ... cmdWords) throws IOException, InterruptedException {
+ String[] pfx = getExecCmdPrefix(numOvs);
+ String[] cmd = new String[pfx.length + cmdWords.length];
+ System.arraycopy(pfx, 0, cmd, 0, pfx.length);
+ System.arraycopy(cmdWords, 0, cmd, pfx.length, cmdWords.length);
+ ProcUtils.runProcess(waitFor, cmd);
+ }
+
+ public void tryInContainer(int waitFor, int numOvs, String ... cmdWords) throws IOException, InterruptedException {
+ String[] pfx = getExecCmdPrefix(numOvs);
+ String[] cmd = new String[pfx.length + cmdWords.length];
+ System.arraycopy(pfx, 0, cmd, 0, pfx.length);
+ System.arraycopy(cmdWords, 0, cmd, pfx.length, cmdWords.length);
+ ProcUtils.tryProcess(waitFor, cmd);
}
/**
* Parse the docker-compose yaml file to extract the port mappings.
* @return a list of the external ports
*/
- private List<String> extractPortsFromYaml() {
+ private List<String> parseDockerComposeYaml() {
List<String> ports = new ArrayList<String>();
YamlReader yamlReader = null;
yamlReader = new YamlReader(new FileReader(tmpDockerComposeFile));
root = (Map) yamlReader.read();
} catch (FileNotFoundException e) {
- LOG.warn("DockerOvs.extractPortsFromYaml error reading yaml file", e);
+ LOG.warn("DockerOvs.parseDockerComposeYaml error reading yaml file", e);
return ports;
} catch (YamlException e) {
- LOG.warn("DockerOvs.extractPortsFromYaml error parsing yaml file", e);
+ LOG.warn("DockerOvs.parseDockerComposeYaml error parsing yaml file", e);
return ports;
}
if (null == root) {
return ports;
}
- for (Object map : root.values()) {
- List portMappings = (List) ((Map)map).get("ports");
+ for (Object entry : root.entrySet()) {
+ String key = ((Map.Entry<String,Map>)entry).getKey();
+ Map map = ((Map.Entry<String,Map>)entry).getValue();
+
+ DockerComposeServiceInfo svc = new DockerComposeServiceInfo();
+ svc.name = key;
+
+ List portMappings = (List) map.get("ports");
if (null == portMappings) {
continue;
}
}
String port = portMappingStr.substring(0, delim);
ports.add(port);
+ svc.port = port;
}
+ //TODO: think this through. What if there is no port?
+ dockerComposeServices.add(svc);
}
return ports;
@Override
public void close() throws Exception {
if (isRunning) {
- runProcess(5000, downCmd);
+ ProcUtils.runProcess(10000, downCmd);
isRunning = false;
}
private void waitForOvsdbServers(long waitFor) throws IOException, InterruptedException {
AtomicInteger numRunningOvs = new AtomicInteger(0);
- int numOvs = ovsdbPorts.size();
+ int numOvs = dockerComposeServices.size();
if (0 == numOvs) {
return;
}
}
}
- /*
- WIP - todo: need to extract teh service name from the yaml or receive it as a param
- private void validateDockerComposeVersion() throws IOException, InterruptedException {
- StringBuilder stringBuilder = new StringBuilder();
- runProcess(2000, stringBuilder, HELP_CMD);
- assertTrue("DockerOvs.validateDockerComposeVersion: docker-compose version does not support exec, try updating",
- stringBuilder.toString().contains(" exec "));
- }
-
- public String exec(long waitFor, String... execCmdWords) throws IOException, InterruptedException {
- List<String> execCmd = new ArrayList<String>(20);
- execCmd.addAll(Arrays.asList(EXEC_CMD_PFX));
- execCmd.add(tmpDockerComposeFile.toString());
- execCmd.add("exec");
- execCmd.add("ovs");
- execCmd.addAll(Arrays.asList(execCmdWords));
-
- StringBuilder stringBuilder = new StringBuilder();
- runProcess(waitFor, stringBuilder, execCmd.toArray(new String[0]));
- return stringBuilder.toString();
- }
- */
-
- /**
- * Run a process and assert the exit code is 0.
- * @param waitFor How long to wait for the command to execute
- * @param words The words of the command to run
- * @throws IOException if something goes wrong on the IO end
- * @throws InterruptedException If this thread is interrupted
- */
- private void runProcess(long waitFor, String... words) throws IOException, InterruptedException {
- runProcess(waitFor, null, words);
- }
-
- /**
- * Run a process, collect the stdout, and assert the exit code is 0.
- * @param waitFor How long to wait for the command to execute
- * @param capturedStdout Whatever the process wrote to standard out
- * @param words The words of the command to run
- * @throws IOException if something goes wrong on the IO end
- * @throws InterruptedException If this thread is interrupted
- */
- private void runProcess(long waitFor,StringBuilder capturedStdout, String... words)
- throws IOException, InterruptedException {
- int exitValue = tryProcess(waitFor, capturedStdout, words);
- Assert.assertEquals("DockerOvs.runProcess exit code is not 0", 0, exitValue);
- }
-
- /**
- * Run a process.
- * @param waitFor How long to wait for the command to execute
- * @param words The words of the command to run
- * @return The process's exit code
- * @throws IOException if something goes wrong on the IO end
- * @throws InterruptedException If this thread is interrupted
- */
- private int tryProcess(long waitFor, String... words) throws IOException, InterruptedException {
- return tryProcess(waitFor, null, words);
- }
-
- /**
- * Run a process, collect the stdout.
- * @param waitFor How long to wait (milliseconds) for the command to execute
- * @param capturedStdout Whatever the process wrote to standard out
- * @param words The words of the command to run
- * @return The process's exit code or -1 if the the command does not complete within waitFor milliseconds
- * @throws IOException if something goes wrong on the IO end
- * @throws InterruptedException If this thread is interrupted
- */
- private int tryProcess(long waitFor, StringBuilder capturedStdout, String... words)
- throws IOException, InterruptedException {
-
- LOG.info("DockerOvs.runProcess running \"{}\", waitFor {}", words, waitFor);
-
- Process proc = new ProcessBuilder(words).start();
- int exitValue = -1;
-
- // Use a try block to guarantee stdout and stderr are closed
- try (BufferedReader stdout = new BufferedReader(new InputStreamReader(proc.getInputStream()));
- BufferedReader stderr = new BufferedReader(new InputStreamReader(proc.getErrorStream()))) {
-
- exitValue = waitForExitValue(waitFor, proc);
-
- while (stderr.ready()) {
- LOG.warn("DockerOvs.runProcess [stderr]: {}", stderr.readLine());
- }
-
- StringBuilder stdoutStringBuilder = (capturedStdout != null) ? capturedStdout : new StringBuilder();
- int read;
- char[] buf = new char[1024];
- while (-1 != (read = stdout.read(buf))) {
- stdoutStringBuilder.append(buf, 0, read);
- }
-
- for (String line : stdoutStringBuilder.toString().split("\\n")) {
- LOG.info("DockerOvs.runProcess [stdout]: {}", line);
- }
- }
-
- return exitValue;
- }
-
- /**
- * Wait for a process to end.
- * @param waitFor how long to wait in milliseconds
- * @param proc Process object
- * @return the process's exit value or -1 if the process did not complete within waitFor milliseconds
- * @throws InterruptedException if this thread is interrupted
- */
- private int waitForExitValue(long waitFor, Process proc) throws InterruptedException {
- //Java 7 has no way to check whether a process is still running without blocking
- //until the process exits. What this hack does is checks the exitValue() which
- //throws an IllegalStateException if the process is still running still it does
- //not have a exit value. We catch that exception and implement our own timeout.
- //Once we no longer need to support Java 7, this has more elegant solutions.
- int exitValue = -1;
- long startTime = System.currentTimeMillis();
- while (true) {
- try {
- exitValue = proc.exitValue();
- break;
- } catch (IllegalThreadStateException e) {
- if ((System.currentTimeMillis() - startTime) < waitFor) {
- Thread.sleep(200);
- } else {
- LOG.warn("DockerOvs.waitForExitValue: timed out while waiting for command to complete", e);
- break;
- }
- }
- }
- return exitValue;
- }
-
/**
* Since the docker-compose file is a resource in the bundle and docker-compose needs it.
* in the file system, we copy it over - ugly but necessary.
return tmpFile;
}
+ /**
+ * Useful for debugging. Dump some interesting config
+ * @throws IOException If something goes wrong with reading the process output
+ * @throws InterruptedException because there's some sleeping in here
+ */
+ public void logState(int dockerInstance) throws IOException, InterruptedException {
+ tryInContainer(5000, dockerInstance, "ip", "addr");
+ tryInContainer(5000, dockerInstance, "ovs-vsctl", "show");
+ tryInContainer(5000, dockerInstance, "ovs-ofctl", "-OOpenFlow13", "show", "br-int");
+ tryInContainer(5000, dockerInstance, "ovs-ofctl", "-OOpenFlow13", "dump-flows", "br-int");
+ tryInContainer(5000, dockerInstance, "ip", "netns", "list");
+ }
+
}
--- /dev/null
+/*
+ * Copyright (c) 2016 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.ovsdb.it.utils;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+import org.junit.Assert;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Run subprocesses and log or return their output.
+ */
+public class ProcUtils {
+ private static final Logger LOG = LoggerFactory.getLogger(ProcUtils.class);
+
+ /**
+ * Run a process and assert the exit code is 0.
+ * @param waitFor How long to wait for the command to execute
+ * @param words The words of the command to run
+ * @throws IOException if something goes wrong on the IO end
+ * @throws InterruptedException If this thread is interrupted
+ */
+ public static void runProcess(long waitFor, String... words) throws
+ IOException, InterruptedException {
+ runProcess(waitFor, null, words);
+ }
+
+ /**
+ * Run a process, collect the stdout, and assert the exit code is 0.
+ * @param waitFor How long to wait for the command to execute
+ * @param capturedStdout Whatever the process wrote to standard out
+ * @param words The words of the command to run
+ * @throws IOException if something goes wrong on the IO end
+ * @throws InterruptedException If this thread is interrupted
+ */
+ public static void runProcess(long waitFor,StringBuilder capturedStdout, String... words)
+ throws IOException, InterruptedException {
+ int exitValue = tryProcess(waitFor, capturedStdout, words);
+ Assert.assertEquals("ProcUtils.runProcess exit code is not 0", 0, exitValue);
+ }
+
+ /**
+ * Run a process.
+ * @param waitFor How long to wait for the command to execute
+ * @param words The words of the command to run
+ * @return The process's exit code
+ * @throws IOException if something goes wrong on the IO end
+ * @throws InterruptedException If this thread is interrupted
+ */
+ public static int tryProcess(long waitFor, String... words) throws IOException, InterruptedException {
+ return tryProcess(waitFor, null, words);
+ }
+
+ /**
+ * Run a process, collect the stdout.
+ * @param waitFor How long to wait (milliseconds) for the command to execute
+ * @param capturedStdout Whatever the process wrote to standard out
+ * @param words The words of the command to run
+ * @return The process's exit code or -1 if the the command does not complete within waitFor milliseconds
+ * @throws IOException if something goes wrong on the IO end
+ * @throws InterruptedException If this thread is interrupted
+ */
+ public static int tryProcess(long waitFor, StringBuilder capturedStdout, String... words)
+ throws IOException, InterruptedException {
+
+ LOG.info("ProcUtils.runProcess running \"{}\", waitFor {}", words, waitFor);
+
+ Process proc = new ProcessBuilder(words).start();
+ int exitValue = -1;
+
+ // Use a try block to guarantee stdout and stderr are closed
+ try (BufferedReader stdout = new BufferedReader(new InputStreamReader(proc.getInputStream()));
+ BufferedReader stderr = new BufferedReader(new InputStreamReader(proc.getErrorStream()))) {
+
+ exitValue = waitForExitValue(waitFor, proc);
+
+ while (stderr.ready()) {
+ LOG.warn("ProcUtils.runProcess [stderr]: {}", stderr.readLine());
+ }
+
+ StringBuilder stdoutStringBuilder = (capturedStdout != null) ? capturedStdout : new StringBuilder();
+ int read;
+ char[] buf = new char[1024];
+ while (-1 != (read = stdout.read(buf))) {
+ stdoutStringBuilder.append(buf, 0, read);
+ }
+
+ for (String line : stdoutStringBuilder.toString().split("\\n")) {
+ LOG.info("ProcUtils.runProcess [stdout]: {}", line);
+ }
+ }
+
+ return exitValue;
+ }
+
+ /**
+ * Wait for a process to end.
+ * @param waitFor how long to wait in milliseconds
+ * @param proc Process object
+ * @return the process's exit value or -1 if the process did not complete within waitFor milliseconds
+ * @throws InterruptedException if this thread is interrupted
+ */
+ private static int waitForExitValue(long waitFor, Process proc) throws InterruptedException {
+ //Java 7 has no way to check whether a process is still running without blocking
+ //until the process exits. What this hack does is checks the exitValue() which
+ //throws an IllegalStateException if the process is still running still it does
+ //not have a exit value. We catch that exception and implement our own timeout.
+ //Once we no longer need to support Java 7, this has more elegant solutions.
+ int exitValue = -1;
+ long startTime = System.currentTimeMillis();
+ while (true) {
+ try {
+ exitValue = proc.exitValue();
+ break;
+ } catch (IllegalThreadStateException e) {
+ if ((System.currentTimeMillis() - startTime) < waitFor) {
+ Thread.sleep(200);
+ } else {
+ LOG.warn("ProcUtils.waitForExitValue: timed out while waiting for command to complete", e);
+ break;
+ }
+ }
+ }
+ return exitValue;
+ }
+}