2b787884fea7a2a4f171c5eb5bb82c2ad3352635
[netvirt.git] / integrationtest / src / test / java / org / opendaylight / ovsdb / integrationtest / schema / openvswitch / OpenVSwitchIT.java
1 /*
2  *  Copyright (C) 2014 Red Hat, Inc.
3  *
4  *  This program and the accompanying materials are made available under the
5  *  terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  *  and is available at http://www.eclipse.org/legal/epl-v10.html
7  *
8  *  Authors : Sam Hague, Matt Oswalt
9  */
10 package org.opendaylight.ovsdb.integrationtest.schema.openvswitch;
11
12 import static org.junit.Assert.assertEquals;
13 import static org.junit.Assert.assertFalse;
14 import static org.junit.Assert.assertNotNull;
15 import static org.junit.Assert.assertNotSame;
16 import static org.junit.Assert.assertNull;
17 import static org.junit.Assert.assertSame;
18 import static org.junit.Assert.assertTrue;
19 import static org.junit.Assert.fail;
20 import static org.junit.Assume.assumeTrue;
21 import static org.opendaylight.ovsdb.lib.operations.Operations.op;
22 import static org.ops4j.pax.exam.CoreOptions.junitBundles;
23 import static org.ops4j.pax.exam.CoreOptions.options;
24 import static org.ops4j.pax.exam.CoreOptions.propagateSystemProperty;
25 import static org.ops4j.pax.exam.CoreOptions.systemProperty;
26
27 import com.google.common.collect.ImmutableMap;
28 import com.google.common.collect.ImmutableSet;
29 import com.google.common.collect.Lists;
30 import com.google.common.collect.Maps;
31 import com.google.common.collect.Sets;
32 import com.google.common.util.concurrent.ListenableFuture;
33 import java.io.IOException;
34 import java.util.HashMap;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.Set;
38 import java.util.concurrent.ExecutionException;
39 import javax.inject.Inject;
40 import org.junit.Before;
41 import org.junit.Rule;
42 import org.junit.Test;
43 import org.junit.rules.TestRule;
44 import org.junit.rules.TestWatcher;
45 import org.junit.runner.Description;
46 import org.junit.runner.RunWith;
47 import org.opendaylight.ovsdb.integrationtest.ConfigurationBundles;
48 import org.opendaylight.ovsdb.integrationtest.OvsdbIntegrationTestBase;
49 import org.opendaylight.ovsdb.lib.MonitorCallBack;
50 import org.opendaylight.ovsdb.lib.OvsdbClient;
51 import org.opendaylight.ovsdb.lib.error.SchemaVersionMismatchException;
52 import org.opendaylight.ovsdb.lib.message.MonitorRequest;
53 import org.opendaylight.ovsdb.lib.message.MonitorRequestBuilder;
54 import org.opendaylight.ovsdb.lib.message.MonitorSelect;
55 import org.opendaylight.ovsdb.lib.message.TableUpdate;
56 import org.opendaylight.ovsdb.lib.message.TableUpdates;
57 import org.opendaylight.ovsdb.lib.notation.Mutator;
58 import org.opendaylight.ovsdb.lib.notation.Row;
59 import org.opendaylight.ovsdb.lib.notation.UUID;
60 import org.opendaylight.ovsdb.lib.notation.Version;
61 import org.opendaylight.ovsdb.lib.operations.OperationResult;
62 import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
63 import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
64 import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
65 import org.opendaylight.ovsdb.lib.schema.TableSchema;
66 import org.opendaylight.ovsdb.lib.schema.typed.TypedBaseTable;
67 import org.opendaylight.ovsdb.schema.openvswitch.Bridge;
68 import org.opendaylight.ovsdb.schema.openvswitch.Controller;
69 import org.opendaylight.ovsdb.schema.openvswitch.FlowSampleCollectorSet;
70 import org.opendaylight.ovsdb.schema.openvswitch.FlowTable;
71 import org.opendaylight.ovsdb.schema.openvswitch.Interface;
72 import org.opendaylight.ovsdb.schema.openvswitch.IPFIX;
73 import org.opendaylight.ovsdb.schema.openvswitch.Manager;
74 import org.opendaylight.ovsdb.schema.openvswitch.Mirror;
75 import org.opendaylight.ovsdb.schema.openvswitch.NetFlow;
76 import org.opendaylight.ovsdb.schema.openvswitch.OpenVSwitch;
77 import org.opendaylight.ovsdb.schema.openvswitch.Port;
78 import org.opendaylight.ovsdb.schema.openvswitch.Qos;
79 import org.opendaylight.ovsdb.schema.openvswitch.Queue;
80 import org.opendaylight.ovsdb.schema.openvswitch.SFlow;
81 import org.opendaylight.ovsdb.schema.openvswitch.SSL;
82 import org.ops4j.pax.exam.Configuration;
83 import org.ops4j.pax.exam.Option;
84 import org.ops4j.pax.exam.junit.PaxExam;
85 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
86 import org.ops4j.pax.exam.spi.reactors.PerSuite;
87 import org.ops4j.pax.exam.util.PathUtils;
88 import org.osgi.framework.BundleContext;
89 import org.slf4j.Logger;
90 import org.slf4j.LoggerFactory;
91
92 @RunWith(PaxExam.class)
93 @ExamReactorStrategy(PerSuite.class)
94 public class OpenVSwitchIT extends OvsdbIntegrationTestBase {
95     private static final Logger LOG = LoggerFactory.getLogger(OpenVSwitchIT.class);
96     private static boolean monitorReady = false;
97     private static boolean schemaSupported = false;
98     private static final String TEST_BRIDGE_NAME = "br_test";
99     private static final String TEST_MANAGER_UUID_STR = "managerUuidName";
100     private static final String ASSERT_TRANS_ERROR = "Transaction should not have errors";
101     private static final String ASSERT_TRANS_RESULT_EMPTY = "Transaction should not be empty";
102     private static final String ASSERT_TRANS_OPERATION_COUNT = "Transaction should match number of operations";
103     private static final String ASSERT_TRANS_UUID = "Transaction UUID should not be null";
104     private Version schemaVersion;
105     private UUID testBridgeUuid = null;
106     private UUID testController1Uuid = null;
107     private UUID testController2Uuid = null;
108     private UUID testFlowSampleCollectorSetUuid = null;
109     private UUID testFlowTableUuid = null;
110     private UUID testInterfaceUuid = null;
111     private UUID testIpfixUuid = null;
112     private UUID testManagerUuid = null;
113     private UUID testMirrorUuid = null;
114     private UUID testNetFlowUuid = null;
115     private UUID testPortUuid = null;
116     private UUID testQosUuid = null;
117     private UUID testQueueUuid = null;
118     private UUID testSFlowUuid = null;
119     private UUID testSslUuid = null;
120     private Version flowSampleCollectorSetFromVersion = Version.fromString("7.1.0");
121     private Version flowTableFromVersion = Version.fromString("6.5.0");
122     private Version prefixesAddedVersion = Version.fromString("7.4.0");
123     private Version externalIdAddedVerson = Version.fromString("7.5.0");
124     private Version ipfixFromVersion = Version.fromString("7.1.0");
125     private Version ipfixCacheFromVersion = Version.fromString("7.3.0");
126
127     private static Map<String, Map<UUID, Row>> tableCache = new HashMap<>();
128     private static Map<String, Map<UUID, Row>> getTableCache () {
129         return tableCache;
130     }
131
132     private static OvsdbClient ovsdbClient;
133     private OvsdbClient getClient () {
134         return ovsdbClient;
135     }
136
137     private static DatabaseSchema dbSchema;
138     private DatabaseSchema getDbSchema () {
139         return dbSchema;
140     }
141
142     @Inject
143     private BundleContext bc;
144
145     @Configuration
146     public Option[] config() throws Exception {
147         return options(
148                 systemProperty("logback.configurationFile").value(
149                         "file:" + PathUtils.getBaseDir()
150                                 + "/src/test/resources/logback.xml"
151                 ),
152                 // To start OSGi console for inspection remotely
153                 systemProperty("osgi.console").value("2401"),
154
155                 propagateSystemProperty("ovsdbserver.ipaddress"),
156                 propagateSystemProperty("ovsdbserver.port"),
157
158                 ConfigurationBundles.controllerBundles(),
159                 ConfigurationBundles.ovsdbLibraryBundles(),
160                 ConfigurationBundles.ovsdbDefaultSchemaBundles(),
161                 junitBundles()
162         );
163     }
164
165     /*
166      * Method adds a log as each test method starts and finishes. This is useful when
167      * the test suite is used because the suites only print a final summary.
168      */
169     @Rule
170     public TestRule watcher = new TestWatcher() {
171         @Override
172         protected void starting(Description description) {
173             LOG.info("TestWatcher: Starting test: {}",
174                     description.getDisplayName());
175         }
176
177         @Override
178         protected void finished(Description description) {
179             LOG.info("TestWatcher: Finished test: {}", description.getDisplayName());
180         }
181     };
182
183     @Before
184     public void setUp () throws ExecutionException, InterruptedException, IOException {
185         areWeReady(bc);
186         assertTrue(OPEN_VSWITCH_SCHEMA + " is required.", checkSchema(OPEN_VSWITCH_SCHEMA));
187         assertTrue("Failed to monitor tables", monitorTables());
188         schemaVersion = getClient().getDatabaseSchema(OPEN_VSWITCH_SCHEMA).getVersion();
189         LOG.info("{} schema version = {}", OPEN_VSWITCH_SCHEMA, schemaVersion);
190     }
191
192     public boolean checkSchema (String schema) {
193         if (schemaSupported) {
194             LOG.info("Schema ({}) is supported", schema);
195             return true;
196         }
197         try {
198             ovsdbClient = getTestConnection();
199             assertNotNull("Invalid Client. Check connection params", ovsdbClient);
200             //Thread.sleep(3000); // Wait for a few seconds to get the Schema exchange done
201             if (isSchemaSupported(ovsdbClient, schema)) {
202                 dbSchema = ovsdbClient.getSchema(schema).get();
203                 assertNotNull(dbSchema);
204                 LOG.info("{} schema in {} with tables: {}",
205                         schema, ovsdbClient.getConnectionInfo(), dbSchema.getTables());
206                 schemaSupported = true;
207                 return true;
208             }
209         } catch (Exception e) {
210             fail("Exception : "+e.getMessage());
211         }
212
213         LOG.info("Schema ({}) is not supported", schema);
214         return false;
215     }
216
217     public UUID getOpenVSwitchTableUuid (OvsdbClient ovs, Map<String, Map<UUID, Row>> tableCache) {
218         OpenVSwitch openVSwitch = getClient().getTypedRowWrapper(OpenVSwitch.class, null);
219         Map<UUID, Row> ovsTable = tableCache.get(openVSwitch.getSchema().getName());
220         if (ovsTable != null) {
221             if (ovsTable.keySet().size() >= 1) {
222                 return (UUID)ovsTable.keySet().toArray()[0];
223             }
224         }
225         return null;
226     }
227
228     public boolean isSchemaSupported (OvsdbClient client, String schema) throws ExecutionException, InterruptedException {
229         ListenableFuture<List<String>> databases = client.getDatabases();
230         List<String> dbNames = databases.get();
231         assertNotNull(dbNames);
232         if (dbNames.contains(schema)) {
233             return true;
234         } else {
235             return false;
236         }
237     }
238
239     /**
240      * As per RFC 7047, section 4.1.5, if a Monitor request is sent without any columns, the update response will not include
241      * the _uuid column.
242      * ----------------------------------------------------------------------------------------------------------------------------------
243      * Each <monitor-request> specifies one or more columns and the manner in which the columns (or the entire table) are to be monitored.
244      * The "columns" member specifies the columns whose values are monitored. It MUST NOT contain duplicates.
245      * If "columns" is omitted, all columns in the table, except for "_uuid", are monitored.
246      * ----------------------------------------------------------------------------------------------------------------------------------
247      * In order to overcome this limitation, this method
248      *
249      * @return MonitorRequest that includes all the Bridge Columns including _uuid
250      */
251     public <T extends TypedBaseTable<GenericTableSchema>> MonitorRequest<GenericTableSchema> getAllColumnsMonitorRequest (Class <T> klazz) {
252         TypedBaseTable<GenericTableSchema> table = getClient().createTypedRowWrapper(klazz);
253         GenericTableSchema tableSchema = table.getSchema();
254         Set<String> columns = tableSchema.getColumns();
255         MonitorRequestBuilder<GenericTableSchema> bridgeBuilder = MonitorRequestBuilder.builder(table.getSchema());
256         for (String column : columns) {
257             bridgeBuilder.addColumn(column);
258         }
259         return bridgeBuilder.with(new MonitorSelect(true, true, true, true)).build();
260     }
261
262     public <T extends TableSchema<T>> MonitorRequest<T> getAllColumnsMonitorRequest (T tableSchema) {
263         Set<String> columns = tableSchema.getColumns();
264         MonitorRequestBuilder<T> monitorBuilder = MonitorRequestBuilder.builder(tableSchema);
265         for (String column : columns) {
266             monitorBuilder.addColumn(column);
267         }
268         return monitorBuilder.with(new MonitorSelect(true, true, true, true)).build();
269     }
270
271     public boolean monitorTables () throws ExecutionException, InterruptedException, IOException {
272         if (monitorReady) {
273             LOG.info("Monitoring is already initialized.");
274             return monitorReady;
275         }
276
277         assertNotNull(getDbSchema());
278
279         List<MonitorRequest<GenericTableSchema>> monitorRequests = Lists.newArrayList();
280         Set<String> tables = getDbSchema().getTables();
281         assertNotNull("ovsdb tables should not be null", tables);
282
283         for (String tableName : tables) {
284             GenericTableSchema tableSchema = getDbSchema().table(tableName, GenericTableSchema.class);
285             monitorRequests.add(this.getAllColumnsMonitorRequest(tableSchema));
286         }
287         TableUpdates updates = getClient().monitor(getDbSchema(), monitorRequests, new UpdateMonitor());
288         assertNotNull(updates);
289         this.updateTableCache(updates);
290
291         monitorReady = true;
292         LOG.info("Monitoring is initialized.");
293         return monitorReady;
294     }
295
296     private void updateTableCache (TableUpdates updates) {
297         for (String tableName : updates.getUpdates().keySet()) {
298             Map<UUID, Row> tUpdate = getTableCache().get(tableName);
299             TableUpdate update = updates.getUpdates().get(tableName);
300             for (UUID uuid : (Set<UUID>)update.getRows().keySet()) {
301                 if (update.getNew(uuid) != null) {
302                     if (tUpdate == null) {
303                         tUpdate = new HashMap<>();
304                         getTableCache().put(tableName, tUpdate);
305                     }
306                     tUpdate.put(uuid, update.getNew(uuid));
307                 } else {
308                     tUpdate.remove(uuid);
309                 }
310             }
311         }
312     }
313
314     private class UpdateMonitor implements MonitorCallBack {
315         @Override
316         public void update(TableUpdates result, DatabaseSchema dbSchema) {
317             updateTableCache(result);
318         }
319
320         @Override
321         public void exception(Throwable t) {
322             LOG.error("Exception t = " + t);
323         }
324     }
325
326     public List<OperationResult> executeTransaction (TransactionBuilder transactionBuilder, String text)
327             throws ExecutionException, InterruptedException {
328         ListenableFuture<List<OperationResult>> results = transactionBuilder.execute();
329         List<OperationResult> operationResults = results.get();
330         LOG.info("{}: {}", text, operationResults);
331         org.junit.Assert.assertFalse(ASSERT_TRANS_RESULT_EMPTY, operationResults.isEmpty());
332         assertEquals(ASSERT_TRANS_OPERATION_COUNT, transactionBuilder.getOperations().size(), operationResults.size());
333         for (OperationResult result : operationResults) {
334             assertNull(ASSERT_TRANS_ERROR, result.getError());
335         }
336         //Thread.sleep(500); // Wait for a few seconds to ensure the cache updates
337         return operationResults;
338     }
339
340     public UUID bridgeInsert () throws ExecutionException, InterruptedException {
341         Bridge bridge = getClient().createTypedRowWrapper(Bridge.class);
342         bridge.setName(TEST_BRIDGE_NAME);
343         bridge.setStatus(ImmutableMap.of("key", "value"));
344         bridge.setFloodVlans(Sets.newHashSet(34L));
345
346         OpenVSwitch openVSwitch = getClient().createTypedRowWrapper(OpenVSwitch.class);
347         openVSwitch.setBridges(Sets.newHashSet(new UUID(TEST_BRIDGE_NAME)));
348
349         TransactionBuilder transactionBuilder = getClient().transactBuilder(getDbSchema())
350                 .add(op.insert(bridge.getSchema())
351                         .withId(TEST_BRIDGE_NAME)
352                         .value(bridge.getNameColumn()))
353                 .add(op.comment("Bridge: Inserting " + TEST_BRIDGE_NAME))
354                 .add(op.update(bridge.getSchema())
355                         .set(bridge.getStatusColumn())
356                         .set(bridge.getFloodVlansColumn())
357                         .where(bridge.getNameColumn().getSchema().opEqual(bridge.getName()))
358                         .and(bridge.getNameColumn().getSchema().opEqual(bridge.getName()))
359                         .build())
360                 .add(op.comment("Bridge: Updating " + TEST_BRIDGE_NAME))
361                 .add(op.mutate(openVSwitch.getSchema())
362                         .addMutation(openVSwitch.getBridgesColumn().getSchema(), Mutator.INSERT,
363                                 openVSwitch.getBridgesColumn().getData()))
364                 .add(op.comment("Open_vSwitch: Mutating " + TEST_BRIDGE_NAME));
365
366         List<OperationResult> operationResults = executeTransaction(transactionBuilder,
367                 "Bridge Insert, Update and Mutate operation results");
368         UUID bridgeUuid = operationResults.get(0).getUuid();
369         assertNotNull(ASSERT_TRANS_UUID, bridgeUuid);
370         return bridgeUuid;
371     }
372
373     public void bridgeDelete (UUID bridgeUuid) throws ExecutionException, InterruptedException {
374         Bridge bridge = getClient().getTypedRowWrapper(Bridge.class, null);
375         OpenVSwitch openVSwitch = getClient().getTypedRowWrapper(OpenVSwitch.class, null);
376
377         TransactionBuilder transactionBuilder = getClient().transactBuilder(getDbSchema())
378                 .add(op.delete(bridge.getSchema())
379                         .where(bridge.getNameColumn().getSchema().opEqual(TEST_BRIDGE_NAME))
380                         .build())
381                 .add(op.comment("Bridge: Deleting " + TEST_BRIDGE_NAME))
382                 .add(op.mutate(openVSwitch.getSchema())
383                         .addMutation(openVSwitch.getBridgesColumn().getSchema(), Mutator.DELETE,
384                                 Sets.newHashSet(bridgeUuid)))
385                 .add(op.comment("Open_vSwitch: Mutating " + TEST_BRIDGE_NAME + " " + bridgeUuid))
386                 .add(op.commit(true));
387
388         executeTransaction(transactionBuilder, "Bridge delete operation results");
389     }
390
391     @Test
392     public void testBridge () throws ExecutionException, InterruptedException {
393         testBridgeUuid = bridgeInsert();
394
395         // Verify that the local cache was updated with the remote changes
396         Bridge bridge = getClient().createTypedRowWrapper(Bridge.class);
397         Row bridgeRow = getTableCache().get(bridge.getSchema().getName()).get(testBridgeUuid);
398         Bridge monitoredBridge = getClient().getTypedRowWrapper(Bridge.class, bridgeRow);
399         assertEquals(TEST_BRIDGE_NAME, monitoredBridge.getNameColumn().getData());
400
401         bridgeDelete(testBridgeUuid);
402     }
403
404     private void controllerInsert () throws ExecutionException, InterruptedException {
405         String controllerUuidStr = "controller";
406         Controller controller1 = getClient().createTypedRowWrapper(Controller.class);
407         controller1.setTarget("tcp:1.1.1.1:6640");
408         Controller controller2 = getClient().createTypedRowWrapper(Controller.class);
409         controller2.setTarget("tcp:2.2.2.2:6640");
410         Bridge bridge = getClient().getTypedRowWrapper(Bridge.class, null);
411
412         // Insert row to Controller table with address in target column
413         // Update row in Bridge table with controller uuid in controller column
414         TransactionBuilder transactionBuilder = getClient().transactBuilder(getDbSchema())
415                 .add(op.insert(controller1.getSchema())
416                         .withId(controllerUuidStr)
417                         .value(controller1.getTargetColumn()))
418                 .add(op.comment("Controller: Inserting controller1 " + controller1.getTargetColumn().getData()))
419                 .add(op.mutate(bridge.getSchema())
420                         .addMutation(bridge.getControllerColumn().getSchema(), Mutator.INSERT,
421                                 Sets.newHashSet(new UUID(controllerUuidStr)))
422                         .where(bridge.getNameColumn().getSchema().opEqual(TEST_BRIDGE_NAME))
423                         .build())
424                 .add(op.comment("Bridge: Mutating controller1 " + controller1.getTargetColumn().getData()));
425
426         List<OperationResult> operationResults = executeTransaction(transactionBuilder,
427                 "Controller: Insert & Mutate operation results for controller1");
428         testController1Uuid = operationResults.get(0).getUuid();
429         assertNotNull(ASSERT_TRANS_UUID, testController1Uuid);
430
431         // Verify that the local cache was updated with the remote changes
432         Row controllerRow = getTableCache().get(controller1.getSchema().getName()).get(testController1Uuid);
433         Controller monitoredController = getClient().getTypedRowWrapper(Controller.class, controllerRow);
434         assertEquals(controller1.getTargetColumn().getData(), monitoredController.getTargetColumn().getData());
435
436         Row bridgeRow = getTableCache().get(bridge.getSchema().getName()).get(testBridgeUuid);
437         Bridge monitoredBridge = getClient().getTypedRowWrapper(Bridge.class, bridgeRow);
438         assertEquals(1, monitoredBridge.getControllerColumn().getData().size());
439
440         transactionBuilder = getClient().transactBuilder(getDbSchema())
441                 .add(op.insert(controller2.getSchema())
442                         .withId(controllerUuidStr)
443                         .value(controller2.getTargetColumn()))
444                 .add(op.comment("Controller: Inserting controller2 " + controller2.getTargetColumn().getData()))
445                 .add(op.mutate(bridge.getSchema())
446                         .addMutation(bridge.getControllerColumn().getSchema(), Mutator.INSERT,
447                                 Sets.newHashSet(new UUID(controllerUuidStr)))
448                         .where(bridge.getNameColumn().getSchema().opEqual(TEST_BRIDGE_NAME))
449                         .build())
450                 .add(op.comment("Bridge: Mutating controller2 " + controller2.getTargetColumn().getData()));
451
452         operationResults = executeTransaction(transactionBuilder,
453                 new String("Controller: Insert & Mutate operation results for controller2"));
454         testController2Uuid = operationResults.get(0).getUuid();
455         assertNotNull(ASSERT_TRANS_UUID, testController2Uuid);
456
457         // Verify that the local cache was updated with the remote changes
458         controllerRow = getTableCache().get(controller2.getSchema().getName()).get(testController2Uuid);
459         monitoredController = getClient().getTypedRowWrapper(Controller.class, controllerRow);
460         assertEquals(controller2.getTargetColumn().getData(), monitoredController.getTargetColumn().getData());
461
462         bridgeRow = getTableCache().get(bridge.getSchema().getName()).get(testBridgeUuid);
463         monitoredBridge = getClient().getTypedRowWrapper(Bridge.class, bridgeRow);
464         assertEquals(2, monitoredBridge.getControllerColumn().getData().size());
465     }
466
467     private void controllerDelete () throws ExecutionException, InterruptedException {
468         Controller controller = getClient().getTypedRowWrapper(Controller.class, null);
469         Bridge bridge = getClient().getTypedRowWrapper(Bridge.class, null);
470         DatabaseSchema dbSchema = getClient().getSchema(OPEN_VSWITCH_SCHEMA).get();
471
472         TransactionBuilder transactionBuilder = getClient().transactBuilder(dbSchema)
473                 .add(op.delete(controller.getSchema())
474                         .where(controller.getUuidColumn().getSchema().opEqual(testController1Uuid))
475                         .build())
476                 .add(op.comment("Controller: Deleting " + testController1Uuid))
477                 .add(op.mutate(bridge.getSchema()) // Delete a controller column in the Bridge table
478                         .addMutation(bridge.getControllerColumn().getSchema(), Mutator.DELETE,
479                                 Sets.newHashSet(testController1Uuid)))
480                 .add(op.comment("Bridge: Mutating " + testController1Uuid))
481                 .add(op.commit(true));
482
483         executeTransaction(transactionBuilder, "Controller: Delete operation results for controller1");
484
485         transactionBuilder
486                 .add(op.delete(controller.getSchema())
487                         .where(controller.getUuidColumn().getSchema().opEqual(testController2Uuid))
488                         .build())
489                 .add(op.comment("Controller: Deleting " + testController2Uuid))
490                 .add(op.mutate(bridge.getSchema()) // Delete a controller column in the Bridge table
491                         .addMutation(bridge.getControllerColumn().getSchema(), Mutator.DELETE,
492                                 Sets.newHashSet(testController2Uuid)))
493                 .add(op.comment("Bridge: Mutating " + testController2Uuid))
494                 .add(op.commit(true));
495
496         executeTransaction(transactionBuilder, "Controller: Delete operation results for controller2");
497     }
498
499     @Test
500     public void testController () throws ExecutionException, InterruptedException {
501         testBridgeUuid = bridgeInsert();
502         controllerInsert();
503         controllerDelete();
504         bridgeDelete(testBridgeUuid);
505     }
506
507     @Test
508     public void testFlowSampleCollectorSetTableNotSupported () {
509         // Don't run this test if the table is not supported
510         assumeTrue(schemaVersion.compareTo(flowSampleCollectorSetFromVersion) < 0);
511
512         boolean isExceptionRaised = false;
513         try {
514             FlowSampleCollectorSet flowSampleCollectorSet = getClient().createTypedRowWrapper(FlowSampleCollectorSet.class);
515         } catch (SchemaVersionMismatchException e) {
516             isExceptionRaised = true;
517         }
518         assertTrue(isExceptionRaised);
519     }
520
521     public void flowSampleCollectorSetInsert () throws ExecutionException, InterruptedException {
522         // Don't run this test if the table is not supported
523         assumeTrue(schemaVersion.compareTo(flowSampleCollectorSetFromVersion) >= 0);
524
525         FlowSampleCollectorSet flowSampleCollectorSet =
526                 getClient().createTypedRowWrapper(FlowSampleCollectorSet.class);
527         flowSampleCollectorSet.setId(Long.valueOf(1));
528         flowSampleCollectorSet.setExternalIds(ImmutableMap.of("I <3", "ovs"));
529         flowSampleCollectorSet.setBridge(testBridgeUuid);
530
531         TransactionBuilder transactionBuilder = getClient().transactBuilder(getDbSchema())
532                 .add(op.insert(flowSampleCollectorSet.getSchema())
533                         .value(flowSampleCollectorSet.getIdColumn())
534                         .value(flowSampleCollectorSet.getExternalIdsColumn())
535                         .value(flowSampleCollectorSet.getBridgeColumn()))
536                 .add(op.comment("FlowSampleCollectorSet: Inserting"));
537
538         List<OperationResult> operationResults = executeTransaction(transactionBuilder,
539                 "FlowSampleCollectorSet: Insert results");
540         testFlowSampleCollectorSetUuid = operationResults.get(0).getUuid();
541         assertNotNull(ASSERT_TRANS_UUID, testFlowSampleCollectorSetUuid);
542
543         // Verify that the local cache was updated with the remote changes
544         Row flowSampleCollectorSetRow = getTableCache().get(flowSampleCollectorSet.getSchema().getName())
545                 .get(testFlowSampleCollectorSetUuid);
546         FlowSampleCollectorSet monitoredflowSampleCollectorSet =
547                 getClient().getTypedRowWrapper(FlowSampleCollectorSet.class, flowSampleCollectorSetRow);
548         assertEquals(flowSampleCollectorSet.getIdColumn().getData(),
549                 monitoredflowSampleCollectorSet.getIdColumn().getData());
550     }
551
552     public void flowSampleCollectorSetDelete () throws ExecutionException, InterruptedException {
553         assumeTrue(schemaVersion.compareTo(flowSampleCollectorSetFromVersion) >= 0);
554
555         FlowSampleCollectorSet flowSampleCollectorSet = getClient().getTypedRowWrapper(FlowSampleCollectorSet.class, null);
556         TransactionBuilder transactionBuilder = getClient().transactBuilder(getDbSchema())
557                 .add(op.delete(flowSampleCollectorSet.getSchema())
558                         .where(flowSampleCollectorSet.getUuidColumn().getSchema().opEqual(testFlowSampleCollectorSetUuid))
559                         .build())
560                 .add(op.comment("FlowSampleCollectorSet: Deleting " + testFlowSampleCollectorSetUuid))
561                 .add(op.commit(true));
562
563         executeTransaction(transactionBuilder, "Bridge delete operation results");
564     }
565
566     @Test
567     public void testFlowSampleCollectorSet () throws ExecutionException, InterruptedException {
568         // Don't run this test if the table is not supported
569         assumeTrue(schemaVersion.compareTo(flowSampleCollectorSetFromVersion) >= 0);
570
571         testBridgeUuid = bridgeInsert();
572         flowSampleCollectorSetInsert();
573         flowSampleCollectorSetDelete();
574         bridgeDelete(testBridgeUuid);
575     }
576
577     @Test
578     public void testFlowTableTableNotSupported () {
579         // Don't run this test if the table is not supported
580         assumeTrue(schemaVersion.compareTo(flowTableFromVersion) < 0);
581
582         boolean isExceptionRaised = false;
583         try {
584             FlowTable flowTable = getClient().createTypedRowWrapper(FlowTable.class);
585         } catch (SchemaVersionMismatchException e) {
586             isExceptionRaised = true;
587         }
588         assertTrue(isExceptionRaised);
589     }
590
591     public void flowTableInsert () throws ExecutionException, InterruptedException {
592         // Don't run this test if the table is not supported
593         assumeTrue(schemaVersion.compareTo(flowTableFromVersion) >= 0);
594
595         String flowTableUuidStr = "testFlowTable";
596         String tableName = "flow_table_row_name";
597         String overflowPolicy = "evict";
598         String groups = "group name";
599         String prefixes = "wildcarding prefixes";
600         Long flowLimit = 50000L;
601         Map<Long, UUID> flowTableBrRef = new HashMap<>();
602         flowTableBrRef.put(1L, new UUID(flowTableUuidStr));
603         FlowTable flowTable = getClient().createTypedRowWrapper(FlowTable.class);
604         flowTable.setName(ImmutableSet.of(tableName));
605         flowTable.setOverflowPolicy(ImmutableSet.of(overflowPolicy));
606         flowTable.setGroups(ImmutableSet.of(groups));
607         if (schemaVersion.compareTo(prefixesAddedVersion) >= 0) {
608             flowTable.setPrefixes(ImmutableSet.of(prefixes));
609         }
610         if (schemaVersion.compareTo(externalIdAddedVerson) >= 0) {
611             flowTable.setExternalIds(ImmutableMap.of("I <3", "OVS"));
612         }
613         flowTable.setFlowLimit(ImmutableSet.of(flowLimit));
614         Bridge bridge = getClient().getTypedRowWrapper(Bridge.class, null);
615
616         TransactionBuilder transactionBuilder = getClient().transactBuilder(getDbSchema())
617                 .add(op.insert(flowTable)
618                         .withId(flowTableUuidStr))
619                 .add(op.comment("Flowtable: Inserting " + flowTableUuidStr))
620                 .add(op.mutate(bridge.getSchema())
621                         .addMutation(bridge.getFlowTablesColumn().getSchema(), Mutator.INSERT, flowTableBrRef)
622                         .where(bridge.getNameColumn().getSchema().opEqual(TEST_BRIDGE_NAME))
623                         .build())
624                 .add(op.comment("Bridge: Mutating " + TEST_BRIDGE_NAME));
625
626         List<OperationResult> operationResults = executeTransaction(transactionBuilder,
627                 "FlowTable: Insert and Mutate results");
628         testFlowTableUuid = operationResults.get(0).getUuid();
629         assertNotNull(ASSERT_TRANS_UUID, testFlowTableUuid);
630
631         // Verify that the local cache was updated with the remote changes
632         Row flowTableRow = getTableCache().get(flowTable.getSchema().getName()).get(testFlowTableUuid);
633         FlowTable monitoredFlowTable = getClient().getTypedRowWrapper(FlowTable.class, flowTableRow);
634         assertEquals(flowTable.getNameColumn().getData(), monitoredFlowTable.getNameColumn().getData());
635     }
636
637     public void flowTableDelete () throws ExecutionException, InterruptedException {
638         // Don't run this test if the table is not supported
639         assumeTrue(schemaVersion.compareTo(flowTableFromVersion) >= 0);
640
641         FlowTable flowTable = getClient().getTypedRowWrapper(FlowTable.class, null);
642         Bridge bridge = getClient().getTypedRowWrapper(Bridge.class, null);
643
644         TransactionBuilder transactionBuilder = getClient().transactBuilder(getDbSchema())
645                 .add(op.delete(flowTable.getSchema())
646                         .where(flowTable.getUuidColumn().getSchema().opEqual(testFlowTableUuid))
647                         .build())
648                 .add(op.comment("FlowTable: Deleting " + testFlowTableUuid))
649                 .add(op.mutate(bridge.getSchema())
650                         .addMutation(bridge.getFlowTablesColumn().getSchema(), Mutator.DELETE,
651                                 Maps.newHashMap(ImmutableMap.of(1L, testFlowTableUuid))))
652                 .add(op.comment("Bridge: Mutating " + testFlowTableUuid))
653                 .add(op.commit(true));
654
655         executeTransaction(transactionBuilder, "FlowTable delete operation results");
656     }
657
658     @Test
659     public void setTestFlowTableSet () throws ExecutionException, InterruptedException {
660         // Don't run this test if the table is not supported
661         assumeTrue(schemaVersion.compareTo(flowTableFromVersion) >= 0);
662
663         UUID testBridgeUuid = bridgeInsert();
664         flowTableInsert();
665         flowTableDelete();
666         bridgeDelete(testBridgeUuid);
667     }
668
669     @Test
670     public void testIpfixTableNotSupported () {
671         // Don't run this test if the table is not supported
672         assumeTrue(schemaVersion.compareTo(ipfixFromVersion) < 0);
673
674         boolean isExceptionRaised = false;
675         try {
676             IPFIX ipfix = getClient().createTypedRowWrapper(IPFIX.class);
677         } catch (SchemaVersionMismatchException e) {
678             isExceptionRaised = true;
679         }
680         assertTrue(isExceptionRaised);
681     }
682
683     public void ipfixInsert () throws ExecutionException, InterruptedException {
684         // Don't run this test if the table is not supported
685         assumeTrue(schemaVersion.compareTo(ipfixFromVersion) >= 0);
686
687         String ipfixUuidStr = "testIpfix";
688         String ipfixTarget = "172.16.20.1:4739";
689         Long obsDomainId = 112L;
690         Long obsPointId = 358L;
691         Long cacheMax = 132L;
692         Long cacheTimeout = 134L;
693         Long sampling = 558L;
694
695         IPFIX ipfix = getClient().createTypedRowWrapper(IPFIX.class);
696         ipfix.setTargets(ImmutableSet.of(ipfixTarget));
697         ipfix.setObsDomainId(ImmutableSet.of(obsDomainId));
698         ipfix.setObsPointId(ImmutableSet.of(obsPointId));
699         // Only set these rows if the schema version supports it
700         if (schemaVersion.compareTo(ipfixCacheFromVersion) >= 0) {
701             ipfix.setCacheMaxFlows(ImmutableSet.of(cacheMax));
702             ipfix.setCacheActiveTimeout(ImmutableSet.of(cacheTimeout));
703         }
704         ipfix.setSampling(ImmutableSet.of(sampling));
705         ipfix.setExternalIds(ImmutableMap.of("I <3", "ovs"));
706         Bridge bridge = getClient().getTypedRowWrapper(Bridge.class, null);
707
708         TransactionBuilder transactionBuilder = getClient().transactBuilder(getDbSchema())
709                 .add(op.insert(ipfix)
710                         .withId(ipfixUuidStr))
711                 .add(op.comment("IPFIX: Inserting " + ipfixUuidStr))
712                 .add(op.mutate(bridge.getSchema())
713                         .addMutation(bridge.getIpfixColumn().getSchema(), Mutator.INSERT,
714                                 Sets.newHashSet(new UUID(ipfixUuidStr)))
715                         .where(bridge.getNameColumn().getSchema().opEqual(TEST_BRIDGE_NAME))
716                         .build())
717                 .add(op.comment("Bridge: Mutating " + ipfixUuidStr));
718
719         List<OperationResult> operationResults = executeTransaction(transactionBuilder,
720                 "IPFIX: Insert and Mutate results");
721         testIpfixUuid = operationResults.get(0).getUuid();
722         assertNotNull(ASSERT_TRANS_UUID, testIpfixUuid);
723
724         // Verify that the local cache was updated with the remote changes
725         Row ipfixRow = getTableCache().get(ipfix.getSchema().getName()).get(testIpfixUuid);
726         IPFIX monitoredIPFIX = getClient().getTypedRowWrapper(IPFIX.class, ipfixRow);
727         assertEquals(testIpfixUuid, monitoredIPFIX.getUuidColumn().getData());
728     }
729
730     public void ipfixDelete () throws ExecutionException, InterruptedException {
731         // Don't run this test if the table is not supported
732         assumeTrue(schemaVersion.compareTo(ipfixFromVersion) >= 0);
733
734         FlowTable flowTable = getClient().getTypedRowWrapper(FlowTable.class, null);
735         Bridge bridge = getClient().getTypedRowWrapper(Bridge.class, null);
736
737         TransactionBuilder transactionBuilder = getClient().transactBuilder(getDbSchema())
738                 .add(op.delete(flowTable.getSchema())
739                         .where(flowTable.getUuidColumn().getSchema().opEqual(testIpfixUuid))
740                         .build())
741                 .add(op.comment("IPFIX: Deleting " + testIpfixUuid))
742                 .add(op.mutate(bridge.getSchema()) // Delete a controller column in the Bridge table
743                         .addMutation(bridge.getMirrorsColumn().getSchema(), Mutator.DELETE,
744                                 Sets.newHashSet(testIpfixUuid)))
745                 .add(op.comment("Bridge: Mutating " + testIpfixUuid))
746                 .add(op.commit(true));
747
748         executeTransaction(transactionBuilder, "IPFIX delete operation results");
749     }
750
751     @Test
752     public void testIpfix () throws ExecutionException, InterruptedException {
753         // Don't run this test if the table is not supported
754         assumeTrue(schemaVersion.compareTo(ipfixFromVersion) >= 0);
755
756         testBridgeUuid = bridgeInsert();
757         ipfixInsert();
758         ipfixDelete();
759         bridgeDelete(testBridgeUuid);
760     }
761
762     public void managerInsert() throws ExecutionException, InterruptedException {
763         ImmutableMap<String, String> externalIds = ImmutableMap.of("slaveof", "themaster");
764         UUID openVSwitchRowUuid = getOpenVSwitchTableUuid(getClient(), getTableCache());
765         OpenVSwitch openVSwitch = getClient().getTypedRowWrapper(OpenVSwitch.class, null);
766         Manager manager = getClient().createTypedRowWrapper(Manager.class);
767         manager.setInactivityProbe(Sets.newHashSet(8192L));
768         manager.setMaxBackoff(Sets.newHashSet(4094L));
769         manager.setTarget(Sets.newHashSet("172.16.50.50:6640"));
770         manager.setExternalIds(externalIds);
771
772         TransactionBuilder transactionBuilder = getClient().transactBuilder(getDbSchema())
773                 .add(op.insert(manager.getSchema())
774                         .withId(TEST_MANAGER_UUID_STR)
775                         .value(manager.getTargetColumn())
776                         .value(manager.getInactivityProbeColumn())
777                         .value(manager.getMaxBackoffColumn())
778                         .value(manager.getExternalIdsColumn()))
779                 .add(op.comment("Manager: Inserting Slave Manager " + TEST_MANAGER_UUID_STR))
780                 .add(op.mutate(openVSwitch.getSchema())
781                         .addMutation(openVSwitch.getManagerOptionsColumn().getSchema(), Mutator.INSERT,
782                                 Sets.newHashSet(new UUID(TEST_MANAGER_UUID_STR)))
783                         .where(openVSwitch.getUuidColumn().getSchema().opEqual(openVSwitchRowUuid))
784                         .build())
785                 .add(op.comment("Open_vSwitch: Mutating " + TEST_MANAGER_UUID_STR));
786
787         List<OperationResult> operationResults = executeTransaction(transactionBuilder,
788                 "Manager: Insert & Mutate operation results");
789         testManagerUuid = operationResults.get(0).getUuid();
790         assertNotNull(ASSERT_TRANS_UUID, testManagerUuid);
791
792         // Verify that the local cache was updated with the remote changes
793         Row managerRow = getTableCache().get(manager.getSchema().getName()).get(testManagerUuid);
794         Manager monitoredManager = getClient().getTypedRowWrapper(Manager.class, managerRow);
795         assertEquals(externalIds, monitoredManager.getExternalIdsColumn().getData());
796     }
797
798     public void managerDelete () throws ExecutionException, InterruptedException {
799         Manager manager = getClient().getTypedRowWrapper(Manager.class, null);
800         OpenVSwitch openVSwitch = getClient().getTypedRowWrapper(OpenVSwitch.class, null);
801
802         TransactionBuilder transactionBuilder = getClient().transactBuilder(getDbSchema())
803                 .add(op.delete(manager.getSchema())
804                         .where(manager.getUuidColumn().getSchema().opEqual(testManagerUuid))
805                         .build())
806                 .add(op.comment("Manager: Deleting " + TEST_MANAGER_UUID_STR))
807                 .add(op.mutate(openVSwitch.getSchema())
808                         .addMutation(openVSwitch.getManagerOptionsColumn().getSchema(), Mutator.DELETE,
809                                 Sets.newHashSet(testManagerUuid)))
810                 .add(op.comment("Open_vSwitch: Mutating " + TEST_MANAGER_UUID_STR + " " + testManagerUuid))
811                 .add(op.commit(true));
812
813         executeTransaction(transactionBuilder, "Manager: Delete operation results");
814     }
815
816     @Test
817     public void testManager () throws ExecutionException, InterruptedException {
818         managerInsert();
819         managerDelete();
820     }
821
822     public void mirrorInsert () throws ExecutionException, InterruptedException {
823         String mirrorUuidStr = "testMirror";
824         String mirrorName = "my_name_is_mirror";
825         Long outputVid = 1024L;
826         Long selectVid = Long.valueOf(2048);
827
828         Mirror mirror = getClient().createTypedRowWrapper(Mirror.class);
829         mirror.setName(ImmutableSet.of(mirrorName));
830         mirror.setExternalIds(ImmutableMap.of("overlays", "ftw"));
831         mirror.setOutputVlan(ImmutableSet.of(outputVid));
832         mirror.setSelectVlan(ImmutableSet.of(selectVid));
833         mirror.setExternalIds(ImmutableMap.of("reading", "urmail"));
834         Bridge bridge = getClient().getTypedRowWrapper(Bridge.class, null);
835
836         TransactionBuilder transactionBuilder = getClient().transactBuilder(getDbSchema())
837                 .add(op.insert(mirror.getSchema())
838                         .withId(mirrorUuidStr)
839                         .value(mirror.getNameColumn())
840                         .value(mirror.getExternalIdsColumn()))
841                 .add(op.comment("Mirror: Inserting " + mirrorUuidStr))
842                 .add(op.mutate(bridge.getSchema())
843                         .addMutation(bridge.getMirrorsColumn().getSchema(), Mutator.INSERT,
844                                 Sets.newHashSet(new UUID(mirrorUuidStr)))
845                         .where(bridge.getNameColumn().getSchema().opEqual(TEST_BRIDGE_NAME))
846                         .build())
847                 .add(op.comment("Bridge: Mutating " + TEST_BRIDGE_NAME));
848
849         List<OperationResult> operationResults = executeTransaction(transactionBuilder,
850                 "Insert and Mutate operation results for Mirror");
851         testMirrorUuid = operationResults.get(0).getUuid();
852         assertNotNull(ASSERT_TRANS_UUID, testMirrorUuid);
853
854         // Verify that the local cache was updated with the remote changes
855         Row mirrorRow = getTableCache().get(mirror.getSchema().getName()).get(testMirrorUuid);
856         Mirror monitoredMirror = getClient().getTypedRowWrapper(Mirror.class, mirrorRow);
857         assertEquals(mirror.getExternalIdsColumn().getData(), monitoredMirror.getExternalIdsColumn().getData());
858     }
859
860     private void mirrorDelete () throws ExecutionException, InterruptedException {
861         Mirror mirror = getClient().getTypedRowWrapper(Mirror.class, null);
862         Bridge bridge = getClient().getTypedRowWrapper(Bridge.class, null);
863         DatabaseSchema dbSchema = getClient().getSchema(OPEN_VSWITCH_SCHEMA).get();
864
865         TransactionBuilder transactionBuilder = getClient().transactBuilder(dbSchema)
866                 .add(op.delete(mirror.getSchema())
867                         .where(mirror.getUuidColumn().getSchema().opEqual(testMirrorUuid))
868                         .build())
869                 .add(op.comment("Mirror: Deleting " + testMirrorUuid))
870                 .add(op.mutate(bridge.getSchema()) // Delete a controller column in the Bridge table
871                         .addMutation(bridge.getMirrorsColumn().getSchema(), Mutator.DELETE,
872                                 Sets.newHashSet(testMirrorUuid)))
873                 .add(op.comment("Bridge: Mutating " + testMirrorUuid))
874                 .add(op.commit(true));
875
876         executeTransaction(transactionBuilder, "Mirror: Delete operation results");
877     }
878
879     @Test
880     public void testMirror () throws ExecutionException, InterruptedException {
881         testBridgeUuid = bridgeInsert();
882         mirrorInsert();
883         mirrorDelete();
884         bridgeDelete(testBridgeUuid);
885     }
886
887     public void netFlowInsert () throws ExecutionException, InterruptedException {
888         String netFlowUuidStr = "testNetFlow";
889         String netFlowTargets = "172.16.20.200:6343";
890         Long engineType = 128L;
891         Long engineID = 32L;
892         Long activityTimeout = 1L;
893         NetFlow netFlow = getClient().createTypedRowWrapper(NetFlow.class);
894         netFlow.setTargets(ImmutableSet.of(netFlowTargets));
895         netFlow.setEngineType(ImmutableSet.of(engineType));
896         netFlow.setEngineId(ImmutableSet.of(engineID));
897         netFlow.setActivityTimeout(ImmutableSet.of(activityTimeout));
898         netFlow.setExternalIds(ImmutableMap.of("big", "baby"));
899         Bridge bridge = getClient().getTypedRowWrapper(Bridge.class, null);
900         TransactionBuilder transactionBuilder = getClient().transactBuilder(getDbSchema())
901                 .add(op.insert(netFlow.getSchema())
902                         .withId(netFlowUuidStr)
903                         .value(netFlow.getTargetsColumn())
904                         .value(netFlow.getEngineTypeColumn())
905                         .value(netFlow.getEngineIdColumn())
906                         .value(netFlow.getActiveTimeoutColumn())
907                         .value(netFlow.getExternalIdsColumn()))
908                 .add(op.comment("Mirror: Inserting " + netFlowUuidStr))
909                 .add(op.mutate(bridge.getSchema())
910                         .addMutation(bridge.getNetflowColumn().getSchema(), Mutator.INSERT,
911                                 Sets.newHashSet(new UUID(netFlowUuidStr)))
912                         .where(bridge.getNameColumn().getSchema().opEqual(TEST_BRIDGE_NAME))
913                         .build())
914                 .add(op.comment("Bridge: Mutating " + TEST_BRIDGE_NAME));
915
916         List<OperationResult> operationResults = executeTransaction(transactionBuilder,
917                 "Insert and Mutate operation results for NetFlow");
918         testNetFlowUuid = operationResults.get(0).getUuid();
919         assertNotNull(ASSERT_TRANS_UUID, testNetFlowUuid);
920
921         // Verify that the local cache was updated with the remote changes
922         Row netFlowRow = getTableCache().get(netFlow.getSchema().getName()).get(testNetFlowUuid);
923         Mirror monitoredNetFlow = getClient().getTypedRowWrapper(Mirror.class, netFlowRow);
924         assertEquals(netFlow.getExternalIdsColumn().getData(), monitoredNetFlow.getExternalIdsColumn().getData());
925     }
926
927     private void netFlowDelete () throws ExecutionException, InterruptedException {
928         NetFlow netFlow = getClient().getTypedRowWrapper(NetFlow.class, null);
929         Bridge bridge = getClient().getTypedRowWrapper(Bridge.class, null);
930         DatabaseSchema dbSchema = getClient().getSchema(OPEN_VSWITCH_SCHEMA).get();
931
932         TransactionBuilder transactionBuilder = getClient().transactBuilder(dbSchema)
933                 .add(op.delete(netFlow.getSchema())
934                         .where(netFlow.getUuidColumn().getSchema().opEqual(testNetFlowUuid))
935                         .build())
936                 .add(op.comment("NetFlow: Deleting " + testNetFlowUuid))
937                 .add(op.mutate(bridge.getSchema()) // Delete a controller column in the Bridge table
938                         .addMutation(bridge.getNetflowColumn().getSchema(), Mutator.DELETE,
939                                 Sets.newHashSet(testNetFlowUuid)))
940                 .add(op.comment("Bridge: Mutating " + testNetFlowUuid))
941                 .add(op.commit(true));
942
943         executeTransaction(transactionBuilder, "NetFlow: Delete operation results");
944     }
945
946     @Test
947     public void testNetFlow () throws ExecutionException, InterruptedException {
948         testBridgeUuid = bridgeInsert();
949         netFlowInsert();
950         netFlowDelete();
951         bridgeDelete(testBridgeUuid);
952     }
953
954     public void portAndInterfaceInsert () throws ExecutionException, InterruptedException {
955         String portUuidStr = "testPort";
956         String intfUuidStr = "testIntf";
957         String tunnelEncap = "vxlan";
958         Port port = getClient().createTypedRowWrapper(Port.class);
959         port.setName("testPort");
960         port.setTag(ImmutableSet.of(1L));
961         port.setMac(ImmutableSet.of("00:00:00:00:00:01"));
962         port.setInterfaces(ImmutableSet.of(new UUID(intfUuidStr)));
963
964         Interface intf = getClient().createTypedRowWrapper(Interface.class);
965         intf.setName(port.getNameColumn().getData());
966         intf.setType(tunnelEncap);
967         intf.setExternalIds(ImmutableMap.of("vm-id", "12345abcedf78910"));
968         // For per Flow TEPs use remote_ip=flow
969         // For per Port TEPs use remote_ip=x.x.x.x (ipv4)
970         intf.setOptions(ImmutableMap.of("local_ip", "172.16.24.145",
971                 "remote_ip", "flow",
972                 "key", "flow",
973                 "dst_port", "8472"));
974
975         Bridge bridge = getClient().getTypedRowWrapper(Bridge.class, null);
976         TransactionBuilder transactionBuilder = getClient().transactBuilder(getDbSchema())
977                 .add(op.insert(port.getSchema())
978                         .withId(portUuidStr)
979                         .value(port.getNameColumn())
980                         .value(port.getMacColumn()))
981                 .add(op.comment("Port: Inserting " + portUuidStr))
982                 .add(op.insert(intf.getSchema())
983                         .withId(intfUuidStr)
984                         .value(intf.getNameColumn()))
985                 .add(op.comment("Interface: Inserting " + intfUuidStr))
986                 .add(op.update(port.getSchema())
987                         .set(port.getTagColumn())
988                         .set(port.getMacColumn())
989                         .set(port.getInterfacesColumn())
990                         .where(port.getNameColumn().getSchema().opEqual(port.getName()))
991                         .build())
992                 .add(op.comment("Port: Updating " + portUuidStr))
993                 .add(op.update(intf.getSchema())
994                         .set(intf.getTypeColumn())
995                         .set(intf.getExternalIdsColumn())
996                         .set(intf.getOptionsColumn())
997                         .where(intf.getNameColumn().getSchema().opEqual(intf.getName()))
998                         .build())
999                 .add(op.comment("Interface: Updating " + intfUuidStr))
1000                 .add(op.mutate(bridge.getSchema())
1001                         .addMutation(bridge.getPortsColumn().getSchema(), Mutator.INSERT, Sets.newHashSet(new UUID(portUuidStr)))
1002                         .where(bridge.getNameColumn().getSchema().opEqual(TEST_BRIDGE_NAME))
1003                         .build())
1004                 .add(op.comment("Bridge: Mutating " + TEST_BRIDGE_NAME));
1005
1006         List<OperationResult> operationResults = executeTransaction(transactionBuilder,
1007                 "Insert and Mutate operation results for Port and Interface");
1008         testPortUuid = operationResults.get(0).getUuid();
1009         assertNotNull(ASSERT_TRANS_UUID, testPortUuid);
1010         testInterfaceUuid = operationResults.get(2).getUuid();
1011         assertNotNull(ASSERT_TRANS_UUID, testInterfaceUuid);
1012
1013         // Verify that the local cache was updated with the remote changes
1014         Row portRow = getTableCache().get(port.getSchema().getName()).get(testPortUuid);
1015         Port monitoredPort = getClient().getTypedRowWrapper(Port.class, portRow);
1016         assertEquals(port.getNameColumn().getData(), monitoredPort.getNameColumn().getData());
1017
1018         Row interfaceRow = getTableCache().get(intf.getSchema().getName()).get(testInterfaceUuid);
1019         Interface monitoredInterface = getClient().getTypedRowWrapper(Interface.class, interfaceRow);
1020         assertEquals(intf.getNameColumn().getData(), monitoredInterface.getNameColumn().getData());
1021     }
1022
1023     private void portAndInterfaceDelete () throws ExecutionException, InterruptedException {
1024         Port port = getClient().getTypedRowWrapper(Port.class, null);
1025         Interface intf = getClient().getTypedRowWrapper(Interface.class, null);
1026         Bridge bridge = getClient().getTypedRowWrapper(Bridge.class, null);
1027         DatabaseSchema dbSchema = getClient().getSchema(OPEN_VSWITCH_SCHEMA).get();
1028
1029         TransactionBuilder transactionBuilder = getClient().transactBuilder(dbSchema)
1030                 .add(op.delete(port.getSchema())
1031                         .where(port.getUuidColumn().getSchema().opEqual(testPortUuid))
1032                         .build())
1033                 .add(op.comment("Port: Deleting " + testPortUuid))
1034                 .add(op.delete(intf.getSchema())
1035                         .where(intf.getUuidColumn().getSchema().opEqual(testInterfaceUuid))
1036                         .build())
1037                 .add(op.comment("Interface: Deleting " + testInterfaceUuid))
1038                 .add(op.mutate(bridge.getSchema()) // Delete a port column in the Bridge table
1039                         .addMutation(bridge.getPortsColumn().getSchema(), Mutator.DELETE,
1040                                 Sets.newHashSet(testPortUuid)))
1041                 .add(op.comment("Bridge: Mutating " + testPortUuid))
1042                 .add(op.commit(true));
1043
1044         executeTransaction(transactionBuilder, "Port and Interface: Delete operation results");
1045     }
1046
1047     @Test
1048     public void testPortAndInterface () throws ExecutionException, InterruptedException {
1049         testBridgeUuid = bridgeInsert();
1050         portAndInterfaceInsert();
1051         portAndInterfaceDelete();
1052         bridgeDelete(testBridgeUuid);
1053     }
1054
1055     public void qosInsert() throws ExecutionException, InterruptedException {
1056         String portUuidStr = "testQosPortUuid";
1057         String intfUuidStr = "testQosIntfUuid";
1058         String qosUuidStr = "testQosUuid";
1059         String qosPort = "testQosPort";
1060
1061         Port port = getClient().createTypedRowWrapper(Port.class);
1062         port.setName(qosPort);
1063         port.setInterfaces(ImmutableSet.of(new UUID(intfUuidStr)));
1064         port.setQos(ImmutableSet.of(new UUID(qosUuidStr)));
1065         port.setOtherConfig(ImmutableMap.of("m0r3", "c0ff33"));
1066
1067         Interface intf = getClient().createTypedRowWrapper(Interface.class);
1068         intf.setName(port.getNameColumn().getData());
1069         intf.setOtherConfig(ImmutableMap.of("proto", "duction"));
1070         intf.setExternalIds(ImmutableMap.of("stringly", "typed"));
1071
1072         Qos qos = getClient().createTypedRowWrapper(Qos.class);
1073         qos.setOtherConfig(ImmutableMap.of("mmm", "kay"));
1074         qos.setType(ImmutableSet.of("404"));
1075
1076         Bridge bridge = getClient().getTypedRowWrapper(Bridge.class, null);
1077
1078         TransactionBuilder transactionBuilder = getClient().transactBuilder(getDbSchema())
1079                 .add(op.insert(port.getSchema())
1080                         .withId(portUuidStr)
1081                         .value(port.getNameColumn()))
1082                 .add(op.comment("Port: Inserting " + portUuidStr))
1083                 .add(op.insert(intf.getSchema())
1084                         .withId(intfUuidStr)
1085                         .value(intf.getExternalIdsColumn())
1086                         .value(intf.getNameColumn())
1087                         .value(intf.getOtherConfigColumn()))
1088                 .add(op.comment("Interface: Inserting " + intfUuidStr))
1089                 .add(op.insert(qos.getSchema())
1090                         .withId(qosUuidStr)
1091                         .value(qos.getTypeColumn())
1092                         .value(qos.getOtherConfigColumn()))
1093                 .add(op.comment("QOS: Inserting " + qosUuidStr))
1094                 .add(op.update(port.getSchema())
1095                         .set(port.getOtherConfigColumn())
1096                         .set(port.getInterfacesColumn())
1097                         .set(port.getQosColumn())
1098                         .where(port.getNameColumn().getSchema().opEqual(port.getName()))
1099                         .build())
1100                 .add(op.comment("Interface: Updating " + intfUuidStr))
1101                 .add(op.mutate(bridge.getSchema())
1102                         .addMutation(bridge.getPortsColumn().getSchema(), Mutator.INSERT,
1103                                 Sets.newHashSet(new UUID(portUuidStr)))
1104                         .where(bridge.getNameColumn().getSchema().opEqual(TEST_BRIDGE_NAME))
1105                         .build())
1106                 .add(op.comment("Bridge: Mutating " + TEST_BRIDGE_NAME));
1107
1108         int insertPortOperationIndex = 0;
1109         int insertInterfaceOperationIndex = 2;
1110         int insertQosOperationIndex = 4;
1111         List<OperationResult> operationResults = executeTransaction(transactionBuilder,
1112                 "Insert and Mutate operation results for Port and Interface");
1113         testPortUuid = operationResults.get(insertPortOperationIndex).getUuid();
1114         assertNotNull(ASSERT_TRANS_UUID, testPortUuid);
1115         testInterfaceUuid = operationResults.get(insertInterfaceOperationIndex).getUuid();
1116         assertNotNull(ASSERT_TRANS_UUID, testInterfaceUuid);
1117         testQosUuid = operationResults.get(insertQosOperationIndex).getUuid();
1118         assertNotNull(ASSERT_TRANS_UUID, testQosUuid);
1119
1120         // Verify that the local cache was updated with the remote changes
1121         Row portRow = getTableCache().get(port.getSchema().getName()).get(testPortUuid);
1122         Port monitoredPort = getClient().getTypedRowWrapper(Port.class, portRow);
1123         assertEquals(port.getNameColumn().getData(), monitoredPort.getNameColumn().getData());
1124
1125         Row interfaceRow = getTableCache().get(intf.getSchema().getName()).get(testInterfaceUuid);
1126         Interface monitoredInterface = getClient().getTypedRowWrapper(Interface.class, interfaceRow);
1127         assertEquals(intf.getNameColumn().getData(), monitoredInterface.getNameColumn().getData());
1128
1129         Row qosRow = getTableCache().get(qos.getSchema().getName()).get(testQosUuid);
1130         Qos monitoredQos = getClient().getTypedRowWrapper(Qos.class, qosRow);
1131         assertEquals(qos.getTypeColumn().getData().toArray()[0], monitoredQos.getTypeColumn().getData());
1132     }
1133
1134     private void qosDelete () throws ExecutionException, InterruptedException {
1135         Port port = getClient().getTypedRowWrapper(Port.class, null);
1136         Interface intf = getClient().getTypedRowWrapper(Interface.class, null);
1137         Qos qos = getClient().getTypedRowWrapper(Qos.class, null);
1138         Bridge bridge = getClient().getTypedRowWrapper(Bridge.class, null);
1139         DatabaseSchema dbSchema = getClient().getSchema(OPEN_VSWITCH_SCHEMA).get();
1140
1141         TransactionBuilder transactionBuilder = getClient().transactBuilder(dbSchema)
1142                 .add(op.delete(port.getSchema())
1143                         .where(port.getUuidColumn().getSchema().opEqual(testPortUuid))
1144                         .build())
1145                 .add(op.comment("Port: Deleting " + testPortUuid))
1146                 .add(op.delete(intf.getSchema())
1147                         .where(intf.getUuidColumn().getSchema().opEqual(testInterfaceUuid))
1148                         .build())
1149                 .add(op.comment("Interface: Deleting " + testInterfaceUuid))
1150                 .add(op.delete(qos.getSchema())
1151                         .where(qos.getUuidColumn().getSchema().opEqual(testQosUuid))
1152                         .build())
1153                 .add(op.comment("Qos: Deleting " + testQosUuid))
1154                 .add(op.mutate(bridge.getSchema()) // Delete a port column in the Bridge table
1155                         .addMutation(bridge.getPortsColumn().getSchema(), Mutator.DELETE,
1156                                 Sets.newHashSet(testPortUuid)))
1157                 .add(op.comment("Bridge: Mutating " + testPortUuid))
1158                 .add(op.mutate(port.getSchema()) // Delete a qos column in the Port table
1159                         .addMutation(port.getQosColumn().getSchema(), Mutator.DELETE,
1160                                 Sets.newHashSet(testQosUuid)))
1161                 .add(op.comment("Port: Mutating " + testPortUuid))
1162                 .add(op.commit(true));
1163
1164         executeTransaction(transactionBuilder, "Qos, Port and Interface: Delete operation results");
1165     }
1166
1167     @Test
1168     public void testQos () throws ExecutionException, InterruptedException {
1169         testBridgeUuid = bridgeInsert();
1170         qosInsert();
1171         qosDelete();
1172         bridgeDelete(testBridgeUuid);
1173     }
1174
1175     public void queueInsert() throws InterruptedException, ExecutionException {
1176         /**
1177          * This is an arbitrary String that is a placeholder for
1178          * the future UUID generated by the OVSDB Server in the
1179          * future transaction. While it is possible to generate
1180          * ones own UUID for the transaction it is not recommended
1181          * since it wouldn't add any conceivable value.
1182          */
1183         String queueUuidStr = "queueUuidStr";
1184         Long dscpVal = Long.valueOf(4);
1185         Queue queue = getClient().createTypedRowWrapper(Queue.class);
1186         // Example of explicit ImmutableSet/Map Attribute declaration
1187         ImmutableSet<Long> dscp = ImmutableSet.of(dscpVal);
1188         ImmutableMap<String, String> externalIds = ImmutableMap.of("little", "coat");
1189         // Example of condensing the attributes bindings in one line
1190         queue.setOtherConfig(ImmutableMap.of("war", "onfun"));
1191         // Bind the Attributes to the transaction. These values end up in columns.
1192         queue.setExternalIds(externalIds);
1193         queue.setDscp(dscp);
1194         // Get the parent Qos table row UUID to insert the queue.
1195         Qos qos = getClient().getTypedRowWrapper(Qos.class, null);
1196         // Queue key that is mapped to the queue record/value/ofp_action_enqueue
1197         Long queueKey = 0L;
1198         // Reference the Port row to insert the Queue with UID or Port name
1199         TransactionBuilder transactionBuilder = getClient().transactBuilder(getDbSchema())
1200                 .add(op.insert(queue.getSchema())
1201                         .withId(queueUuidStr)
1202                         .value(queue.getDscpColumn())
1203                         .value(queue.getExternalIdsColumn())
1204                         .value(queue.getOtherConfigColumn()))
1205                 .add(op.comment("Queue: Inserting " + queueUuidStr))
1206                 .add(op.mutate(qos.getSchema())
1207                         .addMutation(qos.getQueuesColumn().getSchema(), Mutator.INSERT,
1208                                 ImmutableMap.of(queueKey, new UUID(queueUuidStr)))
1209                         .where(qos.getUuidColumn().getSchema().opEqual(testQosUuid))
1210                         .build())
1211                 .add(op.comment("Qos: Mutating " + testQosUuid));
1212
1213         // The transaction index for the Queue insert is used to store the Queue UUID
1214         int insertQueueOperationIndex = 0;
1215         List<OperationResult> operationResults = executeTransaction(transactionBuilder,
1216                 "Insert and Mutate operation results for Queue");
1217         testQueueUuid = operationResults.get(insertQueueOperationIndex).getUuid();
1218         assertNotNull(ASSERT_TRANS_UUID, testQueueUuid);
1219
1220         // Verify that the local cache was updated with the remote changes
1221         Row queueRow = getTableCache().get(queue.getSchema().getName()).get(testQueueUuid);
1222         Queue monitoredQueue = getClient().getTypedRowWrapper(Queue.class, queueRow);
1223         assertEquals(queue.getExternalIdsColumn().getData(), monitoredQueue.getExternalIdsColumn().getData());
1224     }
1225
1226     private void queueDelete () throws ExecutionException, InterruptedException {
1227         Queue queue = getClient().getTypedRowWrapper(Queue.class, null);
1228         Qos qos = getClient().getTypedRowWrapper(Qos.class, null);
1229         DatabaseSchema dbSchema = getClient().getSchema(OPEN_VSWITCH_SCHEMA).get();
1230
1231         TransactionBuilder transactionBuilder = getClient().transactBuilder(dbSchema)
1232                 .add(op.delete(queue.getSchema())
1233                         .where(queue.getUuidColumn().getSchema().opEqual(testQueueUuid))
1234                         .build())
1235                 .add(op.comment("Queue: Deleting " + testQueueUuid))
1236                 .add(op.mutate(qos.getSchema()) // Delete a queue column in the Qos table
1237                         .addMutation(qos.getQueuesColumn().getSchema(), Mutator.DELETE,
1238                                 Maps.newHashMap(ImmutableMap.of(0L,testQueueUuid))))
1239                 .add(op.comment("Queue: Mutating " + testQueueUuid))
1240                 .add(op.commit(true));
1241
1242         executeTransaction(transactionBuilder, "Queue: Delete operation results");
1243     }
1244
1245     @Test
1246     public void testQueue () throws ExecutionException, InterruptedException {
1247         testBridgeUuid = bridgeInsert();
1248         qosInsert();
1249         queueInsert();
1250         queueDelete();
1251         qosDelete();
1252         bridgeDelete(testBridgeUuid);
1253     }
1254
1255     public void sFlowInsert () throws ExecutionException, InterruptedException {
1256         String sFlowUuidStr = "testSFlow";
1257         String sFlowTarget = "172.16.20.200:6343";
1258         Long header = 128L;
1259         Long obsPointId = 358L;
1260         Long polling =10L;
1261         String agent = "172.16.20.210";
1262         Long sampling = 64L;
1263         SFlow sFlow = getClient().createTypedRowWrapper(SFlow.class);
1264         sFlow.setTargets(ImmutableSet.of(sFlowTarget));
1265         sFlow.setHeader(ImmutableSet.of(header));
1266         sFlow.setPolling(ImmutableSet.of(obsPointId));
1267         sFlow.setPolling(ImmutableSet.of(polling));
1268         sFlow.setAgent(ImmutableSet.of(agent));
1269         sFlow.setSampling(ImmutableSet.of(sampling));
1270         sFlow.setExternalIds(ImmutableMap.of("kit", "tah"));
1271         Bridge bridge = getClient().getTypedRowWrapper(Bridge.class, null);
1272         TransactionBuilder transactionBuilder = getClient().transactBuilder(getDbSchema())
1273                 .add(op.insert(sFlow.getSchema())
1274                         .withId(sFlowUuidStr)
1275                         .value(sFlow.getTargetsColumn())
1276                         .value(sFlow.getHeaderColumn())
1277                         .value(sFlow.getPollingColumn())
1278                         .value(sFlow.getAgentColumn())
1279                         .value(sFlow.getSamplingColumn())
1280                         .value(sFlow.getExternalIdsColumn()))
1281                 .add(op.comment("sFlow: Inserting " + sFlowUuidStr))
1282                 .add(op.mutate(bridge.getSchema())
1283                         .addMutation(bridge.getSflowColumn().getSchema(), Mutator.INSERT,
1284                                 Sets.newHashSet(new UUID(sFlowUuidStr)))
1285                         .where(bridge.getNameColumn().getSchema().opEqual(TEST_BRIDGE_NAME))
1286                         .build())
1287                 .add(op.comment("Bridge: Mutating " + TEST_BRIDGE_NAME));
1288         int insertSFlowOperationIndex = 0;
1289         List<OperationResult> operationResults = executeTransaction(transactionBuilder,
1290                 "Insert and Mutate operation results for sFlow");
1291         testSFlowUuid = operationResults.get(insertSFlowOperationIndex).getUuid();
1292         assertNotNull(ASSERT_TRANS_UUID, testSFlowUuid);
1293
1294         // Verify that the local cache was updated with the remote changes
1295         Row sFlowRow = getTableCache().get(sFlow.getSchema().getName()).get(testSFlowUuid);
1296         Queue monitoredSFlow = getClient().getTypedRowWrapper(Queue.class, sFlowRow);
1297         assertEquals(sFlow.getExternalIdsColumn().getData(), monitoredSFlow.getExternalIdsColumn().getData());
1298     }
1299
1300     private void sFlowDelete () throws ExecutionException, InterruptedException {
1301         SFlow sFlow = getClient().getTypedRowWrapper(SFlow.class, null);
1302         Bridge bridge = getClient().getTypedRowWrapper(Bridge.class, null);
1303         DatabaseSchema dbSchema = getClient().getSchema(OPEN_VSWITCH_SCHEMA).get();
1304
1305         TransactionBuilder transactionBuilder = getClient().transactBuilder(dbSchema)
1306                 .add(op.delete(sFlow.getSchema())
1307                         .where(sFlow.getUuidColumn().getSchema().opEqual(testSFlowUuid))
1308                         .build())
1309                 .add(op.comment("SFlow: Deleting " + testSFlowUuid))
1310                 .add(op.mutate(bridge.getSchema()) // Delete an sflow column in the Bridge table
1311                         .addMutation(bridge.getSflowColumn().getSchema(), Mutator.DELETE,
1312                                 Sets.newHashSet(testSFlowUuid)))
1313                 .add(op.comment("Bridge: Mutating " + testSFlowUuid))
1314                 .add(op.commit(true));
1315
1316         executeTransaction(transactionBuilder, "Queue: Delete operation results");
1317     }
1318
1319     @Test
1320     public void testSFlow () throws ExecutionException, InterruptedException {
1321         testBridgeUuid = bridgeInsert();
1322         sFlowInsert();
1323         sFlowDelete();
1324         bridgeDelete(testBridgeUuid);
1325     }
1326
1327     public void sslInsert () throws ExecutionException, InterruptedException {
1328
1329         String sslUuidStr = "sslUuidName";
1330         String caCert = "PARC";
1331         String certificate = "01101110 01100101 01110010 01100100";
1332         String privateKey = "SSL_Table_Test_Secret";
1333         ImmutableMap<String, String> externalIds = ImmutableMap.of("roomba", "powered");
1334
1335         SSL ssl = getClient().createTypedRowWrapper(SSL.class);
1336         ssl.setCaCert(caCert);
1337         ssl.setCertificate(certificate);
1338         ssl.setPrivateKey(privateKey);
1339         ssl.setExternalIds(externalIds);
1340         // Get the parent OVS table UUID in it's single row
1341         UUID openVSwitchRowUuid = getOpenVSwitchTableUuid(getClient(), getTableCache());
1342         OpenVSwitch openVSwitch = getClient().getTypedRowWrapper(OpenVSwitch.class, null);
1343         TransactionBuilder transactionBuilder = getClient().transactBuilder(getDbSchema())
1344                 .add(op.insert(ssl.getSchema())
1345                         .withId(sslUuidStr)
1346                         .value(ssl.getCertificateColumn())
1347                         .value(ssl.getPrivateKeyColumn())
1348                         .value(ssl.getCaCertColumn())
1349                         .value(ssl.getExternalIdsColumn()))
1350                 .add(op.comment("SSL: Inserting " + sslUuidStr))
1351                 .add(op.mutate(openVSwitch.getSchema())
1352                         .addMutation(openVSwitch.getSslColumn().getSchema(), Mutator.INSERT,
1353                                 Sets.newHashSet(new UUID(sslUuidStr)))
1354                         .where(openVSwitch.getUuidColumn().getSchema().opEqual(openVSwitchRowUuid))
1355                         .build())
1356                 .add(op.comment("Open_vSwitch: Mutating " + sslUuidStr));
1357
1358         // The transaction index for the SSL insert is used to store the SSL UUID
1359         int insertSslOperationIndex = 0;
1360         List<OperationResult> operationResults = executeTransaction(transactionBuilder,
1361                 "Insert and Mutate operation results for SSL");
1362         testSslUuid = operationResults.get(insertSslOperationIndex).getUuid();
1363         assertNotNull(ASSERT_TRANS_UUID, testSslUuid);
1364
1365         // Verify that the local cache was updated with the remote changes
1366         Row sslRow = getTableCache().get(ssl.getSchema().getName()).get(testSslUuid);
1367         SSL monitoredSsl = getClient().getTypedRowWrapper(SSL.class, sslRow);
1368         assertEquals(ssl.getExternalIdsColumn().getData(), monitoredSsl.getExternalIdsColumn().getData());
1369     }
1370
1371     public void sslDelete () throws ExecutionException, InterruptedException {
1372         SSL ssl = getClient().getTypedRowWrapper(SSL.class, null);
1373         OpenVSwitch openVSwitch = getClient().getTypedRowWrapper(OpenVSwitch.class, null);
1374
1375         TransactionBuilder transactionBuilder = getClient().transactBuilder(getDbSchema())
1376                 .add(op.delete(ssl.getSchema())
1377                         .where(ssl.getUuidColumn().getSchema().opEqual(testSslUuid))
1378                         .build())
1379                 .add(op.comment("SSL: Deleting " + testSslUuid))
1380                 .add(op.mutate(openVSwitch.getSchema())
1381                         .addMutation(openVSwitch.getSslColumn().getSchema(), Mutator.DELETE,
1382                                 Sets.newHashSet(testSslUuid)))
1383                 .add(op.comment("Open_vSwitch: Mutating " + testSslUuid))
1384                 .add(op.commit(true));
1385
1386         executeTransaction(transactionBuilder, "SSL delete operation results");
1387     }
1388
1389     @Test
1390     public void testSsl () throws ExecutionException, InterruptedException {
1391         sslInsert();
1392         sslDelete();
1393     }
1394
1395     @Test
1396     public void testTyperUtilsSpecialMethodsToString () {
1397         Bridge bridge = getClient().createTypedRowWrapper(Bridge.class);
1398         assertNotNull(bridge);
1399         bridge.setName(TEST_BRIDGE_NAME);
1400         bridge.setStatus(ImmutableMap.of("key", "value"));
1401         bridge.setFloodVlans(Sets.newHashSet(34L));
1402         assertNotNull(bridge.toString());
1403
1404         Bridge nullRowBridge = getClient().getTypedRowWrapper(Bridge.class, null);
1405         assertNotNull(nullRowBridge.toString());
1406     }
1407
1408     @Test
1409     public void testTyperUtilsSpecialMethodsEquals () {
1410         Bridge bridge = getClient().createTypedRowWrapper(Bridge.class);
1411         assertNotNull(bridge);
1412         bridge.setName(TEST_BRIDGE_NAME);
1413         bridge.setStatus(ImmutableMap.of("key", "value"));
1414         bridge.setFloodVlans(Sets.newHashSet(34L));
1415
1416         assertTrue("Equals check on same Bridge object", bridge.equals(bridge));
1417
1418         Bridge bridge2 = getClient().createTypedRowWrapper(Bridge.class);
1419         assertNotNull(bridge2);
1420         bridge2.setName(bridge.getName());
1421         bridge2.setStatus(bridge.getStatusColumn().getData());
1422         bridge2.setFloodVlans(bridge.getFloodVlansColumn().getData());
1423
1424         assertTrue("Equals check for different Bridge objects with same content", bridge.equals(bridge2));
1425
1426         bridge2.setStpEnable(true);
1427         assertFalse("Equals check for different Bridge objects with different content", bridge.equals(bridge2));
1428
1429         Port port = getClient().createTypedRowWrapper(Port.class);
1430         port.setName(bridge.getName());
1431         assertFalse("Equals check for a Bridge object and Port Object", bridge.equals(port));
1432         assertFalse("Equals check for a Typed Proxy object and non-proxy object", port.equals("String"));
1433
1434         Bridge nullRowBridge = getClient().getTypedRowWrapper(Bridge.class, null);
1435         assertTrue("Equals check on Bridge object with null Row", nullRowBridge.equals(nullRowBridge));
1436     }
1437
1438     @Test
1439     public void testTyperUtilsSpecialMethodsHashCode () {
1440         Bridge bridge = getClient().createTypedRowWrapper(Bridge.class);
1441
1442         assertNotNull(bridge);
1443         bridge.setName(TEST_BRIDGE_NAME);
1444         bridge.setStatus(ImmutableMap.of("key", "value"));
1445         bridge.setFloodVlans(Sets.newHashSet(34L));
1446
1447         assertNotSame(bridge.hashCode(), 0);
1448         Bridge nullRowBridge = getClient().getTypedRowWrapper(Bridge.class, null);
1449         assertSame(nullRowBridge.hashCode(), 0);
1450     }
1451 }