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