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

oracle.kv.util.shell.ShellCommandResult Maven / Gradle / Ivy

Go to download

NoSQL Database Server - supplies build and runtime support for the server (store) side of the Oracle NoSQL Database.

The newest version!
/*-
 * Copyright (C) 2011, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This file was distributed by Oracle as part of a version of Oracle NoSQL
 * Database made available at:
 *
 * http://www.oracle.com/technetwork/database/database-technologies/nosqldb/downloads/index.html
 *
 * Please see the LICENSE file included in the top-level directory of the
 * appropriate version of Oracle NoSQL Database for a copy of the license and
 * additional information.
 */

package oracle.kv.util.shell;

import java.io.IOException;
import java.util.Iterator;
import java.util.Map.Entry;

import oracle.kv.impl.admin.CommandJsonUtils;
import oracle.kv.impl.admin.CommandResult;
import oracle.kv.impl.util.JsonUtils;
import oracle.kv.util.ErrorMessage;

import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.ObjectWriter;
import org.codehaus.jackson.node.ArrayNode;
import org.codehaus.jackson.node.ObjectNode;

/**
 * 

* This is the POJO class for all the shell command execution result. In admin * CLI, the output of a command will be turn into this class before * display in the admin console. ShellCommandResult will then handle the * conversion of the command result to meaningful JSON string. The fields in * the JSON are mapping to fields in ShellCommandResult. ShellCommandResult * consists of following fields: *

* operation - The name of the executing operation, in most cases it will be * the same as command name. If there is internal level operation failure, the * operation field may be the name to indicate the internal operation. *

* returnCode - The number to indicate the command result return to caller. * For admin CLI result, 5000 return code indicate the successful execution of * operation, return code greater than 5000 indicate a operation failure. *

* description - This field store the string description of command result. * The description field store information that human readable. It is used * when some command results require manual operation on the JSON result. If * the command is failed, the message information will be stored in description * field. It is not recommended to use description field to do any automation, * programmer should instead use returnCode and returnValue fields for admin * CLI automation purpose. *

* returnValue - This field stores a JSON object. The JSON object field has * no fixed schema. Most of useful information retrieved from server should be * stored in returnValue field. The mapping class of returnValue field is * ObjectNode from "org.codehaus.jackson" implementation of JSON. Below is an * example of converting between ObjectNode and string: *

 * String jsonString = "{\"jsonExmaple\":\"field value\"}"
 * ObjectMapper mapper = new ObjectMapper();
 * ObjectNode on = mapper.readValue(jsonString, ObjectMapper.class);
 *
 * String convertBackToString = mapper.writeValueAsString(on);
 * 

* The following will show an example that run an admin CLI command with JSON * flag, the output will map to fields in ShellCommandResult: * *

 * {@literal kv->} show users -json
 * {
 *  "operation" : "show user",
 *  "returnCode" : 5000,
 *  "description" : "Operation ends successfully",
 *  "returnValue" : {
 *    "users" : [ {
 *      "user" : "id=u1 name=root"
 *    } ]
 *  }
 *}
 *
 */
public class ShellCommandResult {

    public static final String SUCCESS_MESSAGE =
        "Operation ends successfully";

    public static final String CONVERSION_FAILURE_MESSAGE =
        "Fail to convert JSON string";

    public static final String UNSUPPORTED_MESSAGE =
        "JSON output does not suppport.";

    private String operation;

    private int returnCode;

    private String description;

    private ObjectNode returnValue;

    public ShellCommandResult() {}

    public ShellCommandResult(String operation,
                              int returnCode,
                              String description,
                              ObjectNode returnValue) {
        this.operation = operation;
        this.returnCode = returnCode;
        this.description = description;
        this.returnValue = returnValue;
    }

    public String getOperation() {
        return operation;
    }

    public void setOperation(String operation) {
        this.operation = operation;
    }

    public int getReturnCode() {
        return returnCode;
    }

    public void setReturnCode(int returnCode) {
        this.returnCode = returnCode;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public ObjectNode getReturnValue() {
        return returnValue;
    }

    public void setReturnValue(ObjectNode returnValue) {
        this.returnValue = returnValue;
    }

    /**
     * Convert this object to JSON string.
     */
    public String convertToJson() throws IOException {
        final ObjectWriter ow = JsonUtils.createWriter(true);
        return ow.writeValueAsString(this);
    }

    /**
     * Get the JSON output for conversion failure.
     */
    public String getConversionErrorJsonResult(Exception e) {
        return "{" + Shell.eolt +
               "\"operation\" : \"" + getOperation() + "\"," +
               Shell.eolt +
               "\"returnCode\" : 5500," + Shell.eolt +
               "\"description\" : " +
               "\"Exception in generating JSON format result: " +
               e.getMessage() + "\"," + Shell.eolt +
               "\"returnValue\" : " + null +
               Shell.eolt +
               "}";
    }

    /**
     * Return default instance of this class. By default, the return code is
     * 5000 indicate a successful operation.
     */
    public static ShellCommandResult getDefault(String operaionName) {
        final ShellCommandResult scr = new ShellCommandResult();
        scr.setOperation(operaionName);
        scr.setReturnCode(ErrorMessage.NOSQL_5000.getValue());
        scr.setDescription(SUCCESS_MESSAGE);
        return scr;
    }

    /**
     * 

* Convert the JSON v1 admin CLI result string to ShellCommandResult. * Specifically, the following fields will be parsed to map fields in * ShellCommandResult: *

     * {@literal
     * operation -> operation
     * return_code -> returnCode
     * description -> description
     * return_value -> returnValue
     * }
     * 

* cmd_cleanup_job will be removed from previous JSON output. *

* returnValue field is an ObjectNode which can host other JSON structures. * For all other fields from JSON v1 admin CLI output, ShellCommandResult * will move those fields to be wrapped by returnValue field. If any field * name is detected as name_with_underscore, it will convert the * name_with_underscore to nameWithUnderscore to meet the new convention. */ public static ShellCommandResult filterJsonV1Result(String input) throws IOException { final ShellCommandResult scr = new ShellCommandResult(); final ObjectNode v1Result = CommandJsonUtils.readObjectValue(input); final JsonNode operation = v1Result.remove(CommandJsonUtils.FIELD_OPERATION); final JsonNode returnCode = v1Result.remove(CommandJsonUtils.FIELD_RETURN_CODE); final JsonNode description = v1Result.remove(CommandJsonUtils.FIELD_DESCRIPTION); final JsonNode returnValue = v1Result.remove(CommandJsonUtils.FIELD_RETURN_VALUE); v1Result.remove(CommandJsonUtils.FIELD_CLEANUP_JOB); if (operation == null || returnCode == null || description == null) { throw new IOException("Fail to convert JSON result, " + "one of following fields is null: " + CommandJsonUtils.FIELD_OPERATION + ", " + CommandJsonUtils.FIELD_RETURN_CODE + ", " + CommandJsonUtils.FIELD_DESCRIPTION); } scr.setOperation(operation.asText()); scr.setReturnCode(returnCode.asInt()); scr.setDescription(description.asText()); if (returnValue != null) { if (!(returnValue instanceof ObjectNode)) { throw new IOException( "Fail to convert return value, " + "return value is not instance of ObjectNode"); } final ObjectNode v1ReturnValue = (ObjectNode)returnValue; final ObjectNode convertedNode = convertFields(v1ReturnValue); final Iterator> iter = convertedNode.getFields(); /* merge return value fields with v1 result fields */ while(iter.hasNext()) { final Entry entry = iter.next(); v1Result.put(entry.getKey(), entry.getValue()); } } scr.setReturnValue(convertFields(v1Result)); return scr; } private static ObjectNode convertFields(ObjectNode v1Node) throws IOException { final ObjectNode result = JsonUtils.createObjectNode(); final Iterator> iter = v1Node.getFields(); while(iter.hasNext()) { final Entry entry = iter.next(); final String key = entry.getKey(); final String resultKey = translateV1Key(key); if (entry.getValue() instanceof ObjectNode) { final ObjectNode innerNode = (ObjectNode)entry.getValue(); result.put(resultKey, convertFields(innerNode)); } else if (entry.getValue() instanceof ArrayNode) { final ArrayNode innerNode = (ArrayNode)entry.getValue(); result.put(resultKey, convertFields(innerNode)); } else { result.put(resultKey, entry.getValue()); } } return result; } private static ArrayNode convertFields(ArrayNode v1Node) throws IOException { final ArrayNode resultNode = JsonUtils.createArrayNode(); final Iterator iter = v1Node.getElements(); while(iter.hasNext()) { final JsonNode element = iter.next(); if (element instanceof ObjectNode) { final ObjectNode innerNode = (ObjectNode)element; resultNode.add(convertFields(innerNode)); } else if (element instanceof ArrayNode) { final ArrayNode innerNode = (ArrayNode)element; resultNode.add(convertFields(innerNode)); } else { resultNode.add(element); } } return resultNode; } /* * Convert the field_with_underscore to camelCase. */ private static String translateV1Key(String key) throws IOException { final int index = key.indexOf("_"); if (index == -1) { return key; } if (key.startsWith("_") || key.endsWith("_")) { throw new IOException( "Unexpected result. Fail to convert key: " + key); } String firstComp = key.substring(0, index); String upperCase = key.substring(index + 1, index + 2).toUpperCase(); String lastComp = upperCase + key.substring(index + 2); return firstComp + translateV1Key(lastComp); } /* * Convert the previous CommandResult plus name to map the JSON output of * ShellCommandResult. This method is mostly used in exception handling * part of shell command execution. Previously, the JSON output for shell * exception handling has been implemented in along the CommandResult, * all the related exeception contains a CommandResult. This method is to * convert the information in CommandResult to match the new JSON output * format. */ public static String toJsonReport(String command, CommandResult cmdResult) { try { final ShellCommandResult scr = new ShellCommandResult(); scr.setOperation(command); scr.setDescription(cmdResult.getDescription()); scr.setReturnCode(cmdResult.getErrorCode()); final String returnValue = cmdResult.getReturnValue(); if (returnValue != null) { scr.setReturnValue( CommandJsonUtils.readObjectValue(returnValue)); } return scr.convertToJson(); } catch (IOException e) { /* the final resolve is to return the string manually */ return "{" + Shell.eolt + "\"operation\" : \"" + command + "\"," + Shell.eolt + "\"returnCode\" : 5500," + Shell.eolt + "\"description\" : " + "\"Exception in generating JSON format result: " + e.getMessage() + "\"," + Shell.eolt + "\"returnValue\" : " + cmdResult.getReturnValue() + Shell.eolt + "}"; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy