Based on Ashwin's comment to the library infra gerrit (8104), more simplified User Facing APIs are introduced :
1. Bridge rBridge = ovs.createTypedRowWrapper(TestBridge.class);
replaces
TestBridge rBridge = TyperUtils.getTypedRowWrapper(dbSchema, TestBridge.class, new Row<GenericTableSchema>());
2. rBridge.getSchema()
replaces
GenericTableSchema rBridgeSchema = TyperUtils.getTableSchema(dbSchema, TestBridge.class);
More such Simplified alternative APIs will be added based on usage.
Change-Id: Ibdee07b308145bf792c9309d7095a94aac2d23b3
Signed-off-by: Madhu Venugopal <mavenugo@gmail.com>
import java.util.List;
import org.opendaylight.ovsdb.lib.message.MonitorRequest;
+import org.opendaylight.ovsdb.lib.notation.Row;
import org.opendaylight.ovsdb.lib.operations.Operation;
import org.opendaylight.ovsdb.lib.operations.OperationResult;
import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
import org.opendaylight.ovsdb.lib.schema.TableSchema;
import com.google.common.util.concurrent.ListenableFuture;
*/
public void stopEchoService();
+ public DatabaseSchema getDatabaseSchema (String dbName);
+
+ /**
+ * User friendly convenient methods that make use of TyperUtils.getTypedRowWrapper to create a Typed Row Proxy
+ * given the Typed Table Class
+ *
+ * @param klazz Typed Interface
+ * @return Proxy wrapper for the actual raw Row class.
+ */
+ public <T> T createTypedRowWrapper(Class<T> klazz);
+ /**
+ * User friendly convenient methods that make use of getTypedRowWrapper to create a Typed Row Proxy given
+ * DatabaseSchema and Typed Table Class.
+ *
+ * @param dbSchema Database Schema of interest
+ * @param klazz Typed Interface
+ * @return Proxy wrapper for the actual raw Row class.
+ */
+ public <T> T createTypedRowWrapper(DatabaseSchema dbSchema, Class<T> klazz);
+
+ /**
+ * User friendly convenient method to get a Typed Row Proxy given a Typed Table Class and the Row to be wrapped.
+ *
+ * @param klazz Typed Interface
+ * @param row The actual Row that the wrapper is operating on. It can be null if the caller is just interested in getting ColumnSchema.
+ * @return Proxy wrapper for the actual raw Row class.
+ */
+ public <T> T getTypedRowWrapper(final Class<T> klazz, final Row<GenericTableSchema> row);
+
}
import org.opendaylight.ovsdb.lib.message.TableUpdates;
import org.opendaylight.ovsdb.lib.message.TransactBuilder;
import org.opendaylight.ovsdb.lib.message.UpdateNotification;
+import org.opendaylight.ovsdb.lib.notation.Row;
import org.opendaylight.ovsdb.lib.operations.Operation;
import org.opendaylight.ovsdb.lib.operations.OperationResult;
import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
import org.opendaylight.ovsdb.lib.schema.TableSchema;
+import org.opendaylight.ovsdb.lib.schema.typed.TypedTable;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
this.schema = schema;
}
}
+
+ @Override
+ public DatabaseSchema getDatabaseSchema (String dbName) {
+ return schema.get(dbName);
+ }
+
+ /**
+ * This method finds the DatabaseSchema that matches a given Typed Table Class.
+ * With the introduction of TypedTable and TypedColumn annotations, it is possible to express
+ * the Database Name, Table Name & the Database Versions within which the Table is defined and maintained.
+ *
+ * @param klazz Typed Class that represents a Table
+ * @return DatabaseSchema that matches a Typed Table Class
+ */
+ private <T> DatabaseSchema getDatabaseSchemaForTypedTable (Class <T> klazz) {
+ TypedTable typedTable = klazz.getAnnotation(TypedTable.class);
+ if (typedTable != null) {
+ return this.getDatabaseSchema(typedTable.database());
+ }
+ return null;
+ }
+
+ /**
+ * User friendly convenient method that make use of TyperUtils.getTypedRowWrapper to create a Typed Row Proxy
+ * given the Typed Table Class
+ *
+ * @param klazz Typed Interface
+ * @return Proxy wrapper for the actual raw Row class.
+ */
+ @Override
+ public <T> T createTypedRowWrapper(Class<T> klazz) {
+ DatabaseSchema dbSchema = getDatabaseSchemaForTypedTable(klazz);
+ return this.createTypedRowWrapper(dbSchema, klazz);
+ }
+
+ /**
+ * User friendly convenient method that make use of getTypedRowWrapper to create a Typed Row Proxy given
+ * DatabaseSchema and Typed Table Class.
+ *
+ * @param dbSchema Database Schema of interest
+ * @param klazz Typed Interface
+ * @return Proxy wrapper for the actual raw Row class.
+ */
+ @Override
+ public <T> T createTypedRowWrapper(DatabaseSchema dbSchema, Class<T> klazz) {
+ return TyperUtils.getTypedRowWrapper(dbSchema, klazz, new Row<GenericTableSchema>());
+ }
+
+ /**
+ * User friendly convenient method to get a Typed Row Proxy given a Typed Table Class and the Row to be wrapped.
+ *
+ * @param klazz Typed Interface
+ * @param row The actual Row that the wrapper is operating on. It can be null if the caller is just interested in getting ColumnSchema.
+ * @return Proxy wrapper for the actual raw Row class.
+ */
+ @Override
+ public <T> T getTypedRowWrapper(final Class<T> klazz, final Row<GenericTableSchema> row) {
+ DatabaseSchema dbSchema = getDatabaseSchemaForTypedTable(klazz);
+ return TyperUtils.getTypedRowWrapper(dbSchema, klazz, row);
+ }
}
package org.opendaylight.ovsdb.lib.schema.typed;
public enum MethodType {
- GETCOLUMN, GETDATA, SETDATA
+ GETCOLUMN, GETDATA, SETDATA, GETTABLESCHEMA
}
*/
package org.opendaylight.ovsdb.lib.schema.typed;
+import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
+
public interface TypedBaseTable {
+ @TypedColumn(name="", method=MethodType.GETTABLESCHEMA)
+ GenericTableSchema getSchema();
}
return null;
}
+ private static boolean isGetTableSchema (Method method) {
+ TypedColumn typedColumn = method.getAnnotation(TypedColumn.class);
+ if (typedColumn != null) {
+ return typedColumn.method().equals(MethodType.GETTABLESCHEMA) ? true : false;
+ }
+ return false;
+ }
+
private static boolean isGetColumn (Method method) {
TypedColumn typedColumn = method.getAnnotation(TypedColumn.class);
if (typedColumn != null) {
* @return true if valid, false otherwise
*/
private static <T> boolean isValid (DatabaseSchema dbSchema, final Class<T> klazz) {
+ if (dbSchema == null) {
+ return false;
+ }
+
TypedTable typedTable = klazz.getAnnotation(TypedTable.class);
if (typedTable != null) {
if (!dbSchema.getName().equalsIgnoreCase(typedTable.database())) {
return proxy;
}
+ private Object processGetTableSchema() throws Throwable {
+ if (dbSchema == null) return null;
+ return getTableSchema(dbSchema, klazz);
+ }
+
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- if (isSetData(method)) {
+ if (isGetTableSchema(method)) {
+ return processGetTableSchema();
+ } else if (isSetData(method)) {
return processSetData(proxy, method, args);
} else if(isGetData(method)) {
return processGetData(method);
} else if(isGetColumn(method)) {
return processGetColumn(method);
} else {
- throw new RuntimeException("Unsupported method : "+method.getName());
+ /*
+ * TODO : Handle the methods provided by Object class (such as toString, hashCode, equals, etc.).
+ * Reintroduce throwing RuntimeException("Unsupported method : "+method.getName()); after these methods
+ * are handled
+ */
+ return null;
}
}
}
import org.opendaylight.ovsdb.lib.message.OvsdbRPC;
import org.opendaylight.ovsdb.lib.message.UpdateNotification;
import org.opendaylight.ovsdb.lib.notation.Mutator;
-import org.opendaylight.ovsdb.lib.notation.Row;
import org.opendaylight.ovsdb.lib.notation.UUID;
import org.opendaylight.ovsdb.lib.operations.OperationResult;
import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
import org.opendaylight.ovsdb.lib.schema.TableSchema;
-import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Test
public void testTypedBridgeCreate() throws IOException, InterruptedException, ExecutionException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
- GenericTableSchema rBridgeSchema = TyperUtils.getTableSchema(dbSchema, TestBridge.class);
- TestBridge rBridge = TyperUtils.getTypedRowWrapper(dbSchema, TestBridge.class, new Row<GenericTableSchema>());
+ TestBridge rBridge = ovs.createTypedRowWrapper(TestBridge.class);
rBridge.setName(testBridgeName);
rBridge.setStatus(Maps.newHashMap(ImmutableMap.of("key","value")));
rBridge.setFloodVlans(Sets.newHashSet(34));
int insertOperationIndex = 0;
TransactionBuilder transactionBuilder = ovs.transactBuilder()
- .add(op.insert(rBridgeSchema)
+ .add(op.insert(rBridge.getSchema())
.withId(namedUuid)
.value(rBridge.getNameColumn()))
- .add(op.update(rBridgeSchema)
+ .add(op.update(rBridge.getSchema())
.set(rBridge.getStatusColumn())
.set(rBridge.getFloodVlansColumn())
.where(rBridge.getNameColumn().getSchema().opEqual(rBridge.getName()))
--- /dev/null
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Authors : Madhu Venugopal
+ */
+
+package org.opendaylight.ovsdb.lib;
+import org.opendaylight.ovsdb.lib.schema.typed.TypedBaseTable;
+import org.opendaylight.ovsdb.lib.schema.typed.TypedTable;
+
+/**
+ * VersionIncompatibleBridge is used to test the Version Compatibility logic in the Library
+ * with an absurdly low fromVersion and untilVersion which will fail for all the OVS versions.
+ */
+@TypedTable(name="Bridge", database="Open_vSwitch", fromVersion="0.0.1", untilVersion="0.0.2")
+public interface VersionIncompatibleBridge extends TypedBaseTable {
+}
import org.opendaylight.ovsdb.lib.message.OvsdbRPC;
import org.opendaylight.ovsdb.lib.message.UpdateNotification;
import org.opendaylight.ovsdb.lib.notation.Mutator;
-import org.opendaylight.ovsdb.lib.notation.Row;
import org.opendaylight.ovsdb.lib.notation.UUID;
import org.opendaylight.ovsdb.lib.operations.OperationResult;
import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
-import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
-import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
}
private void createTypedBridge() throws IOException, InterruptedException, ExecutionException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
- GenericTableSchema bridgeSchema = TyperUtils.getTableSchema(dbSchema, Bridge.class);
- Bridge bridge = TyperUtils.getTypedRowWrapper(dbSchema, Bridge.class, new Row<GenericTableSchema>());
+ Bridge bridge = ovs.createTypedRowWrapper(Bridge.class);
bridge.setName(testBridgeName);
bridge.setStatus(Maps.newHashMap(ImmutableMap.of("key","value")));
bridge.setFloodVlans(Sets.newHashSet(34));
- GenericTableSchema ovsTable = TyperUtils.getTableSchema(dbSchema, OpenVSwitch.class);
- OpenVSwitch openVSwitch = TyperUtils.getTypedRowWrapper(dbSchema, OpenVSwitch.class, new Row<GenericTableSchema>());
+ OpenVSwitch openVSwitch = ovs.createTypedRowWrapper(OpenVSwitch.class);
openVSwitch.setBridges(Sets.newHashSet(new UUID(testBridgeName)));
int insertOperationIndex = 0;
TransactionBuilder transactionBuilder = ovs.transactBuilder()
- .add(op.insert(bridgeSchema)
+ .add(op.insert(bridge.getSchema())
.withId(testBridgeName)
.value(bridge.getNameColumn()))
- .add(op.update(bridgeSchema)
+ .add(op.update(bridge.getSchema())
.set(bridge.getStatusColumn())
.set(bridge.getFloodVlansColumn())
.where(bridge.getNameColumn().getSchema().opEqual(bridge.getName()))
.and(bridge.getNameColumn().getSchema().opEqual(bridge.getName())).build())
- .add(op.mutate(ovsTable)
+ .add(op.mutate(openVSwitch.getSchema())
.addMutation(openVSwitch.getBridgesColumn().getSchema(), Mutator.INSERT,
openVSwitch.getBridgesColumn().getData()));
@After
public void tearDown() throws InterruptedException, ExecutionException {
- GenericTableSchema bridgeSchema = TyperUtils.getTableSchema(dbSchema, Bridge.class);
- Bridge bridge = TyperUtils.getTypedRowWrapper(dbSchema, Bridge.class, null);
-
- GenericTableSchema ovsTable = TyperUtils.getTableSchema(dbSchema, OpenVSwitch.class);
- OpenVSwitch openVSwitch = TyperUtils.getTypedRowWrapper(dbSchema, OpenVSwitch.class, null);
+ Bridge bridge = ovs.getTypedRowWrapper(Bridge.class, null);
+ OpenVSwitch openVSwitch = ovs.getTypedRowWrapper(OpenVSwitch.class, null);
ListenableFuture<List<OperationResult>> results = ovs.transactBuilder()
- .add(op.delete(bridgeSchema)
+ .add(op.delete(bridge.getSchema())
.where(bridge.getNameColumn().getSchema().opEqual(testBridgeName))
.build())
- .add(op.mutate(ovsTable)
+ .add(op.mutate(openVSwitch.getSchema())
.addMutation(openVSwitch.getBridgesColumn().getSchema(), Mutator.DELETE, Sets.newHashSet(testBridgeUuid)))
.add(op.commit(true))
.execute();