All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.onosproject.ovsdb.rfc.utils.FromJsonUtil Maven / Gradle / Ivy

There is a newer version: 1.6.0
Show newest version
/*
 * 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 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;
import org.onosproject.ovsdb.rfc.exception.AbnormalJsonNodeException;
import org.onosproject.ovsdb.rfc.exception.UnsupportedException;
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 java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 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() {
    }

    /**
     * Verify whether the jsonNode is normal.
     * @param jsonNode JsonNode
     * @param nodeStr the node name of JsonNode
     */
    private static void validateJsonNode(JsonNode jsonNode, String nodeStr) {
        if (!jsonNode.isObject() || !jsonNode.has(nodeStr)) {
            String message = "Abnormal DatabaseSchema JsonNode, it should contain " + nodeStr
                    + " node but was not found";
            throw new AbnormalJsonNodeException(message);
        }
    }

    /**
     * convert JsonNode into DatabaseSchema.
     * @param dbName database name
     * @param dbJson the JsonNode of get_schema result
     * @return DatabaseSchema
     * @throws AbnormalJsonNodeException this is an abnormal JsonNode exception
     */
    public static DatabaseSchema jsonNodeToDbSchema(String dbName, JsonNode dbJson) {
        validateJsonNode(dbJson, "tables");
        validateJsonNode(dbJson, "version");
        String dbVersion = dbJson.get("version").asText();
        Map tables = new HashMap<>();
        Iterator> tablesIter = dbJson.get("tables").fields();
        while (tablesIter.hasNext()) {
            Map.Entry table = tablesIter.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 tableJson table JsonNode
     * @return TableSchema
     * @throws AbnormalJsonNodeException this is an abnormal JsonNode exception
     */
    private static TableSchema jsonNodeToTableSchema(String tableName, JsonNode tableJson) {
        validateJsonNode(tableJson, "columns");
        Map columns = new HashMap<>();
        Iterator> columnsIter = tableJson.get("columns").fields();
        while (columnsIter.hasNext()) {
            Map.Entry column = columnsIter.next();
            columns.put(column.getKey(), jsonNodeToColumnSchema(column.getKey(), column.getValue()));
        }
        return new TableSchema(tableName, columns);
    }

    /**
     * convert JsonNode into ColumnSchema.
     * @param name column name
     * @param columnJson column JsonNode
     * @return ColumnSchema
     * @throws AbnormalJsonNodeException this is an abnormal JsonNode exception
     */
    private static ColumnSchema jsonNodeToColumnSchema(String name, JsonNode columnJson) {
        validateJsonNode(columnJson, "type");
        return new ColumnSchema(name, ColumnTypeFactory.getColumnTypeFromJson(columnJson
                .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 UnsupportedException this is an unsupported 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 UnsupportedException("does not support this rpc method" + methodName);
        }
    }

    /**
     * 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("jsonRpcResponse 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 UnsupportedException this is an unsupported 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 UnsupportedException("does not support this callback 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 jsonNodeToOperationResult(List input,
                                                                  List operations) {
        ObjectMapper objectMapper = ObjectMapperUtil.getObjectMapper(false);
        List operationResults = new ArrayList();
        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().equals("select")) {
                    OperationResult or = objectMapper.convertValue(jsonNode, OperationResult.class);
                    operationResults.add(or);
                } else {
                    List 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 the List of Row
     */
    private static ArrayList createRows(TableSchema tableSchema, JsonNode rowsNode) {
        validateJsonNode(rowsNode, "rows");
        ArrayList rows = Lists.newArrayList();
        for (JsonNode rowNode : rowsNode.get("rows")) {
            rows.add(createRow(tableSchema, null, rowNode)); //FIXME null will throw exception
        }
        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 tableUpdateMap = Maps.newHashMap();
        Iterator> tableUpdatesItr = updatesJson.fields();
        while (tableUpdatesItr.hasNext()) {
            Map.Entry entry = tableUpdatesItr.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 updateJson the table-update in params of Update Notification
     * @return TableUpdate
     */
    public static TableUpdate jsonNodeToTableUpdate(TableSchema tableSchema, JsonNode updateJson) {
        Map rows = Maps.newHashMap();
        Iterator> tableUpdateItr = updateJson.fields();
        while (tableUpdateItr.hasNext()) {
            Map.Entry oldNewRow = tableUpdateItr.next();
            String uuidStr = oldNewRow.getKey();
            Uuid uuid = Uuid.uuid(uuidStr);
            JsonNode newR = oldNewRow.getValue().get("new");
            JsonNode oldR = oldNewRow.getValue().get("old");
            Row newRow = newR != null ? createRow(tableSchema, uuid, newR) : null;
            Row oldRow = oldR != null ? createRow(tableSchema, uuid, 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, Uuid uuid, JsonNode rowNode) {
        if (tableSchema == null) {
            return null;
        }
        Map columns = Maps.newHashMap();
        Iterator> rowIter = rowNode.fields();
        while (rowIter.hasNext()) {
            Map.Entry next = rowIter.next();
            ColumnSchema columnSchema = tableSchema.getColumnSchema(next.getKey());
            if (columnSchema != null) {
                String columnName = columnSchema.name();
                Object obj = TransValueUtil.getValueFromJson(next.getValue(), columnSchema.type());
                columns.put(columnName, new Column(columnName, obj));
            }
        }
        return new Row(tableSchema.name(), uuid, columns);
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy