diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/Callback.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/Callback.java
new file mode 100644
index 0000000..f7ec8b6
--- /dev/null
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/Callback.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.rfc.jsonrpc;
+
+import java.util.List;
+
+import org.onosproject.ovsdb.rfc.message.UpdateNotification;
+
+/**
+ * The callback function interface will be used when the server send to the
+ * client report changes.
+ */
+public interface Callback {
+    /**
+     * The "update" notification is sent by the server to the client to report
+     * changes in tables that are being monitored following a "*monitor"
+     * request.
+     * @param updateNotification the information of the update
+     */
+    void update(UpdateNotification updateNotification);
+
+    /**
+     * The "locked" notification is provided to notify a client that it has been
+     * granted a lock that it had previously requested with the "lock" method.
+     * @param ids the locked ids
+     */
+    void locked(List<String> ids);
+
+    /**
+     * The "stolen" notification is provided to notify a client, which had
+     * previously obtained a lock, that another client has stolen ownership of
+     * that lock.
+     * @param ids the stolen ids
+     */
+    void stolen(List<String> ids);
+
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/JsonReadContext.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/JsonReadContext.java
new file mode 100644
index 0000000..8033f65
--- /dev/null
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/JsonReadContext.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.rfc.jsonrpc;
+
+import java.util.Stack;
+
+/**
+ * Context for decode parameters.
+ */
+public class JsonReadContext {
+    private Stack<Byte> bufStack;
+    private boolean isStartMatch;
+    private int lastReadBytes;
+
+    /**
+     * Constructs a JsonReadContext object. This class only need initial
+     * parameter value for the readToJsonNode method of JsonRpcReaderUtil
+     * entity.
+     */
+    public JsonReadContext() {
+        bufStack = new Stack<Byte>();
+        isStartMatch = false;
+        lastReadBytes = 0;
+    }
+
+    /**
+     * Return bufStack.
+     * @return bufStack
+     */
+    public Stack<Byte> getBufStack() {
+        return bufStack;
+    }
+
+    /**
+     * Set bufStack, used for match the braces and double quotes.
+     * @param bufStack Stack of Byte
+     */
+    public void setBufStack(Stack<Byte> bufStack) {
+        this.bufStack = bufStack;
+    }
+
+    /**
+     * Return isStartMatch.
+     * @return isStartMatch
+     */
+    public boolean isStartMatch() {
+        return isStartMatch;
+    }
+
+    /**
+     * Set isStartMatch.
+     * @param isStartMatch mark whether the matching has started
+     */
+    public void setStartMatch(boolean isStartMatch) {
+        this.isStartMatch = isStartMatch;
+    }
+
+    /**
+     * Return lastReadBytes.
+     * @return lastReadBytes
+     */
+    public int getLastReadBytes() {
+        return lastReadBytes;
+    }
+
+    /**
+     * Set lastReadBytes.
+     * @param lastReadBytes the bytes for last decoding incomplete record
+     */
+    public void setLastReadBytes(int lastReadBytes) {
+        this.lastReadBytes = lastReadBytes;
+    }
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/JsonRpcRequest.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/JsonRpcRequest.java
new file mode 100644
index 0000000..ecff096
--- /dev/null
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/JsonRpcRequest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.rfc.jsonrpc;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.List;
+import java.util.Objects;
+
+import com.google.common.collect.Lists;
+
+/**
+ * Json Rpc Request information that include id,method,params.
+ */
+public class JsonRpcRequest {
+
+    private final String id;
+    private final String method;
+    private final List<Object> params;
+
+    /**
+     * JsonRpcRequest Constructor.
+     * @param id the id node of request information
+     * @param method the method node of request information
+     */
+    public JsonRpcRequest(String id, String method) {
+        checkNotNull(id, "id cannot be null");
+        checkNotNull(method, "method cannot be null");
+        this.id = id;
+        this.method = method;
+        this.params = Lists.newArrayList();
+    }
+
+    /**
+     * JsonRpcRequest Constructor.
+     * @param id the id node of request information
+     * @param method the method node of request information
+     * @param params the params node of request information
+     */
+    public JsonRpcRequest(String id, String method, List<Object> params) {
+        checkNotNull(id, "id cannot be null");
+        checkNotNull(method, "method cannot be null");
+        checkNotNull(params, "params cannot be null");
+        this.id = id;
+        this.method = method;
+        this.params = params;
+    }
+
+    /**
+     * Returns id.
+     * @return id
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * Returns method.
+     * @return method
+     */
+    public String getMethod() {
+        return method;
+    }
+
+    /**
+     * Returns params.
+     * @return params
+     */
+    public List<Object> getParams() {
+        return params;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id, method, params);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof JsonRpcRequest) {
+            final JsonRpcRequest other = (JsonRpcRequest) obj;
+            return Objects.equals(this.id, other.id)
+                    && Objects.equals(this.method, other.method)
+                    && Objects.equals(this.params, other.params);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this).add("id", id).add("method", method)
+                .add("params", params).toString();
+    }
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/JsonRpcResponse.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/JsonRpcResponse.java
new file mode 100644
index 0000000..a2f4541
--- /dev/null
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/JsonRpcResponse.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.rfc.jsonrpc;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.List;
+import java.util.Objects;
+
+import com.google.common.collect.Lists;
+
+/**
+ * Json Rpc Response information that include id,error,result.
+ */
+public class JsonRpcResponse {
+
+    private final String id;
+    private final String error;
+    private final List<Object> result;
+
+    /**
+     * JsonRpcResponse Constructor.
+     * @param id the id node of response information
+     */
+    public JsonRpcResponse(String id) {
+        checkNotNull(id, "id cannot be null");
+        this.id = id;
+        this.error = null;
+        this.result = Lists.newArrayList();
+    }
+
+    /**
+     * JsonRpcResponse Constructor.
+     * @param id the id node of response information
+     * @param error the error node of response information
+     */
+    public JsonRpcResponse(String id, String error) {
+        checkNotNull(id, "id cannot be null");
+        checkNotNull(error, "error cannot be null");
+        this.id = id;
+        this.error = error;
+        this.result = Lists.newArrayList();
+    }
+
+    /**
+     * JsonRpcResponse Constructor.
+     * @param id the id node of response information
+     * @param error the error node of response information
+     * @param result the result node of response information
+     */
+    public JsonRpcResponse(String id, String error, List<Object> result) {
+        checkNotNull(id, "id cannot be null");
+        checkNotNull(error, "error cannot be null");
+        checkNotNull(result, "result cannot be null");
+        this.id = id;
+        this.error = error;
+        this.result = result;
+    }
+
+    /**
+     * Returns id.
+     * @return id
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * Returns error.
+     * @return error
+     */
+    public String getError() {
+        return error;
+    }
+
+    /**
+     * Returns result.
+     * @return result
+     */
+    public List<Object> getResult() {
+        return result;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id, error, result);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof JsonRpcResponse) {
+            final JsonRpcResponse other = (JsonRpcResponse) obj;
+            return Objects.equals(this.id, other.id)
+                    && Objects.equals(this.error, other.error)
+                    && Objects.equals(this.result, other.result);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this).add("id", id).add("error", error)
+                .add("result", result).toString();
+    }
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/OvsdbRPC.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/OvsdbRPC.java
new file mode 100644
index 0000000..5d08b14
--- /dev/null
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/OvsdbRPC.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.rfc.jsonrpc;
+
+import java.util.List;
+
+import org.onosproject.ovsdb.rfc.operations.Operation;
+import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.util.concurrent.ListenableFuture;
+
+/**
+ * The following interface describe the RPC7047's methods that are supported.
+ */
+public interface OvsdbRPC {
+
+    /**
+     * This operation retrieves a database-schema that describes hosted database
+     * db-name.
+     * @param dbnames database name
+     * @return ListenableFuture of JsonNode
+     */
+    ListenableFuture<JsonNode> getSchema(List<String> dbnames);
+
+    /**
+     * The "echo" method can be used by both clients and servers to verify the
+     * liveness of a database connection.
+     * @return return info
+     */
+    ListenableFuture<List<String>> echo();
+
+    /**
+     * The "monitor" request enables a client to replicate tables or subsets of
+     * tables within an OVSDB database by requesting notifications of changes to
+     * those tables and by receiving the complete initial state of a table or a
+     * subset of a table.
+     * @param dbSchema databse schema
+     * @param monitorId a id for monitor
+     * @return ListenableFuture of JsonNode
+     */
+    ListenableFuture<JsonNode> monitor(DatabaseSchema dbSchema, String monitorId);
+
+    /**
+     * This operation retrieves an array whose elements are the names of the
+     * databases that can be accessed over this management protocol connection.
+     * @return database names
+     */
+    ListenableFuture<List<String>> listDbs();
+
+    /**
+     * This RPC method causes the database server to execute a series of
+     * operations in the specified order on a given database.
+     * @param dbSchema database schema
+     * @param operations the operations to execute
+     * @return result the transact result
+     */
+    ListenableFuture<List<JsonNode>> transact(DatabaseSchema dbSchema,
+                                              List<Operation> operations);
+
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Bridge.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Bridge.java
new file mode 100644
index 0000000..bd589f0
--- /dev/null
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Bridge.java
@@ -0,0 +1,559 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.rfc.table;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.onosproject.ovsdb.rfc.notation.Column;
+import org.onosproject.ovsdb.rfc.notation.Row;
+import org.onosproject.ovsdb.rfc.notation.UUID;
+import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
+import org.onosproject.ovsdb.rfc.tableservice.AbstractOvsdbTableService;
+import org.onosproject.ovsdb.rfc.tableservice.ColumnDescription;
+
+/**
+ * This class provides operations of Bridge Table.
+ */
+public class Bridge extends AbstractOvsdbTableService {
+
+    /**
+     * Bridge table column name.
+     */
+    public enum BridgeColumn {
+        NAME("name"), DATAPATHTYPE("datapath_type"), DATAPATHID("datapath_id"),
+        STPENABLE("stpenable"), PORTS("ports"), MIRRORS("mirrors"),
+        NETFLOW("netflow"), SFLOW("sflow"), IPFIX("ipfix"),
+        CONTROLLER("controller"), PROTOCOLS("protocols"),
+        FAILMODE("fail_mode"), STATUS("status"), OTHERCONFIG("other_config"),
+        EXTERNALIDS("external_ids"), FLOODVLANS("flood_vlans"),
+        FLOWTABLES("flow_tables");
+
+        private final String columnName;
+
+        private BridgeColumn(String columnName) {
+            this.columnName = columnName;
+        }
+
+        /**
+         * Returns the table column name for BridgeColumn.
+         * @return the table column name
+         */
+        public String columnName() {
+            return columnName;
+        }
+    }
+
+    /**
+     * Constructs a Bridge object. Generate Bridge Table Description.
+     * @param dbSchema DatabaseSchema
+     * @param row Row
+     */
+    public Bridge(DatabaseSchema dbSchema, Row row) {
+        super(dbSchema, row, OvsdbTable.BRIDGE, VersionNum.VERSION100);
+    }
+
+    /**
+     * Get the Column entity which column name is "name" from the Row entity of
+     * attributes.
+     * @return the Column entity which column name is "name"
+     */
+    public Column getNameColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.NAME
+                                                                     .columnName(),
+                                                             "getNameColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "name" to the Row entity of
+     * attributes.
+     * @param name the column data which column name is "name"
+     */
+    public void setName(String name) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.NAME
+                                                                     .columnName(),
+                                                             "setName",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, name);
+    }
+
+    /**
+     * Get the column data which column name is "name" from the Row entity of
+     * attributes.
+     * @return the column data which column name is "name"
+     */
+    public String getName() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.NAME
+                                                                     .columnName(),
+                                                             "getName",
+                                                             VersionNum.VERSION100);
+        return (String) super.getDataHandler(columndesc);
+    }
+
+    /**
+     * Get the Column entity which column name is "datapath_type" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "datapath_type"
+     */
+    public Column getDatapathTypeColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.DATAPATHTYPE
+                                                                     .columnName(),
+                                                             "getDatapathTypeColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "datapath_type" to the Row
+     * entity of attributes.
+     * @param datapathType the column data which column name is "datapath_type"
+     */
+    public void setDatapathType(String datapathType) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.DATAPATHTYPE
+                                                                     .columnName(),
+                                                             "setDatapathType",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, datapathType);
+    }
+
+    /**
+     * Get the Column entity which column name is "datapath_id" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "datapath_id"
+     */
+    public Column getDatapathIdColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.DATAPATHID
+                                                                     .columnName(),
+                                                             "getDatapathIdColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "datapath_id" to the Row entity
+     * of attributes.
+     * @param datapathId the column data which column name is "datapath_id"
+     */
+    public void setDatapathId(Set<String> datapathId) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.DATAPATHID
+                                                                     .columnName(),
+                                                             "setDatapathId",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, datapathId);
+    }
+
+    /**
+     * Get the Column entity which column name is "stpenable" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "stpenable"
+     */
+    public Column getStpEnableColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.STPENABLE
+                                                                     .columnName(),
+                                                             "getStpEnableColumn",
+                                                             VersionNum.VERSION620);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "stpenable" to the Row entity of
+     * attributes.
+     * @param stpenable the column data which column name is "stpenable"
+     */
+    public void setStpEnable(Boolean stpenable) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.STPENABLE
+                                                                     .columnName(),
+                                                             "setStpEnable",
+                                                             VersionNum.VERSION620);
+        super.setDataHandler(columndesc, stpenable);
+    }
+
+    /**
+     * Get the Column entity which column name is "ports" from the Row entity of
+     * attributes.
+     * @return the Column entity which column name is "ports"
+     */
+    public Column getPortsColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.PORTS
+                                                                     .columnName(),
+                                                             "getPortsColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "ports" to the Row entity of
+     * attributes.
+     * @param ports the column data which column name is "ports"
+     */
+    public void setPorts(Set<UUID> ports) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.PORTS
+                                                                     .columnName(),
+                                                             "setPorts",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, ports);
+    }
+
+    /**
+     * Get the Column entity which column name is "mirrors" from the Row entity
+     * of attributes.
+     * @return the Column entity which column name is "mirrors"
+     */
+    public Column getMirrorsColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.MIRRORS
+                                                                     .columnName(),
+                                                             "getMirrorsColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "mirrors" to the Row entity of
+     * attributes.
+     * @param mirrors the column data which column name is "mirrors"
+     */
+    public void setMirrors(Set<UUID> mirrors) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.MIRRORS
+                                                                     .columnName(),
+                                                             "setMirrors",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, mirrors);
+    }
+
+    /**
+     * Get the Column entity which column name is "netflow" from the Row entity
+     * of attributes.
+     * @return the Column entity which column name is "netflow"
+     */
+    public Column getNetflowColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.NETFLOW
+                                                                     .columnName(),
+                                                             "getNetflowColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "netflow" to the Row entity of
+     * attributes.
+     * @param netflow the column data which column name is "netflow"
+     */
+    public void setNetflow(Set<UUID> netflow) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.NETFLOW
+                                                                     .columnName(),
+                                                             "setNetflow",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, netflow);
+    }
+
+    /**
+     * Get the Column entity which column name is "sflow" from the Row entity of
+     * attributes.
+     * @return the Column entity which column name is "sflow"
+     */
+    public Column getSflowColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.SFLOW
+                                                                     .columnName(),
+                                                             "getSflowColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "sflow" to the Row entity of
+     * attributes.
+     * @param sflow the column data which column name is "sflow"
+     */
+    public void setSflow(Set<UUID> sflow) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.SFLOW
+                                                                     .columnName(),
+                                                             "setSflow",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, sflow);
+    }
+
+    /**
+     * Get the Column entity which column name is "ipfix" from the Row entity of
+     * attributes.
+     * @return the Column entity which column name is "ipfix"
+     */
+    public Column getIpfixColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.IPFIX
+                                                                     .columnName(),
+                                                             "getIpfixColumn",
+                                                             VersionNum.VERSION710);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "ipfix" to the Row entity of
+     * attributes.
+     * @param ipfix the column data which column name is "ipfix"
+     */
+    public void setIpfix(Set<UUID> ipfix) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.IPFIX
+                                                                     .columnName(),
+                                                             "setIpfix",
+                                                             VersionNum.VERSION710);
+        super.setDataHandler(columndesc, ipfix);
+    }
+
+    /**
+     * Get the Column entity which column name is "controller" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "controller"
+     */
+    public Column getControllerColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.CONTROLLER
+                                                                     .columnName(),
+                                                             "getControllerColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "controller" to the Row entity
+     * of attributes.
+     * @param controller the column data which column name is "controller"
+     */
+    public void setController(Set<UUID> controller) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.CONTROLLER
+                                                                     .columnName(),
+                                                             "setController",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, controller);
+    }
+
+    /**
+     * Get the Column entity which column name is "protocols" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "protocols"
+     */
+    public Column getProtocolsColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.PROTOCOLS
+                                                                     .columnName(),
+                                                             "getProtocolsColumn",
+                                                             VersionNum.VERSION6111);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "protocols" to the Row entity of
+     * attributes.
+     * @param protocols the column data which column name is "protocols"
+     */
+    public void setProtocols(Set<String> protocols) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.PROTOCOLS
+                                                                     .columnName(),
+                                                             "setProtocols",
+                                                             VersionNum.VERSION6111);
+        super.setDataHandler(columndesc, protocols);
+    }
+
+    /**
+     * Get the Column entity which column name is "fail_mode" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "fail_mode"
+     */
+    public Column getFailModeColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.FAILMODE
+                                                                     .columnName(),
+                                                             "getFailModeColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "fail_mode" to the Row entity of
+     * attributes.
+     * @param failMode the column data which column name is "fail_mode"
+     */
+    public void setFailMode(Set<String> failMode) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.FAILMODE
+                                                                     .columnName(),
+                                                             "setFailMode",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, failMode);
+    }
+
+    /**
+     * Get the Column entity which column name is "status" from the Row entity
+     * of attributes.
+     * @return the Column entity which column name is "status"
+     */
+    public Column getStatusColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.STATUS
+                                                                     .columnName(),
+                                                             "getStatusColumn",
+                                                             VersionNum.VERSION620);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "status" to the Row entity of
+     * attributes.
+     * @param status the column data which column name is "status"
+     */
+    public void setStatus(Map<String, String> status) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.STATUS
+                                                                     .columnName(),
+                                                             "setStatus",
+                                                             VersionNum.VERSION620);
+        super.setDataHandler(columndesc, status);
+    }
+
+    /**
+     * Get the Column entity which column name is "other_config" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "other_config"
+     */
+    public Column getOtherConfigColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.OTHERCONFIG
+                                                                     .columnName(),
+                                                             "getOtherConfigColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "other_config" to the Row entity
+     * of attributes.
+     * @param otherConfig the column data which column name is "other_config"
+     */
+    public void setOtherConfig(Map<String, String> otherConfig) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.OTHERCONFIG
+                                                                     .columnName(),
+                                                             "setOtherConfig",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, otherConfig);
+    }
+
+    /**
+     * Get the Column entity which column name is "external_ids" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "external_ids"
+     */
+    public Column getExternalIdsColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.EXTERNALIDS
+                                                                     .columnName(),
+                                                             "getExternalIdsColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "external_ids" to the Row entity
+     * of attributes.
+     * @param externalIds the column data which column name is "external_ids"
+     */
+    public void setExternalIds(Map<String, String> externalIds) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.EXTERNALIDS
+                                                                     .columnName(),
+                                                             "setExternalIds",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, externalIds);
+    }
+
+    /**
+     * Get the Column entity which column name is "flood_vlans" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "flood_vlans"
+     */
+    public Column getFloodVlansColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.FLOODVLANS
+                                                                     .columnName(),
+                                                             "getFloodVlansColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "flood_vlans" to the Row entity
+     * of attributes.
+     * @param vlans the column data which column name is "flood_vlans"
+     */
+    public void setFloodVlans(Set<Long> vlans) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.FLOODVLANS
+                                                                     .columnName(),
+                                                             "setFloodVlans",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, vlans);
+    }
+
+    /**
+     * Get the Column entity which column name is "flow_tables" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "flow_tables"
+     */
+    public Column getFlowTablesColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.FLOWTABLES
+                                                                     .columnName(),
+                                                             "getFlowTablesColumn",
+                                                             VersionNum.VERSION650);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "flow_tables" to the Row entity
+     * of attributes.
+     * @param flowTables the column data which column name is "flow_tables"
+     */
+    public void setFlowTables(Map<Long, UUID> flowTables) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             BridgeColumn.FLOWTABLES
+                                                                     .columnName(),
+                                                             "setFlowTables",
+                                                             VersionNum.VERSION650);
+        super.setDataHandler(columndesc, flowTables);
+    }
+
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Controller.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Controller.java
new file mode 100644
index 0000000..912526c
--- /dev/null
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Controller.java
@@ -0,0 +1,556 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.rfc.table;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.onosproject.ovsdb.rfc.notation.Column;
+import org.onosproject.ovsdb.rfc.notation.Row;
+import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
+import org.onosproject.ovsdb.rfc.tableservice.AbstractOvsdbTableService;
+import org.onosproject.ovsdb.rfc.tableservice.ColumnDescription;
+
+/**
+ * This class provides operations of Controller Table.
+ */
+public class Controller extends AbstractOvsdbTableService {
+
+    /**
+     * Controller table column name.
+     */
+    public enum ControllerColumn {
+        TARGET("target"), BURSTLIMIT("controller_burst_limit"),
+        RATELIMIT("controller_rate_limit"), CONNECTIONMODE("connection_mode"),
+        ENABLEASYNCMESSAGES("enable_async_messages"),
+        EXTERNALIDS("external_ids"), LOCALNETMASK("local_netmask"),
+        LOCALGATEWAY("local_gateway"), STATUS("status"), ROLE("role"),
+        INACTIVITYPROBE("inactivity_probe"), ISCONNECTED("is_connected"),
+        OTHERCONFIG("other_config"), MAXBACKOFF("max_backoff"),
+        LOCALIP("local_ip"),
+        DISCOVERUPDATERESOLVCONF("discover_update_resolv_conf"),
+        DISCOVERACCEPTREGEX("discover_accept_regex");
+
+        private final String columnName;
+
+        private ControllerColumn(String columnName) {
+            this.columnName = columnName;
+        }
+
+        /**
+         * Returns the table column name for ControllerColumn.
+         * @return the table column name
+         */
+        public String columnName() {
+            return columnName;
+        }
+    }
+
+    /**
+     * Constructs a Controller object. Generate Controller Table Description.
+     * @param dbSchema DatabaseSchema
+     * @param row Row
+     */
+    public Controller(DatabaseSchema dbSchema, Row row) {
+        super(dbSchema, row, OvsdbTable.CONTROLLER, VersionNum.VERSION100);
+    }
+
+    /**
+     * Get the Column entity which column name is "target" from the Row entity
+     * of attributes.
+     * @return the Column entity which column name is "target"
+     */
+    public Column getTargetColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             ControllerColumn.TARGET
+                                                                     .columnName(),
+                                                             "getTargetColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "target" to the Row entity of
+     * attributes.
+     * @param target the column data which column name is "target"
+     */
+    public void setTarget(String target) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             ControllerColumn.TARGET
+                                                                     .columnName(),
+                                                             "setTarget",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, target);
+    }
+
+    /**
+     * Get the Column entity which column name is "controller_burst_limit" from
+     * the Row entity of attributes.
+     * @return the Column entity which column name is "controller_burst_limit"
+     */
+    public Column getBurstLimitColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             ControllerColumn.BURSTLIMIT
+                                                                     .columnName(),
+                                                             "getBurstLimitColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "controller_burst_limit" to the
+     * Row entity of attributes.
+     * @param burstLimit the column data which column name is
+     *            "controller_burst_limit"
+     */
+    public void setBurstLimit(Long burstLimit) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             ControllerColumn.BURSTLIMIT
+                                                                     .columnName(),
+                                                             "setBurstLimit",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, burstLimit);
+    }
+
+    /**
+     * Get the Column entity which column name is "controller_rate_limit" from
+     * the Row entity of attributes.
+     * @return the Column entity which column name is "controller_rate_limit"
+     */
+    public Column getRateLimitColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             ControllerColumn.RATELIMIT
+                                                                     .columnName(),
+                                                             "getRateLimitColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "controller_rate_limit" to the
+     * Row entity of attributes.
+     * @param rateLimit the column data which column name is
+     *            "controller_rate_limit"
+     */
+    public void setRateLimit(Long rateLimit) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             "controller_rate_limit",
+                                                             "setRateLimit",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, rateLimit);
+    }
+
+    /**
+     * Get the Column entity which column name is "connection_mode" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "connection_mode"
+     */
+    public Column getConnectionModeColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             "connection_mode",
+                                                             "getConnectionModeColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "connection_mode" to the Row
+     * entity of attributes.
+     * @param connectionMode the column data which column name is
+     *            "connection_mode"
+     */
+    public void setConnectionMode(Set<String> connectionMode) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             ControllerColumn.RATELIMIT
+                                                                     .columnName(),
+                                                             "setConnectionMode",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, connectionMode);
+    }
+
+    /**
+     * Get the Column entity which column name is "enable_async_messages" from
+     * the Row entity of attributes.
+     * @return the Column entity which column name is "enable_async_messages"
+     */
+    public Column getEnableAsyncMessagesColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             ControllerColumn.ENABLEASYNCMESSAGES
+                                                                     .columnName(),
+                                                             "getEnableAsyncMessagesColumn",
+                                                             VersionNum.VERSION670);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "enable_async_messages" to the
+     * Row entity of attributes.
+     * @param enableAsyncMessages the column data which column name is
+     *            "enable_async_messages"
+     */
+    public void setEnableAsyncMessages(Set<Boolean> enableAsyncMessages) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             ControllerColumn.ENABLEASYNCMESSAGES
+                                                                     .columnName(),
+                                                             "setEnableAsyncMessages",
+                                                             VersionNum.VERSION670);
+        super.setDataHandler(columndesc, enableAsyncMessages);
+    }
+
+    /**
+     * Get the Column entity which column name is "external_ids" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "external_ids"
+     */
+    public Column getExternalIdsColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             ControllerColumn.EXTERNALIDS
+                                                                     .columnName(),
+                                                             "getExternalIdsColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "external_ids" to the Row entity
+     * of attributes.
+     * @param externalIds the column data which column name is "external_ids"
+     */
+    public void setExternalIds(Map<String, String> externalIds) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             ControllerColumn.EXTERNALIDS
+                                                                     .columnName(),
+                                                             "setExternalIds",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, externalIds);
+    }
+
+    /**
+     * Get the Column entity which column name is "local_netmask" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "local_netmask"
+     */
+    public Column getLocalNetmaskColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             ControllerColumn.LOCALNETMASK
+                                                                     .columnName(),
+                                                             "getLocalNetmaskColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "local_netmask" to the Row
+     * entity of attributes.
+     * @param localNetmask the column data which column name is "local_netmask"
+     */
+    public void setLocalNetmask(Set<String> localNetmask) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             ControllerColumn.LOCALNETMASK
+                                                                     .columnName(),
+                                                             "setLocalNetmask",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, localNetmask);
+    }
+
+    /**
+     * Get the Column entity which column name is "local_gateway" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "local_gateway"
+     */
+    public Column getLocalGatewayColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             ControllerColumn.LOCALGATEWAY
+                                                                     .columnName(),
+                                                             "getLocalGatewayColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "local_gateway" to the Row
+     * entity of attributes.
+     * @param localGateway the column data which column name is "local_gateway"
+     */
+    public void setLocalGateway(Set<String> localGateway) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             ControllerColumn.LOCALGATEWAY
+                                                                     .columnName(),
+                                                             "setLocalGateway",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, localGateway);
+    }
+
+    /**
+     * Get the Column entity which column name is "status" from the Row entity
+     * of attributes.
+     * @return the Column entity which column name is "status"
+     */
+    public Column getStatusColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             ControllerColumn.STATUS
+                                                                     .columnName(),
+                                                             "getStatusColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "status" to the Row entity of
+     * attributes.
+     * @param status the column data which column name is "status"
+     */
+    public void setStatus(Map<String, String> status) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             ControllerColumn.STATUS
+                                                                     .columnName(),
+                                                             "setStatus",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, status);
+    }
+
+    /**
+     * Get the Column entity which column name is "role" from the Row entity of
+     * attributes.
+     * @return the Column entity which column name is "role"
+     */
+    public Column getRoleColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             ControllerColumn.ROLE
+                                                                     .columnName(),
+                                                             "getRoleColumn",
+                                                             VersionNum.VERSION110);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "role" to the Row entity of
+     * attributes.
+     * @param role the column data which column name is "role"
+     */
+    public void setRole(Set<String> role) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             ControllerColumn.ROLE
+                                                                     .columnName(),
+                                                             "setRole",
+                                                             VersionNum.VERSION110);
+        super.setDataHandler(columndesc, role);
+    }
+
+    /**
+     * Get the Column entity which column name is "inactivity_probe" from the
+     * Row entity of attributes.
+     * @return the Column entity which column name is "inactivity_probe"
+     */
+    public Column getInactivityProbeColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             ControllerColumn.INACTIVITYPROBE
+                                                                     .columnName(),
+                                                             "getInactivityProbeColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "inactivity_probe" to the Row
+     * entity of attributes.
+     * @param inactivityProbe the column data which column name is
+     *            "inactivity_probe"
+     */
+    public void setInactivityProbe(Set<Long> inactivityProbe) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             ControllerColumn.INACTIVITYPROBE
+                                                                     .columnName(),
+                                                             "setInactivityProbe",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, inactivityProbe);
+    }
+
+    /**
+     * Get the Column entity which column name is "is_connected" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "is_connected"
+     */
+    public Column getIsConnectedColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             ControllerColumn.ISCONNECTED
+                                                                     .columnName(),
+                                                             "getIsConnectedColumn",
+                                                             VersionNum.VERSION110);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "is_connected" to the Row entity
+     * of attributes.
+     * @param isConnected the column data which column name is "is_connected"
+     */
+    public void setIsConnected(Boolean isConnected) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             ControllerColumn.ISCONNECTED
+                                                                     .columnName(),
+                                                             "setIsConnected",
+                                                             VersionNum.VERSION110);
+        super.setDataHandler(columndesc, isConnected);
+    }
+
+    /**
+     * Get the Column entity which column name is "other_config" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "other_config"
+     */
+    public Column getOtherConfigColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             ControllerColumn.OTHERCONFIG
+                                                                     .columnName(),
+                                                             "getOtherConfigColumn",
+                                                             VersionNum.VERSION680);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "other_config" to the Row entity
+     * of attributes.
+     * @param otherConfig the column data which column name is "other_config"
+     */
+    public void setOtherConfig(Map<String, String> otherConfig) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             ControllerColumn.OTHERCONFIG
+                                                                     .columnName(),
+                                                             "setOtherConfig",
+                                                             VersionNum.VERSION680);
+        super.setDataHandler(columndesc, otherConfig);
+    }
+
+    /**
+     * Get the Column entity which column name is "max_backoff" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "max_backoff"
+     */
+    public Column getMaxBackoffColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             ControllerColumn.MAXBACKOFF
+                                                                     .columnName(),
+                                                             "getMaxBackoffColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "max_backoff" to the Row entity
+     * of attributes.
+     * @param maxBackoff the column data which column name is "max_backoff"
+     */
+    public void setMaxBackoff(Long maxBackoff) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             ControllerColumn.MAXBACKOFF
+                                                                     .columnName(),
+                                                             "setMaxBackoff",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, maxBackoff);
+    }
+
+    /**
+     * Get the Column entity which column name is "local_ip" from the Row entity
+     * of attributes.
+     * @return the Column entity which column name is "local_ip"
+     */
+    public Column getLocalIpColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             ControllerColumn.LOCALIP
+                                                                     .columnName(),
+                                                             "getLocalIpColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "local_ip" to the Row entity of
+     * attributes.
+     * @param localIp the column data which column name is "local_ip"
+     */
+    public void setLocalIp(Set<String> localIp) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             ControllerColumn.LOCALIP
+                                                                     .columnName(),
+                                                             "setLocalIp",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, localIp);
+    }
+
+    /**
+     * Get the Column entity which column name is "discover_update_resolv_conf"
+     * from the Row entity of attributes.
+     * @return the Column entity which column name is
+     *         "discover_update_resolv_conf"
+     */
+    public Column getDiscoverUpdateResolvConfColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             ControllerColumn.DISCOVERUPDATERESOLVCONF
+                                                                     .columnName(),
+                                                             "getDiscoverUpdateResolvConfColumn",
+                                                             VersionNum.VERSION100,
+                                                             VersionNum.VERSION300);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "discover_update_resolv_conf" to
+     * the Row entity of attributes.
+     * @param discoverUpdateResolvConf the column data which column name is
+     *            "discover_update_resolv_conf"
+     */
+    public void setDiscoverUpdateResolvConf(Set<String> discoverUpdateResolvConf) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             ControllerColumn.DISCOVERUPDATERESOLVCONF
+                                                                     .columnName(),
+                                                             "setDiscoverUpdateResolvConf",
+                                                             VersionNum.VERSION100,
+                                                             VersionNum.VERSION300);
+        super.setDataHandler(columndesc, discoverUpdateResolvConf);
+    }
+
+    /**
+     * Get the Column entity which column name is "discover_accept_regex" from
+     * the Row entity of attributes.
+     * @return the Column entity which column name is "discover_accept_regex"
+     */
+    public Column getDiscoverAcceptRegexColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             ControllerColumn.DISCOVERACCEPTREGEX
+                                                                     .columnName(),
+                                                             "getDiscoverAcceptRegexColumn",
+                                                             VersionNum.VERSION100,
+                                                             VersionNum.VERSION300);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "discover_accept_regex" to the
+     * Row entity of attributes.
+     * @param discoverAcceptRegex the column data which column name is
+     *            "discover_accept_regex"
+     */
+    public void setDiscoverAcceptRegex(Set<String> discoverAcceptRegex) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             ControllerColumn.DISCOVERACCEPTREGEX
+                                                                     .columnName(),
+                                                             "setDiscoverAcceptRegex",
+                                                             VersionNum.VERSION100,
+                                                             VersionNum.VERSION300);
+        super.setDataHandler(columndesc, discoverAcceptRegex);
+    }
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Interface.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Interface.java
new file mode 100644
index 0000000..ee94628
--- /dev/null
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Interface.java
@@ -0,0 +1,1024 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.rfc.table;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.onosproject.ovsdb.rfc.notation.Column;
+import org.onosproject.ovsdb.rfc.notation.Row;
+import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
+import org.onosproject.ovsdb.rfc.tableservice.AbstractOvsdbTableService;
+import org.onosproject.ovsdb.rfc.tableservice.ColumnDescription;
+
+/**
+ * This class provides operations of Interface Table.
+ */
+public class Interface extends AbstractOvsdbTableService {
+
+    /**
+     * Interface table column name.
+     */
+    public enum InterfaceColumn {
+        NAME("name"), TYPE("type"), OPTIONS("options"),
+        INGRESSPOLICINGRATE("ingress_policing_rate"),
+        INGRESSPOLICINGBURST("ingress_policing_burst"), MACINUSE("mac_in_use"),
+        MAC("mac"), IFINDEX("ifindex"), EXTERNALIDS("external_ids"),
+        OFPORT("ofport"), OFPORTREQUEST("ofport_request"), BFD("bfd"),
+        BFDSTATUS("bfd_status"), MONITOR("monitor"), CFMMPID("cfm_mpid"),
+        CFMREMOTEMPID("cfm_remote_mpid"), CFMREMOTEMPIDS("cfm_remote_mpids"),
+        CFMFLAPCOUNT("cfm_flap_count"), CFMFAULT("cfm_fault"),
+        CFMFAULTSTATUS("cfm_fault_status"),
+        CFMREMOTEOPSTATE("cfm_remote_opstate"), CFMHEALTH("cfm_health"),
+        LACPCURRENT("lacp_current"), OTHERCONFIG("other_config"),
+        STATISTICS("statistics"), STATUS("status"), ADMINSTATE("admin_state"),
+        LINKSTATE("link_state"), LINKRESETS("link_resets"),
+        LINKSPEED("link_speed"), DUPLEX("duplex"), MTU("mtu"), ERROR("error");
+
+        private final String columnName;
+
+        private InterfaceColumn(String columnName) {
+            this.columnName = columnName;
+        }
+
+        /**
+         * Returns the table column name for InterfaceColumn.
+         * @return the table column name
+         */
+        public String columnName() {
+            return columnName;
+        }
+    }
+
+    /**
+     * Constructs a Interface object. Generate Interface Table Description.
+     * @param dbSchema DatabaseSchema
+     * @param row Row
+     */
+    public Interface(DatabaseSchema dbSchema, Row row) {
+        super(dbSchema, row, OvsdbTable.INTERFACE, VersionNum.VERSION100);
+    }
+
+    /**
+     * Get the Column entity which column name is "name" from the Row entity of
+     * attributes.
+     * @return the Column entity which column name is "name"
+     */
+    public Column getNameColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.NAME
+                                                                     .columnName(),
+                                                             "getNameColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "name" to the Row entity of
+     * attributes.
+     * @param name the column data which column name is "name"
+     */
+    public void setName(String name) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.NAME
+                                                                     .columnName(),
+                                                             "setName",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, name);
+    }
+
+    /**
+     * Get the column data which column name is "name" from the Row entity of
+     * attributes.
+     * @return the column data which column name is "name"
+     */
+    public String getName() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.NAME
+                                                                     .columnName(),
+                                                             "getName",
+                                                             VersionNum.VERSION100);
+        return (String) super.getDataHandler(columndesc);
+    }
+
+    /**
+     * Get the Column entity which column name is "type" from the Row entity of
+     * attributes.
+     * @return the Column entity which column name is "type"
+     */
+    public Column getTypeColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.TYPE
+                                                                     .columnName(),
+                                                             "getTypeColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "type" to the Row entity of
+     * attributes.
+     * @param type the column data which column name is "type"
+     */
+    public void setType(String type) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.TYPE
+                                                                     .columnName(),
+                                                             "setType",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, type);
+    }
+
+    /**
+     * Get the Column entity which column name is "options" from the Row entity
+     * of attributes.
+     * @return the Column entity which column name is "options"
+     */
+    public Column getOptionsColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.OPTIONS
+                                                                     .columnName(),
+                                                             "getOptionsColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "options" to the Row entity of
+     * attributes.
+     * @param options the column data which column name is "options"
+     */
+    public void setOptions(Map<String, String> options) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.OPTIONS
+                                                                     .columnName(),
+                                                             "setOptions",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, options);
+    }
+
+    /**
+     * Get the Column entity which column name is "ingress_policing_rate" from
+     * the Row entity of attributes.
+     * @return the Column entity which column name is "ingress_policing_rate"
+     */
+    public Column getIngressPolicingRateColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.INGRESSPOLICINGRATE
+                                                                     .columnName(),
+                                                             "getIngressPolicingRateColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "ingress_policing_rate" to the
+     * Row entity of attributes.
+     * @param ingressPolicingRate the column data which column name is
+     *            "ingress_policing_rate"
+     */
+    public void setIngressPolicingRate(Set<Long> ingressPolicingRate) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.INGRESSPOLICINGRATE
+                                                                     .columnName(),
+                                                             "setIngressPolicingRate",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, ingressPolicingRate);
+    }
+
+    /**
+     * Get the Column entity which column name is "ingress_policing_burst" from
+     * the Row entity of attributes.
+     * @return the Column entity which column name is "ingress_policing_burst"
+     */
+    public Column getIngressPolicingBurstColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.INGRESSPOLICINGBURST
+                                                                     .columnName(),
+                                                             "getIngressPolicingBurstColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "ingress_policing_burst" to the
+     * Row entity of attributes.
+     * @param ingressPolicingBurst the column data which column name is
+     *            "ingress_policing_burst"
+     */
+    public void setIngressPolicingBurst(Set<Long> ingressPolicingBurst) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.INGRESSPOLICINGBURST
+                                                                     .columnName(),
+                                                             "setIngressPolicingBurst",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, ingressPolicingBurst);
+    }
+
+    /**
+     * Get the Column entity which column name is "mac_in_use" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "mac_in_use"
+     */
+    public Column getMacInUseColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.MACINUSE
+                                                                     .columnName(),
+                                                             "getMacInUseColumn",
+                                                             VersionNum.VERSION710);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "mac_in_use" to the Row entity
+     * of attributes.
+     * @param macInUse the column data which column name is "mac_in_use"
+     */
+    public void setMacInUse(Set<String> macInUse) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.MACINUSE
+                                                                     .columnName(),
+                                                             "setMacInUse",
+                                                             VersionNum.VERSION710);
+        super.setDataHandler(columndesc, macInUse);
+    }
+
+    /**
+     * Get the Column entity which column name is "mac" from the Row entity of
+     * attributes.
+     * @return the Column entity which column name is "mac"
+     */
+    public Column getMacColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.MAC
+                                                                     .columnName(),
+                                                             "getMacColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "mac" to the Row entity of
+     * attributes.
+     * @param mac the column data which column name is "mac"
+     */
+    public void setMac(Set<String> mac) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.MAC
+                                                                     .columnName(),
+                                                             "setMac",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, mac);
+    }
+
+    /**
+     * Get the Column entity which column name is "ifindex" from the Row entity
+     * of attributes.
+     * @return the Column entity which column name is "ifindex"
+     */
+    public Column getIfIndexColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.IFINDEX
+                                                                     .columnName(),
+                                                             "getIfIndexColumn",
+                                                             VersionNum.VERSION721);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "ifindex" to the Row entity of
+     * attributes.
+     * @param ifIndex the column data which column name is "ifindex"
+     */
+    public void setIfIndex(Long ifIndex) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.IFINDEX
+                                                                     .columnName(),
+                                                             "setIfIndex",
+                                                             VersionNum.VERSION721);
+        super.setDataHandler(columndesc, ifIndex);
+    }
+
+    /**
+     * Get the Column entity which column name is "external_ids" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "external_ids"
+     */
+    public Column getExternalIdsColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.EXTERNALIDS
+                                                                     .columnName(),
+                                                             "getExternalIdsColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "external_ids" to the Row entity
+     * of attributes.
+     * @param externalIds the column data which column name is "external_ids"
+     */
+    public void setExternalIds(Map<String, String> externalIds) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.EXTERNALIDS
+                                                                     .columnName(),
+                                                             "setExternalIds",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, externalIds);
+    }
+
+    /**
+     * Get the Column entity which column name is "ofport" from the Row entity
+     * of attributes.
+     * @return the Column entity which column name is "ofport"
+     */
+    public Column getOpenFlowPortColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.OFPORT
+                                                                     .columnName(),
+                                                             "getOpenFlowPortColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "ofport" to the Row entity of
+     * attributes.
+     * @param openFlowPort the column data which column name is "ofport"
+     */
+    public void setOpenFlowPort(Set<Long> openFlowPort) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.OFPORT
+                                                                     .columnName(),
+                                                             "setOpenFlowPort",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, openFlowPort);
+    }
+
+    /**
+     * Get the Column entity which column name is "ofport_request" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "ofport_request"
+     */
+    public Column getOpenFlowPortRequestColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.OFPORTREQUEST
+                                                                     .columnName(),
+                                                             "getOpenFlowPortRequestColumn",
+                                                             VersionNum.VERSION620);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "ofport_request" to the Row
+     * entity of attributes.
+     * @param openFlowPortRequest the column data which column name is
+     *            "ofport_request"
+     */
+    public void setOpenFlowPortRequest(String openFlowPortRequest) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.OFPORTREQUEST
+                                                                     .columnName(),
+                                                             "setOpenFlowPortRequest",
+                                                             VersionNum.VERSION620);
+        super.setDataHandler(columndesc, openFlowPortRequest);
+    }
+
+    /**
+     * Get the Column entity which column name is "bfd" from the Row entity of
+     * attributes.
+     * @return the Column entity which column name is "bfd"
+     */
+    public Column getBfdColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.BFD
+                                                                     .columnName(),
+                                                             "getBfdColumn",
+                                                             VersionNum.VERSION720);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "bfd" to the Row entity of
+     * attributes.
+     * @param bfd the column data which column name is "bfd"
+     */
+    public void setBfd(Map<String, String> bfd) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.BFD
+                                                                     .columnName(),
+                                                             "setBfd",
+                                                             VersionNum.VERSION720);
+        super.setDataHandler(columndesc, bfd);
+    }
+
+    /**
+     * Get the Column entity which column name is "bfd_status" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "bfd_status"
+     */
+    public Column getBfdStatusColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.BFDSTATUS
+                                                                     .columnName(),
+                                                             "getBfdStatusColumn",
+                                                             VersionNum.VERSION720);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "bfd_status" to the Row entity
+     * of attributes.
+     * @param bfdStatus the column data which column name is "bfd_status"
+     */
+    public void setBfdStatus(Map<String, String> bfdStatus) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.BFDSTATUS
+                                                                     .columnName(),
+                                                             "setBfdStatus",
+                                                             VersionNum.VERSION720);
+        super.setDataHandler(columndesc, bfdStatus);
+    }
+
+    /**
+     * Get the Column entity which column name is "monitor" from the Row entity
+     * of attributes.
+     * @return the Column entity which column name is "monitor"
+     */
+    public Column getMonitorColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.MONITOR
+                                                                     .columnName(),
+                                                             "getMonitorColumn",
+                                                             VersionNum.VERSION100,
+                                                             VersionNum.VERSION350);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "monitor" to the Row entity of
+     * attributes.
+     * @param monitor the column data which column name is "monitor"
+     */
+    public void setMonitor(String monitor) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.MONITOR
+                                                                     .columnName(),
+                                                             "setMonitor",
+                                                             VersionNum.VERSION100,
+                                                             VersionNum.VERSION350);
+        super.setDataHandler(columndesc, monitor);
+    }
+
+    /**
+     * Get the Column entity which column name is "cfm_mpid" from the Row entity
+     * of attributes.
+     * @return the Column entity which column name is "cfm_mpid"
+     */
+    public Column getCfmMpidColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.CFMMPID
+                                                                     .columnName(),
+                                                             "getCfmMpidColumn",
+                                                             VersionNum.VERSION400);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "cfm_mpid" to the Row entity of
+     * attributes.
+     * @param cfmMpid the column data which column name is "cfm_mpid"
+     */
+    public void setCfmMpid(Set<Long> cfmMpid) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.CFMMPID
+                                                                     .columnName(),
+                                                             "setCfmMpid",
+                                                             VersionNum.VERSION400);
+        super.setDataHandler(columndesc, cfmMpid);
+    }
+
+    /**
+     * Get the Column entity which column name is "cfm_remote_mpid" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "cfm_remote_mpid"
+     */
+    public Column getCfmRemoteMpidColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.CFMREMOTEMPID
+                                                                     .columnName(),
+                                                             "getCfmRemoteMpidColumn",
+                                                             VersionNum.VERSION400,
+                                                             VersionNum.VERSION520);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "cfm_remote_mpid" to the Row
+     * entity of attributes.
+     * @param cfmRemoteMpid the column data which column name is
+     *            "cfm_remote_mpid"
+     */
+    public void setCfmRemoteMpid(Set<Long> cfmRemoteMpid) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.CFMREMOTEMPID
+                                                                     .columnName(),
+                                                             "setCfmRemoteMpid",
+                                                             VersionNum.VERSION400,
+                                                             VersionNum.VERSION520);
+        super.setDataHandler(columndesc, cfmRemoteMpid);
+    }
+
+    /**
+     * Get the Column entity which column name is "cfm_remote_mpids" from the
+     * Row entity of attributes.
+     * @return the Column entity which column name is "cfm_remote_mpids"
+     */
+    public Column getCfmRemoteMpidsColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.CFMREMOTEMPIDS
+                                                                     .columnName(),
+                                                             "getCfmRemoteMpidsColumn",
+                                                             VersionNum.VERSION600);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "cfm_remote_mpids" to the Row
+     * entity of attributes.
+     * @param cfmRemoteMpids the column data which column name is
+     *            "cfm_remote_mpids"
+     */
+    public void setCfmRemoteMpids(Set<Long> cfmRemoteMpids) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.CFMREMOTEMPIDS
+                                                                     .columnName(),
+                                                             "setCfmRemoteMpids",
+                                                             VersionNum.VERSION600);
+        super.setDataHandler(columndesc, cfmRemoteMpids);
+    }
+
+    /**
+     * Get the Column entity which column name is "cfm_flap_count" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "cfm_flap_count"
+     */
+    public Column getCfmFlapCountColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.CFMFLAPCOUNT
+                                                                     .columnName(),
+                                                             "getCfmFlapCountColumn",
+                                                             VersionNum.VERSION730);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "cfm_flap_count" to the Row
+     * entity of attributes.
+     * @param cfmFlapCount the column data which column name is "cfm_flap_count"
+     */
+    public void setCfmFlapCount(Set<Long> cfmFlapCount) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.CFMFLAPCOUNT
+                                                                     .columnName(),
+                                                             "setCfmFlapCount",
+                                                             VersionNum.VERSION730);
+        super.setDataHandler(columndesc, cfmFlapCount);
+    }
+
+    /**
+     * Get the Column entity which column name is "cfm_fault" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "cfm_fault"
+     */
+    public Column getCfmFaultColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.CFMFAULT
+                                                                     .columnName(),
+                                                             "getCfmFaultColumn",
+                                                             VersionNum.VERSION400);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "cfm_fault" to the Row entity of
+     * attributes.
+     * @param cfmFault the column data which column name is "cfm_fault"
+     */
+    public void setCfmFault(Set<Boolean> cfmFault) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.CFMFAULT
+                                                                     .columnName(),
+                                                             "setCfmFault",
+                                                             VersionNum.VERSION400);
+        super.setDataHandler(columndesc, cfmFault);
+    }
+
+    /**
+     * Get the Column entity which column name is "cfm_fault_status" from the
+     * Row entity of attributes.
+     * @return the Column entity which column name is "cfm_fault_status"
+     */
+    public Column getCfmFaultStatusColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.CFMFAULTSTATUS
+                                                                     .columnName(),
+                                                             "getCfmFaultStatusColumn",
+                                                             VersionNum.VERSION660);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "cfm_fault_status" to the Row
+     * entity of attributes.
+     * @param cfmFaultStatus the column data which column name is
+     *            "cfm_fault_status"
+     */
+    public void setCfmFaultStatus(Set<String> cfmFaultStatus) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.CFMFAULTSTATUS
+                                                                     .columnName(),
+                                                             "setCfmFaultStatus",
+                                                             VersionNum.VERSION660);
+        super.setDataHandler(columndesc, cfmFaultStatus);
+    }
+
+    /**
+     * Get the Column entity which column name is "cfm_remote_opstate" from the
+     * Row entity of attributes.
+     * @return the Column entity which column name is "cfm_remote_opstate"
+     */
+    public Column getCfmRemoteOpStateColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.CFMREMOTEOPSTATE
+                                                                     .columnName(),
+                                                             "getCfmRemoteOpStateColumn",
+                                                             VersionNum.VERSION6100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "cfm_remote_opstate" to the Row
+     * entity of attributes.
+     * @param cfmRemoteOpState the column data which column name is
+     *            "cfm_remote_opstate"
+     */
+    public void setCfmRemoteOpState(Set<String> cfmRemoteOpState) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.CFMREMOTEOPSTATE
+                                                                     .columnName(),
+                                                             "setCfmRemoteOpState",
+                                                             VersionNum.VERSION6100);
+        super.setDataHandler(columndesc, cfmRemoteOpState);
+    }
+
+    /**
+     * Get the Column entity which column name is "cfm_health" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "cfm_health"
+     */
+    public Column getCfmHealthColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.CFMHEALTH
+                                                                     .columnName(),
+                                                             "getCfmHealthColumn",
+                                                             VersionNum.VERSION690);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "cfm_health" to the Row entity
+     * of attributes.
+     * @param cfmHealth the column data which column name is "cfm_health"
+     */
+    public void setCfmHealth(Set<Long> cfmHealth) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.CFMHEALTH
+                                                                     .columnName(),
+                                                             "setCfmHealth",
+                                                             VersionNum.VERSION690);
+        super.setDataHandler(columndesc, cfmHealth);
+    }
+
+    /**
+     * Get the Column entity which column name is "lacp_current" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "lacp_current"
+     */
+    public Column getLacpCurrentColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.LACPCURRENT
+                                                                     .columnName(),
+                                                             "getLacpCurrentColumn",
+                                                             VersionNum.VERSION330);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "lacp_current" to the Row entity
+     * of attributes.
+     * @param lacpCurrent the column data which column name is "lacp_current"
+     */
+    public void setLacpCurrent(Set<Boolean> lacpCurrent) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.LACPCURRENT
+                                                                     .columnName(),
+                                                             "setLacpCurrent",
+                                                             VersionNum.VERSION330);
+        super.setDataHandler(columndesc, lacpCurrent);
+    }
+
+    /**
+     * Get the Column entity which column name is "other_config" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "other_config"
+     */
+    public Column getOtherConfigColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.OTHERCONFIG
+                                                                     .columnName(),
+                                                             "getOtherConfigColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "other_config" to the Row entity
+     * of attributes.
+     * @param otherConfig the column data which column name is "other_config"
+     */
+    public void setOtherConfig(Map<String, String> otherConfig) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.OTHERCONFIG
+                                                                     .columnName(),
+                                                             "setOtherConfig",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, otherConfig);
+    }
+
+    /**
+     * Get the Column entity which column name is "statistics" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "statistics"
+     */
+    public Column getStatisticsColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.STATISTICS
+                                                                     .columnName(),
+                                                             "getStatisticsColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "statistics" to the Row entity
+     * of attributes.
+     * @param statistics the column data which column name is "statistics"
+     */
+    public void setStatistics(Map<String, Long> statistics) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.STATISTICS
+                                                                     .columnName(),
+                                                             "setStatistics",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, statistics);
+    }
+
+    /**
+     * Get the Column entity which column name is "status" from the Row entity
+     * of attributes.
+     * @return the Column entity which column name is "status"
+     */
+    public Column getStatusColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.STATUS
+                                                                     .columnName(),
+                                                             "getStatusColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "status" to the Row entity of
+     * attributes.
+     * @param status the column data which column name is "status"
+     */
+    public void setStatus(Map<String, String> status) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.STATUS
+                                                                     .columnName(),
+                                                             "setStatus",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, status);
+    }
+
+    /**
+     * Get the Column entity which column name is "admin_state" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "admin_state"
+     */
+    public Column getAdminStateColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.ADMINSTATE
+                                                                     .columnName(),
+                                                             "getAdminStateColumn",
+                                                             VersionNum.VERSION106);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "admin_state" to the Row entity
+     * of attributes.
+     * @param adminState the column data which column name is "admin_state"
+     */
+    public void setAdminState(Set<String> adminState) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.ADMINSTATE
+                                                                     .columnName(),
+                                                             "setAdminState",
+                                                             VersionNum.VERSION106);
+        super.setDataHandler(columndesc, adminState);
+    }
+
+    /**
+     * Get the Column entity which column name is "link_state" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "link_state"
+     */
+    public Column getLinkStateColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.LINKSTATE
+                                                                     .columnName(),
+                                                             "getLinkStateColumn",
+                                                             VersionNum.VERSION106);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "link_state" to the Row entity
+     * of attributes.
+     * @param linkState the column data which column name is "link_state"
+     */
+    public void setLinkState(Map<String, String> linkState) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.LINKSTATE
+                                                                     .columnName(),
+                                                             "setLinkState",
+                                                             VersionNum.VERSION106);
+        super.setDataHandler(columndesc, linkState);
+    }
+
+    /**
+     * Get the Column entity which column name is "link_resets" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "link_resets"
+     */
+    public Column getLinkResetsColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.LINKRESETS
+                                                                     .columnName(),
+                                                             "getLinkResetsColumn",
+                                                             VersionNum.VERSION620);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "link_resets" to the Row entity
+     * of attributes.
+     * @param linkResets the column data which column name is "link_resets"
+     */
+    public void setLinkResets(Set<String> linkResets) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.LINKRESETS
+                                                                     .columnName(),
+                                                             "setLinkResets",
+                                                             VersionNum.VERSION620);
+        super.setDataHandler(columndesc, linkResets);
+    }
+
+    /**
+     * Get the Column entity which column name is "link_speed" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "link_speed"
+     */
+    public Column getLinkSpeedColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.LINKSPEED
+                                                                     .columnName(),
+                                                             "getLinkSpeedColumn",
+                                                             VersionNum.VERSION106);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "link_speed" to the Row entity
+     * of attributes.
+     * @param linkSpeed the column data which column name is "link_speed"
+     */
+    public void setLinkSpeed(Set<Long> linkSpeed) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.LINKSPEED
+                                                                     .columnName(),
+                                                             "setLinkSpeed",
+                                                             VersionNum.VERSION106);
+        super.setDataHandler(columndesc, linkSpeed);
+    }
+
+    /**
+     * Get the Column entity which column name is "duplex" from the Row entity
+     * of attributes.
+     * @return the Column entity which column name is "duplex"
+     */
+    public Column getDuplexColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.DUPLEX
+                                                                     .columnName(),
+                                                             "getDuplexColumn",
+                                                             VersionNum.VERSION106);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "duplex" to the Row entity of
+     * attributes.
+     * @param duplex the column data which column name is "duplex"
+     */
+    public void setDuplex(Set<Long> duplex) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.DUPLEX
+                                                                     .columnName(),
+                                                             "setDuplex",
+                                                             VersionNum.VERSION106);
+        super.setDataHandler(columndesc, duplex);
+    }
+
+    /**
+     * Get the Column entity which column name is "mtu" from the Row entity of
+     * attributes.
+     * @return the Column entity which column name is "mtu"
+     */
+    public Column getMtuColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.MTU
+                                                                     .columnName(),
+                                                             "getMtuColumn",
+                                                             VersionNum.VERSION106);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "mtu" to the Row entity of
+     * attributes.
+     * @param mtu the column data which column name is "mtu"
+     */
+    public void setMtu(Set<Long> mtu) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.MTU
+                                                                     .columnName(),
+                                                             "setMtu",
+                                                             VersionNum.VERSION106);
+        super.setDataHandler(columndesc, mtu);
+    }
+
+    /**
+     * Get the Column entity which column name is "error" from the Row entity of
+     * attributes.
+     * @return the Column entity which column name is "error"
+     */
+    public Column getErrorColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.ERROR
+                                                                     .columnName(),
+                                                             "getErrorColumn",
+                                                             VersionNum.VERSION770);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "error" to the Row entity of
+     * attributes.
+     * @param error the column data which column name is "error"
+     */
+    public void setError(Set<String> error) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.ERROR
+                                                                     .columnName(),
+                                                             "setError",
+                                                             VersionNum.VERSION770);
+        super.setDataHandler(columndesc, error);
+    }
+
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/OpenVSwitch.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/OpenVSwitch.java
new file mode 100644
index 0000000..73d7ca1
--- /dev/null
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/OpenVSwitch.java
@@ -0,0 +1,451 @@
+package org.onosproject.ovsdb.rfc.table;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.onosproject.ovsdb.rfc.notation.Column;
+import org.onosproject.ovsdb.rfc.notation.Row;
+import org.onosproject.ovsdb.rfc.notation.UUID;
+import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
+import org.onosproject.ovsdb.rfc.tableservice.AbstractOvsdbTableService;
+import org.onosproject.ovsdb.rfc.tableservice.ColumnDescription;
+
+/**
+ * This class provides operations of Open_vSwitch Table.
+ */
+public class OpenVSwitch extends AbstractOvsdbTableService {
+
+    /**
+     * OpenVSwitch table column name.
+     */
+    public enum OpenVSwitchColumn {
+        BRIDGES("bridges"), MANAGERS("managers"),
+        MANAGEROPTIONS("manager_options"), SSL("ssl"),
+        OTHERCONFIG("other_config"), EXTERNALIDS("external_ids"),
+        NEXTCFG("next_cfg"), CURCFG("cur_cfg"), CAPABILITIES("capabilities"),
+        STATISTICS("statistics"), OVSVERSION("ovs_version"),
+        DBVERSION("db_version"), SYSTEMTYPE("system_type"),
+        SYSTEMVERSION("system_version");
+
+        private final String columnName;
+
+        private OpenVSwitchColumn(String columnName) {
+            this.columnName = columnName;
+        }
+
+        /**
+         * Returns the table column name for OpenVSwitchColumn.
+         * @return the table column name
+         */
+        public String columnName() {
+            return columnName;
+        }
+    }
+
+    /**
+     * Constructs a OpenVSwitch object. Generate Open_vSwitch Table Description.
+     * @param dbSchema DatabaseSchema
+     * @param row Row
+     */
+    public OpenVSwitch(DatabaseSchema dbSchema, Row row) {
+        super(dbSchema, row, OvsdbTable.OPENVSWITCH, VersionNum.VERSION100);
+    }
+
+    /**
+     * Get the Column entity which column name is "bridges" from the Row entity
+     * of attributes.
+     * @return the Column entity which column name is "bridges"
+     */
+    public Column getBridgesColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             OpenVSwitchColumn.BRIDGES
+                                                                     .columnName(),
+                                                             "getBridgesColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "bridges" to the Row entity of
+     * attributes.
+     * @param bridges the column data which column name is "bridges"
+     */
+    public void setBridges(Set<UUID> bridges) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             OpenVSwitchColumn.BRIDGES
+                                                                     .columnName(),
+                                                             "setBridges",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, bridges);
+    }
+
+    /**
+     * Get the Column entity which column name is "managers" from the Row entity
+     * of attributes.
+     * @return the Column entity which column name is "managers"
+     */
+    public Column getManagersColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             OpenVSwitchColumn.MANAGERS
+                                                                     .columnName(),
+                                                             "getManagersColumn",
+                                                             VersionNum.VERSION100,
+                                                             VersionNum.VERSION200);
+        return (Column) super.getDataHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "managers" to the Row entity of
+     * attributes.
+     * @param managers the column data which column name is "managers"
+     */
+    public void setManagers(Set<UUID> managers) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             OpenVSwitchColumn.MANAGERS
+                                                                     .columnName(),
+                                                             "setManagers",
+                                                             VersionNum.VERSION100,
+                                                             VersionNum.VERSION200);
+        super.setDataHandler(columndesc, managers);
+    }
+
+    /**
+     * Get the Column entity which column name is "manager_options" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "manager_options"
+     */
+    public Column getManagerOptionsColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             OpenVSwitchColumn.MANAGEROPTIONS
+                                                                     .columnName(),
+                                                             "getManagerOptionsColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getDataHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "manager_options" to the Row
+     * entity of attributes.
+     * @param managerOptions the column data which column name is
+     *            "manager_options"
+     */
+    public void setManagerOptions(Set<UUID> managerOptions) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             OpenVSwitchColumn.MANAGEROPTIONS
+                                                                     .columnName(),
+                                                             "setManagerOptions",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, managerOptions);
+    }
+
+    /**
+     * Get the Column entity which column name is "ssl" from the Row entity of
+     * attributes.
+     * @return the Column entity which column name is "ssl"
+     */
+    public Column getSslColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             OpenVSwitchColumn.SSL
+                                                                     .columnName(),
+                                                             "getSslColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getDataHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "ssl" to the Row entity of
+     * attributes.
+     * @param ssl the column data which column name is "ssl"
+     */
+    public void setSsl(Set<UUID> ssl) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             OpenVSwitchColumn.SSL
+                                                                     .columnName(),
+                                                             "setSsl",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, ssl);
+    }
+
+    /**
+     * Get the Column entity which column name is "other_config" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "other_config"
+     */
+    public Column getOtherConfigColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             OpenVSwitchColumn.OTHERCONFIG
+                                                                     .columnName(),
+                                                             "getOtherConfigColumn",
+                                                             VersionNum.VERSION510);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "other_config" to the Row entity
+     * of attributes.
+     * @param otherConfig the column data which column name is "other_config"
+     */
+    public void setOtherConfig(Map<String, String> otherConfig) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             OpenVSwitchColumn.OTHERCONFIG
+                                                                     .columnName(),
+                                                             "setOtherConfig",
+                                                             VersionNum.VERSION510);
+        super.setDataHandler(columndesc, otherConfig);
+    }
+
+    /**
+     * Get the Column entity which column name is "external_ids" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "external_ids"
+     */
+    public Column getExternalIdsColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             OpenVSwitchColumn.EXTERNALIDS
+                                                                     .columnName(),
+                                                             "getExternalIdsColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "external_ids" to the Row entity
+     * of attributes.
+     * @param externalIds the column data which column name is "external_ids"
+     */
+    public void setExternalIds(Map<String, String> externalIds) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             OpenVSwitchColumn.EXTERNALIDS
+                                                                     .columnName(),
+                                                             "setExternalIds",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, externalIds);
+    }
+
+    /**
+     * Get the Column entity which column name is "next_cfg" from the Row entity
+     * of attributes.
+     * @return the Column entity which column name is "next_cfg"
+     */
+    public Column getNextConfigColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             OpenVSwitchColumn.NEXTCFG
+                                                                     .columnName(),
+                                                             "getNextConfigColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "next_cfg" to the Row entity of
+     * attributes.
+     * @param nextConfig the column data which column name is "next_cfg"
+     */
+    public void setNextConfig(Long nextConfig) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             OpenVSwitchColumn.NEXTCFG
+                                                                     .columnName(),
+                                                             "setNextConfig",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, nextConfig);
+    }
+
+    /**
+     * Get the Column entity which column name is "cur_cfg" from the Row entity
+     * of attributes.
+     * @return the Column entity which column name is "cur_cfg"
+     */
+    public Column getCurrentConfigColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             OpenVSwitchColumn.CURCFG
+                                                                     .columnName(),
+                                                             "getCurrentConfigColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "cur_cfg" to the Row entity of
+     * attributes.
+     * @param currentConfig the column data which column name is "cur_cfg"
+     */
+    public void setCurrentConfig(Long currentConfig) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             OpenVSwitchColumn.CURCFG
+                                                                     .columnName(),
+                                                             "setCurrentConfig",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, currentConfig);
+    }
+
+    /**
+     * Get the Column entity which column name is "capabilities" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "capabilities"
+     */
+    public Column getCapabilitiesColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             OpenVSwitchColumn.CAPABILITIES
+                                                                     .columnName(),
+                                                             "getCapabilitiesColumn",
+                                                             VersionNum.VERSION100,
+                                                             VersionNum.VERSION670);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "capabilities" to the Row entity
+     * of attributes.
+     * @param capabilities the column data which column name is "capabilities"
+     */
+    public void setCapabilities(Map<String, UUID> capabilities) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             OpenVSwitchColumn.CAPABILITIES
+                                                                     .columnName(),
+                                                             "setCapabilities",
+                                                             VersionNum.VERSION100,
+                                                             VersionNum.VERSION670);
+        super.setDataHandler(columndesc, capabilities);
+    }
+
+    /**
+     * Get the Column entity which column name is "statistics" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "statistics"
+     */
+    public Column getStatisticsColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             OpenVSwitchColumn.STATISTICS
+                                                                     .columnName(),
+                                                             "getStatisticsColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "statistics" to the Row entity
+     * of attributes.
+     * @param statistics the column data which column name is "statistics"
+     */
+    public void setStatistics(Map<String, Long> statistics) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             OpenVSwitchColumn.STATISTICS
+                                                                     .columnName(),
+                                                             "setStatistics",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, statistics);
+    }
+
+    /**
+     * Get the Column entity which column name is "ovs_version" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "ovs_version"
+     */
+    public Column getOvsVersionColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             OpenVSwitchColumn.OVSVERSION
+                                                                     .columnName(),
+                                                             "getOvsVersionColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "ovs_version" to the Row entity
+     * of attributes.
+     * @param ovsVersion the column data which column name is "ovs_version"
+     */
+    public void setOvsVersion(Set<String> ovsVersion) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             OpenVSwitchColumn.OVSVERSION
+                                                                     .columnName(),
+                                                             "setOvsVersion",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, ovsVersion);
+    }
+
+    /**
+     * Get the Column entity which column name is "db_version" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "db_version"
+     */
+    public Column getDbVersionColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             OpenVSwitchColumn.DBVERSION
+                                                                     .columnName(),
+                                                             "getDbVersionColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "db_version" to the Row entity
+     * of attributes.
+     * @param dbVersion the column data which column name is "db_version"
+     */
+    public void setDbVersion(Set<String> dbVersion) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             OpenVSwitchColumn.DBVERSION
+                                                                     .columnName(),
+                                                             "setDbVersion",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, dbVersion);
+    }
+
+    /**
+     * Get the Column entity which column name is "system_type" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "system_type"
+     */
+    public Column getSystemTypeColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             OpenVSwitchColumn.SYSTEMTYPE
+                                                                     .columnName(),
+                                                             "getSystemTypeColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "system_type" to the Row entity
+     * of attributes.
+     * @param systemType the column data which column name is "system_type"
+     */
+    public void setSystemType(Set<String> systemType) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             OpenVSwitchColumn.SYSTEMTYPE
+                                                                     .columnName(),
+                                                             "setSystemType",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, systemType);
+    }
+
+    /**
+     * Get the Column entity which column name is "system_version" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "system_version"
+     */
+    public Column getSystemVersionColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             OpenVSwitchColumn.SYSTEMVERSION
+                                                                     .columnName(),
+                                                             "getSystemVersionColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "system_version" to the Row
+     * entity of attributes.
+     * @param systemVersion the column data which column name is
+     *            "system_version"
+     */
+    public void setSystemVersion(Set<String> systemVersion) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             OpenVSwitchColumn.SYSTEMVERSION
+                                                                     .columnName(),
+                                                             "setSystemVersion",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, systemVersion);
+    }
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/OvsdbTable.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/OvsdbTable.java
new file mode 100644
index 0000000..f2e5150
--- /dev/null
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/OvsdbTable.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.rfc.table;
+
+/**
+ * Ovsdb table name. Refer to RFC7047's Section 9.2.
+ */
+public enum OvsdbTable {
+    INTERFACE("Interface"), BRIDGE("Bridge"), CONTROLLER("Controller"),
+    PORT("Port"), OPENVSWITCH("Open_vSwitch"), FLWTABLE("Flow_Table"),
+    QOS("Qos"), QUEUE("Queue"), MIRROR("Mirror"), MANAGER("Manager"),
+    NETFLOW("NetFlow"), SSL("SSL"), SFLOW("sFlow"), IPFIX("IPFIX"),
+    FLOWSAMPLECOLLECTORSET("Flow_Sample_Collector_Set");
+
+    private final String tableName;
+
+    private OvsdbTable(String tableName) {
+        this.tableName = tableName;
+    }
+
+    /**
+     * Returns the table name for OvsdbTable.
+     * @return the table name
+     */
+    public String tableName() {
+        return tableName;
+    }
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Port.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Port.java
new file mode 100644
index 0000000..996e93f
--- /dev/null
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Port.java
@@ -0,0 +1,575 @@
+package org.onosproject.ovsdb.rfc.table;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.onosproject.ovsdb.rfc.notation.Column;
+import org.onosproject.ovsdb.rfc.notation.Row;
+import org.onosproject.ovsdb.rfc.notation.UUID;
+import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
+import org.onosproject.ovsdb.rfc.tableservice.AbstractOvsdbTableService;
+import org.onosproject.ovsdb.rfc.tableservice.ColumnDescription;
+
+/**
+ * This class provides operations of Port Table.
+ */
+public class Port extends AbstractOvsdbTableService {
+
+    /**
+     * Port table column name.
+     */
+    public enum PortColumn {
+        NAME("name"), INTERFACES("interfaces"), TRUNKS("trunks"), TAG("tag"),
+        VLANMODE("vlan_mode"), QOS("qos"), MAC("mac"), BONDTYPE("bond_type"),
+        BONDMODE("bond_mode"), LACP("lacp"), BONDUPDELAY("bond_updelay"),
+        BONDDOWNDELAY("bond_downdelay"), BONDFAKEIFACE("bond_fake_iface"),
+        FAKEBRIDGE("fake_bridge"), STATUS("status"), STATISTICS("statistics"),
+        OTHERCONFIG("other_config"), EXTERNALIDS("external_ids");
+
+        private final String columnName;
+
+        private PortColumn(String columnName) {
+            this.columnName = columnName;
+        }
+
+        /**
+         * Returns the table column name for PortColumn.
+         * @return the table column name
+         */
+        public String columnName() {
+            return columnName;
+        }
+    }
+
+    /**
+     * Constructs a Port object. Generate Port Table Description.
+     * @param dbSchema DatabaseSchema
+     * @param row Row
+     */
+    public Port(DatabaseSchema dbSchema, Row row) {
+        super(dbSchema, row, OvsdbTable.PORT, VersionNum.VERSION100);
+    }
+
+    /**
+     * Get the Column entity which column name is "name" from the Row entity of
+     * attributes.
+     * @return the Column entity
+     */
+    public Column getNameColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.NAME
+                                                                     .columnName(),
+                                                             "getNameColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "name" to the Row entity of
+     * attributes.
+     * @param name the column data which column name is "name"
+     */
+    public void setName(String name) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.NAME
+                                                                     .columnName(),
+                                                             "setName",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, name);
+    }
+
+    /**
+     * Get the Column entity which column name is "name" from the Row entity of
+     * attributes.
+     * @return the Column entity
+     */
+    public String getName() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.NAME
+                                                                     .columnName(),
+                                                             "getName",
+                                                             VersionNum.VERSION100);
+        return (String) super.getDataHandler(columndesc);
+    }
+
+    /**
+     * Get the Column entity which column name is "interfaces" from the Row
+     * entity of attributes.
+     * @return the Column entity
+     */
+    public Column getInterfacesColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.INTERFACES
+                                                                     .columnName(),
+                                                             "getInterfacesColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "interfaces" to the Row entity
+     * of attributes.
+     * @param interfaces the column data which column name is "interfaces"
+     */
+    public void setInterfaces(Set<UUID> interfaces) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.INTERFACES
+                                                                     .columnName(),
+                                                             "setInterfaces",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, interfaces);
+    }
+
+    /**
+     * Get the Column entity which column name is "trunks" from the Row entity
+     * of attributes.
+     * @return the Column entity
+     */
+    public Column getTrunksColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.TRUNKS
+                                                                     .columnName(),
+                                                             "getTrunksColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "trunks" to the Row entity of
+     * attributes.
+     * @param trunks the column data which column name is "trunks"
+     */
+    public void setTrunks(Set<Long> trunks) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.TRUNKS
+                                                                     .columnName(),
+                                                             "setTrunks",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, trunks);
+    }
+
+    /**
+     * Get the Column entity which column name is "tag" from the Row entity of
+     * attributes.
+     * @return the Column entity
+     */
+    public Column getTagColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.TAG
+                                                                     .columnName(),
+                                                             "getTagColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "tag" to the Row entity of
+     * attributes.
+     * @param tag the column data which column name is "tag"
+     */
+    public void setTag(Set<Long> tag) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.TAG
+                                                                     .columnName(),
+                                                             "setTag",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, tag);
+    }
+
+    /**
+     * Get the Column entity which column name is "vlan_mode" from the Row
+     * entity of attributes.
+     * @return the Column entity
+     */
+    public Column getVlanModeColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.VLANMODE
+                                                                     .columnName(),
+                                                             "getVlanModeColumn",
+                                                             VersionNum.VERSION610);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "vlan_mode" to the Row entity of
+     * attributes.
+     * @param vlanMode the column data which column name is "vlan_mode"
+     */
+    public void setVlanMode(Set<String> vlanMode) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.VLANMODE
+                                                                     .columnName(),
+                                                             "setVlanMode",
+                                                             VersionNum.VERSION610);
+        super.setDataHandler(columndesc, vlanMode);
+    }
+
+    /**
+     * Get the Column entity which column name is "qos" from the Row entity of
+     * attributes.
+     * @return the Column entity
+     */
+    public Column getQosColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.QOS
+                                                                     .columnName(),
+                                                             "getQosColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "qos" to the Row entity of
+     * attributes.
+     * @param qos the column data which column name is "qos"
+     */
+    public void setQos(Set<UUID> qos) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.QOS
+                                                                     .columnName(),
+                                                             "setQos",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, qos);
+    }
+
+    /**
+     * Get the Column entity which column name is "mac" from the Row entity of
+     * attributes.
+     * @return the Column entity
+     */
+    public Column getMacColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.MAC
+                                                                     .columnName(),
+                                                             "getMacColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "mac" to the Row entity of
+     * attributes.
+     * @param mac the column data which column name is "mac"
+     */
+    public void setMac(Set<String> mac) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.MAC
+                                                                     .columnName(),
+                                                             "setMac",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, mac);
+    }
+
+    /**
+     * Get the Column entity which column name is "bond_type" from the Row
+     * entity of attributes.
+     * @return the Column entity
+     */
+    public Column getBondTypeColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.BONDTYPE
+                                                                     .columnName(),
+                                                             "getBondTypeColumn",
+                                                             VersionNum.VERSION102,
+                                                             VersionNum.VERSION103);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "bond_type" to the Row entity of
+     * attributes.
+     * @param bondtype the column data which column name is "bond_type"
+     */
+    public void setBondType(Set<String> bondtype) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.BONDTYPE
+                                                                     .columnName(),
+                                                             "setBondType",
+                                                             VersionNum.VERSION102,
+                                                             VersionNum.VERSION103);
+        super.setDataHandler(columndesc, bondtype);
+    }
+
+    /**
+     * Get the Column entity which column name is "bond_mode" from the Row
+     * entity of attributes.
+     * @return the Column entity
+     */
+    public Column getBondModeColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.BONDMODE
+                                                                     .columnName(),
+                                                             "getBondModeColumn",
+                                                             VersionNum.VERSION104);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "bond_mode" to the Row entity of
+     * attributes.
+     * @param bondmode the column data which column name is "bond_mode"
+     */
+    public void setBondMode(Set<String> bondmode) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.BONDMODE
+                                                                     .columnName(),
+                                                             "setBondMode",
+                                                             VersionNum.VERSION104);
+        super.setDataHandler(columndesc, bondmode);
+    }
+
+    /**
+     * Get the Column entity which column name is "lacp" from the Row entity of
+     * attributes.
+     * @return the Column entity
+     */
+    public Column getLacpColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.LACP
+                                                                     .columnName(),
+                                                             "getLacpColumn",
+                                                             VersionNum.VERSION130);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "lacp" to the Row entity of
+     * attributes.
+     * @param lacp the column data which column name is "lacp"
+     */
+    public void setLacp(Set<String> lacp) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.LACP
+                                                                     .columnName(),
+                                                             "setLacp",
+                                                             VersionNum.VERSION130);
+        super.setDataHandler(columndesc, lacp);
+    }
+
+    /**
+     * Get the Column entity which column name is "bond_updelay" from the Row
+     * entity of attributes.
+     * @return the Column entity
+     */
+    public Column getBondUpDelayColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.BONDUPDELAY
+                                                                     .columnName(),
+                                                             "getBondUpDelayColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "bond_updelay" to the Row entity
+     * of attributes.
+     * @param bondUpDelay the column data which column name is "bond_updelay"
+     */
+    public void setBondUpDelay(Set<Long> bondUpDelay) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.BONDUPDELAY
+                                                                     .columnName(),
+                                                             "setBondUpDelay",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, bondUpDelay);
+    }
+
+    /**
+     * Get the Column entity which column name is "bond_downdelay" from the Row
+     * entity of attributes.
+     * @return the Column entity
+     */
+    public Column getBondDownDelayColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.BONDDOWNDELAY
+                                                                     .columnName(),
+                                                             "getBondDownDelayColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "bond_downdelay" to the Row
+     * entity of attributes.
+     * @param bondDownDelay the column data which column name is
+     *            "bond_downdelay"
+     */
+    public void setBondDownDelay(Set<Long> bondDownDelay) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.BONDDOWNDELAY
+                                                                     .columnName(),
+                                                             "setBondDownDelay",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, bondDownDelay);
+    }
+
+    /**
+     * Get the Column entity which column name is "bond_fake_iface" from the Row
+     * entity of attributes.
+     * @return the Column entity
+     */
+    public Column getBondFakeInterfaceColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.BONDFAKEIFACE
+                                                                     .columnName(),
+                                                             "getBondFakeInterfaceColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "bond_fake_iface" to the Row
+     * entity of attributes.
+     * @param bondFakeInterface the column data which column name is
+     *            "bond_fake_iface"
+     */
+    public void setBondFakeInterface(Set<Boolean> bondFakeInterface) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.BONDFAKEIFACE
+                                                                     .columnName(),
+                                                             "setBondFakeInterface",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, bondFakeInterface);
+    }
+
+    /**
+     * Get the Column entity which column name is "fake_bridge" from the Row
+     * entity of attributes.
+     * @return the Column entity
+     */
+    public Column getFakeBridgeColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.FAKEBRIDGE
+                                                                     .columnName(),
+                                                             "getFakeBridgeColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "fake_bridge" to the Row entity
+     * of attributes.
+     * @param fakeBridge the column data which column name is "fake_bridge"
+     */
+    public void setFakeBridge(Set<Boolean> fakeBridge) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.FAKEBRIDGE
+                                                                     .columnName(),
+                                                             "setFakeBridge",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, fakeBridge);
+    }
+
+    /**
+     * Get the Column entity which column name is "status" from the Row entity
+     * of attributes.
+     * @return the Column entity
+     */
+    public Column getStatusColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.STATUS
+                                                                     .columnName(),
+                                                             "getStatusColumn",
+                                                             VersionNum.VERSION620);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "status" to the Row entity of
+     * attributes.
+     * @param status the column data which column name is "status"
+     */
+    public void setStatus(Map<String, String> status) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.STATUS
+                                                                     .columnName(),
+                                                             "setStatus",
+                                                             VersionNum.VERSION620);
+        super.setDataHandler(columndesc, status);
+    }
+
+    /**
+     * Get the Column entity which column name is "statistics" from the Row
+     * entity of attributes.
+     * @return the Column entity
+     */
+    public Column getStatisticsColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.STATISTICS
+                                                                     .columnName(),
+                                                             "getStatisticsColumn",
+                                                             VersionNum.VERSION630);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "statistics" to the Row entity
+     * of attributes.
+     * @param statistics the column data which column name is "statistics"
+     */
+    public void setStatistics(Map<String, Long> statistics) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.STATISTICS
+                                                                     .columnName(),
+                                                             "setStatistics",
+                                                             VersionNum.VERSION630);
+        super.setDataHandler(columndesc, statistics);
+    }
+
+    /**
+     * Get the Column entity which column name is "other_config" from the Row
+     * entity of attributes.
+     * @return the Column entity
+     */
+    public Column getOtherConfigColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.OTHERCONFIG
+                                                                     .columnName(),
+                                                             "getOtherConfigColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "other_config" to the Row entity
+     * of attributes.
+     * @param otherConfig the column data which column name is "other_config"
+     */
+    public void setOtherConfig(Map<String, String> otherConfig) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.OTHERCONFIG
+                                                                     .columnName(),
+                                                             "setOtherConfig",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, otherConfig);
+    }
+
+    /**
+     * Get the Column entity which column name is "external_ids" from the Row
+     * entity of attributes.
+     * @return the Column entity
+     */
+    public Column getExternalIdsColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.EXTERNALIDS
+                                                                     .columnName(),
+                                                             "getExternalIdsColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "external_ids" to the Row entity
+     * of attributes.
+     * @param externalIds the column data which column name is "external_ids"
+     */
+    public void setExternalIds(Map<String, String> externalIds) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             PortColumn.EXTERNALIDS
+                                                                     .columnName(),
+                                                             "setExternalIds",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, externalIds);
+    }
+
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/TableGenerator.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/TableGenerator.java
new file mode 100644
index 0000000..644d16b
--- /dev/null
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/TableGenerator.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.rfc.table;
+
+import org.onosproject.ovsdb.rfc.notation.Row;
+import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
+
+/**
+ * Table generator.
+ */
+public final class TableGenerator {
+
+    /**
+     * Constructs a TableGenerator object. Utility classes should not have a
+     * public or default constructor, otherwise it will compile failed. This
+     * class should not be instantiated.
+     */
+    private TableGenerator() {
+    }
+
+    /**
+     * Create table.
+     * @param dbSchema DatabaseSchema entity
+     * @param tableName table name
+     * @return Object table entity
+     */
+    public static Object createTable(DatabaseSchema dbSchema,
+                                     OvsdbTable tableName) {
+        Row row = new Row();
+        return generateTable(dbSchema, row, tableName);
+    }
+
+    /**
+     * Get table from Row.
+     * @param dbSchema DatabaseSchema entity
+     * @param row Row entity
+     * @param tableName table name
+     * @return Object table entity
+     */
+    public static Object getTable(DatabaseSchema dbSchema, Row row,
+                                  OvsdbTable tableName) {
+        return generateTable(dbSchema, row, tableName);
+    }
+
+    /**
+     * Generate the table by table name.
+     * @param dbSchema DatabaseSchema entity
+     * @param row Row entity
+     * @param tableName table name
+     * @return Object Table entity
+     */
+    private static Object generateTable(DatabaseSchema dbSchema, Row row,
+                                        OvsdbTable tableName) {
+        switch (tableName) {
+        case INTERFACE:
+            return new Interface(dbSchema, row);
+        case BRIDGE:
+            return new Bridge(dbSchema, row);
+        case CONTROLLER:
+            return new Controller(dbSchema, row);
+        case OPENVSWITCH:
+            return new OpenVSwitch(dbSchema, row);
+        case PORT:
+            return new Port(dbSchema, row);
+        default:
+            return null;
+        }
+    }
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/VersionNum.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/VersionNum.java
new file mode 100644
index 0000000..f308266
--- /dev/null
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/VersionNum.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.rfc.table;
+
+/**
+ * The version number of tables and columns.
+ */
+public enum VersionNum {
+    VERSION100("1.0.0"), VERSION102("1.0.2"), VERSION103("1.0.3"),
+    VERSION104("1.0.4"), VERSION106("1.0.6"), VERSION110("1.1.0"),
+    VERSION130("1.3.0"), VERSION200("2.0.0"), VERSION300("3.0.0"),
+    VERSION330("3.3.0"), VERSION350("3.5.0"), VERSION400("4.0.0"),
+    VERSION510("5.1.0"), VERSION520("5.2.0"), VERSION600("6.0.0"),
+    VERSION610("6.1.0"), VERSION620("6.2.0"), VERSION630("6.3.0"),
+    VERSION640("6.4.0"), VERSION650("6.5.0"), VERSION660("6.6.0"),
+    VERSION670("6.7.0"), VERSION680("6.8.0"), VERSION690("6.9.0"),
+    VERSION6100("6.10.0"), VERSION6111("6.11.1"), VERSION710("7.1.0"),
+    VERSION720("7.2.0"), VERSION721("7.2.1"), VERSION730("7.3.0"),
+    VERSION740("7.4.0"), VERSION750("7.5.0"), VERSION770("7.7.0");
+
+    private final String versionNum;
+
+    private VersionNum(String versionNum) {
+        this.versionNum = versionNum;
+    }
+
+    /**
+     * Returns the version number for VersionNum.
+     * @return the version number
+     */
+    public String versionNum() {
+        return versionNum;
+    }
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/AbstractOvsdbTableService.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/AbstractOvsdbTableService.java
new file mode 100644
index 0000000..0fd6214
--- /dev/null
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/AbstractOvsdbTableService.java
@@ -0,0 +1,327 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.rfc.tableservice;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Objects;
+
+import org.onosproject.ovsdb.rfc.error.ColumnSchemaNotFoundException;
+import org.onosproject.ovsdb.rfc.error.TableSchemaNotFoundException;
+import org.onosproject.ovsdb.rfc.error.TypedSchemaException;
+import org.onosproject.ovsdb.rfc.error.VersionMismatchException;
+import org.onosproject.ovsdb.rfc.notation.Column;
+import org.onosproject.ovsdb.rfc.notation.Row;
+import org.onosproject.ovsdb.rfc.notation.UUID;
+import org.onosproject.ovsdb.rfc.schema.ColumnSchema;
+import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
+import org.onosproject.ovsdb.rfc.schema.TableSchema;
+import org.onosproject.ovsdb.rfc.table.OvsdbTable;
+import org.onosproject.ovsdb.rfc.table.VersionNum;
+import org.onosproject.ovsdb.rfc.utils.VersionUtil;
+
+/**
+ * Representation of conversion between Ovsdb table and Row.
+ */
+public abstract class AbstractOvsdbTableService implements OvsdbTableService {
+
+    private final DatabaseSchema dbSchema;
+    private final Row row;
+    private final TableDescription tableDesc;
+
+    /**
+     * Constructs a AbstractOvsdbTableService object.
+     * @param dbSchema DatabaseSchema entity
+     * @param row Row entity
+     * @param table table name
+     * @param formVersion the initial version
+     */
+    public AbstractOvsdbTableService(DatabaseSchema dbSchema, Row row,
+                                     OvsdbTable table, VersionNum formVersion) {
+        checkNotNull(dbSchema, "database schema cannot be null");
+        checkNotNull(row, "row cannot be null");
+        checkNotNull(table, "table cannot be null");
+        checkNotNull(formVersion, "the initial version cannot be null");
+        this.dbSchema = dbSchema;
+        this.row = row;
+        TableDescription tableDesc = new TableDescription(table, formVersion);
+        this.tableDesc = tableDesc;
+        row.setTableSchema(dbSchema.getTableSchema(table.tableName()));
+    }
+
+    /**
+     * Check whether the parameter of dbSchema is valid and check whether the
+     * table is existent in Database Schema.
+     */
+    private boolean isValid() {
+        if (dbSchema == null) {
+            return false;
+        }
+        if (!dbSchema.name().equalsIgnoreCase(tableDesc.database())) {
+            return false;
+        }
+        checkTableSchemaVersion();
+        return true;
+    }
+
+    /**
+     * Check the table version.
+     */
+    private void checkTableSchemaVersion() {
+        String fromVersion = tableDesc.fromVersion();
+        String untilVersion = tableDesc.untilVersion();
+        String schemaVersion = dbSchema.version();
+        checkVersion(schemaVersion, fromVersion, untilVersion);
+    }
+
+    /**
+     * Check the column version.
+     * @param columnDesc ColumnDescription entity
+     */
+    private void checkColumnSchemaVersion(ColumnDescription columnDesc) {
+        String fromVersion = columnDesc.fromVersion();
+        String untilVersion = columnDesc.untilVersion();
+        String schemaVersion = dbSchema.version();
+        checkVersion(schemaVersion, fromVersion, untilVersion);
+    }
+
+    /**
+     * Check whether the DatabaseSchema version between the initial version and
+     * the end of the version.
+     * @param schemaVersion DatabaseSchema version
+     * @param fromVersion The initial version
+     * @param untilVersion The end of the version
+     * @throws VersionMismatchException this is a version mismatch exception
+     */
+    private void checkVersion(String schemaVersion, String fromVersion,
+                              String untilVersion) {
+        VersionUtil.versionMatch(fromVersion);
+        VersionUtil.versionMatch(untilVersion);
+        if (!fromVersion.equals(VersionUtil.DEFAULT_VERSION_STRING)) {
+            if (VersionUtil.versionCompare(schemaVersion, fromVersion) < 0) {
+                String message = VersionMismatchException
+                        .createFromMessage(schemaVersion, fromVersion);
+                throw new VersionMismatchException(message);
+            }
+        }
+        if (!untilVersion.equals(VersionUtil.DEFAULT_VERSION_STRING)) {
+            if (VersionUtil.versionCompare(untilVersion, schemaVersion) < 0) {
+                String message = VersionMismatchException
+                        .createToMessage(schemaVersion, untilVersion);
+                throw new VersionMismatchException(message);
+            }
+        }
+    }
+
+    /**
+     * Returns TableSchema from dbSchema by table name.
+     * @return TableSchema
+     */
+    private TableSchema getTableSchema() {
+        String tableName = tableDesc.name();
+        return dbSchema.getTableSchema(tableName);
+    }
+
+    /**
+     * Returns ColumnSchema from TableSchema by column name.
+     * @param tableSchema TableSchema entity
+     * @param columnName column name
+     * @return ColumnSchema
+     */
+    private ColumnSchema getColumnSchema(TableSchema tableSchema,
+                                         String columnName) {
+        return tableSchema.getColumnSchema(columnName);
+    }
+
+    @Override
+    public Column getColumnHandler(ColumnDescription columnDesc) {
+        if (!isValid()) {
+            return null;
+        }
+        String columnName = columnDesc.name();
+        checkColumnSchemaVersion(columnDesc);
+        if (columnName == null) {
+            throw new TypedSchemaException("Error processing GetColumn : "
+                    + tableDesc.name() + "." + columnDesc.method());
+        }
+        TableSchema tableSchema = getTableSchema();
+        if (tableSchema == null) {
+            String message = TableSchemaNotFoundException
+                    .createMessage(tableDesc.name(), dbSchema.name());
+            throw new TableSchemaNotFoundException(message);
+        }
+        ColumnSchema columnSchema = getColumnSchema(tableSchema, columnName);
+        if (columnSchema == null) {
+            String message = ColumnSchemaNotFoundException
+                    .createMessage(columnName, tableSchema.name());
+            throw new ColumnSchemaNotFoundException(message);
+        }
+        if (row == null) {
+            return new Column(columnSchema, null);
+        }
+        return row.getColumn(columnSchema);
+    }
+
+    @Override
+    public Object getDataHandler(ColumnDescription columnDesc) {
+        if (!isValid()) {
+            return null;
+        }
+        String columnName = columnDesc.name();
+        checkColumnSchemaVersion(columnDesc);
+        if (columnName == null) {
+            throw new TypedSchemaException("Error processing GetColumn : "
+                    + tableDesc.name() + "." + columnDesc.method());
+        }
+        TableSchema tableSchema = getTableSchema();
+        if (tableSchema == null) {
+            String message = TableSchemaNotFoundException
+                    .createMessage(tableDesc.name(), dbSchema.name());
+            throw new TableSchemaNotFoundException(message);
+        }
+        ColumnSchema columnSchema = getColumnSchema(tableSchema, columnName);
+        if (columnSchema == null) {
+            String message = ColumnSchemaNotFoundException
+                    .createMessage(columnName, tableSchema.name());
+            throw new ColumnSchemaNotFoundException(message);
+        }
+        if (row == null || row.getColumn(columnSchema) == null) {
+            return null;
+        }
+        return row.getColumn(columnSchema).data();
+    }
+
+    @Override
+    public void setDataHandler(ColumnDescription columnDesc, Object obj) {
+        if (!isValid()) {
+            return;
+        }
+        String columnName = columnDesc.name();
+        checkColumnSchemaVersion(columnDesc);
+        if (columnName == null) {
+            throw new TypedSchemaException("Unable to locate Column Name for "
+                    + tableDesc.name() + "." + columnDesc.method());
+        }
+        TableSchema tableSchema = getTableSchema();
+        ColumnSchema columnSchema = getColumnSchema(tableSchema, columnName);
+        Column column = new Column(columnSchema, obj);
+        row.addColumn(columnName, column);
+    }
+
+    @Override
+    public Object getTbSchema() {
+        if (!isValid()) {
+            return null;
+        }
+        if (dbSchema == null) {
+            return null;
+        }
+        return getTableSchema();
+    }
+
+    @Override
+    public UUID getUuid() {
+        if (!isValid()) {
+            return null;
+        }
+        ColumnDescription columnDesc = new ColumnDescription("_uuid",
+                                                             "getTbUuid");
+        return (UUID) getDataHandler(columnDesc);
+    }
+
+    @Override
+    public Column getUuidColumn() {
+        if (!isValid()) {
+            return null;
+        }
+        ColumnDescription columnDesc = new ColumnDescription("_uuid",
+                                                             "getTbUuidColumn");
+        return (Column) getColumnHandler(columnDesc);
+    }
+
+    @Override
+    public UUID getVersion() {
+        if (!isValid()) {
+            return null;
+        }
+        ColumnDescription columnDesc = new ColumnDescription("_version",
+                                                             "getTbVersion");
+        return (UUID) getDataHandler(columnDesc);
+    }
+
+    @Override
+    public Column getVersionColumn() {
+        if (!isValid()) {
+            return null;
+        }
+        ColumnDescription columnDesc = new ColumnDescription("_version",
+                                                             "getTbVersionColumn");
+        return (Column) getColumnHandler(columnDesc);
+    }
+
+    /**
+     * Get DatabaseSchema entity.
+     * @return DatabaseSchema entity
+     */
+    public DatabaseSchema dbSchema() {
+        return dbSchema;
+    }
+
+    /**
+     * Get Row entity.
+     * @return Row entity
+     */
+    public Row getRow() {
+        if (!isValid()) {
+            return null;
+        }
+        return this.row;
+    }
+
+    /**
+     * Get TableDescription entity.
+     * @return TableDescription entity
+     */
+    public TableDescription tableDesc() {
+        return tableDesc;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(row);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof AbstractOvsdbTableService) {
+            final AbstractOvsdbTableService other = (AbstractOvsdbTableService) obj;
+            return Objects.equals(this.row, other.row);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        TableSchema schema = (TableSchema) getTbSchema();
+        String tableName = schema.name();
+        return toStringHelper(this).add("tableName", tableName).add("row", row)
+                .toString();
+    }
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/ColumnDescription.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/ColumnDescription.java
new file mode 100644
index 0000000..910b329
--- /dev/null
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/ColumnDescription.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.rfc.tableservice;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.onosproject.ovsdb.rfc.table.VersionNum;
+import org.onosproject.ovsdb.rfc.utils.VersionUtil;
+
+/**
+ * Column description.
+ */
+public class ColumnDescription {
+
+    // The column name
+    private final String name;
+    // The method name
+    private final String method;
+    // The initial version
+    private final String fromVersion;
+    // The end of the version
+    private final String untilVersion;
+
+    /**
+     * Constructs a MonitorRequest object.
+     * @param name column name
+     * @param method method name
+     */
+    public ColumnDescription(String name, String method) {
+        checkNotNull(name, "name cannot be null");
+        checkNotNull(method, "method cannot be null");
+        this.name = name;
+        this.method = method;
+        this.fromVersion = VersionUtil.DEFAULT_VERSION_STRING;
+        this.untilVersion = VersionUtil.DEFAULT_VERSION_STRING;
+    }
+
+    /**
+     * Constructs a MonitorRequest object.
+     * @param name column name
+     * @param method method name
+     * @param fromVersion the initial version
+     */
+    public ColumnDescription(String name, String method, VersionNum fromVersion) {
+        checkNotNull(name, "name cannot be null");
+        checkNotNull(method, "method cannot be null");
+        checkNotNull(fromVersion, "the initial version cannot be null");
+        this.name = name;
+        this.method = method;
+        this.fromVersion = fromVersion.versionNum();
+        this.untilVersion = VersionUtil.DEFAULT_VERSION_STRING;
+    }
+
+    /**
+     * Constructs a MonitorRequest object.
+     * @param name column name
+     * @param method method name
+     * @param fromVersion the initial version
+     * @param untilVersion the end of the version
+     */
+    public ColumnDescription(String name, String method, VersionNum fromVersion,
+                             VersionNum untilVersion) {
+        checkNotNull(name, "name cannot be null");
+        checkNotNull(method, "method cannot be null");
+        checkNotNull(fromVersion, "the initial version cannot be null");
+        checkNotNull(untilVersion, "the end of the version cannot be null");
+        this.name = name;
+        this.method = method;
+        this.fromVersion = fromVersion.versionNum();
+        this.untilVersion = untilVersion.versionNum();
+    }
+
+    /**
+     * Returns the column name.
+     * @return the column name
+     */
+    public String name() {
+        return name;
+    }
+
+    /**
+     * Returns the method name.
+     * @return the method name
+     */
+    public String method() {
+        return method;
+    }
+
+    /**
+     * Returns the initial version.
+     * @return the initial version
+     */
+    public String fromVersion() {
+        return fromVersion;
+    }
+
+    /**
+     * Returns the end of the version.
+     * @return the end of the version
+     */
+    public String untilVersion() {
+        return untilVersion;
+    }
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/OvsdbTableService.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/OvsdbTableService.java
new file mode 100644
index 0000000..3af4c22
--- /dev/null
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/OvsdbTableService.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.rfc.tableservice;
+
+import org.onosproject.ovsdb.rfc.notation.Column;
+import org.onosproject.ovsdb.rfc.notation.UUID;
+
+/**
+ * Representation of conversion between Ovsdb table and Row.
+ */
+public interface OvsdbTableService {
+
+    /**
+     * Get Column from row.
+     * @param columndesc Column description
+     * @return Column
+     */
+    public Column getColumnHandler(ColumnDescription columndesc);
+
+    /**
+     * Get Data from row.
+     * @param columndesc Column description
+     * @return Object column data
+     */
+    public Object getDataHandler(ColumnDescription columndesc);
+
+    /**
+     * Set column data of row.
+     * @param columndesc Column description
+     * @param obj column data
+     */
+    public void setDataHandler(ColumnDescription columndesc, Object obj);
+
+    /**
+     * Returns the TableSchema from row.
+     * @return Object TableSchema
+     */
+    public Object getTbSchema();
+
+    /**
+     * Returns UUID which column name is _uuid.
+     * @return UUID
+     */
+    public UUID getUuid();
+
+    /**
+     * Returns UUID Column which column name is _uuid.
+     * @return UUID Column
+     */
+    public Column getUuidColumn();
+
+    /**
+     * Returns UUID which column name is _version.
+     * @return UUID
+     */
+    public UUID getVersion();
+
+    /**
+     * Returns UUID Column which column name is _version.
+     * @return UUID Column
+     */
+    public Column getVersionColumn();
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/TableDescription.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/TableDescription.java
new file mode 100644
index 0000000..d120cab
--- /dev/null
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/TableDescription.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.rfc.tableservice;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.onosproject.ovsdb.rfc.table.OvsdbTable;
+import org.onosproject.ovsdb.rfc.table.VersionNum;
+import org.onosproject.ovsdb.rfc.utils.VersionUtil;
+
+/**
+ * Table description.
+ */
+public class TableDescription {
+
+    // The table name
+    private final String name;
+    // The database name
+    private final String database = "Open_vSwitch";
+    // The initial version
+    private final String fromVersion;
+    // The end of the version
+    private final String untilVersion;
+
+    /**
+     * Constructs a MonitorRequest object.
+     * @param table OvsdbTable entity
+     */
+    public TableDescription(OvsdbTable table) {
+        checkNotNull(table, "table cannot be null");
+        this.name = table.tableName();
+        this.fromVersion = VersionUtil.DEFAULT_VERSION_STRING;
+        this.untilVersion = VersionUtil.DEFAULT_VERSION_STRING;
+    }
+
+    /**
+     * Constructs a MonitorRequest object.
+     * @param table OvsdbTable entity
+     * @param fromVersion the initial version
+     */
+    public TableDescription(OvsdbTable table, VersionNum fromVersion) {
+        checkNotNull(table, "table cannot be null");
+        checkNotNull(fromVersion, "the initial version cannot be null");
+        this.name = table.tableName();
+        this.fromVersion = fromVersion.versionNum();
+        this.untilVersion = VersionUtil.DEFAULT_VERSION_STRING;
+    }
+
+    /**
+     * Constructs a MonitorRequest object.
+     * @param table OvsdbTable entity
+     * @param fromVersion the initial version
+     * @param untilVersion the end of the version
+     */
+    public TableDescription(OvsdbTable table, VersionNum fromVersion, VersionNum untilVersion) {
+        checkNotNull(table, "table cannot be null");
+        checkNotNull(fromVersion, "the initial version cannot be null");
+        checkNotNull(untilVersion, "the end of the version cannot be null");
+        this.name = table.tableName();
+        this.fromVersion = fromVersion.versionNum();
+        this.untilVersion = untilVersion.versionNum();
+    }
+
+    /**
+     * Returns the column name.
+     * @return the column name
+     */
+    public String name() {
+        return name;
+    }
+
+    /**
+     * Returns the database name.
+     * @return the database name
+     */
+    public String database() {
+        return database;
+    }
+
+    /**
+     * Returns the initial version.
+     * @return the initial version
+     */
+    public String fromVersion() {
+        return fromVersion;
+    }
+
+    /**
+     * Returns the end of the version.
+     * @return the end of the version
+     */
+    public String untilVersion() {
+        return untilVersion;
+    }
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/ConditionUtil.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/ConditionUtil.java
new file mode 100644
index 0000000..527b8bf
--- /dev/null
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/ConditionUtil.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.rfc.utils;
+
+import org.onosproject.ovsdb.rfc.notation.Condition;
+import org.onosproject.ovsdb.rfc.notation.Condition.Function;
+
+/**
+ * Condition utility class.
+ */
+public final class ConditionUtil {
+
+    /**
+     * Constructs a ConditionUtil object. Utility classes should not have a
+     * public or default constructor, otherwise IDE will compile unsuccessfully. This
+     * class should not be instantiated.
+     */
+    private ConditionUtil() {
+    }
+
+    /**
+     * Returns a Condition that means Function.EQUALS .
+     * @param columnName column name
+     * @param data column value
+     * @return Condition
+     */
+    public static Condition equals(String columnName, Object data) {
+        Object value = TransValueUtil.getFormatData(data);
+        return new Condition(columnName, Function.EQUALS, value);
+    }
+
+    /**
+     * Returns a Condition that means Function.NOT_EQUALS .
+     * @param columnName column name
+     * @param data column value
+     * @return Condition
+     */
+    public static Condition unEquals(String columnName, Object data) {
+        Object value = TransValueUtil.getFormatData(data);
+        return new Condition(columnName, Function.NOT_EQUALS, value);
+    }
+
+    /**
+     * Returns a Condition that means Function.GREATER_THAN .
+     * @param columnName column name
+     * @param data column value
+     * @return Condition
+     */
+    public static Condition greaterThan(String columnName, Object data) {
+        Object value = TransValueUtil.getFormatData(data);
+        return new Condition(columnName, Function.GREATER_THAN, value);
+    }
+
+    /**
+     * Returns a Condition that means Function.GREATER_THAN_OR_EQUALS .
+     * @param columnName column name
+     * @param data column value
+     * @return Condition
+     */
+    public static Condition greaterThanOrEquals(String columnName, Object data) {
+        Object value = TransValueUtil.getFormatData(data);
+        return new Condition(columnName, Function.GREATER_THAN_OR_EQUALS, value);
+    }
+
+    /**
+     * Returns a Condition that means Function.LESS_THAN .
+     * @param columnName column name
+     * @param data column value
+     * @return Condition
+     */
+    public static Condition lesserThan(String columnName, Object data) {
+        Object value = TransValueUtil.getFormatData(data);
+        return new Condition(columnName, Function.LESS_THAN, value);
+    }
+
+    /**
+     * Returns a Condition that means Function.LESS_THAN_OR_EQUALS .
+     * @param columnName column name
+     * @param data column value
+     * @return Condition
+     */
+    public static Condition lesserThanOrEquals(String columnName, Object data) {
+        Object value = TransValueUtil.getFormatData(data);
+        return new Condition(columnName, Function.LESS_THAN_OR_EQUALS, value);
+    }
+
+    /**
+     * Returns a Condition that means Function.INCLUDES .
+     * @param columnName column name
+     * @param data column value
+     * @return Condition
+     */
+    public static Condition includes(String columnName, Object data) {
+        Object value = TransValueUtil.getFormatData(data);
+        return new Condition(columnName, Function.INCLUDES, value);
+    }
+
+    /**
+     * Returns a Condition that means Function.EXCLUDES .
+     * @param columnName column name
+     * @param data column value
+     * @return Condition
+     */
+    public static Condition excludes(String columnName, Object data) {
+        Object value = TransValueUtil.getFormatData(data);
+        return new Condition(columnName, Function.EXCLUDES, value);
+    }
+
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/FromJsonUtil.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/FromJsonUtil.java
new file mode 100644
index 0000000..8ccecbe
--- /dev/null
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/FromJsonUtil.java
@@ -0,0 +1,345 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.rfc.utils;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.onosproject.ovsdb.rfc.error.AbnormalSchemaException;
+import org.onosproject.ovsdb.rfc.error.JsonParsingException;
+import org.onosproject.ovsdb.rfc.error.UnknownResultException;
+import org.onosproject.ovsdb.rfc.jsonrpc.Callback;
+import org.onosproject.ovsdb.rfc.jsonrpc.JsonRpcResponse;
+import org.onosproject.ovsdb.rfc.message.OperationResult;
+import org.onosproject.ovsdb.rfc.message.RowUpdate;
+import org.onosproject.ovsdb.rfc.message.TableUpdate;
+import org.onosproject.ovsdb.rfc.message.TableUpdates;
+import org.onosproject.ovsdb.rfc.message.UpdateNotification;
+import org.onosproject.ovsdb.rfc.notation.Column;
+import org.onosproject.ovsdb.rfc.notation.Row;
+import org.onosproject.ovsdb.rfc.notation.UUID;
+import org.onosproject.ovsdb.rfc.operations.Operation;
+import org.onosproject.ovsdb.rfc.schema.ColumnSchema;
+import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
+import org.onosproject.ovsdb.rfc.schema.TableSchema;
+import org.onosproject.ovsdb.rfc.schema.type.ColumnTypeFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+/**
+ * JsonNode utility class. convert JsonNode into Object.
+ */
+public final class FromJsonUtil {
+
+    private static final Logger log = LoggerFactory
+            .getLogger(FromJsonUtil.class);
+
+    /**
+     * Constructs a FromJsonUtil object. Utility classes should not have a
+     * public or default constructor, otherwise IDE will compile unsuccessfully. This
+     * class should not be instantiated.
+     */
+    private FromJsonUtil() {
+    }
+
+    /**
+     * convert JsonNode into DatabaseSchema.
+     * @param dbName database name
+     * @param json the JsonNode of get_schema result
+     * @return DatabaseSchema
+     * @throws JsonParsingException this is a JsonNode parse exception
+     */
+    public static DatabaseSchema jsonNodeToDbSchema(String dbName, JsonNode json) {
+        if (!json.isObject() || !json.has("tables")) {
+            throw new JsonParsingException(
+                                           "bad DatabaseSchema root, expected \"tables\" as child but was not found");
+        }
+        if (!json.isObject() || !json.has("version")) {
+            throw new JsonParsingException(
+                                           "bad DatabaseSchema root, expected \"version\" as child but was not found");
+        }
+
+        String dbVersion = json.get("version").asText();
+
+        Map<String, TableSchema> tables = new HashMap<>();
+        for (Iterator<Map.Entry<String, JsonNode>> iter = json.get("tables")
+                .fields(); iter.hasNext();) {
+            Map.Entry<String, JsonNode> table = iter.next();
+            tables.put(table.getKey(),
+                       jsonNodeToTableSchema(table.getKey(), table.getValue()));
+        }
+
+        return new DatabaseSchema(dbName, dbVersion, tables);
+    }
+
+    /**
+     * convert JsonNode into TableSchema.
+     * @param tableName table name
+     * @param json table JsonNode
+     * @return TableSchema
+     * @throws AbnormalSchemaException this is an abnormal schema exception
+     */
+    private static TableSchema jsonNodeToTableSchema(String tableName,
+                                                     JsonNode json) {
+
+        if (!json.isObject() || !json.has("columns")) {
+            throw new AbnormalSchemaException(
+                                              "bad tableschema root, expected \"columns\" as child");
+        }
+
+        Map<String, ColumnSchema> columns = new HashMap<>();
+        for (Iterator<Map.Entry<String, JsonNode>> iter = json.get("columns")
+                .fields(); iter.hasNext();) {
+            Map.Entry<String, JsonNode> column = iter.next();
+            columns.put(column.getKey(),
+                        jsonNodeToColumnSchema(column.getKey(),
+                                               column.getValue()));
+        }
+
+        return new TableSchema(tableName, columns);
+    }
+
+    /**
+     * convert JsonNode into ColumnSchema.
+     * @param name column name
+     * @param json JsonNode
+     * @return ColumnSchema
+     * @throws AbnormalSchemaException this is an abnormal schema exception
+     */
+    private static ColumnSchema jsonNodeToColumnSchema(String name,
+                                                       JsonNode json) {
+        if (!json.isObject() || !json.has("type")) {
+            throw new AbnormalSchemaException(
+                                              "bad column schema root, expected \"type\" as child");
+        }
+
+        return new ColumnSchema(name,
+                                ColumnTypeFactory.getColumnTypeFromJson(json
+                                        .get("type")));
+    }
+
+    /**
+     * convert JsonNode into the returnType of methods in OvsdbRPC class.
+     * @param resultJsonNode the result JsonNode
+     * @param methodName the method name of methods in OvsdbRPC class
+     * @param objectMapper ObjectMapper entity
+     * @return Object
+     * @throws UnknownResultException this is an unknown result exception
+     */
+    private static Object convertResultType(JsonNode resultJsonNode,
+                                            String methodName,
+                                            ObjectMapper objectMapper) {
+        switch (methodName) {
+        case "getSchema":
+        case "monitor":
+            return resultJsonNode;
+        case "echo":
+        case "listDbs":
+            return objectMapper
+                    .convertValue(resultJsonNode, objectMapper.getTypeFactory()
+                            .constructParametricType(List.class, String.class));
+        case "transact":
+            return objectMapper
+                    .convertValue(resultJsonNode,
+                                  objectMapper
+                                          .getTypeFactory()
+                                          .constructParametricType(List.class,
+                                                                   JsonNode.class));
+        default:
+            throw new UnknownResultException("Don't know how to handle this");
+        }
+    }
+
+    /**
+     * convert JsonNode into the returnType of methods in OvsdbRPC class.
+     * @param jsonNode the result JsonNode
+     * @param methodName the method name of methods in OvsdbRPC class
+     * @return Object
+     */
+    public static Object jsonResultParser(JsonNode jsonNode, String methodName) {
+        ObjectMapper objectMapper = ObjectMapperUtil.getObjectMapper();
+        JsonNode error = jsonNode.get("error");
+        if (error != null && !error.isNull()) {
+            log.error("Error : {}", error.toString());
+        }
+        JsonNode resultJsonNode = jsonNode.get("result");
+        Object result = convertResultType(resultJsonNode, methodName,
+                                          objectMapper);
+        return result;
+    }
+
+    /**
+     * When monitor the ovsdb tables, if a table update, ovs send update
+     * notification, then call callback function.
+     * @param jsonNode the result JsonNode
+     * @param callback the callback function
+     * @throws UnknownResultException this is an unknown result exception
+     */
+    public static void jsonCallbackRequestParser(JsonNode jsonNode,
+                                                 Callback callback) {
+        ObjectMapper objectMapper = ObjectMapperUtil.getObjectMapper();
+        JsonNode params = jsonNode.get("params");
+        Object param = null;
+        String methodName = jsonNode.get("method").asText();
+        switch (methodName) {
+        case "update":
+            param = objectMapper.convertValue(params, UpdateNotification.class);
+            callback.update((UpdateNotification) param);
+            break;
+        default:
+            throw new UnknownResultException("Cannot handle this method: "
+                    + methodName);
+        }
+    }
+
+    /**
+     * Ovs send echo request to keep the heart, need we return echo result.
+     * @param jsonNode the result JsonNode
+     * @return JsonRpcResponse String
+     */
+    public static String getEchoRequestStr(JsonNode jsonNode) {
+        ObjectMapper objectMapper = ObjectMapperUtil.getObjectMapper();
+        String str = null;
+        if (jsonNode.get("method").asText().equals("echo")) {
+            JsonRpcResponse response = new JsonRpcResponse(jsonNode.get("id")
+                    .asText());
+            try {
+                str = objectMapper.writeValueAsString(response);
+            } catch (JsonProcessingException e) {
+                log.error("JsonProcessingException while converting JsonNode into string ", e);
+            }
+        }
+        return str;
+    }
+
+    /**
+     * Convert the List of Operation result into List of OperationResult .
+     * @param input the List of JsonNode
+     * @param operations the List of Operation
+     * @return the List of OperationResult
+     */
+    public static List<OperationResult> jsonNodeToOperationResult(List<JsonNode> input,
+                                                                  List<Operation> operations) {
+        ObjectMapper objectMapper = ObjectMapperUtil.getObjectMapper(false);
+        List<OperationResult> operationResults = new ArrayList<OperationResult>();
+        for (int i = 0; i < input.size(); i++) {
+            JsonNode jsonNode = input.get(i);
+            Operation operation = operations.get(i);
+            if (jsonNode != null && jsonNode.size() > 0) {
+                if (i >= operations.size() || operation.getOp() != "select") {
+                    OperationResult or = objectMapper.convertValue(jsonNode,
+                                                   OperationResult.class);
+                    operationResults.add(or);
+                } else {
+                    List<Row> rows = createRows(operation.getTableSchema(), jsonNode);
+                    OperationResult or = new OperationResult(rows);
+                    operationResults.add(or);
+                }
+            }
+        }
+        return operationResults;
+    }
+
+    /**
+     * Convert Operation JsonNode into Rows.
+     * @param tableSchema TableSchema entity
+     * @param rowsNode JsonNode
+     * @return ArrayList<Row> the List of Row
+     */
+    private static ArrayList<Row> createRows(TableSchema tableSchema,
+                                             JsonNode rowsNode) {
+        ArrayList<Row> rows = Lists.newArrayList();
+        for (JsonNode rowNode : rowsNode.get("rows")) {
+            rows.add(createRow(tableSchema, rowNode));
+        }
+        return rows;
+    }
+
+    /**
+     * convert the params of Update Notification into TableUpdates.
+     * @param updatesJson the params of Update Notification
+     * @param dbSchema DatabaseSchema entity
+     * @return TableUpdates
+     */
+    public static TableUpdates jsonNodeToTableUpdates(JsonNode updatesJson,
+                                                      DatabaseSchema dbSchema) {
+        Map<String, TableUpdate> tableUpdateMap = Maps.newHashMap();
+        for (Iterator<Map.Entry<String, JsonNode>> itr = updatesJson.fields(); itr
+                .hasNext();) {
+            Map.Entry<String, JsonNode> entry = itr.next();
+            TableSchema tableSchema = dbSchema.getTableSchema(entry.getKey());
+            TableUpdate tableUpdate = jsonNodeToTableUpdate(tableSchema,
+                                                            entry.getValue());
+            tableUpdateMap.put(entry.getKey(), tableUpdate);
+        }
+        return TableUpdates.tableUpdates(tableUpdateMap);
+    }
+
+    /**
+     * convert the params of Update Notification into TableUpdate.
+     * @param tableSchema TableSchema entity
+     * @param value the table-update in params of Update Notification
+     * @return TableUpdate
+     */
+    public static TableUpdate jsonNodeToTableUpdate(TableSchema tableSchema,
+                                                    JsonNode value) {
+        Map<UUID, RowUpdate> rows = Maps.newHashMap();
+        Iterator<Entry<String, JsonNode>> fields = value.fields();
+        while (fields.hasNext()) {
+            Map.Entry<String, JsonNode> idOldNew = fields.next();
+            String uuidStr = idOldNew.getKey();
+            UUID uuid = UUID.uuid(uuidStr);
+            JsonNode newR = idOldNew.getValue().get("new");
+            JsonNode oldR = idOldNew.getValue().get("old");
+            Row newRow = newR != null ? createRow(tableSchema, newR) : null;
+            Row oldRow = oldR != null ? createRow(tableSchema, oldR) : null;
+            RowUpdate rowUpdate = new RowUpdate(uuid, oldRow, newRow);
+            rows.put(uuid, rowUpdate);
+        }
+        return TableUpdate.tableUpdate(rows);
+    }
+
+    /**
+     * Convert Operation JsonNode into Row.
+     * @param tableSchema TableSchema entity
+     * @param rowNode JsonNode
+     * @return Row
+     */
+    private static Row createRow(TableSchema tableSchema, JsonNode rowNode) {
+        List<Column> columns = Lists.newArrayList();
+        for (Iterator<Map.Entry<String, JsonNode>> iter = rowNode.fields(); iter
+                .hasNext();) {
+            Map.Entry<String, JsonNode> next = iter.next();
+            ColumnSchema schema = tableSchema.getColumnSchema(next.getKey());
+            if (schema != null) {
+                Object o = TransValueUtil.getValueFromJson(next.getValue(), schema.type());
+                columns.add(new Column(schema, o));
+            }
+        }
+        return new Row(tableSchema, columns);
+    }
+
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/JsonRpcReaderUtil.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/JsonRpcReaderUtil.java
new file mode 100644
index 0000000..bf1938d
--- /dev/null
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/JsonRpcReaderUtil.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.rfc.utils;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufInputStream;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Stack;
+
+import org.onosproject.ovsdb.rfc.error.UnsupportedEncodingException;
+import org.onosproject.ovsdb.rfc.jsonrpc.JsonReadContext;
+
+import com.fasterxml.jackson.core.JsonEncoding;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.io.IOContext;
+import com.fasterxml.jackson.core.json.ByteSourceJsonBootstrapper;
+import com.fasterxml.jackson.core.util.BufferRecycler;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.MappingJsonFactory;
+
+/**
+ * Decoder utility class.
+ */
+public final class JsonRpcReaderUtil {
+
+    /**
+     * Constructs a JsonRpcReaderUtil object. Utility classes should not have a
+     * public or default constructor, otherwise IDE will compile unsuccessfully.
+     * This class should not be instantiated.
+     */
+    private JsonRpcReaderUtil() {
+    }
+
+    /**
+     * Decode the bytes to Json object.
+     * @param in input of bytes
+     * @param out ouput of Json object list
+     * @param jrContext context for the last decoding process
+     * @throws IOException IOException
+     * @throws JsonParseException JsonParseException
+     */
+    public static void readToJsonNode(ByteBuf in, List<Object> out,
+                                      JsonReadContext jrContext)
+            throws JsonParseException, IOException {
+        int lastReadBytes = jrContext.getLastReadBytes();
+        if (lastReadBytes == 0) {
+            if (in.readableBytes() < 4) {
+                return;
+            }
+            checkEncoding(in);
+        }
+
+        int i = lastReadBytes + in.readerIndex();
+        Stack<Byte> bufStack = jrContext.getBufStack();
+        for (; i < in.writerIndex(); i++) {
+            byte b = in.getByte(i);
+            switch (b) {
+            case '{':
+                if (!isDoubleQuote(bufStack)) {
+                    bufStack.push(b);
+                    jrContext.setStartMatch(true);
+                }
+                break;
+            case '}':
+                if (!isDoubleQuote(bufStack)) {
+                    bufStack.pop();
+                }
+                break;
+            case '"':
+                if (in.getByte(i - 1) != '\\') {
+                    if (!bufStack.isEmpty() && bufStack.peek() != '"') {
+                        bufStack.push(b);
+                    } else {
+                        bufStack.pop();
+                    }
+                }
+                break;
+            default:
+                break;
+            }
+
+            if (jrContext.isStartMatch() && bufStack.isEmpty()) {
+                ByteBuf buf = in.readSlice(i - in.readerIndex() + 1);
+                JsonParser jf = new MappingJsonFactory()
+                        .createParser(new ByteBufInputStream(buf));
+                JsonNode jsonNode = jf.readValueAsTree();
+                out.add(jsonNode);
+                lastReadBytes = 0;
+                jrContext.setLastReadBytes(lastReadBytes);
+                break;
+            }
+        }
+
+        if (i >= in.writerIndex()) {
+            lastReadBytes = in.readableBytes();
+            jrContext.setLastReadBytes(lastReadBytes);
+        }
+    }
+
+    /**
+     * Filter the invalid characters before decoding.
+     * @param in input of bytes
+     * @param lastReadBytes the bytes for last decoding incomplete record
+     */
+    private static void fliterCharaters(ByteBuf in) {
+        while (in.isReadable()) {
+            int ch = in.getByte(in.readerIndex());
+            if ((ch != ' ') && (ch != '\n') && (ch != '\t') && (ch != '\r')) {
+                break;
+            } else {
+                in.readByte();
+            }
+        }
+    }
+
+    /**
+     * Check whether the peek of the stack element is double quote.
+     * @param jrContext context for the last decoding process
+     * @return boolean
+     */
+    private static boolean isDoubleQuote(Stack<Byte> bufStack) {
+        if (!bufStack.isEmpty() && bufStack.peek() == '"') {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Check whether the encoding is valid.
+     * @param in input of bytes
+     * @throws IOException this is an IO exception
+     * @throws UnsupportedEncodingException this is an unsupported encode
+     *             exception
+     */
+    private static void checkEncoding(ByteBuf in) throws IOException {
+        int inputStart = 0;
+        int inputLength = 4;
+        fliterCharaters(in);
+        byte[] buff = new byte[4];
+        in.getBytes(in.readerIndex(), buff);
+        ByteSourceJsonBootstrapper strapper = new ByteSourceJsonBootstrapper(
+                                                                             new IOContext(
+                                                                                           new BufferRecycler(),
+                                                                                           null,
+                                                                                           false),
+                                                                             buff,
+                                                                             inputStart,
+                                                                             inputLength);
+        JsonEncoding jsonEncoding = strapper.detectEncoding();
+        if (!JsonEncoding.UTF8.equals(jsonEncoding)) {
+            throw new UnsupportedEncodingException(
+                                                   "Only UTF-8 encoding is supported.");
+        }
+    }
+
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/JsonRpcWriterUtil.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/JsonRpcWriterUtil.java
new file mode 100644
index 0000000..7511c36
--- /dev/null
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/JsonRpcWriterUtil.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.rfc.utils;
+
+import java.util.List;
+
+import org.onosproject.ovsdb.rfc.jsonrpc.JsonRpcRequest;
+import org.onosproject.ovsdb.rfc.operations.Operation;
+import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
+
+/**
+ * RPC Methods request utility class. Refer to RFC7047's Section 4.1.
+ */
+public final class JsonRpcWriterUtil {
+
+    /**
+     * Constructs a JsonRpcWriterUtil object. Utility classes should not have a
+     * public or default constructor, otherwise IDE will compile unsuccessfully.
+     * This class should not be instantiated.
+     */
+    private JsonRpcWriterUtil() {
+    }
+
+    /**
+     * Returns string of RPC request.
+     * @param uuid id of request object
+     * @param methodName method of request object
+     * @param params params of request object
+     * @return RPC Request String
+     */
+    private static String getRequestStr(String uuid, String methodName,
+                                        List params) {
+        JsonRpcRequest request;
+        if (params != null) {
+            request = new JsonRpcRequest(uuid, methodName, params);
+        } else {
+            request = new JsonRpcRequest(uuid, methodName);
+        }
+        String str = ObjectMapperUtil.convertToString(request);
+        return str;
+    }
+
+    /**
+     * Returns string of get_schema request.
+     * @param uuid id of get_schema request
+     * @param dbnames params of get_schema request
+     * @return get_schema Request String
+     */
+    public static String getSchemaStr(String uuid, List<String> dbnames) {
+        String methodName = "get_schema";
+        return getRequestStr(uuid, methodName, dbnames);
+    }
+
+    /**
+     * Returns string of echo request.
+     * @param uuid id of echo request
+     * @return echo Request String
+     */
+    public static String echoStr(String uuid) {
+        String methodName = "echo";
+        return getRequestStr(uuid, methodName, null);
+    }
+
+    /**
+     * Returns string of monitor request.
+     * @param uuid id of monitor request
+     * @param monotorId json-value in params of monitor request
+     * @param dbSchema DatabaseSchema entity
+     * @return monitor Request String
+     */
+    public static String monitorStr(String uuid, String monotorId,
+                                    DatabaseSchema dbSchema) {
+        String methodName = "monitor";
+        return getRequestStr(uuid, methodName,
+                             ParamUtil.getMonitorParams(monotorId, dbSchema));
+    }
+
+    /**
+     * Returns string of list_dbs request.
+     * @param uuid id of list_dbs request
+     * @return list_dbs Request String
+     */
+    public static String listDbsStr(String uuid) {
+        String methodName = "list_dbs";
+        return getRequestStr(uuid, methodName, null);
+    }
+
+    /**
+     * Returns string of transact request.
+     * @param uuid id of transact request
+     * @param dbSchema DatabaseSchema entity
+     * @param operations operation* in params of transact request
+     * @return transact Request String
+     */
+    public static String transactStr(String uuid, DatabaseSchema dbSchema,
+                                     List<Operation> operations) {
+        String methodName = "transact";
+        return getRequestStr(uuid, methodName,
+                             ParamUtil.getTransactParams(dbSchema, operations));
+    }
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/MutationUtil.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/MutationUtil.java
new file mode 100644
index 0000000..5ab2b7a
--- /dev/null
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/MutationUtil.java
@@ -0,0 +1,92 @@
+package org.onosproject.ovsdb.rfc.utils;
+
+import org.onosproject.ovsdb.rfc.notation.Mutation;
+import org.onosproject.ovsdb.rfc.notation.Mutation.Mutator;
+
+public final class MutationUtil {
+
+    /**
+     * Constructs a MutationUtil object. Utility classes should not have a
+     * public or default constructor, otherwise IDE will compile unsuccessfully. This
+     * class should not be instantiated.
+     */
+    private MutationUtil() {
+    }
+
+    /**
+     * Returns a Mutation that means += .
+     * @param columnName column name
+     * @param data column value
+     * @return Mutation
+     */
+    public static Mutation sum(String columnName, Object data) {
+        Object value = TransValueUtil.getFormatData(data);
+        return new Mutation(columnName, Mutator.SUM, value);
+    }
+
+    /**
+     * Returns a Mutation that means -= .
+     * @param columnName column name
+     * @param data column value
+     * @return Mutation
+     */
+    public static Mutation difference(String columnName, Object data) {
+        Object value = TransValueUtil.getFormatData(data);
+        return new Mutation(columnName, Mutator.DIFFERENCE, value);
+    }
+
+    /**
+     * Returns a Mutation that means *= .
+     * @param columnName column name
+     * @param data column value
+     * @return Mutation
+     */
+    public static Mutation product(String columnName, Object data) {
+        Object value = TransValueUtil.getFormatData(data);
+        return new Mutation(columnName, Mutator.PRODUCT, value);
+    }
+
+    /**
+     * Returns a Mutation that means /= .
+     * @param columnName column name
+     * @param data column value
+     * @return Mutation
+     */
+    public static Mutation quotient(String columnName, Object data) {
+        Object value = TransValueUtil.getFormatData(data);
+        return new Mutation(columnName, Mutator.QUOTIENT, value);
+    }
+
+    /**
+     * Returns a Mutation that means %= .
+     * @param columnName column name
+     * @param data column value
+     * @return Mutation
+     */
+    public static Mutation remainder(String columnName, Object data) {
+        Object value = TransValueUtil.getFormatData(data);
+        return new Mutation(columnName, Mutator.REMAINDER, value);
+    }
+
+    /**
+     * Returns a Mutation that means insert .
+     * @param columnName column name
+     * @param data column value
+     * @return Mutation
+     */
+    public static Mutation insert(String columnName, Object data) {
+        Object value = TransValueUtil.getFormatData(data);
+        return new Mutation(columnName, Mutator.INSERT, value);
+    }
+
+    /**
+     * Returns a Mutation that means delete .
+     * @param columnName column name
+     * @param data column value
+     * @return Mutation
+     */
+    public static Mutation delete(String columnName, Object data) {
+        Object value = TransValueUtil.getFormatData(data);
+        return new Mutation(columnName, Mutator.DELETE, value);
+    }
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/ParamUtil.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/ParamUtil.java
new file mode 100644
index 0000000..d11356e
--- /dev/null
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/ParamUtil.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.rfc.utils;
+
+import java.util.List;
+import java.util.Set;
+
+import org.onosproject.ovsdb.rfc.message.MonitorRequest;
+import org.onosproject.ovsdb.rfc.message.MonitorSelect;
+import org.onosproject.ovsdb.rfc.operations.Operation;
+import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
+import org.onosproject.ovsdb.rfc.schema.TableSchema;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+/**
+ * Params utility class. Params of the request object, refer to RFC7047's Section
+ * 4.1.
+ */
+public final class ParamUtil {
+
+    /**
+     * Constructs a ParamUtil object. Utility classes should not have a
+     * public or default constructor, otherwise IDE will compile unsuccessfully. This
+     * class should not be instantiated.
+     */
+    private ParamUtil() {
+    }
+
+    /**
+     * Returns MonitorRequest, refer to RFC7047's Section 4.1.5.
+     * @param tableSchema entity
+     * @return MonitorRequest
+     */
+    private static MonitorRequest getAllColumnsMonitorRequest(TableSchema tableSchema) {
+        String tableName = tableSchema.name();
+        Set<String> columns = tableSchema.getColumnNames();
+        MonitorSelect select = new MonitorSelect(true, true, true, true);
+        MonitorRequest monitorRequest = new MonitorRequest(tableName, columns,
+                                                           select);
+        return monitorRequest;
+    }
+
+    /**
+     * Returns params of monitor method, refer to RFC7047's Section 4.1.5.
+     * @param monotorId json-value, refer to RFC7047's Section 4.1.5.
+     * @param dbSchema DatabaseSchema entity
+     * @return List of Object, the params of monitor request
+     */
+    public static List<Object> getMonitorParams(String monotorId,
+                                                DatabaseSchema dbSchema) {
+        Set<String> tables = dbSchema.getTableNames();
+        List<MonitorRequest> monitorRequests = Lists.newArrayList();
+        for (String tableName : tables) {
+            TableSchema tableSchema = dbSchema.getTableSchema(tableName);
+            monitorRequests.add(getAllColumnsMonitorRequest(tableSchema));
+        }
+        ImmutableMap<String, MonitorRequest> reqMap = Maps
+                .uniqueIndex(monitorRequests,
+                             new Function<MonitorRequest, String>() {
+                                 @Override
+                                 public String apply(MonitorRequest input) {
+                                     return input.getTableName();
+                                 }
+                             });
+        return Lists.<Object>newArrayList(dbSchema.name(), monotorId,
+                                           reqMap);
+    }
+
+    /**
+     * Returns params of transact method, refer to RFC7047's Section 4.1.3.
+     * @param dbSchema DatabaseSchema entity
+     * @param operations operation*, refer to RFC7047's Section 4.1.3.
+     * @return List of Object, the params of transact request
+     */
+    public static List<Object> getTransactParams(DatabaseSchema dbSchema,
+                                                 List<Operation> operations) {
+        List<Object> lists = Lists.newArrayList((Object) dbSchema.name());
+        lists.addAll(operations);
+        return lists;
+    }
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/StringEncoderUtil.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/StringEncoderUtil.java
new file mode 100644
index 0000000..0e414d8
--- /dev/null
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/StringEncoderUtil.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.rfc.utils;
+
+import io.netty.handler.codec.string.StringEncoder;
+import io.netty.util.CharsetUtil;
+
+/**
+ * StringEncoder utility class.Only UTF-8 encoding is supported refer to
+ * RFC7047's Section 3.1.
+ */
+public final class StringEncoderUtil {
+
+    /**
+     * Constructs a StringEncoderUtil object. Utility classes should not have a
+     * public or default constructor, otherwise IDE will compile unsuccessfully. This
+     * class should not be instantiated.
+     */
+    private StringEncoderUtil() {
+    }
+
+    /**
+     * Returns StringEncoder of UTF_8 .
+     * @return StringEncoder
+     */
+    public static StringEncoder getEncoder() {
+        return new StringEncoder(CharsetUtil.UTF_8);
+    }
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/VersionUtil.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/VersionUtil.java
new file mode 100644
index 0000000..9c5e970
--- /dev/null
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/VersionUtil.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ovsdb.rfc.utils;
+
+/**
+ * Version utility class.
+ */
+public final class VersionUtil {
+
+    /**
+     * Constructs a VersionUtil object. Utility classes should not have a public
+     * or default constructor, otherwise IDE will compile unsuccessfully. This
+     * class should not be instantiated.
+     */
+    private VersionUtil() {
+    }
+
+    public static final String DEFAULT_VERSION_STRING = "0.0.0";
+    private static final String FORMAT = "(\\d+)\\.(\\d+)\\.(\\d+)";
+
+    /**
+     * Match version by the format.
+     * @param version the version String
+     * @throws IllegalArgumentException this is an illegal argument exception
+     */
+    public static void versionMatch(String version) {
+        if (!version.matches(FORMAT)) {
+            throw new IllegalArgumentException("<" + version
+                    + "> does not match format " + FORMAT);
+        }
+    }
+
+    /**
+     * Compare fromVersion and toVersion.
+     * @param fromVersion the initial version
+     * @param toVersion the end of the version
+     * @return a long number
+     */
+    public static long versionCompare(String fromVersion, String toVersion) {
+        Long fromNum = Long.parseLong(fromVersion.replace(".", ""));
+        Long toNum = Long.parseLong(toVersion.replace(".", ""));
+        return (fromNum - toNum);
+    }
+}
