2 * Copyright (C) 2014 EBay Software Foundation
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
8 * Authors : Ashwin Raveendran
10 package org.opendaylight.ovsdb.integrationtest.ovsdbclient;
12 import static org.opendaylight.ovsdb.lib.operations.Operations.op;
14 import java.io.IOException;
15 import java.util.List;
18 import java.util.concurrent.ExecutionException;
19 import java.util.concurrent.TimeoutException;
21 import org.junit.After;
22 import org.junit.Assert;
23 import org.junit.Before;
24 import org.junit.Test;
25 import org.opendaylight.ovsdb.lib.MonitorCallBack;
26 import org.opendaylight.ovsdb.lib.OvsdbClient;
27 import org.opendaylight.ovsdb.lib.impl.OvsdbConnectionService;
28 import org.opendaylight.ovsdb.lib.message.MonitorRequest;
29 import org.opendaylight.ovsdb.lib.message.MonitorRequestBuilder;
30 import org.opendaylight.ovsdb.lib.message.MonitorSelect;
31 import org.opendaylight.ovsdb.lib.message.TableUpdate;
32 import org.opendaylight.ovsdb.lib.message.TableUpdates;
33 import org.opendaylight.ovsdb.lib.message.UpdateNotification;
34 import org.opendaylight.ovsdb.lib.notation.Column;
35 import org.opendaylight.ovsdb.lib.notation.Mutator;
36 import org.opendaylight.ovsdb.lib.notation.Row;
37 import org.opendaylight.ovsdb.lib.notation.UUID;
38 import org.opendaylight.ovsdb.lib.operations.OperationResult;
39 import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
40 import org.opendaylight.ovsdb.lib.schema.ColumnSchema;
41 import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
42 import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
43 import org.opendaylight.ovsdb.lib.schema.TableSchema;
45 import com.google.common.collect.ImmutableMap;
46 import com.google.common.collect.Lists;
47 import com.google.common.collect.Sets;
48 import com.google.common.util.concurrent.ListenableFuture;
51 public class OvsdbClientTestIT extends OvsdbTestBase {
54 DatabaseSchema dbSchema = null;
55 static String testBridgeName = "br-test";
56 static UUID testBridgeUuid = null;
59 * Test general OVSDB transactions (viz., insert, select, update,
60 * mutate, comment, delete, where, commit) as well as the special
61 * transactions (viz., abort and assert)
64 public void testTransact() throws IOException, InterruptedException, ExecutionException {
65 Assert.assertNotNull(dbSchema);
66 TableSchema<GenericTableSchema> bridge = dbSchema.table("Bridge", GenericTableSchema.class);
67 ColumnSchema<GenericTableSchema, String> name = bridge.column("name", String.class);
69 createBridgeTransaction();
75 * Test OVS monitor request and reply, with and without specific column filters,
76 * for the Bridge table in the OVSDB. The setup involves creating a test bridge with 5
77 * flood_vlans and 2 key-value pairs, and monitoring the DB update.
80 public void testMonitorRequest() throws ExecutionException, InterruptedException, IOException {
81 Assert.assertNotNull(dbSchema);
82 // Create Test Bridge before testing the Monitor operation
83 createBridgeTransaction();
84 sendBridgeMonitorRequest(true); // Test monitor request with Column filters
85 sendBridgeMonitorRequest(false); // Test monitor request without filters
88 public void sendBridgeMonitorRequest(boolean filter) throws ExecutionException, InterruptedException, IOException {
89 Assert.assertNotNull(dbSchema);
90 GenericTableSchema bridge = dbSchema.table("Bridge", GenericTableSchema.class);
92 List<MonitorRequest<GenericTableSchema>> monitorRequests = Lists.newArrayList();
93 ColumnSchema<GenericTableSchema, Set<Integer>> flood_vlans = bridge.multiValuedColumn("flood_vlans", Integer.class);
94 ColumnSchema<GenericTableSchema, Map<String, String>> externalIds = bridge.multiValuedColumn("external_ids", String.class, String.class);
95 ColumnSchema<GenericTableSchema, String> name = bridge.column("name", String.class);
96 MonitorRequestBuilder<GenericTableSchema> builder = MonitorRequestBuilder.builder(bridge);
98 builder.addColumn(bridge.column("name"))
99 .addColumn(bridge.column("fail_mode", String.class))
100 .addColumn(flood_vlans)
101 .addColumn(externalIds);
103 monitorRequests.add(builder.with(new MonitorSelect(true, true, true, true))
106 final List<Object> results = Lists.newArrayList();
108 TableUpdates updates = ovs.monitor(dbSchema, monitorRequests, new MonitorCallBack() {
110 public void update(TableUpdates result, DatabaseSchema dbSchema) {
112 System.out.println("result = " + result);
116 public void exception(Throwable t) {
118 System.out.println("t = " + t);
121 if (updates != null) {
122 results.add(updates);
124 for (int i = 0; i < 3 ; i++) { //wait 3 seconds to get a result
125 System.out.println("waiting on monitor response for Bridge Table...");
126 if (!results.isEmpty()) {
132 Assert.assertTrue(!results.isEmpty());
133 Object result = results.get(0);
134 Assert.assertTrue(result instanceof TableUpdates);
135 updates = (TableUpdates) result;
136 TableUpdate<GenericTableSchema> update = updates.getUpdate(bridge);
137 Assert.assertTrue(update.getRows().size() > 0);
138 for (UUID uuid : update.getRows().keySet()) {
139 Row<GenericTableSchema> aNew = update.getNew(uuid);
140 if (!aNew.getColumn(name).getData().equals(testBridgeName)) {
144 Assert.assertEquals(builder.getColumns().size(), aNew.getColumns().size());
146 // As per RFC7047, Section 4.1.5 : If "columns" is omitted, all columns in the table, except for "_uuid", are monitored.
147 Assert.assertEquals(bridge.getColumns().size() - 1, aNew.getColumns().size());
149 for (Column<GenericTableSchema, ?> column: aNew.getColumns()) {
150 if (column.getSchema().equals(flood_vlans)) {
151 // Test for the 5 flood_vlans inserted in Bridge br-test in createBridgeTransaction
152 Set<Integer> data = column.getData(flood_vlans);
153 Assert.assertNotNull(data);
154 Assert.assertTrue(!data.isEmpty());
155 Assert.assertEquals(5, data.size());
156 } else if (column.getSchema().equals(externalIds)) {
157 // Test for the {"key", "value"} external_ids inserted in Bridge br-test in createBridgeTransaction
158 Map<String, String> data = column.getData(externalIds);
159 Assert.assertNotNull(data);
160 Assert.assertNotNull(data.get("key"));
161 Assert.assertEquals("value", data.get("key"));
162 // Test for {"key2", "value2"} external_ids mutation-inserted in Bridge br-test in createBridgeTransaction
163 Assert.assertNotNull(data.get("key2"));
164 Assert.assertEquals("value2", data.get("key2"));
169 Assert.fail("Bridge being monitored :"+testBridgeName+" Not found");
173 * TODO : selectOpenVSwitchTableUuid method isn't working as expected due to the Jackson
174 * parsing challenges on the Row object returned by the Select operation.
176 private UUID selectOpenVSwitchTableUuid() throws ExecutionException, InterruptedException {
177 Assert.assertNotNull(dbSchema);
178 GenericTableSchema ovsTable = dbSchema.table("Open_vSwitch", GenericTableSchema.class);
180 List<MonitorRequest<GenericTableSchema>> monitorRequests = Lists.newArrayList();
181 ColumnSchema<GenericTableSchema, UUID> _uuid = ovsTable.column("_uuid", UUID.class);
183 List<OperationResult> results = ovs.transactBuilder(dbSchema)
184 .add(op.select(ovsTable)
189 Assert.assertTrue(!results.isEmpty());
190 OperationResult result = results.get(0);
191 List<Row<GenericTableSchema>> rows = result.getRows();
192 Row<GenericTableSchema> ovsTableRow = rows.get(0);
193 return ovsTableRow.getColumn(_uuid).getData();
196 private void createBridgeTransaction() throws IOException, InterruptedException, ExecutionException {
197 Assert.assertNotNull(dbSchema);
198 TableSchema<GenericTableSchema> bridge = dbSchema.table("Bridge", GenericTableSchema.class);
199 GenericTableSchema ovsTable = dbSchema.table("Open_vSwitch", GenericTableSchema.class);
201 ColumnSchema<GenericTableSchema, String> name = bridge.column("name", String.class);
202 ColumnSchema<GenericTableSchema, String> fail_mode = bridge.column("fail_mode", String.class);
203 ColumnSchema<GenericTableSchema, Set<Integer>> flood_vlans = bridge.multiValuedColumn("flood_vlans", Integer.class);
204 ColumnSchema<GenericTableSchema, Map<String, String>> externalIds = bridge.multiValuedColumn("external_ids", String.class, String.class);
205 ColumnSchema<GenericTableSchema, Set<UUID>> bridges = ovsTable.multiValuedColumn("bridges", UUID.class);
206 ColumnSchema<GenericTableSchema, UUID> _uuid = ovsTable.column("_uuid", UUID.class);
208 String namedUuid = "br_test";
209 int insertOperationIndex = 0;
210 UUID parentTable = selectOpenVSwitchTableUuid();
211 TransactionBuilder transactionBuilder = ovs.transactBuilder(dbSchema)
213 * Make sure that the position of insert operation matches the insertOperationIndex.
214 * This will be used later when the Results are processed.
216 .add(op.insert(bridge)
218 .value(name, testBridgeName)
219 .value(flood_vlans, Sets.newHashSet(100, 101, 4001))
220 .value(externalIds, ImmutableMap.of("key","value")))
221 .add(op.comment("Inserting Bridge br-int"))
222 .add(op.update(bridge)
223 .set(fail_mode, "secure")
224 .where(name.opEqual(testBridgeName))
226 .add(op.select(bridge)
229 .where(name.opEqual(testBridgeName))
231 .add(op.mutate(bridge)
232 .addMutation(flood_vlans, Mutator.INSERT, Sets.newHashSet(200,400))
233 .where(name.opEqual(testBridgeName))
235 .add(op.mutate(bridge)
236 .addMutation(externalIds, Mutator.INSERT, ImmutableMap.of("key2","value2"))
237 .where(name.opEqual(testBridgeName))
239 .add(op.mutate(ovsTable)
240 .addMutation(bridges, Mutator.INSERT, Sets.newHashSet(new UUID(namedUuid)))
241 .where(_uuid.opEqual(parentTable))
243 .add(op.commit(true));
245 ListenableFuture<List<OperationResult>> results = transactionBuilder.execute();
246 List<OperationResult> operationResults = results.get();
247 Assert.assertFalse(operationResults.isEmpty());
248 // Check if Results matches the number of operations in transaction
249 Assert.assertEquals(transactionBuilder.getOperations().size(), operationResults.size());
250 System.out.println("Insert & Update operation results = " + operationResults);
251 for (OperationResult result : operationResults) {
252 Assert.assertNull(result.getError());
254 testBridgeUuid = operationResults.get(insertOperationIndex).getUuid();
257 private void assertTransaction() throws InterruptedException, ExecutionException {
258 Assert.assertNotNull(dbSchema);
259 TableSchema<GenericTableSchema> bridge = dbSchema.table("Bridge", GenericTableSchema.class);
260 ColumnSchema<GenericTableSchema, String> name = bridge.column("name", String.class);
263 * Adding a separate Assert operation in a transaction. Lets not mix this with other
264 * valid transactions as above.
266 ListenableFuture<List<OperationResult>> results = ovs.transactBuilder(dbSchema)
267 .add(op.delete(bridge)
268 .where(name.opEqual(testBridgeName))
270 .add(op.assertion("Assert12345")) // Failing intentionally
273 List<OperationResult> operationResults = results.get();
274 Assert.assertFalse(operationResults.isEmpty());
275 /* Testing for an Assertion Error */
276 Assert.assertFalse(operationResults.get(1).getError() == null);
277 System.out.println("Assert operation results = " + operationResults);
280 private void abortTransaction() throws InterruptedException, ExecutionException {
281 Assert.assertNotNull(dbSchema);
282 TableSchema<GenericTableSchema> bridge = dbSchema.table("Bridge", GenericTableSchema.class);
283 ColumnSchema<GenericTableSchema, String> name = bridge.column("name", String.class);
286 * Adding a separate Abort operation in a transaction. Lets not mix this with other
287 * valid transactions as above.
289 ListenableFuture<List<OperationResult>> results = ovs.transactBuilder(dbSchema)
290 .add(op.delete(bridge)
291 .where(name.opEqual(testBridgeName))
296 List<OperationResult> operationResults = results.get();
297 Assert.assertFalse(operationResults.isEmpty());
298 /* Testing for Abort Error */
299 Assert.assertFalse(operationResults.get(1).getError() == null);
300 System.out.println("Abort operation results = " + operationResults);
303 public void testGetDBs() throws ExecutionException, InterruptedException {
304 ListenableFuture<List<String>> databases = ovs.getDatabases();
305 List<String> dbNames = databases.get();
306 Assert.assertNotNull(dbNames);
307 boolean hasOpenVswitchSchema = false;
308 for(String dbName : dbNames) {
309 if (dbName.equals(OPEN_VSWITCH_SCHEMA)) {
310 hasOpenVswitchSchema = true;
314 Assert.assertTrue(OPEN_VSWITCH_SCHEMA+" schema is not supported by the switch", hasOpenVswitchSchema);
318 public void setUp() throws IOException, ExecutionException, InterruptedException, TimeoutException {
323 ovs = getTestConnection();
324 System.out.println("Connection Info :" + ovs.getConnectionInfo().toString());
326 dbSchema = ovs.getSchema(OPEN_VSWITCH_SCHEMA).get();
330 public void tearDown() throws InterruptedException, ExecutionException {
331 if (dbSchema == null) {
334 TableSchema<GenericTableSchema> bridge = dbSchema.table("Bridge", GenericTableSchema.class);
335 ColumnSchema<GenericTableSchema, String> name = bridge.column("name", String.class);
336 GenericTableSchema ovsTable = dbSchema.table("Open_vSwitch", GenericTableSchema.class);
337 ColumnSchema<GenericTableSchema, Set<UUID>> bridges = ovsTable.multiValuedColumn("bridges", UUID.class);
338 ColumnSchema<GenericTableSchema, UUID> _uuid = ovsTable.column("_uuid", UUID.class);
339 UUID parentTable = selectOpenVSwitchTableUuid();
341 ListenableFuture<List<OperationResult>> results = ovs.transactBuilder(dbSchema)
342 .add(op.delete(bridge)
343 .where(name.opEqual(testBridgeName))
345 .add(op.mutate(ovsTable)
346 .addMutation(bridges, Mutator.DELETE, Sets.newHashSet(testBridgeUuid))
347 .where(_uuid.opEqual(parentTable))
349 .add(op.commit(true))
352 List<OperationResult> operationResults = results.get();
353 System.out.println("Delete operation results = " + operationResults);
354 OvsdbConnectionService.getService().disconnect(ovs);
359 public void update(Object node, UpdateNotification upadateNotification) {
360 // TODO Auto-generated method stub
365 public void locked(Object node, List<String> ids) {
366 // TODO Auto-generated method stub
370 public void stolen(Object node, List<String> ids) {
371 // TODO Auto-generated method stub