[ONOS-2447]RFC7047's API and its implementation and five main tables.
provide RFC7047's API and its implementation, and five main table which
contain Bridge, Controller, Interface, Open_vSwitch and Port
Change-Id: I9e995a056fd55c986f5866c85ac712f1792cff4f
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);
+ }
+}