From da199f68ebdebb8d99f034243a073245a03fb24a Mon Sep 17 00:00:00 2001 From: Madhu Venugopal Date: Tue, 1 Jul 2014 01:11:34 -0700 Subject: [PATCH] Plugin migration to use the new Schema independent Library. Plugin layer is completely migrated to use the new Schema independent Library. Since the existing plugin layer has a lot of Open_vSwitch assumption, this migration did not remove such an assumption and break functionalities. Rather, a few design compromises were made in an effort to make this transition smoother. Once these commits are merged, we will introduce more Schema independent APIs that will have no assumption on the underlying Schemas. Because of this reason, you will see a few places with access to OvsVswitchdSchemaConstants class, which indicates that the Open_vSwitch schema assumption is made. Also, there are a few "special" case handling done on the ConfigurationService to deal with existing API assumptions. These assumptions are marked as Special. Again, when the new APIs are introduced these Assumptions can be easily removed. The plugin layer changes helped in hardening the Library layer and hence resulted in some Library changes as well. Enough effort is invested in both the PAX-EXAM based IT and regular Plugin IT code to ensure smooth migration. Change-Id: Ie6365a23e3fa9b6ca4431d3eba7494330c8a07ca Signed-off-by: Madhu Venugopal --- commons/integrationtest/pom.xml | 4 + .../integrationtest/plugin/OvsdbPluginIT.java | 81 +- .../ovsdb/lib/MonitorCallBack.java | 3 +- .../ovsdb/lib/impl/OvsdbClientImpl.java | 8 +- .../jsonrpc/JsonRpcServiceBinderHandler.java | 41 +- .../ovsdb/lib/message/UpdateNotification.java | 13 +- .../ovsdb/lib/notation/json/Converter.java | 2 +- .../ovsdb/lib/operations/Operations.java | 8 + .../ovsdb/lib/operations/Update.java | 15 + .../ovsdb/lib/schema/ColumnSchema.java | 8 + .../ovsdb/lib/OvsdbClientTestIT.java | 4 +- plugin/pom.xml | 15 +- .../opendaylight/ovsdb/plugin/Activator.java | 13 +- .../ovsdb/plugin/ConfigurationService.java | 1503 ++++++----------- .../ovsdb/plugin/ConnectionService.java | 254 +-- .../plugin/IConnectionServiceInternal.java | 2 - .../ovsdb/plugin/InventoryService.java | 119 +- .../plugin/InventoryServiceInternal.java | 19 +- .../org/opendaylight/ovsdb/plugin/NodeDB.java | 120 +- .../ovsdb/plugin/OVSDBConfigService.java | 87 +- .../ovsdb/plugin/OVSDBInventoryListener.java | 8 +- .../plugin/OvsVswitchdSchemaConstants.java | 13 + .../ovsdb/plugin/OvsdbTestAddBridgeIT.java | 3 +- .../ovsdb/plugin/OvsdbTestAddPortIT.java | 3 +- .../ovsdb/plugin/OvsdbTestAddTunnelIT.java | 4 +- .../ovsdb/plugin/OvsdbTestAddVlanIT.java | 3 +- .../ovsdb/plugin/OvsdbTestBase.java | 19 +- .../ovsdb/plugin/OvsdbTestBridgeConfigIT.java | 3 +- .../ovsdb/plugin/OvsdbTestDeletePortIT.java | 3 +- .../plugin/OvsdbTestGetBridgeDomainsIT.java | 4 +- .../ovsdb/plugin/OvsdbTestSetManagerIT.java | 4 +- .../plugin/OvsdbTestSetOFControllerIT.java | 4 +- pom.xml | 7 +- .../schema/openvswitch/BridgeTestCases.java | 25 +- .../openvswitch/ControllerTestCases.java | 24 +- .../schema/openvswitch/MonitorTestCases.java | 2 +- 36 files changed, 1082 insertions(+), 1366 deletions(-) diff --git a/commons/integrationtest/pom.xml b/commons/integrationtest/pom.xml index b99370175..019ebfcb8 100644 --- a/commons/integrationtest/pom.xml +++ b/commons/integrationtest/pom.xml @@ -76,11 +76,15 @@ ovsdb_plugin ${ovsdb.plugin.version} + org.opendaylight.ovsdb ovsdb_schema.Open_vSwitch diff --git a/integrationtest/src/test/java/org/opendaylight/ovsdb/integrationtest/plugin/OvsdbPluginIT.java b/integrationtest/src/test/java/org/opendaylight/ovsdb/integrationtest/plugin/OvsdbPluginIT.java index 5a0301fdb..d64112c46 100644 --- a/integrationtest/src/test/java/org/opendaylight/ovsdb/integrationtest/plugin/OvsdbPluginIT.java +++ b/integrationtest/src/test/java/org/opendaylight/ovsdb/integrationtest/plugin/OvsdbPluginIT.java @@ -12,6 +12,7 @@ package org.opendaylight.ovsdb.integrationtest.plugin; 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.assertTrue; import static org.junit.Assert.fail; import static org.ops4j.pax.exam.CoreOptions.junitBundles; @@ -25,6 +26,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; @@ -36,13 +38,18 @@ import org.junit.runner.RunWith; import org.opendaylight.controller.sal.connection.ConnectionConstants; import org.opendaylight.controller.sal.core.Node; import org.opendaylight.controller.sal.utils.ServiceHelper; +import org.opendaylight.controller.sal.utils.Status; import org.opendaylight.ovsdb.integrationtest.ConfigurationBundles; import org.opendaylight.ovsdb.integrationtest.OvsdbIntegrationTestBase; import org.opendaylight.ovsdb.lib.OvsdbClient; import org.opendaylight.ovsdb.lib.OvsdbConnectionInfo; +import org.opendaylight.ovsdb.lib.notation.Row; import org.opendaylight.ovsdb.plugin.Connection; import org.opendaylight.ovsdb.plugin.IConnectionServiceInternal; import org.opendaylight.ovsdb.plugin.OVSDBConfigService; +import org.opendaylight.ovsdb.plugin.StatusWithUuid; +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; @@ -52,6 +59,9 @@ 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; + @RunWith(PaxExam.class) public class OvsdbPluginIT extends OvsdbIntegrationTestBase { private Logger log = LoggerFactory.getLogger(OvsdbPluginIT.class); @@ -78,6 +88,7 @@ public class OvsdbPluginIT extends OvsdbIntegrationTestBase { ConfigurationBundles.controllerBundles(), ConfigurationBundles.ovsdbLibraryBundles(), + ConfigurationBundles.ovsdbDefaultSchemaBundles(), mavenBundle("org.opendaylight.ovsdb", "ovsdb_plugin").versionAsInProject(), junitBundles() ); @@ -154,7 +165,7 @@ public class OvsdbPluginIT extends OvsdbIntegrationTestBase { } @Test - public void tableTest() throws Exception { + public void apiTests() throws Exception { Thread.sleep(5000); IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this); @@ -169,11 +180,77 @@ public class OvsdbPluginIT extends OvsdbIntegrationTestBase { identifier = connectionInfo.getRemoteAddress().getHostAddress()+":"+connectionInfo.getRemotePort(); } assertEquals(Node.fromString("OVS|"+identifier), connectionService.getNodes().get(0)); - System.out.println("Nodes = "+ connectionService.getNodes()); + /* + * Test sequence : + * 1. Print Cache and Assert to make sure the bridge is not created yet. + * 2. Create a bridge with a valid parent_uuid & Assert to make sure the return status is success. + * 3. Assert to make sure the bridge is created with a valid Uuid. + * 4. Delete the bridge & Assert to make sure the return status is success. + * 5. Assert to make sure the bridge is deleted + */ + + this.endToEndApiTest(connection, getOpenVSwitchTableUUID(connection)); + + /* + * Repeat all of the above tests without the parent_uuid + */ + + this.endToEndApiTest(connection, null); + } + + public void endToEndApiTest(Connection connection, String parentUuid) throws Exception { + // 1. Print Cache and Assert to make sure the bridge is not created yet. + printCache(); + + // 2. Create a bridge with a valid parent_uuid & Assert to make sure the return status is success. + StatusWithUuid status = insertBridge(connection, parentUuid); + assertTrue(status.isSuccess()); + + Thread.sleep(2000); // TODO : Remove this Sleep once the Select operation is resolved. + + // 3. Assert to make sure the bridge is created with a valid Uuid. + printCache(); + Bridge bridge = connection.getClient().getTypedRowWrapper(Bridge.class, null); + Row bridgeRow = ovsdbConfigService.getRow(node, bridge.getSchema().getName(), status.getUuid().toString()); + assertNotNull(bridgeRow); + bridge = connection.getClient().getTypedRowWrapper(Bridge.class, bridgeRow); + assertEquals(bridge.getUuid(), status.getUuid()); + // 4. Delete the bridge & Assert to make sure the return status is success. + Status delStatus = ovsdbConfigService.deleteRow(node, bridge.getSchema().getName(), status.getUuid().toString()); + assertTrue(delStatus.isSuccess()); + Thread.sleep(2000); // TODO : Remove this Sleep once the Select operation is resolved. + + // 5. Assert to make sure the bridge is deleted + bridgeRow = ovsdbConfigService.getRow(node, bridge.getSchema().getName(), status.getUuid().toString()); + assertNull(bridgeRow); + } + + public StatusWithUuid insertBridge(Connection connection, String parentUuid) throws Exception { + Bridge bridge = connection.getClient().createTypedRowWrapper(Bridge.class); + bridge.setName("br_test1"); + bridge.setStatus(ImmutableMap.of("key", "value")); + bridge.setFloodVlans(Sets.newHashSet(34)); + return ovsdbConfigService.insertRow(node, bridge.getSchema().getName(), parentUuid, bridge.getRow()); + } + + public String getOpenVSwitchTableUUID(Connection connection) throws Exception { + OpenVSwitch openVSwitch = connection.getClient().getTypedRowWrapper(OpenVSwitch.class, null); + ConcurrentMap row = ovsdbConfigService.getRows(node, openVSwitch.getSchema().getName()); + if (row == null || row.size() == 0) return null; + return (String)row.keySet().toArray()[0]; + } + + public void printCache() throws Exception { List tables = ovsdbConfigService.getTables(node); System.out.println("Tables = "+tables); assertNotNull(tables); + for (String table : tables) { + System.out.println("Table "+table); + ConcurrentMap row = ovsdbConfigService.getRows(node, table); + System.out.println(row); + } } + } diff --git a/library/src/main/java/org/opendaylight/ovsdb/lib/MonitorCallBack.java b/library/src/main/java/org/opendaylight/ovsdb/lib/MonitorCallBack.java index d4d712836..5e8127cf6 100644 --- a/library/src/main/java/org/opendaylight/ovsdb/lib/MonitorCallBack.java +++ b/library/src/main/java/org/opendaylight/ovsdb/lib/MonitorCallBack.java @@ -13,10 +13,11 @@ package org.opendaylight.ovsdb.lib; import org.opendaylight.ovsdb.lib.message.TableUpdates; +import org.opendaylight.ovsdb.lib.schema.DatabaseSchema; public interface MonitorCallBack { - void update(TableUpdates result); + void update(TableUpdates result, DatabaseSchema dbSchema); void exception(Throwable t); } diff --git a/library/src/main/java/org/opendaylight/ovsdb/lib/impl/OvsdbClientImpl.java b/library/src/main/java/org/opendaylight/ovsdb/lib/impl/OvsdbClientImpl.java index 9efc10799..a396a0e1d 100644 --- a/library/src/main/java/org/opendaylight/ovsdb/lib/impl/OvsdbClientImpl.java +++ b/library/src/main/java/org/opendaylight/ovsdb/lib/impl/OvsdbClientImpl.java @@ -85,8 +85,8 @@ public class OvsdbClientImpl implements OvsdbClient { if (rpcCallback == null) { OvsdbRPC.Callback temp = new OvsdbRPC.Callback() { @Override - public void update(Object node, UpdateNotification upadateNotification) { - Object key = upadateNotification.getContext(); + public void update(Object node, UpdateNotification updateNotification) { + Object key = updateNotification.getContext(); CallbackContext callbackContext = monitorCallbacks.get(key); MonitorCallBack monitorCallBack = callbackContext.monitorCallBack; if (monitorCallBack == null) { @@ -94,7 +94,7 @@ public class OvsdbClientImpl implements OvsdbClient { logger.info("callback received with context {}, but no known handler. Ignoring!", key); return; } - _transformingCallback(upadateNotification.getUpdates(), monitorCallBack, callbackContext.schema); + _transformingCallback(updateNotification.getUpdates(), monitorCallBack, callbackContext.schema); } @Override @@ -127,7 +127,7 @@ public class OvsdbClientImpl implements OvsdbClient { } TableUpdates updates = new TableUpdates(tableUpdateMap); - monitorCallBack.update(updates); + monitorCallBack.update(updates, dbSchema); } } diff --git a/library/src/main/java/org/opendaylight/ovsdb/lib/jsonrpc/JsonRpcServiceBinderHandler.java b/library/src/main/java/org/opendaylight/ovsdb/lib/jsonrpc/JsonRpcServiceBinderHandler.java index 8b93dffed..14242ea82 100644 --- a/library/src/main/java/org/opendaylight/ovsdb/lib/jsonrpc/JsonRpcServiceBinderHandler.java +++ b/library/src/main/java/org/opendaylight/ovsdb/lib/jsonrpc/JsonRpcServiceBinderHandler.java @@ -13,6 +13,8 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -25,6 +27,7 @@ import com.google.common.util.concurrent.SettableFuture; public class JsonRpcServiceBinderHandler extends ChannelInboundHandlerAdapter { protected static final Logger logger = LoggerFactory.getLogger(JsonRpcServiceBinderHandler.class); Map> waitingForReply = Maps.newHashMap(); + ExecutorService executorService = Executors.newFixedThreadPool(10); JsonRpcEndpoint factory = null; Object context = null; @@ -41,23 +44,33 @@ public class JsonRpcServiceBinderHandler extends ChannelInboundHandlerAdapter { } @Override - public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + public void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception { + executorService.execute(new Runnable() { + @Override + public void run() { + if (msg instanceof JsonNode) { + JsonNode jsonNode = (JsonNode) msg; + if (jsonNode.has("result")) { + try { + factory.processResult(jsonNode); + } catch (NoSuchMethodException e) { + /* + ChannelRead is a method invoked during Netty message receive event. + The only sane thing we can do is to print a meaningful error message. + */ + logger.error("NoSuchMethodException when handling "+msg.toString(), e); + } + } else if (jsonNode.hasNonNull("method")) { + if (jsonNode.has("id") && !Strings.isNullOrEmpty(jsonNode.get("id").asText())) { + factory.processRequest(context, jsonNode); + } + } - if (msg instanceof JsonNode) { - JsonNode jsonNode = (JsonNode) msg; - - if (jsonNode.has("result")) { - factory.processResult(jsonNode); - } else if (jsonNode.hasNonNull("method")) { - if (jsonNode.has("id") && !Strings.isNullOrEmpty(jsonNode.get("id").asText())) { - factory.processRequest(context, jsonNode); + return; } + ctx.channel().close(); } - - return; - } - - ctx.channel().close(); + }); } @Override diff --git a/library/src/main/java/org/opendaylight/ovsdb/lib/message/UpdateNotification.java b/library/src/main/java/org/opendaylight/ovsdb/lib/message/UpdateNotification.java index cf7412c05..6a084e187 100644 --- a/library/src/main/java/org/opendaylight/ovsdb/lib/message/UpdateNotification.java +++ b/library/src/main/java/org/opendaylight/ovsdb/lib/message/UpdateNotification.java @@ -9,15 +9,17 @@ */ package org.opendaylight.ovsdb.lib.message; +import org.opendaylight.ovsdb.lib.notation.json.Converter.UpdateNotificationConverter; +import org.opendaylight.ovsdb.lib.schema.DatabaseSchema; + import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.databind.JsonNode; -import org.opendaylight.ovsdb.lib.message.temp.TableUpdates; -import org.opendaylight.ovsdb.lib.notation.json.Converter.UpdateNotificationConverter; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; @JsonDeserialize(converter = UpdateNotificationConverter.class) public class UpdateNotification { Object context; + DatabaseSchema databaseSchema; TableUpdates update; private JsonNode updatesJson; @@ -48,4 +50,11 @@ public class UpdateNotification { public JsonNode getUpdates() { return updatesJson; } + + public DatabaseSchema getDatabaseSchema() { + return databaseSchema; + } + public void setDatabaseSchema(DatabaseSchema databaseSchema) { + this.databaseSchema = databaseSchema; + } } diff --git a/library/src/main/java/org/opendaylight/ovsdb/lib/notation/json/Converter.java b/library/src/main/java/org/opendaylight/ovsdb/lib/notation/json/Converter.java index 017122230..e94af9114 100644 --- a/library/src/main/java/org/opendaylight/ovsdb/lib/notation/json/Converter.java +++ b/library/src/main/java/org/opendaylight/ovsdb/lib/notation/json/Converter.java @@ -9,7 +9,7 @@ */ package org.opendaylight.ovsdb.lib.notation.json; -import org.opendaylight.ovsdb.lib.message.temp.TableUpdates; +import org.opendaylight.ovsdb.lib.message.TableUpdates; import org.opendaylight.ovsdb.lib.message.UpdateNotification; import org.opendaylight.ovsdb.lib.notation.OvsDBMap; import org.opendaylight.ovsdb.lib.notation.OvsDBSet; diff --git a/library/src/main/java/org/opendaylight/ovsdb/lib/operations/Operations.java b/library/src/main/java/org/opendaylight/ovsdb/lib/operations/Operations.java index 19d7b9e6e..3671e514e 100644 --- a/library/src/main/java/org/opendaylight/ovsdb/lib/operations/Operations.java +++ b/library/src/main/java/org/opendaylight/ovsdb/lib/operations/Operations.java @@ -35,6 +35,14 @@ public class Operations { return new Update<>(schema); } + public > Update update(TypedBaseTable typedTable) { + return new Update<>(typedTable); + } + + public > Update update(TableSchema schema, Row row) { + return new Update<>(schema, row); + } + public > Delete delete(TableSchema schema) { return new Delete<>(schema); } diff --git a/library/src/main/java/org/opendaylight/ovsdb/lib/operations/Update.java b/library/src/main/java/org/opendaylight/ovsdb/lib/operations/Update.java index 3f71b515d..1670e9370 100644 --- a/library/src/main/java/org/opendaylight/ovsdb/lib/operations/Update.java +++ b/library/src/main/java/org/opendaylight/ovsdb/lib/operations/Update.java @@ -12,13 +12,16 @@ package org.opendaylight.ovsdb.lib.operations; +import java.util.Collection; import java.util.List; import java.util.Map; import org.opendaylight.ovsdb.lib.notation.Column; import org.opendaylight.ovsdb.lib.notation.Condition; +import org.opendaylight.ovsdb.lib.notation.Row; import org.opendaylight.ovsdb.lib.schema.ColumnSchema; import org.opendaylight.ovsdb.lib.schema.TableSchema; +import org.opendaylight.ovsdb.lib.schema.typed.TypedBaseTable; import com.google.common.collect.Lists; import com.google.common.collect.Maps; @@ -42,6 +45,18 @@ public class Update> extends Operation implements Co return this; } + public Update(TableSchema schema, Row row) { + super(schema, UPDATE); + Collection> columns = row.getColumns(); + for (Column column : columns) { + this.set(column); + } + } + + public Update(TypedBaseTable typedTable) { + this(typedTable.getSchema(), typedTable.getRow()); + } + public , D> Update set(ColumnSchema columnSchema, D value) { columnSchema.validate(value); Object untypedValue = columnSchema.getNormalizeData(value); diff --git a/library/src/main/java/org/opendaylight/ovsdb/lib/schema/ColumnSchema.java b/library/src/main/java/org/opendaylight/ovsdb/lib/schema/ColumnSchema.java index 27aef09ca..da9602604 100644 --- a/library/src/main/java/org/opendaylight/ovsdb/lib/schema/ColumnSchema.java +++ b/library/src/main/java/org/opendaylight/ovsdb/lib/schema/ColumnSchema.java @@ -64,6 +64,14 @@ public class ColumnSchema, D> { return new Condition(this.getName(), Function.LESS_THAN_OR_EQUALS, data); } + public Condition opIncludes(D data) { + return new Condition(this.getName(), Function.INCLUDES, data); + } + + public Condition opExcludes(D data) { + return new Condition(this.getName(), Function.EXCLUDES, data); + } + // --- Operations on the column ----------//:w diff --git a/library/src/test/java/org/opendaylight/ovsdb/lib/OvsdbClientTestIT.java b/library/src/test/java/org/opendaylight/ovsdb/lib/OvsdbClientTestIT.java index daf6fb8af..f8360ddf5 100644 --- a/library/src/test/java/org/opendaylight/ovsdb/lib/OvsdbClientTestIT.java +++ b/library/src/test/java/org/opendaylight/ovsdb/lib/OvsdbClientTestIT.java @@ -97,7 +97,7 @@ public class OvsdbClientTestIT extends OvsdbTestBase { MonitorHandle monitor = ovs.monitor(dbSchema, monitorRequests, new MonitorCallBack() { @Override - public void update(TableUpdates result) { + public void update(TableUpdates result, DatabaseSchema dbSchema) { results.add(result); System.out.println("result = " + result); } @@ -168,7 +168,7 @@ public class OvsdbClientTestIT extends OvsdbTestBase { MonitorHandle monitor = ovs.monitor(dbSchema, monitorRequests, new MonitorCallBack() { @Override - public void update(TableUpdates result) { + public void update(TableUpdates result, DatabaseSchema dbSchema) { results.add(result); } diff --git a/plugin/pom.xml b/plugin/pom.xml index 948d94b64..827088885 100755 --- a/plugin/pom.xml +++ b/plugin/pom.xml @@ -14,6 +14,9 @@ true + 1.0.0-SNAPSHOT + 1.0.0-SNAPSHOT + 1.0.0-SNAPSHOT @@ -115,6 +118,16 @@ ovsdb_library 1.0.0-SNAPSHOT + + org.opendaylight.ovsdb + ovsdb_schema.Open_vSwitch + ${schema.Open_vSwitch.version} + + + org.opendaylight.ovsdb + ovsdb_schema.hardware_vtep + ${schema.hardware_vtep.version} + org.slf4j slf4j-api @@ -150,11 +163,11 @@ org.opendaylight.controller.clustering.services, org.opendaylight.controller.sal.networkconfig.bridgedomain, org.opendaylight.ovsdb.lib.table, - org.opendaylight.ovsdb.plugin, org.opendaylight.ovsdb.lib.notation, org.opendaylight.ovsdb.lib.database, org.opendaylight.ovsdb.lib.operations, org.opendaylight.ovsdb.lib.message, + org.opendaylight.ovsdb.schema.openvswitch, org.apache.commons.lang3.builder, org.apache.commons.lang3.tuple, org.apache.felix.dm, diff --git a/plugin/src/main/java/org/opendaylight/ovsdb/plugin/Activator.java b/plugin/src/main/java/org/opendaylight/ovsdb/plugin/Activator.java index 6c0773c5b..d2264e0e1 100644 --- a/plugin/src/main/java/org/opendaylight/ovsdb/plugin/Activator.java +++ b/plugin/src/main/java/org/opendaylight/ovsdb/plugin/Activator.java @@ -84,6 +84,10 @@ public class Activator extends ComponentActivatorAbstractBase { .setService(InventoryServiceInternal.class) .setCallbacks("setInventoryServiceInternal", "unsetInventoryServiceInternal") .setRequired(true)); + c.add(createServiceDependency() + .setService(IClusterGlobalServices.class) + .setCallbacks("setClusterServices", "unsetClusterServices") + .setRequired(false)); } if (imp.equals(ConnectionService.class)) { @@ -100,10 +104,6 @@ public class Activator extends ComponentActivatorAbstractBase { .setService(InventoryServiceInternal.class) .setCallbacks("setInventoryServiceInternal", "unsetInventoryServiceInternal") .setRequired(true)); - c.add(createServiceDependency() - .setService(IClusterGlobalServices.class) - .setCallbacks("setClusterServices", "unsetClusterServices") - .setRequired(false)); c.add(createServiceDependency() .setService(OvsdbConnection.class) .setCallbacks("setOvsdbConnection", "unsetOvsdbConnection") @@ -121,6 +121,11 @@ public class Activator extends ComponentActivatorAbstractBase { .setCallbacks("setPluginOutInventoryServices", "unsetPluginOutInventoryServices") .setRequired(true)); + c.add(createServiceDependency() + .setService(OVSDBConfigService.class) + .setCallbacks("setConfigService", "unsetConfigService") + .setRequired(false)); + } if (imp.equals(NodeFactory.class)) { diff --git a/plugin/src/main/java/org/opendaylight/ovsdb/plugin/ConfigurationService.java b/plugin/src/main/java/org/opendaylight/ovsdb/plugin/ConfigurationService.java index 00d3066e2..1b9e6bfd2 100644 --- a/plugin/src/main/java/org/opendaylight/ovsdb/plugin/ConfigurationService.java +++ b/plugin/src/main/java/org/opendaylight/ovsdb/plugin/ConfigurationService.java @@ -11,14 +11,12 @@ package org.opendaylight.ovsdb.plugin; import static org.opendaylight.ovsdb.lib.operations.Operations.op; -import java.io.IOException; import java.math.BigInteger; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; -import java.util.LinkedHashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -27,6 +25,7 @@ import java.util.concurrent.ExecutionException; import org.eclipse.osgi.framework.console.CommandInterpreter; import org.eclipse.osgi.framework.console.CommandProvider; +import org.opendaylight.controller.clustering.services.IClusterGlobalServices; import org.opendaylight.controller.sal.connection.ConnectionConstants; import org.opendaylight.controller.sal.core.Node; import org.opendaylight.controller.sal.core.NodeConnector; @@ -35,51 +34,31 @@ import org.opendaylight.controller.sal.networkconfig.bridgedomain.IPluginInBridg import org.opendaylight.controller.sal.utils.Status; import org.opendaylight.controller.sal.utils.StatusCode; import org.opendaylight.ovsdb.lib.OvsdbClient; -import org.opendaylight.ovsdb.lib.database.OVSInstance; import org.opendaylight.ovsdb.lib.database.OvsdbType; -import org.opendaylight.ovsdb.lib.message.TransactBuilder; import org.opendaylight.ovsdb.lib.notation.Column; -import org.opendaylight.ovsdb.lib.notation.Condition; -import org.opendaylight.ovsdb.lib.notation.Function; -import org.opendaylight.ovsdb.lib.notation.Mutation; import org.opendaylight.ovsdb.lib.notation.Mutator; -import org.opendaylight.ovsdb.lib.notation.OvsDBMap; import org.opendaylight.ovsdb.lib.notation.OvsDBSet; import org.opendaylight.ovsdb.lib.notation.Row; import org.opendaylight.ovsdb.lib.notation.UUID; -import org.opendaylight.ovsdb.lib.operations.DeleteOperation; import org.opendaylight.ovsdb.lib.operations.Insert; -import org.opendaylight.ovsdb.lib.operations.InsertOperation; -import org.opendaylight.ovsdb.lib.operations.MutateOperation; import org.opendaylight.ovsdb.lib.operations.Operation; import org.opendaylight.ovsdb.lib.operations.OperationResult; import org.opendaylight.ovsdb.lib.operations.TransactionBuilder; -import org.opendaylight.ovsdb.lib.operations.UpdateOperation; import org.opendaylight.ovsdb.lib.schema.ColumnSchema; import org.opendaylight.ovsdb.lib.schema.DatabaseSchema; import org.opendaylight.ovsdb.lib.schema.GenericTableSchema; import org.opendaylight.ovsdb.lib.schema.TableSchema; -import org.opendaylight.ovsdb.lib.table.Bridge; -import org.opendaylight.ovsdb.lib.table.Controller; -import org.opendaylight.ovsdb.lib.table.IPFIX; -import org.opendaylight.ovsdb.lib.table.Interface; -import org.opendaylight.ovsdb.lib.table.Manager; -import org.opendaylight.ovsdb.lib.table.Mirror; -import org.opendaylight.ovsdb.lib.table.NetFlow; -import org.opendaylight.ovsdb.lib.table.Open_vSwitch; -import org.opendaylight.ovsdb.lib.table.Port; -import org.opendaylight.ovsdb.lib.table.Qos; -import org.opendaylight.ovsdb.lib.table.Queue; -import org.opendaylight.ovsdb.lib.table.SFlow; -import org.opendaylight.ovsdb.lib.table.SSL; -import org.opendaylight.ovsdb.lib.table.Table; +import org.opendaylight.ovsdb.schema.openvswitch.Bridge; +import org.opendaylight.ovsdb.schema.openvswitch.Controller; +import org.opendaylight.ovsdb.schema.openvswitch.Interface; +import org.opendaylight.ovsdb.schema.openvswitch.Manager; +import org.opendaylight.ovsdb.schema.openvswitch.OpenVSwitch; +import org.opendaylight.ovsdb.schema.openvswitch.Port; import org.osgi.framework.BundleContext; import org.osgi.framework.FrameworkUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.util.concurrent.ListenableFuture; public class ConfigurationService implements IPluginInBridgeDomainConfigService, OVSDBConfigService, @@ -91,6 +70,8 @@ public class ConfigurationService implements IPluginInBridgeDomainConfigService, IConnectionServiceInternal connectionService; InventoryServiceInternal inventoryServiceInternal; boolean forceConnect = false; + protected static final String OPENFLOW_10 = "1.0"; + protected static final String OPENFLOW_13 = "1.3"; void init() { } @@ -149,560 +130,26 @@ public class ConfigurationService implements IPluginInBridgeDomainConfigService, } } - private Connection getConnection (Node node) { - Connection connection = connectionService.getConnection(node); - if (connection == null || !connection.getClient().isActive()) { - return null; - } - - return connection; - } - - /** - * Add a new bridge - * @param node Node serving this configuration service - * @param bridgeIdentifier String representation of a Bridge Connector - * @return Bridge Connector configurations - */ - @Override - public Status createBridgeDomain(Node node, String bridgeIdentifier, - Map configs) { - try{ - if (connectionService == null) { - logger.error("Couldn't refer to the ConnectionService"); - return new Status(StatusCode.NOSERVICE); - } - - Connection connection = this.getConnection(node); - if (connection == null) { - return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available"); - } - - Map> ovsTable = inventoryServiceInternal.getTableCache(node, Open_vSwitch.NAME.getName()); - String newBridge = "new_bridge"; - String newInterface = "new_interface"; - String newPort = "new_port"; - String newSwitch = "new_switch"; - - Operation addSwitchRequest = null; - - if(ovsTable != null){ - String ovsTableUUID = (String) ovsTable.keySet().toArray()[0]; - UUID bridgeUuidPair = new UUID(newBridge); - Mutation bm = new Mutation("bridges", Mutator.INSERT, bridgeUuidPair); - List mutations = new ArrayList(); - mutations.add(bm); - - UUID uuid = new UUID(ovsTableUUID); - Condition condition = new Condition("_uuid", Function.EQUALS, uuid); - List where = new ArrayList(); - where.add(condition); - addSwitchRequest = new MutateOperation(Open_vSwitch.NAME.getName(), where, mutations); - } - else{ - Open_vSwitch ovsTableRow = new Open_vSwitch(); - OvsDBSet bridges = new OvsDBSet(); - UUID bridgeUuidPair = new UUID(newBridge); - bridges.add(bridgeUuidPair); - ovsTableRow.setBridges(bridges); - addSwitchRequest = new InsertOperation(Open_vSwitch.NAME.getName(), newSwitch, ovsTableRow); - } - - Bridge bridgeRow = new Bridge(); - bridgeRow.setName(bridgeIdentifier); - OvsDBSet ports = new OvsDBSet(); - UUID port = new UUID(newPort); - ports.add(port); - bridgeRow.setPorts(ports); - InsertOperation addBridgeRequest = new InsertOperation(Bridge.NAME.getName(), newBridge, bridgeRow); - - Port portRow = new Port(); - portRow.setName(bridgeIdentifier); - OvsDBSet interfaces = new OvsDBSet(); - UUID interfaceid = new UUID(newInterface); - interfaces.add(interfaceid); - portRow.setInterfaces(interfaces); - InsertOperation addPortRequest = new InsertOperation(Port.NAME.getName(), newPort, portRow); - - Interface interfaceRow = new Interface(); - interfaceRow.setName(bridgeIdentifier); - interfaceRow.setType("internal"); - InsertOperation addIntfRequest = new InsertOperation(Interface.NAME.getName(), newInterface, interfaceRow); - - /* Update config version */ - String ovsTableUUID = (String) ovsTable.keySet().toArray()[0]; - Mutation bm = new Mutation("next_cfg", Mutator.SUM, 1); - List mutations = new ArrayList(); - mutations.add(bm); - - UUID uuid = new UUID(ovsTableUUID); - Condition condition = new Condition("_uuid", Function.EQUALS, uuid); - List where = new ArrayList(); - where.add(condition); - MutateOperation updateCfgVerRequest = new MutateOperation(Open_vSwitch.NAME.getName(), where, mutations); - - TransactBuilder transaction = new TransactBuilder(); - transaction.addOperations(new ArrayList( - Arrays.asList(addSwitchRequest, - addIntfRequest, - addPortRequest, - addBridgeRequest, - updateCfgVerRequest))); - - ListenableFuture> transResponse = connection.getClient().transactBuilder().execute(); - List tr = transResponse.get(); - List requests = transaction.getRequests(); - Status status = new Status(StatusCode.SUCCESS); - for (int i = 0; i < tr.size() ; i++) { - if (i < requests.size()) requests.get(i).setResult(tr.get(i)); - if (tr.get(i) != null && tr.get(i).getError() != null && tr.get(i).getError().trim().length() > 0) { - OperationResult result = tr.get(i); - status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails()); - } - } - - if (tr.size() > requests.size()) { - OperationResult result = tr.get(tr.size()-1); - logger.error("Error creating Bridge : {}\n Error : {}\n Details : {}", bridgeIdentifier, - result.getError(), - result.getDetails()); - status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails()); - } - if (status.isSuccess()) { - setBridgeOFController(node, bridgeIdentifier); - } - return status; - } catch(Exception e){ - logger.error("Error in createBridgeDomain(): ",e); - } - return new Status(StatusCode.INTERNALERROR); - } - - /** - * Create a Port Attached to a Bridge - * Ex. ovs-vsctl add-port br0 vif0 - * @param node Node serving this configuration service - * @param bridgeIdentifier String representation of a Bridge Domain - * @param portIdentifier String representation of a user defined Port Name - */ - @Override - public Status addPort(Node node, String bridgeIdentifier, String portIdentifier, - Map configs) { - try{ - if (connectionService == null) { - logger.error("Couldn't refer to the ConnectionService"); - return new Status(StatusCode.NOSERVICE); - } - Connection connection = this.getConnection(node); - if (connection == null) { - return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available"); - } - if (connection != null) { - Map> brTable = inventoryServiceInternal.getTableCache(node, Bridge.NAME.getName()); - String newBridge = "new_bridge"; - String newInterface = "new_interface"; - String newPort = "new_port"; - - if(brTable != null){ - Operation addBrMutRequest = null; - String brUuid = null; - for (String uuid : brTable.keySet()) { - Bridge bridge = (Bridge) brTable.get(uuid); - if (bridge.getName().contains(bridgeIdentifier)) { - brUuid = uuid; - } - } - - UUID brUuidPair = new UUID(newPort); - Mutation bm = new Mutation("ports", Mutator.INSERT, brUuidPair); - List mutations = new ArrayList(); - mutations.add(bm); - - UUID uuid = new UUID(brUuid); - Condition condition = new Condition("_uuid", Function.EQUALS, uuid); - List where = new ArrayList(); - where.add(condition); - addBrMutRequest = new MutateOperation(Bridge.NAME.getName(), where, mutations); - - OvsDBMap options = null; - String type = null; - OvsDBSet tags = null; - if (configs != null) { - type = (String) configs.get(ConfigConstants.TYPE); - Map customConfigs = (Map) configs.get(ConfigConstants.CUSTOM); - if (customConfigs != null) { - options = new OvsDBMap(); - for (String customConfig : customConfigs.keySet()) { - options.put(customConfig, customConfigs.get(customConfig)); - } - } - } - - Interface interfaceRow = new Interface(); - interfaceRow.setName(portIdentifier); - - if (type != null) { - logger.debug("Port type : " + type); - if (type.equalsIgnoreCase(OvsdbType.PortType.TUNNEL.name())) { - interfaceRow.setType((String)configs.get(ConfigConstants.TUNNEL_TYPE)); - if (options == null) options = new OvsDBMap(); - options.put("remote_ip", (String)configs.get(ConfigConstants.DEST_IP)); - } else if (type.equalsIgnoreCase(OvsdbType.PortType.VLAN.name())) { - tags = new OvsDBSet(); - tags.add(BigInteger.valueOf(Integer.parseInt((String)configs.get(ConfigConstants.VLAN)))); - } else if (type.equalsIgnoreCase(OvsdbType.PortType.PATCH.name()) || - type.equalsIgnoreCase(OvsdbType.PortType.INTERNAL.name())) { - interfaceRow.setType(type.toLowerCase()); - } - } - if (options != null) { - interfaceRow.setOptions(options); - } - - InsertOperation addIntfRequest = new InsertOperation(Interface.NAME.getName(), - newInterface, interfaceRow); - - Port portRow = new Port(); - portRow.setName(portIdentifier); - if (tags != null) portRow.setTag(tags); - OvsDBSet interfaces = new OvsDBSet(); - UUID interfaceid = new UUID(newInterface); - interfaces.add(interfaceid); - portRow.setInterfaces(interfaces); - InsertOperation addPortRequest = new InsertOperation(Port.NAME.getName(), newPort, portRow); - - TransactBuilder transaction = new TransactBuilder(); - transaction.addOperations(new ArrayList - (Arrays.asList(addBrMutRequest, addPortRequest, addIntfRequest))); - - ListenableFuture> transResponse = connection.getClient().transactBuilder().execute(); - List tr = transResponse.get(); - List requests = transaction.getRequests(); - Status status = new Status(StatusCode.SUCCESS); - for (int i = 0; i < tr.size() ; i++) { - if (i < requests.size()) requests.get(i).setResult(tr.get(i)); - if (tr.get(i).getError() != null && tr.get(i).getError().trim().length() > 0) { - OperationResult result = tr.get(i); - status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails()); - } - } - - if (tr.size() > requests.size()) { - OperationResult result = tr.get(tr.size()-1); - logger.error("Error creating Bridge : {}\n Error : {}\n Details : {}", bridgeIdentifier, - result.getError(), - result.getDetails()); - status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails()); - } - return status; - } - return new Status(StatusCode.INTERNALERROR); - } - } catch(Exception e){ - logger.error("Error in addPort()",e); - } - return new Status(StatusCode.INTERNALERROR); - } - - /** - * Implements the OVS Connection for Managers - * - * @param node Node serving this configuration service - * @param managerip String Representing IP and connection types - */ - @SuppressWarnings("unchecked") - public boolean setManager(Node node, String managerip) { - try{ - if (connectionService == null) { - logger.error("Couldn't refer to the ConnectionService"); - return false; - } - Connection connection = this.getConnection(node); - if (connection == null) { - return false; - } - - if (connection != null) { - String newmanager = "new_manager"; - - OVSInstance instance = OVSInstance.monitorOVS(); - - Map ovsoutter = new LinkedHashMap(); - Map ovsinner = new LinkedHashMap(); - ArrayList ovsalist1 = new ArrayList(); - ArrayList ovsalist2 = new ArrayList(); - ArrayList ovsalist3 = new ArrayList(); - ArrayList ovsalist4 = new ArrayList(); - - //OVS Table Update - ovsoutter.put("where", ovsalist1); - ovsalist1.add(ovsalist2); - ovsalist2.add("_uuid"); - ovsalist2.add("=="); - ovsalist2.add(ovsalist3); - ovsalist3.add("uuid"); - ovsalist3.add(instance.getUuid()); - ovsoutter.put("op", "update"); - ovsoutter.put("table", "Open_vSwitch"); - ovsoutter.put("row", ovsinner); - ovsinner.put("manager_options", ovsalist4); - ovsalist4.add("named-uuid"); - ovsalist4.add(newmanager); - - Map mgroutside = new LinkedHashMap(); - Map mgrinside = new LinkedHashMap(); - - //Manager Table Insert - mgroutside.put("uuid-name", newmanager); - mgroutside.put("op", "insert"); - mgroutside.put("table","Manager"); - mgroutside.put("row", mgrinside); - mgrinside.put("target", managerip); - - Object[] params = {"Open_vSwitch", ovsoutter, mgroutside}; - OvsdbMessage msg = new OvsdbMessage("transact", params); - - //connection.sendMessage(msg); - - } - }catch(Exception e){ - logger.error("Error in setManager(): ",e); - } - return true; - } - - @Override - public Status addBridgeDomainConfig(Node node, String bridgeIdentfier, - Map configs) { - String mgmt = (String)configs.get(ConfigConstants.MGMT); - if (mgmt != null) { - if (setManager(node, mgmt)) return new Status(StatusCode.SUCCESS); - } - return new Status(StatusCode.BADREQUEST); - } - - @Override - public Status addPortConfig(Node node, String bridgeIdentifier, String portIdentifier, - Map configs) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Status deletePort(Node node, String bridgeIdentifier, String portIdentifier) { - - try{ - if (connectionService == null) { - logger.error("Couldn't refer to the ConnectionService"); - return new Status(StatusCode.NOSERVICE); - } - - Connection connection = this.getConnection(node); - if (connection == null) { - return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available"); - } - - Map> brTable = inventoryServiceInternal.getTableCache(node, Bridge.NAME.getName()); - Map> portTable = inventoryServiceInternal.getTableCache(node, Port.NAME.getName()); - Operation delPortRequest = null; - String brUuid = null; - String portUuid = null; - if(brTable != null){ - for (String uuid : brTable.keySet()) { - Bridge bridge = (Bridge) brTable.get(uuid); - if (bridge.getName().contains(bridgeIdentifier)) { - brUuid = uuid; - } - } - } - if(portTable != null){ - for (String uuid : portTable.keySet()) { - Port port = (Port) portTable.get(uuid); - if (port.getName().contains(portIdentifier)) { - portUuid = uuid; - } - } - } - - UUID portUuidPair = new UUID(portUuid); - Mutation bm = new Mutation("ports", Mutator.DELETE, portUuidPair); - List mutations = new ArrayList(); - mutations.add(bm); - - UUID uuid = new UUID(brUuid); - Condition condition = new Condition("_uuid", Function.EQUALS, uuid); - List where = new ArrayList(); - where.add(condition); - delPortRequest = new MutateOperation(Bridge.NAME.getName(), where, mutations); - - TransactBuilder transaction = new TransactBuilder(); - transaction.addOperations(new ArrayList(Arrays.asList(delPortRequest))); - - ListenableFuture> transResponse = connection.getClient().transactBuilder().execute(); - List tr = transResponse.get(); - List requests = transaction.getRequests(); - Status status = new Status(StatusCode.SUCCESS); - for (int i = 0; i < tr.size() ; i++) { - if (i < requests.size()) requests.get(i).setResult(tr.get(i)); - if (tr.get(i).getError() != null && tr.get(i).getError().trim().length() > 0) { - OperationResult result = tr.get(i); - status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails()); - } - } - - if (tr.size() > requests.size()) { - OperationResult result = tr.get(tr.size()-1); - logger.error("Error creating Bridge : {}\n Error : {}\n Details : {}", bridgeIdentifier, - result.getError(), - result.getDetails()); - status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails()); - } - return status; - } catch(Exception e){ - logger.error("Error in deletePort()",e); - } - return new Status(StatusCode.INTERNALERROR); - } - - @Override - public Node getBridgeDomainNode(Node node, String bridgeIdentifier) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Map getPortConfigs(Node node, String bridgeIdentifier, - String portIdentifier) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Status removeBridgeDomainConfig(Node node, String bridgeIdentifier, - Map configs) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Status removePortConfig(Node node, String bridgeIdentifier, String portIdentifier, - Map configs) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Status deleteBridgeDomain(Node node, String bridgeIdentifier) { - - try { - if (connectionService == null) { - logger.error("Couldn't refer to the ConnectionService"); - return new Status(StatusCode.NOSERVICE); - } - Connection connection = this.getConnection(node); - if (connection == null) { - return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available"); - } - Map> ovsTable = inventoryServiceInternal.getTableCache(node, Open_vSwitch.NAME.getName()); - Map> brTable = inventoryServiceInternal.getTableCache(node, Bridge.NAME.getName()); - Operation delBrRequest = null; - String ovsUuid = null; - String brUuid = null; - - if (brTable != null) { - for (String uuid : brTable.keySet()) { - Bridge bridge = (Bridge) brTable.get(uuid); - if (bridge.getName().contains(bridgeIdentifier)) { - brUuid = uuid; - } - } - } - if (ovsTable != null) { - ovsUuid = (String) ovsTable.keySet().toArray()[0]; - } - UUID bridgeUuidPair = new UUID(brUuid); - Mutation bm = new Mutation("bridges", Mutator.DELETE, bridgeUuidPair); - List mutations = new ArrayList(); - mutations.add(bm); - - UUID uuid = new UUID(ovsUuid); - Condition condition = new Condition("_uuid", Function.EQUALS, uuid); - List where = new ArrayList(); - where.add(condition); - delBrRequest = new MutateOperation(Open_vSwitch.NAME.getName(), where, mutations); - - TransactBuilder transaction = new TransactBuilder(); - transaction.addOperations(new ArrayList(Arrays.asList(delBrRequest))); - - ListenableFuture> transResponse = connection.getClient().transactBuilder().execute(); - List tr = transResponse.get(); - List requests = transaction.getRequests(); - Status status = new Status(StatusCode.SUCCESS); - for (int i = 0; i < tr.size(); i++) { - if (i < requests.size()) requests.get(i).setResult(tr.get(i)); - if (tr.get(i) != null && tr.get(i).getError() != null && tr.get(i).getError().trim().length() > 0) { - OperationResult result = tr.get(i); - status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails()); - } - } + private IClusterGlobalServices clusterServices; - if (tr.size() > requests.size()) { - OperationResult result = tr.get(tr.size() - 1); - logger.error("Error deleting Bridge : {}\n Error : {}\n Details : {}", - bridgeIdentifier, result.getError(), result.getDetails()); - status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails()); - } - return status; - } catch (Exception e) { - logger.error("Error in deleteBridgeDomain(): ",e); - } - return new Status(StatusCode.INTERNALERROR); + public void setClusterServices(IClusterGlobalServices i) { + this.clusterServices = i; } - @Override - public Map getBridgeDomainConfigs(Node node, String bridgeIdentifier) { - // TODO Auto-generated method stub - return null; - } - - @Override - public List getBridgeDomains(Node node) { - List brlist = new ArrayList(); - Map> brTableCache = inventoryServiceInternal.getTableCache(node, Bridge.NAME.getName()); - if(brTableCache != null){ - for (String uuid : brTableCache.keySet()) { - Bridge bridge = (Bridge) brTableCache.get(uuid); - brlist.add(bridge.getName()); - } + public void unsetClusterServices(IClusterGlobalServices i) { + if (this.clusterServices == i) { + this.clusterServices = null; } - return brlist; } - @Override - public NodeConnector getNodeConnector(Node arg0, String arg1, String arg2) { - return null; - } - - Boolean setBridgeOFController(Node node, String bridgeIdentifier) { - if (connectionService == null) { - logger.error("Couldn't refer to the ConnectionService"); - return false; + private Connection getConnection (Node node) { + Connection connection = connectionService.getConnection(node); + if (connection == null || !connection.getClient().isActive()) { + return null; } - try{ - Map> brTableCache = inventoryServiceInternal.getTableCache(node, Bridge.NAME.getName()); - for (String uuid : brTableCache.keySet()) { - Bridge bridge = (Bridge)brTableCache.get(uuid); - if (bridge.getName().contains(bridgeIdentifier)) { - return connectionService.setOFController(node, uuid); - } - } - } catch(Exception e) { - logger.error("Error in setBridgeOFController()",e); - } - return false; + return connection; } - /* * There are a few Open_vSwitch schema specific special case handling to be done for * the older API (such as by inserting a mandatory Interface row automatically upon inserting @@ -710,7 +157,9 @@ public class ConfigurationService implements IPluginInBridgeDomainConfigService, */ private void handleSpecialInsertCase(OvsdbClient client, String databaseName, String tableName, String uuid, Row row, TransactionBuilder transactionBuilder) { - if (databaseName.equals(OvsVswitchdSchemaConstants.DATABASE_NAME) && tableName.equals("Port")) { + Port port = client.getTypedRowWrapper(Port.class, null); + if (databaseName.equals(OvsVswitchdSchemaConstants.DATABASE_NAME) && tableName.equals(port.getSchema().getName())) { + port = client.getTypedRowWrapper(Port.class, row); DatabaseSchema dbSchema = client.getDatabaseSchema(databaseName); TableSchema tableSchema = dbSchema.table(tableName, GenericTableSchema.class); ColumnSchema> columnSchema = tableSchema.multiValuedColumn("interfaces", UUID.class); @@ -719,7 +168,7 @@ public class ConfigurationService implements IPluginInBridgeDomainConfigService, Insert portOperation = (Insert)priorOperations.get(0); portOperation.value(columnSchema, new UUID(namedUuid)); - Column nameColumn = row.getColumn(tableSchema.column("name")); + Column nameColumn = port.getNameColumn(); List> columns = new ArrayList>(); columns.add(nameColumn); Row intfRow = new Row(columns); @@ -733,9 +182,8 @@ public class ConfigurationService implements IPluginInBridgeDomainConfigService, * Due to some additional special case(s), the Transaction is further amended by handleSpecialInsertCase */ private void processInsertTransaction(OvsdbClient client, String databaseName, String childTable, - String parentTable, String parent_uuid, String parentColumn, String namedUuid, + String parentTable, String parentUuid, String parentColumn, String namedUuid, Row row, TransactionBuilder transactionBuilder) { - logger.debug("processTransaction : {} {} {} \n {} {} {} \n {}", client.getConnectionInfo(), databaseName, childTable, parentTable, parent_uuid, parentColumn, row.toString()); DatabaseSchema dbSchema = client.getDatabaseSchema(databaseName); TableSchema childTableSchema = dbSchema.table(childTable, GenericTableSchema.class); transactionBuilder.add(op.insert(childTableSchema, row) @@ -749,7 +197,7 @@ public class ConfigurationService implements IPluginInBridgeDomainConfigService, transactionBuilder .add(op.mutate(parentTableSchema) .addMutation(parentColumnSchema, Mutator.INSERT, new UUID(namedUuid)) - .where(_uuid.opEqual(new UUID(parent_uuid))) + .where(_uuid.opEqual(new UUID(parentUuid))) .build()); } /* @@ -760,6 +208,23 @@ public class ConfigurationService implements IPluginInBridgeDomainConfigService, handleSpecialInsertCase(client, databaseName, childTable, namedUuid, row, transactionBuilder); } + /* + * TODO : Move all the Special Cases out of ConfigurationService and into the Schema specific bundles. + * But that makes plugin more reliant on the Typed Bundles more than just API wrapper. + * Keeping these Special Handling locally till we introduce the full schema independent APIs in the + * plugin layer. + */ + public String getSpecialCaseParentUUID(Node node, String databaseName, String childTableName) { + if (databaseName.equals(OvsVswitchdSchemaConstants.DATABASE_NAME) && childTableName.equals("Bridge")) { + Connection connection = connectionService.getConnection(node); + OpenVSwitch openVSwitch = connection.getClient().getTypedRowWrapper(OpenVSwitch.class, null); + ConcurrentMap row = this.getRows(node, openVSwitch.getSchema().getName()); + if (row == null || row.size() == 0) return null; + return (String)row.keySet().toArray()[0]; + } + return null; + } + /* * Though this is a New API that takes in Row object, this still is considered a * Deprecated call because of the assumption with a Single Row insertion. @@ -767,9 +232,7 @@ public class ConfigurationService implements IPluginInBridgeDomainConfigService, * Row being inserted in one Table and other Rows that needs mutate in other Tables. */ @Override - public StatusWithUuid insertRow(Node node, String tableName, String parent_uuid, Row row) throws InterruptedException, ExecutionException, JsonParseException, IOException { - logger.debug("insertRow {} {} {} {}", node, tableName, parent_uuid, row); - + public StatusWithUuid insertRow(Node node, String tableName, String parentUuid, Row row) { String[] parentColumn = OvsVswitchdSchemaConstants.getParentColumnToMutate(tableName); if (parentColumn == null) { parentColumn = new String[]{null, null}; @@ -777,458 +240,288 @@ public class ConfigurationService implements IPluginInBridgeDomainConfigService, Connection connection = connectionService.getConnection(node); OvsdbClient client = connection.getClient(); + + if (parentUuid == null) { + parentUuid = this.getSpecialCaseParentUUID(node, OvsVswitchdSchemaConstants.DATABASE_NAME, tableName); + } + logger.debug("insertRow Connection : {} Table : {} ParentTable : {} Parent UUID: {} ParentColumn : {} Row : {}", + client.getConnectionInfo(), tableName, parentColumn[0], parentColumn[1], parentUuid, row); + TransactionBuilder transactionBuilder = client.transactBuilder(); String namedUuid = "Transaction_"+ tableName; this.processInsertTransaction(client, OvsVswitchdSchemaConstants.DATABASE_NAME, tableName, - parentColumn[0], parent_uuid, parentColumn[1], namedUuid, + parentColumn[0], parentUuid, parentColumn[1], namedUuid, row, transactionBuilder); ListenableFuture> results = transactionBuilder.execute(); - List operationResults = results.get(); - if (operationResults.isEmpty() || (transactionBuilder.getOperations().size() != operationResults.size())) { - return new StatusWithUuid(StatusCode.INTERNALERROR); - } - logger.debug("Insert row : {} operation results : {} ", row, operationResults); - for (OperationResult result : operationResults) { - if (result.getError() != null) { - return new StatusWithUuid(StatusCode.BADREQUEST, result.getError()); + List operationResults; + try { + operationResults = results.get(); + if (operationResults.isEmpty() || (transactionBuilder.getOperations().size() != operationResults.size())) { + return new StatusWithUuid(StatusCode.INTERNALERROR); + } + for (OperationResult result : operationResults) { + if (result.getError() != null) { + return new StatusWithUuid(StatusCode.BADREQUEST, result.getError()); + } } + UUID uuid = operationResults.get(0).getUuid(); + return new StatusWithUuid(StatusCode.SUCCESS, uuid); + } catch (InterruptedException | ExecutionException e) { + // TODO Auto-generated catch block + return new StatusWithUuid(StatusCode.INTERNALERROR, e.getLocalizedMessage()); } - UUID uuid = operationResults.get(0).getUuid(); - return new StatusWithUuid(StatusCode.SUCCESS, uuid); - } - /* - * Deprecated Old Insert Row API that was using static library schema Objects. - */ - @Override - @Deprecated - public StatusWithUuid insertRow(Node node, String tableName, String parent_uuid, Table row) { - logger.debug("Deprecated API : tableName : {}, parent_uuid : {} Row : {}", tableName, parent_uuid, row.toString()); - StatusWithUuid statusWithUUID = null; - return statusWithUUID; } @Override - public Status updateRow (Node node, String tableName, String parentUUID, String rowUUID, Table row) { - try{ - if (connectionService == null) { - logger.error("Couldn't refer to the ConnectionService"); - return new Status(StatusCode.NOSERVICE); - } - - Connection connection = this.getConnection(node); - if (connection == null) { - return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available"); - } - - Map> ovsTable = inventoryServiceInternal.getTableCache(node, Open_vSwitch.NAME.getName()); + public Status updateRow (Node node, String tableName, String parentUUID, String rowUUID, Row row) { + String databaseName = OvsVswitchdSchemaConstants.DATABASE_NAME; + Connection connection = connectionService.getConnection(node); + OvsdbClient client = connection.getClient(); - if (ovsTable == null) { - return new Status(StatusCode.NOTFOUND, "There are no Open_vSwitch instance in the Open_vSwitch table"); + logger.debug("updateRow : Connection : {} databaseName : {} tableName : {} rowUUID : {} row : {}", + client.getConnectionInfo(), databaseName, tableName, rowUUID, row.toString()); + try{ + TransactionBuilder transactionBuilder = client.transactBuilder(); + DatabaseSchema dbSchema = client.getDatabaseSchema(databaseName); + TableSchema tableSchema = dbSchema.table(tableName, GenericTableSchema.class); + ColumnSchema _uuid = tableSchema.column("_uuid", UUID.class); + transactionBuilder.add(op.update(tableSchema, row) + .where(_uuid.opEqual(new UUID(rowUUID))) + .build()); + + ListenableFuture> results = transactionBuilder.execute(); + List operationResults = results.get(); + if (operationResults.isEmpty() || (transactionBuilder.getOperations().size() != operationResults.size())) { + return new StatusWithUuid(StatusCode.INTERNALERROR); } - - UUID uuid = new UUID(rowUUID); - Condition condition = new Condition("_uuid", Function.EQUALS, uuid); - List where = new ArrayList(); - where.add(condition); - Operation updateRequest = new UpdateOperation(tableName, where, row); - - TransactBuilder transaction = new TransactBuilder(); - transaction.addOperations(new ArrayList( - Arrays.asList(updateRequest))); - - ListenableFuture> transResponse = connection.getClient().transactBuilder().execute(); - List tr = transResponse.get(); - List requests = transaction.getRequests(); - Status status = new Status(StatusCode.SUCCESS); - for (int i = 0; i < tr.size() ; i++) { - if (i < requests.size()) requests.get(i).setResult(tr.get(i)); - if (tr.get(i) != null && tr.get(i).getError() != null && tr.get(i).getError().trim().length() > 0) { - OperationResult result = tr.get(i); - status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails()); + for (OperationResult result : operationResults) { + if (result.getError() != null) { + return new StatusWithUuid(StatusCode.BADREQUEST, result.getError()); } } - - if (tr.size() > requests.size()) { - OperationResult result = tr.get(tr.size()-1); - logger.error("Error Updating Row : {}/{}\n Error : {}\n Details : {}", tableName, row, - result.getError(), - result.getDetails()); - status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails()); - } - if (status.isSuccess()) { - status = new Status(StatusCode.SUCCESS); - } - return status; + return new StatusWithUuid(StatusCode.SUCCESS); } catch(Exception e){ logger.error("Error in updateRow(): ",e); } return new Status(StatusCode.INTERNALERROR); } - @Override - public Status deleteRow(Node node, String tableName, String uuid) { - if (tableName.equalsIgnoreCase("Bridge")) { - return deleteBridgeRow(node, uuid); - } - else if (tableName.equalsIgnoreCase("Capbility")) { - return new Status(StatusCode.NOTIMPLEMENTED, "Delete operation for this Table is not implemented yet."); - } - else if (tableName.equalsIgnoreCase("Controller")) { - return deleteControllerRow(node, uuid); - } - else if (tableName.equalsIgnoreCase("Interface")) { - return deleteInterfaceRow(node, uuid); - } - else if (tableName.equalsIgnoreCase("Manager")) { - return deleteManagerRow(node, uuid); - } - else if (tableName.equalsIgnoreCase("Mirror")) { - return deleteMirrorRow(node, uuid); - } - else if (tableName.equalsIgnoreCase("NetFlow")) { - return deleteNetFlowRow(node, uuid); - } - else if (tableName.equalsIgnoreCase("Open_vSwitch")) { - return deleteOpen_vSwitchRow(node, uuid); - } - else if (tableName.equalsIgnoreCase("Port")) { - return deletePortRow(node, uuid); - } - else if (tableName.equalsIgnoreCase("QoS")) { - return deleteQosRow(node, uuid); - } - else if (tableName.equalsIgnoreCase("Queue")) { - return deleteQueueRow(node, uuid); - } - else if (tableName.equalsIgnoreCase("sFlow")) { - return deleteSflowRow(node, uuid); - } - else if (tableName.equalsIgnoreCase("IPFIX")) { - return deleteIpFixRow(node, uuid); - } - else if (tableName.equalsIgnoreCase("SSL")) { - return deleteSSLRow(node, uuid); - } - return new Status(StatusCode.NOTFOUND, "Table "+tableName+" not supported"); - } - - @Override - public ConcurrentMap> getRows(Node node, String tableName) throws Exception{ - try{ - if (inventoryServiceInternal == null) { - throw new Exception("Inventory Service is Unavailable."); - } - ConcurrentMap> ovsTable = inventoryServiceInternal.getTableCache(node, tableName); - return ovsTable; - } catch(Exception e){ - throw new Exception("Unable to read table due to "+e.getMessage()); - } - } - - @Override - public Table getRow(Node node, String tableName, String uuid) throws Exception { - try{ - if (inventoryServiceInternal == null) { - throw new Exception("Inventory Service is Unavailable."); - } - Map> ovsTable = inventoryServiceInternal.getTableCache(node, tableName); - if (ovsTable == null) return null; - return ovsTable.get(uuid); - } catch(Exception e){ - throw new Exception("Unable to read table due to "+e.getMessage()); - } - } - - @Override - public String getSerializedRows(Node node, String tableName) throws Exception{ - try{ - Map> ovsTable = this.getRows(node, tableName); - if (ovsTable == null) return null; - ObjectMapper mapper = new ObjectMapper(); - return mapper.writeValueAsString(ovsTable); - } catch(Exception e){ - throw new Exception("Unable to read table due to "+e.getMessage()); - } - } - - @Override - public String getSerializedRow(Node node, String tableName, String uuid) throws Exception { - try{ - Table row = this.getRow(node, tableName, uuid); - if (row == null) return null; - ObjectMapper mapper = new ObjectMapper(); - return mapper.writeValueAsString(row); - } catch(Exception e){ - throw new Exception("Unable to read table due to "+e.getMessage()); - } - } - - @Override - public List getTables(Node node) { - ConcurrentMap>> cache = inventoryServiceInternal.getCache(node); - if (cache == null) return null; - return new ArrayList(cache.keySet()); - } - - - private Status deleteBridgeRow(Node node, String uuid) { - // Set up variables for generic _deleteTableRow() - String parentTableName=Open_vSwitch.NAME.getName(); - String childTableName=Bridge.NAME.getName(); - String parentColumn = "bridges"; - - return _deleteTableRow(node,uuid,parentTableName,childTableName,parentColumn); - } - - private Status deletePortRow(Node node, String uuid) { - // Set up variables for generic _deleteTableRow() - String parentTableName=Bridge.NAME.getName(); - String childTableName=Port.NAME.getName(); - String parentColumn = "ports"; - - return _deleteTableRow(node,uuid,parentTableName,childTableName,parentColumn); - } - - private Status deleteInterfaceRow(Node node, String uuid) { - // Since Port<-Interface tables have a 1:n relationship, need to test if this is the last interface - // assigned to a port before attempting delete. - Map> portTable = inventoryServiceInternal.getTableCache(node, Port.NAME.getName()); - Map> interfaceTable = inventoryServiceInternal.getTableCache(node, Interface.NAME.getName()); - // Check that the UUID exists - if (portTable == null || interfaceTable == null || uuid == null || interfaceTable.get(uuid) == null) { - return new Status(StatusCode.NOTFOUND, ""); - } - - // Since the above past, it's safe to use the generic _deleteTableRow method - // Set up variables for generic _deleteTableRow() - String parentTableName=Port.NAME.getName(); - String childTableName=Interface.NAME.getName(); - String parentColumn = "interfaces"; - - return _deleteTableRow(node,uuid,parentTableName,childTableName,parentColumn); - } - - private Status deleteControllerRow(Node node, String uuid) { - // Set up variables for generic _deleteTableRow() - String parentTableName=Bridge.NAME.getName(); - String childTableName=Controller.NAME.getName(); - String parentColumn = "controller"; - - return _deleteTableRow(node,uuid,parentTableName,childTableName,parentColumn); - } - - private Status deleteOpen_vSwitchRow(Node node, String uuid) { - return new Status(StatusCode.NOTIMPLEMENTED, "delete operation for this Table is not implemented yet."); - } - - private Status deleteSSLRow(Node node, String uuid) { - // Set up variables for generic _deleteTableRow() - String parentTableName=Open_vSwitch.NAME.getName(); - String childTableName=SSL.NAME.getName(); - String parentColumn = "ssl"; - - return _deleteTableRow(node,uuid,parentTableName,childTableName,parentColumn); - } - - private Status deleteSflowRow(Node node, String uuid) { - // Set up variables for generic _deleteTableRow() - String parentTableName=Bridge.NAME.getName(); - String childTableName=SFlow.NAME.getName(); - String parentColumn = "sflow"; - - return _deleteTableRow(node,uuid,parentTableName,childTableName,parentColumn); - } + private void processDeleteTransaction(OvsdbClient client, String databaseName, String childTable, + String parentTable, String parentColumn, String uuid, TransactionBuilder transactionBuilder) { + DatabaseSchema dbSchema = client.getDatabaseSchema(databaseName); + TableSchema childTableSchema = dbSchema.table(childTable, GenericTableSchema.class); + TableSchema parentTableSchema = dbSchema.table(parentTable, GenericTableSchema.class); + ColumnSchema parentColumnSchema = parentTableSchema.column(parentColumn, UUID.class); - private Status deleteIpFixRow(Node node, String uuid) { - // Set up variables for generic _deleteTableRow() - String parentTableName=Bridge.NAME.getName(); - String childTableName=IPFIX.NAME.getName(); - String parentColumn = "ipfix"; + if (parentColumn != null) { + transactionBuilder + .add(op.mutate(parentTableSchema) + .addMutation(parentColumnSchema, Mutator.DELETE, new UUID(uuid)) + .where(parentColumnSchema.opIncludes(new UUID(uuid))) + .build()); + } - return _deleteTableRow(node,uuid,parentTableName,childTableName,parentColumn); + ColumnSchema _uuid = childTableSchema.column("_uuid", UUID.class); + transactionBuilder.add(op.delete(childTableSchema) + .where(_uuid.opEqual(new UUID(uuid))) + .build()); } - private Status deleteQueueRow(Node node, String uuid) { - // Set up variables for _deleteRootTableRow() - // This doesn't do a mutate on parent, but simply deletes row - String childTableName=Queue.NAME.getName(); + @Override + public Status deleteRow(Node node, String tableName, String uuid) { + String databaseName = OvsVswitchdSchemaConstants.DATABASE_NAME; + Connection connection = connectionService.getConnection(node); + OvsdbClient client = connection.getClient(); - return _deleteRootTableRow(node,uuid,childTableName); - } + String[] parentColumn = OvsVswitchdSchemaConstants.getParentColumnToMutate(tableName); + if (parentColumn == null) { + parentColumn = new String[]{null, null}; + } - private Status deleteQosRow(Node node, String uuid) { - // Set up variables for generic _deleteTableRow() - String parentTableName=Port.NAME.getName(); - String childTableName=Qos.NAME.getName(); - String parentColumn = "qos"; + logger.debug("deleteRow : Connection : {} databaseName : {} tableName : {} Uuid : {} ParentTable : {} ParentColumn : {}", + client.getConnectionInfo(), databaseName, tableName, uuid, parentColumn[0], parentColumn[1]); - return _deleteTableRow(node,uuid,parentTableName,childTableName,parentColumn); - } + TransactionBuilder transactionBuilder = client.transactBuilder(); + this.processDeleteTransaction(client, OvsVswitchdSchemaConstants.DATABASE_NAME, tableName, + parentColumn[0], parentColumn[1], uuid, transactionBuilder); - private Status deleteNetFlowRow(Node node, String uuid) { - // Set up variables for generic _deleteTableRow() - String parentTableName=Bridge.NAME.getName(); - String childTableName=NetFlow.NAME.getName(); - String parentColumn = "netflow"; + ListenableFuture> results = transactionBuilder.execute(); + List operationResults; + try { + operationResults = results.get(); + if (operationResults.isEmpty() || (transactionBuilder.getOperations().size() != operationResults.size())) { + return new StatusWithUuid(StatusCode.INTERNALERROR); + } + for (OperationResult result : operationResults) { + if (result.getError() != null) { + return new StatusWithUuid(StatusCode.BADREQUEST, result.getError()); + } + } + } catch (InterruptedException | ExecutionException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } - return _deleteTableRow(node,uuid,parentTableName,childTableName,parentColumn); + return new Status(StatusCode.SUCCESS); } - private Status deleteMirrorRow(Node node, String uuid) { - // Set up variables for generic _deleteTableRow() - String parentTableName=Bridge.NAME.getName(); - String childTableName=Mirror.NAME.getName(); - String parentColumn = "mirrors"; - return _deleteTableRow(node,uuid,parentTableName,childTableName,parentColumn); + @Override + public ConcurrentMap getRows(Node node, String tableName) { + ConcurrentMap ovsTable = inventoryServiceInternal.getTableCache(node, OvsVswitchdSchemaConstants.DATABASE_NAME, tableName); + return ovsTable; } - private Status deleteManagerRow(Node node, String uuid) { - // Set up variables for generic _deleteTableRow() - String parentTableName=Open_vSwitch.NAME.getName(); - String childTableName=Manager.NAME.getName(); - String parentColumn = "manager_options"; - - return _deleteTableRow(node,uuid,parentTableName,childTableName,parentColumn); + @Override + public Row getRow(Node node, String tableName, String uuid) { + Map ovsTable = inventoryServiceInternal.getTableCache(node, OvsVswitchdSchemaConstants.DATABASE_NAME, tableName); + if (ovsTable == null) return null; + return ovsTable.get(uuid); } - private Status _deleteTableRow(Node node,String uuid,String parentTableName, String childTableName, String parentColumn) { - try { - // Check there is a connectionService - if (connectionService == null) { - logger.error("Couldn't refer to the ConnectionService"); - return new Status(StatusCode.NOSERVICE); - } + @Override + public List getTables(Node node) { + ConcurrentMap> cache = inventoryServiceInternal.getCache(node, OvsVswitchdSchemaConstants.DATABASE_NAME); + if (cache == null) return null; + return new ArrayList(cache.keySet()); + } - // Establish the connection - Connection connection = this.getConnection(node); - if (connection == null) { - return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available"); - } + private List getControllerIPAddresses(Connection connection) { + List controllers = null; + InetAddress controllerIP = null; - // Remove from Parent and Child - Map> parentTable = inventoryServiceInternal.getTableCache(node, parentTableName); - Map> childTable = inventoryServiceInternal.getTableCache(node, childTableName); + controllers = new ArrayList(); + String addressString = System.getProperty("ovsdb.controller.address"); - // Check that the UUID exists - if (parentTable == null || childTable == null || uuid == null || childTable.get(uuid) == null) { - return new Status(StatusCode.NOTFOUND, ""); + if (addressString != null) { + try { + controllerIP = InetAddress.getByName(addressString); + if (controllerIP != null) { + controllers.add(controllerIP); + return controllers; + } + } catch (UnknownHostException e) { + logger.error("Host {} is invalid", addressString); } + } - // Initialise the actual request var - Operation delRequest = null; - - // Prepare the mutator to remove the child UUID from the parentColumn list in the parent TABLE - UUID rowUuid = new UUID(uuid); - Mutation mutator = new Mutation(parentColumn, Mutator.DELETE, rowUuid); - List mutations = new ArrayList(); - mutations.add(mutator); - - Status status = new Status(StatusCode.SUCCESS); - - // INCLUDES condition ensures that it captures all rows in the parent table (ie duplicates) that have the child UUID - Condition condition = new Condition(parentColumn, Function.INCLUDES, rowUuid); - List where = new ArrayList(); - where.add(condition); - delRequest = new MutateOperation(parentTableName, where, mutations); - - TransactBuilder transaction = new TransactBuilder(); - transaction.addOperations(new ArrayList(Arrays.asList(delRequest))); - - // This executes the transaction. - ListenableFuture> transResponse = connection.getClient().transactBuilder().execute(); + if (clusterServices != null) { + controllers = clusterServices.getClusteredControllers(); + if (controllers != null && controllers.size() > 0) { + if (controllers.size() == 1) { + InetAddress controller = controllers.get(0); + if (!controller.equals(InetAddress.getLoopbackAddress())) { + return controllers; + } + } else { + return controllers; + } + } + } - // Pull the responses - List tr = transResponse.get(); - List requests = transaction.getRequests(); + addressString = System.getProperty("of.address"); - for (int i = 0; i < tr.size(); i++) { - if (i < requests.size()) requests.get(i).setResult(tr.get(i)); - if (tr.get(i) != null && tr.get(i).getError() != null && tr.get(i).getError().trim().length() > 0) { - OperationResult result = tr.get(i); - status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails()); + if (addressString != null) { + try { + controllerIP = InetAddress.getByName(addressString); + if (controllerIP != null) { + controllers.add(controllerIP); + return controllers; } + } catch (UnknownHostException e) { + logger.error("Host {} is invalid", addressString); } + } - if (tr.size() > requests.size()) { - OperationResult result = tr.get(tr.size() - 1); - logger.error("Error deleting: {}\n Error : {}\n Details : {}", - uuid, result.getError(), result.getDetails()); - status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails()); - } - return status; + try { + controllerIP = connection.getClient().getConnectionInfo().getLocalAddress(); + controllers.add(controllerIP); + return controllers; } catch (Exception e) { - logger.error("Error in _deleteTableRow",e); + logger.debug("Invalid connection provided to getControllerIPAddresses", e); } - return new Status(StatusCode.INTERNALERROR); + return controllers; } - private Status _deleteRootTableRow(Node node,String uuid,String TableName) { - try { - // Check there is a connectionService - if (connectionService == null) { - logger.error("Couldn't refer to the ConnectionService"); - return new Status(StatusCode.NOSERVICE); - } - - // Establish the connection - Connection connection = this.getConnection(node); - if (connection == null) { - return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available"); + private short getControllerOFPort() { + Short defaultOpenFlowPort = 6633; + Short openFlowPort = defaultOpenFlowPort; + String portString = System.getProperty("of.listenPort"); + if (portString != null) { + try { + openFlowPort = Short.decode(portString).shortValue(); + } catch (NumberFormatException e) { + logger.warn("Invalid port:{}, use default({})", portString, + openFlowPort); } + } + return openFlowPort; + } - Map> table = inventoryServiceInternal.getTableCache(node, TableName); - - // Check that the UUID exists - if (table == null || table.get(uuid) == null) { - return new Status(StatusCode.NOTFOUND, ""); - } + @Override + public Boolean setOFController(Node node, String bridgeUUID) throws InterruptedException, ExecutionException { + Connection connection = this.getConnection(node); + if (connection == null) { + return false; + } - // Initialise the actual request var - Operation delRequest = null; + OvsDBSet protocols = new OvsDBSet(); - UUID rowUuid = new UUID(uuid); + String ofVersion = System.getProperty("ovsdb.of.version", OPENFLOW_10); + switch (ofVersion) { + case OPENFLOW_13: + protocols.add("OpenFlow13"); + break; + case OPENFLOW_10: + default: + protocols.add("OpenFlow10"); + break; + } - Status status = new Status(StatusCode.SUCCESS); + Bridge bridge = connection.getClient().createTypedRowWrapper(Bridge.class); + bridge.setProtocols(protocols); + Status status = this.updateRow(node, bridge.getSchema().getName(), null, bridgeUUID, bridge.getRow()); + logger.debug("Bridge {} updated to {} with Status {}", bridgeUUID, protocols.toArray()[0], status); + if (!status.isSuccess()) return status.isSuccess(); - Condition condition = new Condition("_uuid", Function.EQUALS, rowUuid); - List where = new ArrayList(); - where.add(condition); - delRequest = new DeleteOperation(TableName, where); + List ofControllerAddrs = this.getControllerIPAddresses(connection); + short ofControllerPort = getControllerOFPort(); + for (InetAddress ofControllerAddress : ofControllerAddrs) { + String newController = "tcp:"+ofControllerAddress.getHostAddress()+":"+ofControllerPort; + Controller controllerRow = connection.getClient().createTypedRowWrapper(Controller.class); + controllerRow.setTarget(newController); + status = this.insertRow(node, controllerRow.getSchema().getName(), bridgeUUID, controllerRow.getRow()); + } + return status.isSuccess(); + } - TransactBuilder transaction = new TransactBuilder(); - transaction.addOperations(new ArrayList(Arrays.asList(delRequest))); - // This executes the transaction. - ListenableFuture> transResponse = connection.getClient().transactBuilder().execute(); + Boolean setBridgeOFController(Node node, String bridgeIdentifier) { + if (connectionService == null) { + logger.error("Couldn't refer to the ConnectionService"); + return false; + } - // Pull the responses - List tr = transResponse.get(); - List requests = transaction.getRequests(); + try{ + Connection connection = connectionService.getConnection(node); + Bridge bridge = connection.getClient().getTypedRowWrapper(Bridge.class, null); - for (int i = 0; i < tr.size(); i++) { - if (i < requests.size()) requests.get(i).setResult(tr.get(i)); - if (tr.get(i) != null && tr.get(i).getError() != null && tr.get(i).getError().trim().length() > 0) { - OperationResult result = tr.get(i); - status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails()); + Map brTableCache = inventoryServiceInternal.getTableCache(node, OvsVswitchdSchemaConstants.DATABASE_NAME, bridge.getSchema().getName()); + for (String uuid : brTableCache.keySet()) { + bridge = connection.getClient().getTypedRowWrapper(Bridge.class, brTableCache.get(uuid)); + if (bridge.getName().contains(bridgeIdentifier)) { + return setOFController(node, uuid); } } - - if (tr.size() > requests.size()) { - OperationResult result = tr.get(tr.size() - 1); - logger.error("Error deleting: {}\n Error : {}\n Details : {}", - uuid, result.getError(), result.getDetails()); - status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails()); - } - return status; - } catch (Exception e) { - logger.error("Error in _deleteRootTableRow",e); + } catch(Exception e) { + logger.error("Error in setBridgeOFController()",e); } - return new Status(StatusCode.INTERNALERROR); + return false; } + public void _ovsconnect (CommandInterpreter ci) { String bridgeName = ci.nextArgument(); if (bridgeName == null) { @@ -1545,5 +838,281 @@ public class ConfigurationService implements IPluginInBridgeDomainConfigService, help.append("\t printCache - Prints Table Cache"); return help.toString(); } + + + /** + * Add a new bridge + * @param node Node serving this configuration service + * @param bridgeIdentifier String representation of a Bridge Connector + * @return Bridge Connector configurations + */ + @Override + @Deprecated + public Status createBridgeDomain(Node node, String bridgeIdentifier, Map configs) { + Connection connection = connectionService.getConnection(node); + OvsdbClient client = connection.getClient(); + Bridge bridge = client.createTypedRowWrapper(Bridge.class); + bridge.setName(bridgeIdentifier); + + String ovsTableUuid = this.getSpecialCaseParentUUID(node, OvsVswitchdSchemaConstants.DATABASE_NAME, bridge.getSchema().getName()); + return this.insertRow(node, bridge.getSchema().getName(), ovsTableUuid, bridge.getRow()); + } + + /** + * Create a Port Attached to a Bridge + * Ex. ovs-vsctl add-port br0 vif0 + * @param node Node serving this configuration service + * @param bridgeIdentifier String representation of a Bridge Domain + * @param portIdentifier String representation of a user defined Port Name + */ + @Override + @Deprecated + public Status addPort(Node node, String bridgeIdentifier, String portIdentifier, + Map configs) { + Connection connection = connectionService.getConnection(node); + OvsdbClient client = connection.getClient(); + + Bridge bridge = client.getTypedRowWrapper(Bridge.class, null); + ConcurrentMap rows = this.getRows(node, bridge.getSchema().getName()); + if (rows == null || rows.size() == 0) { + return new Status(StatusCode.NOTFOUND); + } + for (String bridgeUuid : rows.keySet()) { + Row bridgeRow = rows.get(bridgeUuid); + bridge = client.getTypedRowWrapper(Bridge.class, bridgeRow); + if (bridge.getName().equals(bridgeIdentifier)) break; + } + if (bridge.getName() == null || !bridge.getName().equals(bridgeIdentifier)) { + return new Status(StatusCode.NOTFOUND); + } + + Map options = null; + String type = null; + Set tags = null; + if (configs != null) { + type = (String) configs.get(ConfigConstants.TYPE); + Map customConfigs = (Map) configs.get(ConfigConstants.CUSTOM); + if (customConfigs != null) { + options = new HashMap(); + for (String customConfig : customConfigs.keySet()) { + options.put(customConfig, customConfigs.get(customConfig)); + } + } + } + + if (type != null) { + logger.debug("Port type : " + type); + if (type.equalsIgnoreCase(OvsdbType.PortType.VLAN.name())) { + tags = new HashSet(); + tags.add(BigInteger.valueOf(Integer.parseInt((String)configs.get(ConfigConstants.VLAN)))); + } + } + + Port port = client.createTypedRowWrapper(Port.class); + port.setName(portIdentifier); + if (tags != null) port.setTag(tags); + StatusWithUuid portStatus = this.insertRow(node, port.getSchema().getName(), bridge.getUuid().toString(), port.getRow()); + + if (!portStatus.isSuccess()) return portStatus; + // Ugly hack by adding a sleep for the Monitor Update to catch up. + // TODO : Remove this once the Select operation is in place. + // We are currently relying on the local Cache for any GET operation and that might fail if we try to + // fetch the last installed entry. Hence we need the Select operation to work. + + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + Interface interfaceRow = client.createTypedRowWrapper(Interface.class); + ConcurrentMap intfRows = this.getRows(node, interfaceRow.getSchema().getName()); + if (intfRows == null || intfRows.size() == 0) { + return new Status(StatusCode.NOTFOUND); + } + for (String intfUuid : intfRows.keySet()) { + Row intfRow = rows.get(intfUuid); + interfaceRow = client.getTypedRowWrapper(Interface.class, intfRow); + if (interfaceRow == null || interfaceRow.getName() == null) continue; + if (interfaceRow.getName().equals(portIdentifier)) break; + } + if (interfaceRow.getName() == null || !interfaceRow.getName().equals(portIdentifier)) { + return new Status(StatusCode.NOTFOUND); + } + + if (type != null) { + logger.debug("Interface type : " + type); + if (type.equalsIgnoreCase(OvsdbType.PortType.TUNNEL.name())) { + interfaceRow.setType((String)configs.get(ConfigConstants.TUNNEL_TYPE)); + if (options == null) options = new HashMap(); + options.put("remote_ip", (String)configs.get(ConfigConstants.DEST_IP)); + } else if (type.equalsIgnoreCase(OvsdbType.PortType.PATCH.name()) || + type.equalsIgnoreCase(OvsdbType.PortType.INTERNAL.name())) { + interfaceRow.setType(type.toLowerCase()); + } + } + if (options != null) { + interfaceRow.setOptions(options); + } + + Status intfStatus = null; + intfStatus = this.updateRow(node, interfaceRow.getSchema().getName(), portStatus.getUuid().toString(), + interfaceRow.getUuid().toString(), interfaceRow.getRow()); + + if (intfStatus.isSuccess()) return portStatus; + return intfStatus; + } + + /** + * Implements the OVS Connection for Managers + * + * @param node Node serving this configuration service + * @param managerip String Representing IP and connection types + */ + @SuppressWarnings("unchecked") + @Deprecated + public boolean setManager(Node node, String managerip) { + Connection connection = connectionService.getConnection(node); + OvsdbClient client = connection.getClient(); + Manager manager = client.createTypedRowWrapper(Manager.class); + manager.setTarget(managerip); + + OpenVSwitch openVSwitch = connection.getClient().getTypedRowWrapper(OpenVSwitch.class, null); + ConcurrentMap row = this.getRows(node, openVSwitch.getSchema().getName()); + if (row == null || row.size() == 0) { + return false; + } + String ovsTableUuid = (String)row.keySet().toArray()[0]; + + Status status = this.insertRow(node, manager.getSchema().getName(), ovsTableUuid, manager.getRow()); + return status.isSuccess(); + } + + @Override + @Deprecated + public Status addBridgeDomainConfig(Node node, String bridgeIdentfier, + Map configs) { + String mgmt = (String)configs.get(ConfigConstants.MGMT); + if (mgmt != null) { + if (setManager(node, mgmt)) return new Status(StatusCode.SUCCESS); + } + return new Status(StatusCode.BADREQUEST); + } + + @Override + @Deprecated + public Status deletePort(Node node, String bridgeIdentifier, String portIdentifier) { + Connection connection = connectionService.getConnection(node); + OvsdbClient client = connection.getClient(); + + Port port = client.getTypedRowWrapper(Port.class, null); + ConcurrentMap rows = this.getRows(node, port.getSchema().getName()); + if (rows == null || rows.size() == 0) { + return new Status(StatusCode.NOTFOUND); + } + for (String portUuid : rows.keySet()) { + Row bridgeRow = rows.get(portUuid); + port = client.getTypedRowWrapper(Port.class, bridgeRow); + if (port.getName().equals(portIdentifier)) break; + } + if (port.getName() == null || !port.getName().equals(portIdentifier)) { + return new Status(StatusCode.NOTFOUND); + } + return this.deleteRow(node, port.getSchema().getName(), port.getUuid().toString()); + } + + @Override + @Deprecated + public Status deleteBridgeDomain(Node node, String bridgeIdentifier) { + Connection connection = connectionService.getConnection(node); + OvsdbClient client = connection.getClient(); + + Bridge bridge = client.getTypedRowWrapper(Bridge.class, null); + ConcurrentMap rows = this.getRows(node, bridge.getSchema().getName()); + if (rows == null || rows.size() == 0) { + return new Status(StatusCode.NOTFOUND); + } + for (String bridgeUuid : rows.keySet()) { + Row bridgeRow = rows.get(bridgeUuid); + bridge = client.getTypedRowWrapper(Bridge.class, bridgeRow); + if (bridge.getName().equals(bridgeIdentifier)) break; + } + if (bridge.getName() == null || !bridge.getName().equals(bridgeIdentifier)) { + return new Status(StatusCode.NOTFOUND); + } + return this.deleteRow(node, bridge.getSchema().getName(), bridge.getUuid().toString()); + } + + @Override + public List getBridgeDomains(Node node) { + if (connectionService == null) { + logger.error("Couldn't refer to the ConnectionService"); + return null; + } + + Connection connection = connectionService.getConnection(node); + Bridge bridge = connection.getClient().getTypedRowWrapper(Bridge.class, null); + List brlist = new ArrayList(); + Map brTableCache = inventoryServiceInternal.getTableCache(node, OvsVswitchdSchemaConstants.DATABASE_NAME, bridge.getSchema().getName()); + if(brTableCache != null){ + for (String uuid : brTableCache.keySet()) { + bridge = connection.getClient().getTypedRowWrapper(Bridge.class, brTableCache.get(uuid)); + brlist.add(bridge.getName()); + } + } + return brlist; + } + + @Override + public NodeConnector getNodeConnector(Node arg0, String arg1, String arg2) { + return null; + } + + @Override + @Deprecated + public Status addPortConfig(Node node, String bridgeIdentifier, String portIdentifier, + Map configs) { + // TODO Auto-generated method stub + return null; + } + + @Override + @Deprecated + public Node getBridgeDomainNode(Node node, String bridgeIdentifier) { + // TODO Auto-generated method stub + return null; + } + + @Override + @Deprecated + public Map getPortConfigs(Node node, String bridgeIdentifier, + String portIdentifier) { + // TODO Auto-generated method stub + return null; + } + + @Override + @Deprecated + public Status removeBridgeDomainConfig(Node node, String bridgeIdentifier, + Map configs) { + // TODO Auto-generated method stub + return null; + } + + @Override + @Deprecated + public Status removePortConfig(Node node, String bridgeIdentifier, String portIdentifier, + Map configs) { + // TODO Auto-generated method stub + return null; + } + + @Override + @Deprecated + public Map getBridgeDomainConfigs(Node node, String bridgeIdentifier) { + // TODO Auto-generated method stub + return null; + } } diff --git a/plugin/src/main/java/org/opendaylight/ovsdb/plugin/ConnectionService.java b/plugin/src/main/java/org/opendaylight/ovsdb/plugin/ConnectionService.java index ba94d76bc..8c391ce56 100644 --- a/plugin/src/main/java/org/opendaylight/ovsdb/plugin/ConnectionService.java +++ b/plugin/src/main/java/org/opendaylight/ovsdb/plugin/ConnectionService.java @@ -12,8 +12,8 @@ package org.opendaylight.ovsdb.plugin; import io.netty.channel.Channel; import io.netty.channel.ChannelHandler; +import java.io.IOException; import java.net.InetAddress; -import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; @@ -24,7 +24,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ExecutionException; -import org.opendaylight.controller.clustering.services.IClusterGlobalServices; import org.opendaylight.controller.sal.connection.ConnectionConstants; import org.opendaylight.controller.sal.connection.IPluginInConnectionService; import org.opendaylight.controller.sal.core.Node; @@ -32,21 +31,24 @@ import org.opendaylight.controller.sal.core.Property; import org.opendaylight.controller.sal.utils.ServiceHelper; import org.opendaylight.controller.sal.utils.Status; import org.opendaylight.controller.sal.utils.StatusCode; +import org.opendaylight.ovsdb.lib.MonitorCallBack; +import org.opendaylight.ovsdb.lib.MonitorHandle; import org.opendaylight.ovsdb.lib.OvsdbClient; import org.opendaylight.ovsdb.lib.OvsdbConnection; import org.opendaylight.ovsdb.lib.OvsdbConnectionInfo; import org.opendaylight.ovsdb.lib.OvsdbConnectionListener; -import org.opendaylight.ovsdb.lib.message.OvsdbRPC; -import org.opendaylight.ovsdb.lib.message.UpdateNotification; -import org.opendaylight.ovsdb.lib.notation.OvsDBSet; +import org.opendaylight.ovsdb.lib.message.MonitorRequest; +import org.opendaylight.ovsdb.lib.message.MonitorRequestBuilder; +import org.opendaylight.ovsdb.lib.message.MonitorSelect; +import org.opendaylight.ovsdb.lib.message.TableUpdates; import org.opendaylight.ovsdb.lib.schema.DatabaseSchema; -import org.opendaylight.ovsdb.lib.table.Bridge; -import org.opendaylight.ovsdb.lib.table.Controller; -import org.opendaylight.ovsdb.lib.table.Open_vSwitch; -import org.opendaylight.ovsdb.lib.table.Table; +import org.opendaylight.ovsdb.lib.schema.GenericTableSchema; +import org.opendaylight.ovsdb.lib.schema.TableSchema; +import org.opendaylight.ovsdb.schema.openvswitch.OpenVSwitch; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.collect.Lists; import com.google.common.util.concurrent.ListenableFuture; @@ -54,21 +56,15 @@ import com.google.common.util.concurrent.ListenableFuture; * Represents the openflow plugin component in charge of programming the flows * the flow programming and relay them to functional modules above SAL. */ -public class ConnectionService implements IPluginInConnectionService, IConnectionServiceInternal, OvsdbRPC.Callback, OvsdbConnectionListener { +public class ConnectionService implements IPluginInConnectionService, IConnectionServiceInternal, OvsdbConnectionListener { protected static final Logger logger = LoggerFactory.getLogger(ConnectionService.class); // Properties that can be set in config.ini private static final String OVSDB_LISTENPORT = "ovsdb.listenPort"; - private static final String OVSDB_AUTOCONFIGURECONTROLLER = "ovsdb.autoconfigurecontroller"; - protected static final String OPENFLOW_10 = "1.0"; - protected static final String OPENFLOW_13 = "1.3"; - private static final Integer defaultOvsdbPort = 6640; - private static final boolean defaultAutoConfigureController = true; private OvsdbConnection connectionLib; private static Integer ovsdbListenPort = defaultOvsdbPort; - private static boolean autoConfigureController = defaultAutoConfigureController; private ConcurrentMap ovsdbConnections; private List handlers = null; private InventoryServiceInternal inventoryServiceInternal; @@ -108,10 +104,6 @@ public class ConnectionService implements IPluginInConnectionService, IConnectio listenPort = Integer.decode(portString).intValue(); } ovsdbListenPort = listenPort; - - // Keep the default value if the property is not set - if (System.getProperty(OVSDB_AUTOCONFIGURECONTROLLER) != null) - autoConfigureController = Boolean.getBoolean(OVSDB_AUTOCONFIGURECONTROLLER); } /** @@ -218,6 +210,10 @@ public class ConnectionService implements IPluginInConnectionService, IConnectio Connection connection = new Connection(identifier, client); Node node = connection.getNode(); ovsdbConnections.put(identifier, connection); + List dbs = client.getDatabases().get(); + for (String db : dbs) { + client.getSchema(db).get(); + } // Keeping the Initial inventory update(s) on its own thread. new Thread() { Connection connection; @@ -227,7 +223,7 @@ public class ConnectionService implements IPluginInConnectionService, IConnectio public void run() { try { initializeInventoryForNewNode(connection); - } catch (InterruptedException | ExecutionException e) { + } catch (InterruptedException | ExecutionException | IOException e) { logger.error("Failed to initialize inventory for node with identifier " + identifier, e); ovsdbConnections.remove(identifier); } @@ -247,7 +243,7 @@ public class ConnectionService implements IPluginInConnectionService, IConnectio inventoryServiceInternal.removeNode(node); } - private void initializeInventoryForNewNode (Connection connection) throws InterruptedException, ExecutionException { + private void initializeInventoryForNewNode (Connection connection) throws InterruptedException, ExecutionException, IOException { OvsdbClient client = connection.getClient(); InetAddress address = client.getConnectionInfo().getRemoteAddress(); int port = client.getConnectionInfo().getRemotePort(); @@ -258,187 +254,77 @@ public class ConnectionService implements IPluginInConnectionService, IConnectio props.add(l4Port); inventoryServiceInternal.addNode(connection.getNode(), props); - List dbNames = Arrays.asList(Open_vSwitch.NAME.getName()); - ListenableFuture dbSchemaF = client.getSchema("Open_vSwitch"); + OpenVSwitch openVSwitch = connection.getClient().getTypedRowWrapper(OpenVSwitch.class, null); + List dbNames = Arrays.asList(openVSwitch.getSchema().getName()); + ListenableFuture dbSchemaF = client.getSchema(OvsVswitchdSchemaConstants.DATABASE_NAME); DatabaseSchema databaseSchema = dbSchemaF.get(); - inventoryServiceInternal.updateDatabaseSchema(connection.getNode(), databaseSchema); -/* - MonitorRequestBuilder monitorReq = null; //ashwin(not sure if we need) : new MonitorRequestBuilder(); - for (Table table : Tables.getTables()) { - if (databaseSchema.getTables().contains(table.getTableName().getName())) { - //ashwin(not sure if we need) monitorReq.monitor(table); - } else { - logger.debug("We know about table {} but it is not in the schema of {}", table.getTableName().getName(), connection.getNode().getNodeIDString()); - } - } - - ListenableFuture monResponse = null; //TODO : ashwin(not sure if we need)connection.getRpc().monitor(monitorReq); - TableUpdates updates = monResponse.get(); - if (updates.getError() != null) { - logger.error("Error configuring monitor, error : {}, details : {}", - updates.getError(), - updates.getDetails()); - throw new RuntimeException("Failed to setup a monitor in OVSDB"); - } - UpdateNotification monitor = new UpdateNotification(); - monitor.setUpdate(updates); - this.update(connection.getNode(), monitor); - if (autoConfigureController) { - this.updateOFControllers(connection.getNode()); - } - */ + this.monitorTables(connection.getNode()); inventoryServiceInternal.notifyNodeAdded(connection.getNode()); } - private IClusterGlobalServices clusterServices; - - public void setClusterServices(IClusterGlobalServices i) { - this.clusterServices = i; - } - - public void unsetClusterServices(IClusterGlobalServices i) { - if (this.clusterServices == i) { - this.clusterServices = null; + public void monitorTables(Node node) throws ExecutionException, InterruptedException, IOException { + OvsdbClient client = ovsdbConnections.get(node.getID()).getClient(); + List databases = client.getDatabases().get(); + if (databases == null) { + logger.error("Unable to get Databases for the ovsdb connection : {}", client.getConnectionInfo()); + return; } - } - - private List getControllerIPAddresses(Connection connection) { - List controllers = null; - InetAddress controllerIP = null; - - controllers = new ArrayList(); - String addressString = System.getProperty("ovsdb.controller.address"); - - if (addressString != null) { - try { - controllerIP = InetAddress.getByName(addressString); - if (controllerIP != null) { - controllers.add(controllerIP); - return controllers; - } - } catch (UnknownHostException e) { - logger.error("Host {} is invalid", addressString); + for (String database : databases) { + DatabaseSchema dbSchema = client.getSchema(database).get(); + if (dbSchema == null) { + logger.error("Unable to get Database Schema for the ovsdb connection : {} , database : {}", client.getConnectionInfo(), database); + return; } - } - - if (clusterServices != null) { - controllers = clusterServices.getClusteredControllers(); - if (controllers != null && controllers.size() > 0) { - if (controllers.size() == 1) { - InetAddress controller = controllers.get(0); - if (!controller.equals(InetAddress.getLoopbackAddress())) { - return controllers; - } - } else { - return controllers; - } + Set tables = dbSchema.getTables(); + if (tables == null) { + logger.warn("Database {} without any tables. Strange !", database); + continue; } - } - - addressString = System.getProperty("of.address"); - - if (addressString != null) { - try { - controllerIP = InetAddress.getByName(addressString); - if (controllerIP != null) { - controllers.add(controllerIP); - return controllers; - } - } catch (UnknownHostException e) { - logger.error("Host {} is invalid", addressString); + List> monitorRequests = Lists.newArrayList(); + for (String tableName : tables) { + GenericTableSchema tableSchema = dbSchema.table(tableName, GenericTableSchema.class); + monitorRequests.add(this.getAllColumnsMonitorRequest(tableSchema)); } + MonitorHandle monitor = client.monitor(dbSchema, monitorRequests, new UpdateMonitor(node)); } - - try { - controllerIP = connection.getClient().getConnectionInfo().getLocalAddress(); - controllers.add(controllerIP); - return controllers; - } catch (Exception e) { - logger.debug("Invalid connection provided to getControllerIPAddresses", e); - } - return controllers; } - private short getControllerOFPort() { - Short defaultOpenFlowPort = 6633; - Short openFlowPort = defaultOpenFlowPort; - String portString = System.getProperty("of.listenPort"); - if (portString != null) { - try { - openFlowPort = Short.decode(portString).shortValue(); - } catch (NumberFormatException e) { - logger.warn("Invalid port:{}, use default({})", portString, - openFlowPort); - } + /** + * As per RFC 7047, section 4.1.5, if a Monitor request is sent without any columns, the update response will not include + * the _uuid column. + * ---------------------------------------------------------------------------------------------------------------------------------- + * Each specifies one or more columns and the manner in which the columns (or the entire table) are to be monitored. + * The "columns" member specifies the columns whose values are monitored. It MUST NOT contain duplicates. + * If "columns" is omitted, all columns in the table, except for "_uuid", are monitored. + * ---------------------------------------------------------------------------------------------------------------------------------- + * In order to overcome this limitation, this method + * + * @return MonitorRequest that includes all the Bridge Columns including _uuid + */ + public > MonitorRequest getAllColumnsMonitorRequest (T tableSchema) { + Set columns = tableSchema.getColumns(); + MonitorRequestBuilder monitorBuilder = MonitorRequestBuilder.builder(tableSchema); + for (String column : columns) { + monitorBuilder.addColumn(column); } - return openFlowPort; + return monitorBuilder.with(new MonitorSelect(true, true, true, true)).build(); } - @Override - public Boolean setOFController(Node node, String bridgeUUID) throws InterruptedException, ExecutionException { - Connection connection = this.getConnection(node); - if (connection == null) { - return false; + private class UpdateMonitor implements MonitorCallBack { + Node node = null; + public UpdateMonitor(Node node) { + this.node = node; } - OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this); - OvsDBSet protocols = new OvsDBSet(); - - String ofVersion = System.getProperty("ovsdb.of.version", OPENFLOW_10); - switch (ofVersion) { - case OPENFLOW_13: - protocols.add("OpenFlow13"); - break; - case OPENFLOW_10: - default: - protocols.add("OpenFlow10"); - break; + @Override + public void update(TableUpdates result, DatabaseSchema dbSchema) { + inventoryServiceInternal.processTableUpdates(node, dbSchema.getName(), result); } - Bridge bridge = new Bridge(); - bridge.setProtocols(protocols); - Status status = ovsdbTable.updateRow(node, Bridge.NAME.getName(), null, bridgeUUID, bridge); - logger.debug("Bridge {} updated to {} with Status {}", bridgeUUID, protocols.toArray()[0], status); - - List ofControllerAddrs = this.getControllerIPAddresses(connection); - short ofControllerPort = getControllerOFPort(); - for (InetAddress ofControllerAddress : ofControllerAddrs) { - String newController = "tcp:"+ofControllerAddress.getHostAddress()+":"+ofControllerPort; - Controller controllerRow = new Controller(); - controllerRow.setTarget(newController); - if (ovsdbTable != null) { - ovsdbTable.insertRow(node, Controller.NAME.getName(), bridgeUUID, controllerRow); - } + @Override + public void exception(Throwable t) { + System.out.println("Exception t = " + t); } - return true; - } - - private void updateOFControllers (Node node) { - Map> bridges = inventoryServiceInternal.getTableCache(node, Bridge.NAME.getName()); - if (bridges == null) return; - for (String bridgeUUID : bridges.keySet()) { - try { - this.setOFController(node, bridgeUUID); - } catch (Exception e) { - logger.error("Failed updateOFControllers", e); - } - } - } - - @Override - public void update(Object context, UpdateNotification updateNotification) { - if (updateNotification == null) return; - inventoryServiceInternal.processTableUpdates((Node)context, updateNotification.getUpdate()); - } - - @Override - public void locked(Object context, List ids) { - // TODO Auto-generated method stub - } - - @Override - public void stolen(Object context, List ids) { - // TODO Auto-generated method stub } private String getConnectionIdentifier(OvsdbClient client) { diff --git a/plugin/src/main/java/org/opendaylight/ovsdb/plugin/IConnectionServiceInternal.java b/plugin/src/main/java/org/opendaylight/ovsdb/plugin/IConnectionServiceInternal.java index ee3567e03..925438a4a 100644 --- a/plugin/src/main/java/org/opendaylight/ovsdb/plugin/IConnectionServiceInternal.java +++ b/plugin/src/main/java/org/opendaylight/ovsdb/plugin/IConnectionServiceInternal.java @@ -11,7 +11,6 @@ package org.opendaylight.ovsdb.plugin; import java.util.List; import java.util.Map; -import java.util.concurrent.ExecutionException; import org.opendaylight.controller.sal.connection.ConnectionConstants; import org.opendaylight.controller.sal.core.Node; @@ -20,5 +19,4 @@ public interface IConnectionServiceInternal { public Connection getConnection(Node node); public List getNodes(); public Node connect(String identifier, Map params); - public Boolean setOFController(Node node, String bridgeUUID) throws InterruptedException, ExecutionException; } diff --git a/plugin/src/main/java/org/opendaylight/ovsdb/plugin/InventoryService.java b/plugin/src/main/java/org/opendaylight/ovsdb/plugin/InventoryService.java index 05da8671b..d8359e0e0 100644 --- a/plugin/src/main/java/org/opendaylight/ovsdb/plugin/InventoryService.java +++ b/plugin/src/main/java/org/opendaylight/ovsdb/plugin/InventoryService.java @@ -9,7 +9,6 @@ */ package org.opendaylight.ovsdb.plugin; -import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -18,6 +17,7 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.CopyOnWriteArraySet; +import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -32,13 +32,10 @@ import org.opendaylight.controller.sal.inventory.IPluginInInventoryService; import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService; import org.opendaylight.controller.sal.utils.HexEncode; import org.opendaylight.controller.sal.utils.ServiceHelper; -import org.opendaylight.ovsdb.lib.message.temp.TableUpdate; -import org.opendaylight.ovsdb.lib.message.temp.TableUpdate.Row; -import org.opendaylight.ovsdb.lib.message.temp.TableUpdates; -import org.opendaylight.ovsdb.lib.notation.OvsDBSet; -import org.opendaylight.ovsdb.lib.schema.DatabaseSchema; -import org.opendaylight.ovsdb.lib.table.Bridge; -import org.opendaylight.ovsdb.lib.table.Table; +import org.opendaylight.ovsdb.lib.message.TableUpdate; +import org.opendaylight.ovsdb.lib.message.TableUpdates; +import org.opendaylight.ovsdb.lib.notation.Row; +import org.opendaylight.ovsdb.schema.openvswitch.Bridge; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -58,6 +55,7 @@ public class InventoryService implements IPluginInInventoryService, InventorySer private ConcurrentMap> nodeConnectorProps; private ConcurrentMap dbCache = Maps.newConcurrentMap(); private ScheduledExecutorService executor; + private OVSDBConfigService configurationService; /** * Function called by the dependency manager when all the required @@ -107,6 +105,14 @@ public class InventoryService implements IPluginInInventoryService, InventorySer this.pluginOutInventoryServices.remove(service); } + public void setConfigurationService(OVSDBConfigService service) { + configurationService = service; + } + + public void unsetConfigurationService(OVSDBConfigService service) { + configurationService = null; + } + /** * Retrieve nodes from openflow */ @@ -126,46 +132,46 @@ public class InventoryService implements IPluginInInventoryService, InventorySer @Override - public ConcurrentMap>> getCache(Node n) { + public ConcurrentMap> getCache(Node n, String databaseName) { NodeDB db = dbCache.get(n); if (db == null) return null; - return db.getTableCache(); + return db.getDatabase(databaseName); } @Override - public ConcurrentMap> getTableCache(Node n, String tableName) { + public ConcurrentMap getTableCache(Node n, String databaseName, String tableName) { NodeDB db = dbCache.get(n); if (db == null) return null; - return db.getTableCache(tableName); + return db.getTableCache(databaseName, tableName); } @Override - public Table getRow(Node n, String tableName, String uuid) { + public Row getRow(Node n, String databaseName, String tableName, String uuid) { NodeDB db = dbCache.get(n); if (db == null) return null; - return db.getRow(tableName, uuid); + return db.getRow(databaseName, tableName, uuid); } @Override - public void updateRow(Node n, String tableName, String uuid, Table row) { + public void updateRow(Node n, String databaseName, String tableName, String uuid, Row row) { NodeDB db = dbCache.get(n); if (db == null) { db = new NodeDB(); dbCache.put(n, db); } - db.updateRow(tableName, uuid, row); + db.updateRow(databaseName, tableName, uuid, row); } @Override - public void removeRow(Node n, String tableName, String uuid) { + public void removeRow(Node n, String databaseName, String tableName, String uuid) { NodeDB db = dbCache.get(n); - if (db != null) db.removeRow(tableName, uuid); + if (db != null) db.removeRow(databaseName, tableName, uuid); } @Override - public void processTableUpdates(Node n, TableUpdates tableUpdates) { + public void processTableUpdates(Node n, String databaseName, TableUpdates tableUpdates) { NodeDB db = dbCache.get(n); if (db == null) { db = new NodeDB(); @@ -173,36 +179,34 @@ public class InventoryService implements IPluginInInventoryService, InventorySer } OVSDBInventoryListener inventoryListener = (OVSDBInventoryListener)ServiceHelper.getGlobalInstance(OVSDBInventoryListener.class, this); - Set available = tableUpdates.availableUpdates(); - for (Table.Name name : available) { - TableUpdate tableUpdate = tableUpdates.getUpdate(name); - Collection> rows = tableUpdate.getRows(); - for (Row row : rows) { - String uuid = row.getId(); - Table newRow = (Table)row.getNew(); - Table oldRow = (Table)row.getOld(); - if (newRow != null) { - db.updateRow(name.getName(), uuid, newRow); - if (name.getName().equalsIgnoreCase("bridge")) { - logger.debug("Received Bridge Table udpate for node {}", n); - // OVSDB has the Bridge name info while OpenFlow Spec is not - // Clear on that. From a user/manageability standpoint, it is easier - // to handle Bridge names compared to dpids. - // Updating the Openflow bridge name via the SAL Description update. - - // updateOFBridgeName(n, (Bridge)newRow); - } - if ((oldRow == null) && (inventoryListener != null)) { - inventoryListener.rowAdded(n, name.getName(), uuid, newRow); - } else if (inventoryListener != null) { - inventoryListener.rowUpdated(n, name.getName(), uuid, oldRow, newRow); - } - } else if (oldRow != null) { - if (inventoryListener != null) { - inventoryListener.rowRemoved(n, name.getName(), uuid, oldRow, null); - } - db.removeRow(name.getName(), uuid); + for (String tableName : tableUpdates.getUpdates().keySet()) { + Map tCache = db.getTableCache(databaseName, tableName); + TableUpdate update = tableUpdates.getUpdates().get(tableName); + + if (update.getNew() != null) { + boolean isNewRow = (tCache == null || tCache.get(update.getUuid().toString()) == null) ? true : false; + db.updateRow(databaseName, tableName, update.getUuid().toString(), update.getNew()); + if (isNewRow) { + this.handleOpenVSwitchSpecialCase(n, databaseName, tableName, update); + if (inventoryListener != null) inventoryListener.rowAdded(n, tableName, update.getUuid().toString(), update.getNew()); + } else { + if (inventoryListener != null) inventoryListener.rowUpdated(n, tableName, update.getUuid().toString(), update.getOld(), update.getNew()); + } + } else if (update.getOld() != null){ + if (tCache != null) { + if (inventoryListener != null) inventoryListener.rowRemoved(n, tableName, update.getUuid().toString(), update.getOld(), update.getNew()); } + db.removeRow(databaseName, tableName, update.getUuid().toString()); + } + } + } + + private void handleOpenVSwitchSpecialCase(Node node, String databaseName, String tableName, TableUpdate update) { + if (OvsVswitchdSchemaConstants.shouldConfigureController(databaseName, tableName)) { + try { + if (configurationService != null) configurationService.setOFController(node, update.getUuid().toString()); + } catch (InterruptedException | ExecutionException e) { + e.printStackTrace(); } } } @@ -211,7 +215,7 @@ public class InventoryService implements IPluginInInventoryService, InventorySer Runnable updateNameRunnable = new Runnable() { @Override public void run() { - OvsDBSet dpids = bridge.getDatapath_id(); + Set dpids = bridge.getDatapathIdColumn().getData(); String bridgeName = bridge.getName(); if (dpids == null || bridgeName == null) return; for (String dpid : dpids) { @@ -275,23 +279,6 @@ public class InventoryService implements IPluginInInventoryService, InventorySer } } - @Override - public DatabaseSchema getDatabaseSchema(Node n) { - NodeDB db = dbCache.get(n); - if (db != null) return db.getSchema(); - return null; - } - - @Override - public void updateDatabaseSchema(Node n, DatabaseSchema schema) { - NodeDB db = dbCache.get(n); - if (db == null) { - db = new NodeDB(); - dbCache.put(n, db); - } - db.setSchema(schema); - } - @Override public void removeNode(Node node) { OVSDBInventoryListener inventoryListener = (OVSDBInventoryListener)ServiceHelper.getGlobalInstance(OVSDBInventoryListener.class, this); diff --git a/plugin/src/main/java/org/opendaylight/ovsdb/plugin/InventoryServiceInternal.java b/plugin/src/main/java/org/opendaylight/ovsdb/plugin/InventoryServiceInternal.java index aad9e3eef..0cdbac09d 100644 --- a/plugin/src/main/java/org/opendaylight/ovsdb/plugin/InventoryServiceInternal.java +++ b/plugin/src/main/java/org/opendaylight/ovsdb/plugin/InventoryServiceInternal.java @@ -16,19 +16,16 @@ import org.opendaylight.controller.sal.core.Node; import org.opendaylight.controller.sal.core.Property; import org.opendaylight.controller.sal.core.UpdateType; import org.opendaylight.controller.sal.inventory.IPluginInInventoryService; -import org.opendaylight.ovsdb.lib.message.temp.TableUpdates; -import org.opendaylight.ovsdb.lib.schema.DatabaseSchema; -import org.opendaylight.ovsdb.lib.table.Table; +import org.opendaylight.ovsdb.lib.message.TableUpdates; +import org.opendaylight.ovsdb.lib.notation.Row; public interface InventoryServiceInternal extends IPluginInInventoryService { - public ConcurrentMap>> getCache(Node n); - public ConcurrentMap> getTableCache(Node n, String tableName); - public Table getRow (Node n, String tableName, String uuid); - public void updateRow(Node n, String tableName, String uuid, Table row); - public void removeRow(Node n, String tableName, String uuid); - public void processTableUpdates(Node n, TableUpdates tableUpdates); - public void updateDatabaseSchema(Node n, DatabaseSchema schema); - public DatabaseSchema getDatabaseSchema(Node n); + public ConcurrentMap> getCache(Node n, String databaseName); + public ConcurrentMap getTableCache(Node n, String databaseName, String tableName); + public Row getRow (Node n, String databaseName, String tableName, String uuid); + public void updateRow(Node n, String databaseName, String tableName, String uuid, Row row); + public void removeRow(Node n, String databaseName, String tableName, String uuid); + public void processTableUpdates(Node n, String databaseName,TableUpdates tableUpdates); public void printCache(Node n); public void addNode(Node n, Set props); diff --git a/plugin/src/main/java/org/opendaylight/ovsdb/plugin/NodeDB.java b/plugin/src/main/java/org/opendaylight/ovsdb/plugin/NodeDB.java index ae868033f..d6118c0d4 100644 --- a/plugin/src/main/java/org/opendaylight/ovsdb/plugin/NodeDB.java +++ b/plugin/src/main/java/org/opendaylight/ovsdb/plugin/NodeDB.java @@ -13,61 +13,109 @@ import java.util.Map; import java.util.concurrent.ConcurrentMap; import org.apache.commons.collections.MapUtils; -import org.opendaylight.ovsdb.lib.schema.DatabaseSchema; -import org.opendaylight.ovsdb.lib.table.Table; +import org.opendaylight.ovsdb.lib.notation.Row; import com.google.common.collect.Maps; public class NodeDB { - private DatabaseSchema schema; - ConcurrentMap>> cache = Maps.newConcurrentMap(); + ConcurrentMap> dbCache = Maps.newConcurrentMap(); - public DatabaseSchema getSchema() { - return schema; + public ConcurrentMap> getDatabase(String dbName) { + ConcurrentMap tdbMap = dbCache.get(dbName); + if (tdbMap == null) return null; + ConcurrentMap> retMap = Maps.newConcurrentMap(); + for (String tableName : tdbMap.keySet()) { + TableDB tdb = tdbMap.get(tableName); + retMap.put(tableName, tdb.getTableCache(tableName)); + } + return retMap; } - public void setSchema(DatabaseSchema schema) { - this.schema = schema; + public ConcurrentMap getTableCache(String dbName, String tableName) { + ConcurrentMap> tdbMap = getDatabase(dbName); + if (tdbMap == null) return null; + return tdbMap.get(tableName); } - public ConcurrentMap>> getTableCache() { - return cache; + private void setDBCache(String dbName, ConcurrentMap table) { + dbCache.put(dbName, table); } - public ConcurrentMap> getTableCache(String tableName) { - return cache.get(tableName); + public Row getRow (String dbName, String tableName, String uuid) { + ConcurrentMap> db = getDatabase(dbName); + if (db == null) return null; + ConcurrentMap tdb = db.get(tableName); + if (tdb == null) return null; + return tdb.get(uuid); } - private void setTableCache(String tableName, ConcurrentMap> tableCache) { - cache.put(tableName, tableCache); + public void updateRow(String dbName, String tableName, String uuid, Row row) { + ConcurrentMap db = dbCache.get(dbName); + if (db == null) { + db = Maps.newConcurrentMap(); + setDBCache(dbName, db); + } + TableDB tdb = db.get(tableName); + if (tdb == null) { + tdb = new TableDB(); + db.put(tableName, tdb); + } + tdb.updateRow(tableName, uuid, row); } - public Table getRow (String tableName, String uuid) { - Map> tableCache = getTableCache(tableName); - if (tableCache != null) { - return tableCache.get(uuid); - } - return null; + public void removeRow(String dbName, String tableName, String uuid) { + ConcurrentMap db = dbCache.get(dbName); + if (db == null) return; + TableDB tdb = db.get(tableName); + if (tdb == null) return; + tdb.removeRow(tableName, uuid); } - public void updateRow(String tableName, String uuid, Table row) { - ConcurrentMap> tableCache = getTableCache(tableName); - if (tableCache == null) { - tableCache = Maps.newConcurrentMap(); - setTableCache(tableName, tableCache); - } - tableCache.put(uuid, row); + public void printTableCache() { + MapUtils.debugPrint(System.out, null, dbCache); } - public void removeRow(String tableName, String uuid) { - Map> tableCache = getTableCache(tableName); - if (tableCache != null) { - tableCache.remove(uuid); + public class TableDB { + ConcurrentMap> cache = Maps.newConcurrentMap(); + + public ConcurrentMap> getTableCache() { + return cache; } - } - public void printTableCache() { - System.out.println(schema.getTables()); - MapUtils.debugPrint(System.out, null, cache); + public ConcurrentMap getTableCache(String tableName) { + return cache.get(tableName); + } + + private void setTableCache(String tableName, ConcurrentMap tableCache) { + cache.put(tableName, tableCache); + } + + public Row getRow (String tableName, String uuid) { + Map tableCache = getTableCache(tableName); + if (tableCache != null) { + return tableCache.get(uuid); + } + return null; + } + + public void updateRow(String tableName, String uuid, Row row) { + ConcurrentMap tableCache = getTableCache(tableName); + if (tableCache == null) { + tableCache = Maps.newConcurrentMap(); + setTableCache(tableName, tableCache); + } + tableCache.put(uuid, row); + } + + public void removeRow(String tableName, String uuid) { + Map tableCache = getTableCache(tableName); + if (tableCache != null) { + tableCache.remove(uuid); + } + } + + public void printTableCache() { + MapUtils.debugPrint(System.out, null, cache); + } } -} +} \ No newline at end of file diff --git a/plugin/src/main/java/org/opendaylight/ovsdb/plugin/OVSDBConfigService.java b/plugin/src/main/java/org/opendaylight/ovsdb/plugin/OVSDBConfigService.java index 76960bb5e..80896a430 100644 --- a/plugin/src/main/java/org/opendaylight/ovsdb/plugin/OVSDBConfigService.java +++ b/plugin/src/main/java/org/opendaylight/ovsdb/plugin/OVSDBConfigService.java @@ -9,7 +9,6 @@ */ package org.opendaylight.ovsdb.plugin; -import java.io.IOException; import java.util.List; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ExecutionException; @@ -18,23 +17,11 @@ import org.opendaylight.controller.sal.core.Node; import org.opendaylight.controller.sal.utils.Status; import org.opendaylight.ovsdb.lib.notation.Row; import org.opendaylight.ovsdb.lib.schema.GenericTableSchema; -import org.opendaylight.ovsdb.lib.table.Table; - -import com.fasterxml.jackson.core.JsonParseException; public interface OVSDBConfigService { - public StatusWithUuid insertRow (Node node, String tableName, String parentUUID, Table row); - public Status deleteRow (Node node, String tableName, String rowUUID); - public Status updateRow (Node node, String tableName, String parentUUID, String rowUUID, Table row); - public String getSerializedRow(Node node, String tableName, String uuid) throws Exception; - public String getSerializedRows(Node node, String tableName) throws Exception; - public Table getRow(Node node, String tableName, String uuid) throws Exception; - public ConcurrentMap> getRows(Node node, String tableName) throws Exception; - public List getTables(Node node) throws Exception; - /** - * This version of insertRow is a short-term replacement for the older & now deprecated version. + * This version of insertRow is a short-term replacement for the older & now deprecated method of the same name. * This API assumes an Open_vSwitch database Schema. * * @param node OVSDB Node @@ -42,11 +29,75 @@ public interface OVSDBConfigService { * @param parentUuid UUID of the parent table to which this operation will result in attaching/mutating. * @param row Row of table Content to be inserted * @return UUID of the inserted Row + */ + public StatusWithUuid insertRow(Node node, String tableName, String parentUuid, Row row); + + /** + * This version of updateRow is a short-term replacement for the older & now deprecated method of the same name. + * This API assumes an Open_vSwitch database Schema. + * + * @param node OVSDB Node + * @param tableName Table on which the row is Updated + * @param parentUuid UUID of the parent row on which this operation might result in mutating. + * @param rowUuid UUID of the row that is being updated + * @param row Row of table Content to be Updated. Include just those columns that needs to be updated. + */ + public Status updateRow (Node node, String tableName, String parentUuid, String rowUuid, Row row); + + /** + * This version of deleteRow is a short-term replacement for the older & now deprecated method of the same name. + * This API assumes an Open_vSwitch database Schema. + * + * @param node OVSDB Node + * @param tableName Table on which the row is Updated + * @param rowUuid UUID of the row that is being deleted + */ + + public Status deleteRow (Node node, String tableName, String rowUUID); + + /** + * This version of getRow is a short-term replacement for the older & now deprecated method of the same name. + * This API assumes an Open_vSwitch database Schema. + * + * @param node OVSDB Node + * @param tableName Table Name + * @param rowUuid UUID of the row being queried + * @return a row with a list of Column data that corresponds to an unique Row-identifier called uuid in a given table. + */ + + public Row getRow(Node node, String tableName, String uuid); + + /** + * This version of getRows is a short-term replacement for the older & now deprecated method of the same name. + * This API assumes an Open_vSwitch database Schema. + * + * @param node OVSDB Node + * @param tableName Table Name + * @return List of rows that makes the entire Table. + */ + + public ConcurrentMap getRows(Node node, String tableName); + + /** + * Returns all the Tables in a given Ndoe. + * This API assumes an Open_vSwitch database Schema. + * + * @param node OVSDB node + * @return List of Table Names that make up Open_vSwitch schema. + */ + public List getTables(Node node); + + /** + * setOFController is a convenience method used by existing applications to setup Openflow Controller on + * a Open_vSwitch Bridge. + * This API assumes an Open_vSwitch database Schema. + * + * @param node Node + * @param bridgeUUID uuid of the Bridge for which the ip-address of Openflow Controller should be programmed. + * @return Boolean representing success or failure of the operation. + * * @throws InterruptedException * @throws ExecutionException - * @throws JsonParseException - * @throws IOException */ - public StatusWithUuid insertRow(Node node, String tableName, String parentUuid, - Row row) throws InterruptedException, ExecutionException, JsonParseException, IOException; + Boolean setOFController(Node node, String bridgeUUID) throws InterruptedException, ExecutionException; } diff --git a/plugin/src/main/java/org/opendaylight/ovsdb/plugin/OVSDBInventoryListener.java b/plugin/src/main/java/org/opendaylight/ovsdb/plugin/OVSDBInventoryListener.java index 87c6ead04..dffbef1e1 100644 --- a/plugin/src/main/java/org/opendaylight/ovsdb/plugin/OVSDBInventoryListener.java +++ b/plugin/src/main/java/org/opendaylight/ovsdb/plugin/OVSDBInventoryListener.java @@ -10,12 +10,12 @@ package org.opendaylight.ovsdb.plugin; import org.opendaylight.controller.sal.core.Node; -import org.opendaylight.ovsdb.lib.table.Table; +import org.opendaylight.ovsdb.lib.notation.Row; public interface OVSDBInventoryListener { public void nodeAdded(Node node); public void nodeRemoved(Node node); - public void rowAdded(Node node, String tableName, String uuid, Table row); - public void rowUpdated(Node node, String tableName, String uuid, Table old, Table row); - public void rowRemoved(Node node, String tableName, String uuid, Table row, Object context); + public void rowAdded(Node node, String tableName, String uuid, Row row); + public void rowUpdated(Node node, String tableName, String uuid, Row old, Row row); + public void rowRemoved(Node node, String tableName, String uuid, Row row, Object context); } diff --git a/plugin/src/main/java/org/opendaylight/ovsdb/plugin/OvsVswitchdSchemaConstants.java b/plugin/src/main/java/org/opendaylight/ovsdb/plugin/OvsVswitchdSchemaConstants.java index bd5275478..03be637b7 100644 --- a/plugin/src/main/java/org/opendaylight/ovsdb/plugin/OvsVswitchdSchemaConstants.java +++ b/plugin/src/main/java/org/opendaylight/ovsdb/plugin/OvsVswitchdSchemaConstants.java @@ -5,6 +5,10 @@ import com.google.common.collect.Maps; public class OvsVswitchdSchemaConstants { public static String DATABASE_NAME = "Open_vSwitch"; + private static final String OVSDB_AUTOCONFIGURECONTROLLER = "ovsdb.autoconfigurecontroller"; + private static final boolean defaultAutoConfigureController = true; + private static boolean autoConfigureController = defaultAutoConfigureController; + private static Map columnToMutate = Maps.newHashMap(); public static String[] getParentColumnToMutate(String childTabletoInsert) { return columnToMutate.get(childTabletoInsert); @@ -25,5 +29,14 @@ public class OvsVswitchdSchemaConstants { addParentColumnToMutate("Netflow", "Bridge", "netflow"); addParentColumnToMutate("Mirror", "Bridge", "mirrors"); addParentColumnToMutate("Manager", "Open_vSwitch", "manager_options"); + addParentColumnToMutate("Controller", "Bridge", "controller"); + // Keep the default value if the property is not set + if (System.getProperty(OVSDB_AUTOCONFIGURECONTROLLER) != null) + autoConfigureController = Boolean.getBoolean(OVSDB_AUTOCONFIGURECONTROLLER); + } + + public static boolean shouldConfigureController (String databaseName, String tableName) { + if (autoConfigureController && databaseName.equals(DATABASE_NAME) && tableName.equals("Bridge")) return true; + return false; } } diff --git a/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestAddBridgeIT.java b/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestAddBridgeIT.java index 53540804d..eb6cba7d0 100644 --- a/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestAddBridgeIT.java +++ b/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestAddBridgeIT.java @@ -31,8 +31,7 @@ public class OvsdbTestAddBridgeIT extends OvsdbTestBase { * @param node Node serving this configuration service * @param bridgeDomainIdentifier String representation of a Bridge Domain */ - ConfigurationService configurationService = new ConfigurationService(); - configurationService.setConnectionServiceInternal(connectionService); + ConfigurationService configurationService = testObjects.configurationService; configurationService.createBridgeDomain(node, BRIDGE_NAME, null); } diff --git a/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestAddPortIT.java b/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestAddPortIT.java index c9f089946..d88d71a79 100644 --- a/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestAddPortIT.java +++ b/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestAddPortIT.java @@ -41,8 +41,7 @@ public class OvsdbTestAddPortIT extends OvsdbTestBase { * @param bridgeDomainIdentifier String representation of a Bridge Domain * @param portIdentifier String representation of a user defined Port Name */ - ConfigurationService configurationService = new ConfigurationService(); - configurationService.setConnectionServiceInternal(connectionService); + ConfigurationService configurationService = testObjects.configurationService; configurationService.addPort(node, BRIDGE_NAME, PORT_NAME, null); } } \ No newline at end of file diff --git a/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestAddTunnelIT.java b/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestAddTunnelIT.java index 32029ba8a..368184d30 100644 --- a/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestAddTunnelIT.java +++ b/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestAddTunnelIT.java @@ -26,7 +26,6 @@ public class OvsdbTestAddTunnelIT extends OvsdbTestBase { @Test public void addTunnel() throws Throwable{ TestObjects testObjects = getTestConnection(); - ConnectionService connectionService = testObjects.connectionService; Node node = testObjects.node; /** @@ -55,8 +54,7 @@ public class OvsdbTestAddTunnelIT extends OvsdbTestBase { * @param tunencap is the tunnel encapsulation options being CAPWAP, GRE or VXLAN * The Bridge must already be defined before calling addTunnel. */ - ConfigurationService configurationService = new ConfigurationService(); - configurationService.setConnectionServiceInternal(connectionService); + ConfigurationService configurationService = testObjects.configurationService; Map configs = new HashMap(); configs.put(ConfigConstants.TYPE, "TUNNEL"); configs.put(ConfigConstants.TUNNEL_TYPE, tunencap); diff --git a/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestAddVlanIT.java b/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestAddVlanIT.java index 496a97679..fd37e6361 100644 --- a/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestAddVlanIT.java +++ b/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestAddVlanIT.java @@ -39,8 +39,7 @@ public class OvsdbTestAddVlanIT extends OvsdbTestBase { * @param portIdentifier String representation of a user defined Port Name * @param vlanid Integer note: only one VID is accepted with tag=x method */ - ConfigurationService configurationService = new ConfigurationService(); - configurationService.setConnectionServiceInternal(connectionService); + ConfigurationService configurationService = testObjects.configurationService; Map configs = new HashMap(); configs.put(ConfigConstants.TYPE, "VLAN"); configs.put(ConfigConstants.VLAN, vlanid+""); diff --git a/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestBase.java b/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestBase.java index e9644dbcd..379231142 100644 --- a/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestBase.java +++ b/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestBase.java @@ -19,6 +19,7 @@ import junit.framework.Assert; import org.opendaylight.controller.sal.connection.ConnectionConstants; import org.opendaylight.controller.sal.core.Node; import org.opendaylight.controller.sal.core.NodeConnector; +import org.opendaylight.ovsdb.lib.impl.OvsdbConnectionService; public abstract class OvsdbTestBase { private final static String identifier = "TEST"; @@ -39,11 +40,13 @@ public abstract class OvsdbTestBase { public class TestObjects { public final ConnectionService connectionService; public final InventoryService inventoryService; + public final ConfigurationService configurationService; public final Node node; - public TestObjects(ConnectionService connectionService, Node node, InventoryService inventoryService) { + public TestObjects(ConnectionService connectionService, Node node, InventoryService inventoryService, ConfigurationService configurationService) { this.connectionService = connectionService; this.inventoryService = inventoryService; + this.configurationService = configurationService; this.node = node; } } @@ -68,6 +71,12 @@ public abstract class OvsdbTestBase { InventoryService inventory = new InventoryService(); inventory.init(); connectionService.setInventoryServiceInternal(inventory); + connectionService.setOvsdbConnection(OvsdbConnectionService.getService()); + ConfigurationService configurationService = new ConfigurationService(); + configurationService.setConnectionServiceInternal(connectionService); + configurationService.setInventoryServiceInternal(inventory); + inventory.setConfigurationService(configurationService); + Map params = new HashMap(); params.put(ConnectionConstants.ADDRESS, address); @@ -77,7 +86,13 @@ public abstract class OvsdbTestBase { if (node == null) { throw new IOException("Failed to connect to the ovsdb server"); } - return new TestObjects(connectionService, node, inventory); + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } // TODO : Remove this once Select is operational + return new TestObjects(connectionService, node, inventory, configurationService); } } diff --git a/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestBridgeConfigIT.java b/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestBridgeConfigIT.java index d8891f91e..ac62266da 100644 --- a/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestBridgeConfigIT.java +++ b/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestBridgeConfigIT.java @@ -35,8 +35,7 @@ public class OvsdbTestBridgeConfigIT extends OvsdbTestBase { //Will accept multiple array pairs. Pairs must be arrays not maps. configs.put(ConfigConstants.CUSTOM, exterIDPairs); - ConfigurationService configurationService = new ConfigurationService(); - configurationService.setConnectionServiceInternal(connectionService); + ConfigurationService configurationService = testObjects.configurationService; configurationService.addBridgeDomainConfig(node, BRIDGE_NAME, configs); } diff --git a/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestDeletePortIT.java b/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestDeletePortIT.java index 3fd246d31..c72f4bbb2 100644 --- a/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestDeletePortIT.java +++ b/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestDeletePortIT.java @@ -31,8 +31,7 @@ public class OvsdbTestDeletePortIT extends OvsdbTestBase { * @param bridgeDomainIdentifier String representation of a Bridge Domain * @param portIdentifier String representation of a user defined Port Name */ - ConfigurationService configurationService = new ConfigurationService(); - configurationService.setConnectionServiceInternal(connectionService); + ConfigurationService configurationService = testObjects.configurationService; configurationService.deletePort(node, BRIDGE_NAME, PORT_NAME); } } diff --git a/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestGetBridgeDomainsIT.java b/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestGetBridgeDomainsIT.java index 0d78f847b..630b1e276 100644 --- a/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestGetBridgeDomainsIT.java +++ b/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestGetBridgeDomainsIT.java @@ -44,9 +44,7 @@ public class OvsdbTestGetBridgeDomainsIT extends OvsdbTestBase { * @param node Node serving this configuration service * */ - ConfigurationService configurationService = new ConfigurationService(); - configurationService.setConnectionServiceInternal(connectionService); - configurationService.setInventoryServiceInternal(inventoryService); + ConfigurationService configurationService = testObjects.configurationService; List ls = configurationService.getBridgeDomains(node); } } diff --git a/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestSetManagerIT.java b/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestSetManagerIT.java index 4dba77856..1ab5f3de3 100644 --- a/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestSetManagerIT.java +++ b/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestSetManagerIT.java @@ -21,7 +21,6 @@ public class OvsdbTestSetManagerIT extends OvsdbTestBase { @Test public void setManager() throws Throwable{ TestObjects testObjects = getTestConnection(); - ConnectionService connectionService = testObjects.connectionService; Node node = testObjects.node; @@ -38,8 +37,7 @@ public class OvsdbTestSetManagerIT extends OvsdbTestBase { * @param String with IP and connection type ex. type:ip:port * */ - ConfigurationService configurationService = new ConfigurationService(); - configurationService.setConnectionServiceInternal(connectionService); + ConfigurationService configurationService = testObjects.configurationService; configurationService.setManager(node, manager); } diff --git a/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestSetOFControllerIT.java b/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestSetOFControllerIT.java index e7d9737cd..1c490ed40 100644 --- a/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestSetOFControllerIT.java +++ b/plugin/src/test/java/org/opendaylight/ovsdb/plugin/OvsdbTestSetOFControllerIT.java @@ -25,14 +25,12 @@ public class OvsdbTestSetOFControllerIT extends OvsdbTestBase { @Test public void setController() throws Throwable{ TestObjects testObjects = getTestConnection(); - ConnectionService connectionService = testObjects.connectionService; Node node = testObjects.node; Map configs = new HashMap(); configs.put(ConfigConstants.DEST_IP, "192.168.254.1"); configs.put(ConfigConstants.CUSTOM, "6633"); - ConfigurationService configurationService = new ConfigurationService(); - configurationService.setConnectionServiceInternal(connectionService); + ConfigurationService configurationService = testObjects.configurationService; configurationService.setBridgeOFController(node, BRIDGE_NAME); } diff --git a/pom.xml b/pom.xml index 0ab3fdfa9..11b671eba 100755 --- a/pom.xml +++ b/pom.xml @@ -20,11 +20,14 @@ schemas/Open_vSwitch schemas/hardware_vtep plugin - northbound - neutron commons/parent commons/integrationtest + diff --git a/schemas/Open_vSwitch/src/test/java/org/opendaylight/ovsdb/schema/openvswitch/BridgeTestCases.java b/schemas/Open_vSwitch/src/test/java/org/opendaylight/ovsdb/schema/openvswitch/BridgeTestCases.java index f8e218f84..1f6cc3cda 100644 --- a/schemas/Open_vSwitch/src/test/java/org/opendaylight/ovsdb/schema/openvswitch/BridgeTestCases.java +++ b/schemas/Open_vSwitch/src/test/java/org/opendaylight/ovsdb/schema/openvswitch/BridgeTestCases.java @@ -10,10 +10,16 @@ package org.opendaylight.ovsdb.schema.openvswitch; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Sets; -import com.google.common.util.concurrent.ListenableFuture; +import static org.opendaylight.ovsdb.lib.operations.Operations.op; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; + import junit.framework.Assert; + import org.junit.Before; import org.junit.Test; import org.opendaylight.ovsdb.lib.message.UpdateNotification; @@ -25,17 +31,15 @@ import org.opendaylight.ovsdb.lib.operations.TransactionBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.util.List; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeoutException; - -import static org.opendaylight.ovsdb.lib.operations.Operations.op; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Sets; +import com.google.common.util.concurrent.ListenableFuture; +; public class BridgeTestCases extends OpenVswitchSchemaTestBase { Logger logger = LoggerFactory.getLogger(BridgeTestCases.class); + @Override @Before public void setUp() throws ExecutionException, InterruptedException, TimeoutException, IOException { super.setUp(); @@ -78,6 +82,7 @@ public class BridgeTestCases extends OpenVswitchSchemaTestBase { } OpenVswitchSchemaSuiteIT.setTestBridgeUuid(operationResults.get(insertOperationIndex).getUuid()); + Thread.sleep(3000); // Wait for cache to catchup Row bridgeRow = OpenVswitchSchemaSuiteIT.getTableCache().get(bridge.getSchema().getName()).get(OpenVswitchSchemaSuiteIT.getTestBridgeUuid()); Bridge monitoredBridge = ovs.getTypedRowWrapper(Bridge.class, bridgeRow); Assert.assertEquals(monitoredBridge.getNameColumn().getData(), bridge.getNameColumn().getData()); diff --git a/schemas/Open_vSwitch/src/test/java/org/opendaylight/ovsdb/schema/openvswitch/ControllerTestCases.java b/schemas/Open_vSwitch/src/test/java/org/opendaylight/ovsdb/schema/openvswitch/ControllerTestCases.java index 9f2ddf8bf..f1bd7c0d2 100644 --- a/schemas/Open_vSwitch/src/test/java/org/opendaylight/ovsdb/schema/openvswitch/ControllerTestCases.java +++ b/schemas/Open_vSwitch/src/test/java/org/opendaylight/ovsdb/schema/openvswitch/ControllerTestCases.java @@ -10,9 +10,16 @@ package org.opendaylight.ovsdb.schema.openvswitch; -import com.google.common.collect.Sets; -import com.google.common.util.concurrent.ListenableFuture; +import static org.opendaylight.ovsdb.lib.operations.Operations.op; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; + import junit.framework.Assert; + import org.junit.Before; import org.junit.Test; import org.opendaylight.ovsdb.lib.message.UpdateNotification; @@ -24,17 +31,13 @@ import org.opendaylight.ovsdb.lib.operations.TransactionBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.util.List; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeoutException; - -import static org.opendaylight.ovsdb.lib.operations.Operations.op; +import com.google.common.collect.Sets; +import com.google.common.util.concurrent.ListenableFuture; public class ControllerTestCases extends OpenVswitchSchemaTestBase { Logger logger = LoggerFactory.getLogger(ControllerTestCases.class); + @Override @Before public void setUp() throws ExecutionException, InterruptedException, TimeoutException, IOException { super.setUp(); @@ -71,6 +74,7 @@ public class ControllerTestCases extends OpenVswitchSchemaTestBase { Assert.assertNull(result.getError()); } + Thread.sleep(3000); // Wait for cache to catchup Row bridgeRow = OpenVswitchSchemaSuiteIT.getTableCache().get(bridge.getSchema().getName()).get(OpenVswitchSchemaSuiteIT.getTestBridgeUuid()); Bridge monitoredBridge = ovs.getTypedRowWrapper(Bridge.class, bridgeRow); Assert.assertEquals(1, monitoredBridge.getControllerColumn().getData().size()); @@ -95,7 +99,7 @@ public class ControllerTestCases extends OpenVswitchSchemaTestBase { for (OperationResult result : operationResults) { Assert.assertNull(result.getError()); } - + Thread.sleep(3000); // Wait for cache to catchup bridgeRow = OpenVswitchSchemaSuiteIT.getTableCache().get(bridge.getSchema().getName()).get(OpenVswitchSchemaSuiteIT.getTestBridgeUuid()); monitoredBridge = ovs.getTypedRowWrapper(Bridge.class, bridgeRow); Assert.assertEquals(2, monitoredBridge.getControllerColumn().getData().size()); diff --git a/schemas/Open_vSwitch/src/test/java/org/opendaylight/ovsdb/schema/openvswitch/MonitorTestCases.java b/schemas/Open_vSwitch/src/test/java/org/opendaylight/ovsdb/schema/openvswitch/MonitorTestCases.java index 90b60e1b1..975b32e87 100644 --- a/schemas/Open_vSwitch/src/test/java/org/opendaylight/ovsdb/schema/openvswitch/MonitorTestCases.java +++ b/schemas/Open_vSwitch/src/test/java/org/opendaylight/ovsdb/schema/openvswitch/MonitorTestCases.java @@ -106,7 +106,7 @@ public class MonitorTestCases extends OpenVswitchSchemaTestBase { private class UpdateMonitor implements MonitorCallBack { @Override - public void update(TableUpdates result) { + public void update(TableUpdates result, DatabaseSchema dbSchema) { for (String tableName : result.getUpdates().keySet()) { Map tUpdate = OpenVswitchSchemaSuiteIT.getTableCache().get(tableName); TableUpdate update = result.getUpdates().get(tableName); -- 2.36.6