Added proper Typed Schema Wrapper infra to Library which enables a simple mechanism... 04/8104/3
authorMadhu Venugopal <mavenugo@gmail.com>
Wed, 18 Jun 2014 05:41:47 +0000 (22:41 -0700)
committerMadhu Venugopal <mavenugo@gmail.com>
Wed, 18 Jun 2014 23:34:08 +0000 (16:34 -0700)
* Added ovsdb.lib.schema.typed package with infra classes that supports this functionality.
* TyperUtils.java uses Reflection to provide the required Wrapper functionality with the help of Java annotations (TypedTable & TypedColumn)
* MethodType option of TypedColumn is modified to support GETCOLUMN in addition to GETDATA and SETDATA method types
* Changed the existing Typed IT code and introduced TestBridge.java (Bridge Table of ovs-vswitchd schema)

Change-Id: Ica6d14474ccecfd38fd025f7d5911b951312e9f7
Signed-off-by: Madhu Venugopal <mavenugo@gmail.com>
12 files changed:
library/pom.xml
library/src/main/java/org/opendaylight/ovsdb/lib/notation/Row.java
library/src/main/java/org/opendaylight/ovsdb/lib/operations/Insert.java
library/src/main/java/org/opendaylight/ovsdb/lib/operations/Update.java
library/src/main/java/org/opendaylight/ovsdb/lib/schema/GenericTableSchema.java
library/src/main/java/org/opendaylight/ovsdb/lib/schema/typed/MethodType.java [new file with mode: 0644]
library/src/main/java/org/opendaylight/ovsdb/lib/schema/typed/TypedBaseTable.java [new file with mode: 0644]
library/src/main/java/org/opendaylight/ovsdb/lib/schema/typed/TypedColumn.java [new file with mode: 0644]
library/src/main/java/org/opendaylight/ovsdb/lib/schema/typed/TypedTable.java [new file with mode: 0644]
library/src/main/java/org/opendaylight/ovsdb/lib/schema/typed/TyperUtils.java [new file with mode: 0644]
library/src/test/java/org/opendaylight/ovsdb/lib/OvsDBClientTestITTyped.java
library/src/test/java/org/opendaylight/ovsdb/lib/TestBridge.java [new file with mode: 0644]

index 099054923f0b909c5138d32eee48adc3ed0032d3..31f5c3c9c39a13f03429acc2b56beaf3847a82ec 100755 (executable)
                 org.opendaylight.ovsdb.lib.database,
                 org.opendaylight.ovsdb.lib.operations,
                 org.opendaylight.ovsdb.lib.message,
-                org.opendaylight.ovsdb.lib.schema</Export-Package>
+                org.opendaylight.ovsdb.lib.schema,
+                org.opendaylight.ovsdb.lib.schema.typed</Export-Package>
           </instructions>
           <manifestLocation>${project.basedir}/META-INF</manifestLocation>
         </configuration>
index c97191d8ee7fdc17d5b14293fcc9ad38cce8721d..cb696f3b9a730fe912511412b5406efb70fae062 100644 (file)
 
 package org.opendaylight.ovsdb.lib.notation;
 
+import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 
 import org.opendaylight.ovsdb.lib.schema.ColumnSchema;
 import org.opendaylight.ovsdb.lib.schema.TableSchema;
 
+import com.google.common.collect.Maps;
+
 public class Row<E extends TableSchema<E>> {
-    List<Column<E, ?>> columns;
+    protected Map<String, Column<E, ?>> columns;
 
-    private Row() { }
+    public Row() {
+        this.columns = Maps.newHashMap();
+    }
 
     public Row(List<Column<E, ?>> columns) {
-        this.columns = columns;
+        this.columns = Maps.newHashMap();
+        for (Column<E, ?> column : columns) {
+            this.columns.put(column.getSchema().getName(), column);
+        }
     }
 
     public <D> Column<E, D> getColumn(ColumnSchema<E, D> schema) {
-        for (Column<E, ?> column : columns) {
-           if (column.getSchema().equals(schema)) {
-               return (Column<E, D>) column;
-           }
-        }
-        return null;
+        return (Column<E, D>) columns.get(schema.getName());
+    }
+
+    public Collection<Column<E, ?>> getColumns() {
+        return columns.values();
     }
 
-    public List<Column<E, ?>> getColumns() {
-        return columns;
+    public void addColumn(String columnName, Column<E, ?> data) {
+        this.columns.put(columnName, data);
     }
 }
index dce4eb017ee3cd9df7e43561dfa91e0490d20d64..95d70541b37da4ed10a5e774a4da56c28ff3134b 100644 (file)
@@ -11,6 +11,7 @@ package org.opendaylight.ovsdb.lib.operations;
 
 import java.util.Map;
 
+import org.opendaylight.ovsdb.lib.notation.Column;
 import org.opendaylight.ovsdb.lib.schema.ColumnSchema;
 import org.opendaylight.ovsdb.lib.schema.TableSchema;
 
@@ -51,6 +52,12 @@ public class Insert<E extends TableSchema<E>> extends Operation<E> {
         return this;
     }
 
+    public <D, C extends TableSchema<C>> Insert<E> value(Column<C, D> column) {
+        ColumnSchema<C, D> columnSchema = column.getSchema();
+        D value = column.getData();
+        return this.value(columnSchema, value);
+    }
+
     public String getUuid() {
         return uuid;
     }
index ce6d506d5414e13bfb0a846bfb69538cd9988384..3f71b515d308982a29208ee020cb31fda5b24e17 100644 (file)
@@ -15,6 +15,7 @@ package org.opendaylight.ovsdb.lib.operations;
 import java.util.List;
 import java.util.Map;
 
+import org.opendaylight.ovsdb.lib.notation.Column;
 import org.opendaylight.ovsdb.lib.notation.Condition;
 import org.opendaylight.ovsdb.lib.schema.ColumnSchema;
 import org.opendaylight.ovsdb.lib.schema.TableSchema;
@@ -48,6 +49,12 @@ public class Update<E extends TableSchema<E>> extends Operation<E> implements Co
         return this;
     }
 
+    public <T extends TableSchema<T>, D> Update<E> set(Column<T, D> column) {
+        ColumnSchema<T, D> columnSchema = column.getSchema();
+        D value = column.getData();
+        return this.set(columnSchema, value);
+    }
+
     public Where where(Condition condition) {
         where.add(condition);
         return new Where(this);
index f6ebfae19c55aa86f8673719e56fc608762652f0..2b35a3e388554fa8650bb98a7009795579720a5d 100644 (file)
@@ -27,6 +27,10 @@ public class GenericTableSchema extends TableSchema<GenericTableSchema> {
         super(tableName);
     }
 
+    public GenericTableSchema (TableSchema tableSchema) {
+        super(tableSchema.getName(), tableSchema.getColumnSchemas());
+    }
+
     public GenericTableSchema fromJson(String tableName, JsonNode json) {
 
         if (!json.isObject() || !json.has("columns")) {
diff --git a/library/src/main/java/org/opendaylight/ovsdb/lib/schema/typed/MethodType.java b/library/src/main/java/org/opendaylight/ovsdb/lib/schema/typed/MethodType.java
new file mode 100644 (file)
index 0000000..bcb0ea1
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * 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.schema.typed;
+
+public enum MethodType {
+    GETCOLUMN, GETDATA, SETDATA
+}
diff --git a/library/src/main/java/org/opendaylight/ovsdb/lib/schema/typed/TypedBaseTable.java b/library/src/main/java/org/opendaylight/ovsdb/lib/schema/typed/TypedBaseTable.java
new file mode 100644 (file)
index 0000000..fc0fa59
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * 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.schema.typed;
+
+public interface TypedBaseTable {
+}
diff --git a/library/src/main/java/org/opendaylight/ovsdb/lib/schema/typed/TypedColumn.java b/library/src/main/java/org/opendaylight/ovsdb/lib/schema/typed/TypedColumn.java
new file mode 100644 (file)
index 0000000..5e0b73d
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * 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.schema.typed;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface TypedColumn {
+    public String name();
+    public MethodType method();
+}
diff --git a/library/src/main/java/org/opendaylight/ovsdb/lib/schema/typed/TypedTable.java b/library/src/main/java/org/opendaylight/ovsdb/lib/schema/typed/TypedTable.java
new file mode 100644 (file)
index 0000000..c7a91a8
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * 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.schema.typed;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface TypedTable {
+    public String name();
+    public String database();
+}
diff --git a/library/src/main/java/org/opendaylight/ovsdb/lib/schema/typed/TyperUtils.java b/library/src/main/java/org/opendaylight/ovsdb/lib/schema/typed/TyperUtils.java
new file mode 100644 (file)
index 0000000..12161c4
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * 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.schema.typed;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+
+import org.opendaylight.ovsdb.lib.notation.Column;
+import org.opendaylight.ovsdb.lib.notation.Row;
+import org.opendaylight.ovsdb.lib.schema.ColumnSchema;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
+
+import com.google.common.reflect.Reflection;
+
+public class TyperUtils {
+    private static final String GET_STARTS_WITH="get";
+    private static final String SET_STARTS_WITH="set";
+    private static final String GETCOLUMN_ENDS_WITH="Column";
+
+    private static <T> String getTableName (Class<T> klazz) {
+        TypedTable typedTable = klazz.getAnnotation(TypedTable.class);
+        if (typedTable != null) {
+            return typedTable.name();
+        }
+        return klazz.getSimpleName();
+    }
+
+    public static <T> GenericTableSchema getTableSchema(DatabaseSchema dbSchema, Class<T> klazz) {
+        String tableName = getTableName(klazz);
+        return dbSchema.table(tableName, GenericTableSchema.class);
+    }
+
+    public static ColumnSchema<GenericTableSchema, Object> getColumnSchema(GenericTableSchema tableSchema, String columnName, Class<Object> metaClass) {
+        return tableSchema.column(columnName, metaClass);
+    }
+
+    private static String getColumnName (Method method) {
+        TypedColumn typedColumn = method.getAnnotation(TypedColumn.class);
+        if (typedColumn != null) {
+            return typedColumn.name();
+        }
+
+        /*
+         * Attempting to get the column name by parsing the method name with a following convention :
+         * 1. GETDATA : get<ColumnName>
+         * 2. SETDATA : set<ColumnName>
+         * 3. GETCOLUMN : get<ColumnName>Column
+         * where <ColumnName> is the name of the column that we are interested in.
+         */
+        int index = GET_STARTS_WITH.length();
+        if (isGetData(method) || isSetData(method)) {
+            return method.getName().substring(index, method.getName().length()).toLowerCase();
+        } else if (isGetColumn(method)) {
+            return method.getName().substring(index, method.getName().indexOf(GETCOLUMN_ENDS_WITH, index)).toLowerCase();
+        }
+
+        return null;
+    }
+
+    private static boolean isGetColumn (Method method) {
+        TypedColumn typedColumn = method.getAnnotation(TypedColumn.class);
+        if (typedColumn != null) {
+            return typedColumn.method().equals(MethodType.GETCOLUMN) ? true : false;
+        }
+
+        if (method.getName().startsWith(GET_STARTS_WITH) && method.getName().endsWith(GETCOLUMN_ENDS_WITH)) {
+            return true;
+        }
+        return false;
+    }
+
+    private static boolean isGetData (Method method) {
+        TypedColumn typedColumn = method.getAnnotation(TypedColumn.class);
+        if (typedColumn != null) {
+            return typedColumn.method().equals(MethodType.GETDATA) ? true : false;
+        }
+
+        if (method.getName().startsWith(GET_STARTS_WITH) && !method.getName().endsWith(GETCOLUMN_ENDS_WITH)) {
+            return true;
+        }
+        return false;
+    }
+
+    private static boolean isSetData (Method method) {
+        TypedColumn typedColumn = method.getAnnotation(TypedColumn.class);
+        if (typedColumn != null) {
+            return typedColumn.method().equals(MethodType.SETDATA) ? true : false;
+        }
+
+        if (method.getName().startsWith(SET_STARTS_WITH)) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Method that checks validity of the parameter passed to getTypedRowWrapper.
+     * This method checks for a valid Database Schema matching the expected Database for a given table
+     * and checks for the presence of the Table in Database Schema.
+     *
+     * @param dbSchema DatabaseSchema as learnt from a OVSDB connection
+     * @param klazz Typed Class that represents a Table
+     * @return true if valid, false otherwise
+     */
+    private static <T> boolean isValid (DatabaseSchema dbSchema, final Class<T> klazz) {
+        TypedTable typedTable = klazz.getAnnotation(TypedTable.class);
+        if (typedTable != null) {
+            if (!dbSchema.getName().equalsIgnoreCase(typedTable.database())) {
+                return false;
+            }
+        }
+
+        if (!dbSchema.getTables().contains(getTableName(klazz))) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * This method returns a Typed Proxy implementation for the klazz passed as a parameter.
+     * Per design choice, the Typed Proxy implementation is just a Wrapper on top of the actual Row which is untyped.
+     * Being just a wrapper, it is state-less and more of a convenience functionality to provide a type-safe infrastructure
+     * for the applications to built on top of. And this Typed infra is completely optional.
+     *
+     * It is the applications responsibilty to pass on the raw Row parameter & this method will return the appropriate
+     * Proxy wrapper for the passed klazz Type. The raw Row parameter may be null if the caller is interested in just the
+     * ColumnSchema. But that is not a very common use-case.
+     *
+     * @param dbSchema DatabaseSchema as learnt from a OVSDB connection
+     * @param klazz Typed Class that represents a Table
+     * @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
+     */
+    public static <T> T getTypedRowWrapper(final DatabaseSchema dbSchema, final Class<T> klazz, final Row<GenericTableSchema> row) {
+        if (!isValid(dbSchema, klazz)) {
+            return null;
+        }
+        return Reflection.newProxy(klazz, new InvocationHandler() {
+            private Object processGetData(Method method) throws Throwable {
+                String columnName = getColumnName(method);
+                if (columnName == null) {
+                    throw new RuntimeException("Error processing Getter : "+ method.getName());
+                }
+                GenericTableSchema tableSchema = getTableSchema(dbSchema, klazz);
+                if (tableSchema == null) {
+                    throw new RuntimeException("Unable to locate TableSchema for "+getTableName(klazz)+ " in "+ dbSchema.getName());
+                }
+                ColumnSchema<GenericTableSchema, Object> columnSchema = getColumnSchema(tableSchema, columnName, (Class<Object>) method.getReturnType());
+                if (columnSchema == null) {
+                    throw new RuntimeException("Unable to locate ColumnSchema for "+columnName+ " in "+ tableSchema.getName());
+                }
+                if (row == null) {
+                    return null;
+                }
+                return row.getColumn(columnSchema).getData();
+            }
+
+            private Object processGetColumn(Method method) throws Throwable {
+                String columnName = getColumnName(method);
+                if (columnName == null) {
+                    throw new RuntimeException("Error processing GetColumn : "+ method.getName());
+                }
+                GenericTableSchema tableSchema = getTableSchema(dbSchema, klazz);
+                if (tableSchema == null) {
+                    throw new RuntimeException("Unable to locate TableSchema for "+getTableName(klazz)+ " in "+ dbSchema.getName());
+                }
+                ColumnSchema<GenericTableSchema, Object> columnSchema = getColumnSchema(tableSchema, columnName, (Class<Object>) method.getReturnType());
+                if (columnSchema == null) {
+                    throw new RuntimeException("Unable to locate ColumnSchema for "+columnName+ " in "+ tableSchema.getName());
+                }
+                // When the row is null, that might indicate that the user maybe interested only in the ColumnSchema and not on the Data.
+                if (row == null) {
+                    return new Column<GenericTableSchema, Object>(columnSchema, null);
+                }
+                return row.getColumn(columnSchema);
+            }
+
+            private Object processSetData(Object proxy, Method method, Object[] args) throws Throwable {
+                if (args == null || args.length != 1) {
+                    throw new RuntimeException("Setter method : "+method.getName() + " requires 1 argument");
+                }
+                String columnName = getColumnName(method);
+                if (columnName == null) {
+                    throw new RuntimeException("Unable to locate Column Name for "+method.getName());
+                }
+                GenericTableSchema tableSchema = getTableSchema(dbSchema, klazz);
+                ColumnSchema<GenericTableSchema, Object> columnSchema = getColumnSchema(tableSchema, columnName,
+                                                                                        (Class<Object>) args[0].getClass());
+                Column<GenericTableSchema, Object> column = new Column<GenericTableSchema, Object>(columnSchema, args[0]);
+                row.addColumn(columnName, column);
+                return proxy;
+            }
+
+            @Override
+            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+                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());
+                }
+            }
+        }
+        );
+    }
+}
index 0913883b5fe2d72d988bbc543bf3e6248d51fd42..3e3a2326749a2cc8de98137691cfec3320c984ed 100644 (file)
@@ -7,13 +7,14 @@
  *
  * Authors : Ashwin Raveendran, Madhu Venugopal
  */
+
 package org.opendaylight.ovsdb.lib;
 
 import static org.opendaylight.ovsdb.lib.operations.Operations.op;
 
 import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
@@ -27,6 +28,7 @@ import org.junit.Test;
 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;
@@ -34,7 +36,7 @@ import org.opendaylight.ovsdb.lib.schema.ColumnSchema;
 import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
 import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
 import org.opendaylight.ovsdb.lib.schema.TableSchema;
-import org.opendaylight.ovsdb.lib.schema.temp.Reference;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -51,53 +53,29 @@ public class OvsDBClientTestITTyped extends OvsdbTestBase {
     static String testBridgeName = "br-test";
     static UUID testBridgeUuid = null;
 
-    public static class Bridge extends TableSchema<Bridge> {
-
-        public Bridge (TableSchema<Bridge> tableSchema) {
-            super("Bridge", tableSchema.getColumnSchemas());
-        }
-
-        public Bridge(String name, Map<String, ColumnSchema> columns) {
-            super(name, columns);
-        }
-
-        public ColumnSchema<Bridge, String> name() {
-            return column("name", String.class);
-        }
-
-        public ColumnSchema<Bridge, Integer> floodVlans() {
-            return column("flood_vlans", Integer.class);
-        }
-
-        public ColumnSchema<Bridge, Map> status() {
-            return column("status", Map.class);
-        }
-
-        public ColumnSchema<Bridge, Reference> netflow() {
-            return column("netflow", Reference.class);
-        }
-    }
-
-
     @Test
-    public void testTypedBridgeCreate() throws IOException, InterruptedException, ExecutionException {
-        Bridge bridge = dbSchema.table("Bridge", Bridge.class);
+    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>());
+        rBridge.setName(testBridgeName);
+        rBridge.setStatus(Maps.newHashMap(ImmutableMap.of("key","value")));
+        rBridge.setFloodVlans(Sets.newHashSet(34));
+
         GenericTableSchema ovsTable = dbSchema.table("Open_vSwitch", GenericTableSchema.class);
         ColumnSchema<GenericTableSchema, Set<UUID>> bridges = ovsTable.multiValuedColumn("bridges", UUID.class);
 
-        GenericTableSchema anytable = null;
         String namedUuid = "br_test";
         int insertOperationIndex = 0;
 
         TransactionBuilder transactionBuilder = ovs.transactBuilder()
-                .add(op.insert(bridge)
+                .add(op.insert(rBridgeSchema)
                         .withId(namedUuid)
-                        .value(bridge.name(), testBridgeName))
-                .add(op.update(bridge)
-                        .set(bridge.status(), Maps.newHashMap(ImmutableMap.of("key","value")))
-                        .set(bridge.floodVlans(), 34)
-                        .where(bridge.name().opEqual(testBridgeName))
-                        .and(bridge.name().opEqual(testBridgeName)).build())
+                        .value(rBridge.getNameColumn()))
+                .add(op.update(rBridgeSchema)
+                        .set(rBridge.getStatusColumn())
+                        .set(rBridge.getFloodVlansColumn())
+                        .where(rBridge.getNameColumn().getSchema().opEqual(rBridge.getName()))
+                        .and(rBridge.getNameColumn().getSchema().opEqual(rBridge.getName())).build())
                 .add(op.mutate(ovsTable)
                         .addMutation(bridges, Mutator.INSERT, Sets.newHashSet(new UUID(namedUuid))));
 
@@ -174,5 +152,4 @@ public class OvsDBClientTestITTyped extends OvsdbTestBase {
         // TODO Auto-generated method stub
 
     }
-
 }
diff --git a/library/src/test/java/org/opendaylight/ovsdb/lib/TestBridge.java b/library/src/test/java/org/opendaylight/ovsdb/lib/TestBridge.java
new file mode 100644 (file)
index 0000000..b2cdb49
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * 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 java.util.Map;
+import java.util.Set;
+
+import org.opendaylight.ovsdb.lib.notation.Column;
+import org.opendaylight.ovsdb.lib.notation.UUID;
+import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
+import org.opendaylight.ovsdb.lib.schema.typed.MethodType;
+import org.opendaylight.ovsdb.lib.schema.typed.TypedBaseTable;
+import org.opendaylight.ovsdb.lib.schema.typed.TypedColumn;
+import org.opendaylight.ovsdb.lib.schema.typed.TypedTable;
+
+/**
+ * Statically Typed Bridge Table as defined in ovs-vswitchd.conf.db
+ */
+
+/*
+ * Interface name was set to TestBridge on purpose to test the @TypeTable annotation
+ * functionality of TyperHelper.java
+ */
+@TypedTable(name="Bridge", database="Open_vSwitch")
+public interface TestBridge extends TypedBaseTable {
+    /*
+     * Its a good practice to set the @TypedColumn to these Statically typed Tables & Columns.
+     * Implementations can choose to use GETDATA or GETCOLUMN or both to get the data.
+     * But GETCOLUMN gives more info on ColumnSchema.
+     * The following "name" column is decorated with both GETDATA and GETCOLUMN and the corresponding test
+     * will test both the options.
+     */
+    @TypedColumn(name="name", method=MethodType.GETDATA)
+    public String getName();
+
+    @TypedColumn(name="name", method=MethodType.GETCOLUMN)
+    public Column<GenericTableSchema, String> getNameColumn();
+
+    @TypedColumn(name="name", method=MethodType.SETDATA)
+    public void setName(String name);
+
+   /*
+    * Annotations are NOT added to the Status column on purpose to test the backup
+    * functionality on getter, setter, column name derivation etc.  TyperHelper.java.
+    */
+    public Column<GenericTableSchema, Map<String, String>> getStatusColumn();
+    public void setStatus(Map<String, String> status);
+
+    /*
+     * TypedColumn's name Annotation should override the method name based Column derivation.
+     * The method name and TypedColumn name was kept different on purpose to test the name
+     * resolution priority of TyperHelper.java
+     */
+    @TypedColumn(name="flood_vlans", method=MethodType.GETCOLUMN)
+    public Column<GenericTableSchema, Set<Integer>> getFloodVlansColumn();
+
+    @TypedColumn(name="flood_vlans", method=MethodType.SETDATA)
+    public void setFloodVlans(Set<Integer> vlans);
+
+
+    @TypedColumn(name="ports", method=MethodType.GETCOLUMN)
+    public Column<GenericTableSchema, Set<UUID>> getPortsColumn();
+
+    @TypedColumn(name="ports", method=MethodType.SETDATA)
+    public void setPorts(Set<UUID> ports);
+
+
+    @TypedColumn(name="mirrors", method=MethodType.GETCOLUMN)
+    public Column<GenericTableSchema, Set<UUID>> getMirrorsColumn();
+
+    @TypedColumn(name="mirrors", method=MethodType.SETDATA)
+    public void setMirrors(Set<UUID> mirrors);
+
+
+    @TypedColumn(name="controller", method=MethodType.GETCOLUMN)
+    public Column<GenericTableSchema, Set<UUID>> getControllerColumn();
+
+    @TypedColumn(name="controller", method=MethodType.SETDATA)
+    public void setController(Set<UUID> controller);
+
+
+    @TypedColumn(name="datapath_id", method=MethodType.GETCOLUMN)
+    public Column<GenericTableSchema, Set<String>> getDatapathIdColumn();
+
+    @TypedColumn(name="datapath_id", method=MethodType.SETDATA)
+    public void setDatapathId(Set<String> datapathId);
+
+
+    @TypedColumn(name="datapath_type", method=MethodType.GETCOLUMN)
+    public Column<GenericTableSchema, String> getDatapathTypeColumn();
+
+    @TypedColumn(name="datapath_type", method=MethodType.SETDATA)
+    public void setDatapathType(String datapathType);
+
+
+    @TypedColumn(name="fail_mode", method=MethodType.GETCOLUMN)
+    public Column<GenericTableSchema, Set<String>> getFailModeColumn();
+
+    @TypedColumn(name="fail_mode", method=MethodType.SETDATA)
+    public void setFailMode(Set<String> failMode);
+
+
+    @TypedColumn(name="sflow", method=MethodType.GETCOLUMN)
+    public Column<GenericTableSchema, Set<UUID>> getSflowColumn();
+
+    @TypedColumn(name="sflow", method=MethodType.SETDATA)
+    public void setSflow(Set<UUID> sflow);
+
+
+    @TypedColumn(name="netflow", method=MethodType.GETCOLUMN)
+    public Column<GenericTableSchema, Set<UUID>> getNetflowColumn();
+
+    @TypedColumn(name="netflow", method=MethodType.SETDATA)
+    public void setNetflow(Set<UUID> netflow);
+
+
+    @TypedColumn(name="flow_tables", method=MethodType.GETCOLUMN)
+    public Column<GenericTableSchema, Map<Integer, UUID>> getFlowTablesColumn();
+
+    @TypedColumn(name="flow_tables", method=MethodType.SETDATA)
+    public void setFlowTables(Map<Integer, UUID> flowTables);
+
+
+    @TypedColumn(name="stp_enable", method=MethodType.GETCOLUMN)
+    public Column<GenericTableSchema, Boolean> getStpEnableColumn();
+
+    @TypedColumn(name="stp_enable", method=MethodType.SETDATA)
+    public void setStpEnable(Boolean stp_enable);
+
+
+    @TypedColumn(name="protocols", method=MethodType.GETCOLUMN)
+    public Column<GenericTableSchema, Set<String>> getProtocolsColumn();
+
+    @TypedColumn(name="protocols", method=MethodType.SETDATA)
+    public void setProtocols(Set<String> protocols);
+
+
+    @TypedColumn(name="other_config", method=MethodType.GETCOLUMN)
+    public Column<GenericTableSchema, Map<String, String>> getOtherConfigColumn();
+
+    @TypedColumn(name="other_config", method=MethodType.SETDATA)
+    public void setOtherConfig(Map<String, String> other_config);
+
+
+    @TypedColumn(name="external_ids", method=MethodType.GETCOLUMN)
+    public Column<GenericTableSchema, Map<String, String>> getExternalIdsColumn();
+
+    @TypedColumn(name="external_ids", method=MethodType.SETDATA)
+    public void setExternalIds(Map<String, String> externalIds);
+
+
+    @TypedColumn(name="ipfix", method=MethodType.GETCOLUMN)
+    public Column<GenericTableSchema, Set<UUID>> getIpfixColumn();
+
+    @TypedColumn(name="ipfix", method=MethodType.SETDATA)
+    public void setIpfix(Set<UUID> ipfix);
+}