Search in sources :

Example 1 with Variable

use of org.batfish.datamodel.questions.Question.InstanceData.Variable in project batfish by batfish.

the class Client method validateType.

/**
 * Validate the contents contained in json-encoded {@code value} matches the type required by
 * {@code variable}, and the length of input string meets the requirement of minimum length if
 * specified in {@code variable}. Call {@link Variable#getType()} on {@code variable} gives the
 * expected type.
 *
 * @throws BatfishException if the content encoded in input {@code value} does not satisfy the
 *     requirements specified in {@code variable}.
 */
static void validateType(JsonNode value, Variable variable) throws BatfishException {
    int minLength = variable.getMinLength() == null ? 0 : variable.getMinLength();
    if (value.isTextual() && value.textValue().length() < minLength) {
        throw new BatfishException(String.format("Must be at least %s characters in length", minLength));
    }
    Variable.Type expectedType = variable.getType();
    switch(expectedType) {
        case BOOLEAN:
            if (!value.isBoolean()) {
                throw new BatfishException(String.format("It is not a valid JSON %s value", expectedType.getName()));
            }
            break;
        case COMPARATOR:
            if (!(COMPARATORS.contains(value.textValue()))) {
                throw new BatfishException(String.format("It is not a known %s. Valid options are:" + " %s", expectedType.getName(), COMPARATORS));
            }
            break;
        case DOUBLE:
            if (!value.isDouble()) {
                throw new BatfishException(String.format("It is not a valid JSON %s value", expectedType.getName()));
            }
            break;
        case FLOAT:
            if (!value.isFloat()) {
                throw new BatfishException(String.format("It is not a valid JSON %s value", expectedType.getName()));
            }
            break;
        case INTEGER:
            if (!value.isInt()) {
                throw new BatfishException(String.format("It is not a valid JSON %s value", expectedType.getName()));
            }
            break;
        case LONG:
            if (!value.isLong()) {
                throw new BatfishException(String.format("It is not a valid JSON %s value", expectedType.getName()));
            }
            break;
        case IP:
            // TODO: Need to double check isInetAddress()
            if (!(value.isTextual())) {
                throw new BatfishException(String.format("A Batfish %s must be a JSON string", expectedType.getName()));
            }
            new Ip(value.textValue());
            break;
        case IP_PROTOCOL:
            if (!value.isTextual()) {
                throw new BatfishException(String.format("A Batfish %s must be a JSON string", expectedType.getName()));
            }
            try {
                IpProtocol.fromString(value.textValue());
            } catch (IllegalArgumentException e) {
                throw new BatfishException(String.format("Unknown %s string", expectedType.getName()));
            }
            break;
        case IP_WILDCARD:
            if (!value.isTextual()) {
                throw new BatfishException(String.format("A Batfish %s must be a JSON string", expectedType.getName()));
            }
            new IpWildcard(value.textValue());
            break;
        case JAVA_REGEX:
            if (!value.isTextual()) {
                throw new BatfishException(String.format("A Batfish %s must be a JSON string", expectedType.getName()));
            }
            try {
                Pattern.compile(value.textValue());
            } catch (PatternSyntaxException e) {
                throw new BatfishException("It is not a valid Java regular " + "expression", e);
            }
            break;
        case JSON_PATH_REGEX:
            if (!value.isTextual()) {
                throw new BatfishException(String.format("A Batfish %s must be a JSON string", expectedType.getName()));
            }
            validateJsonPathRegex(value.textValue());
            break;
        case PREFIX:
            if (!value.isTextual()) {
                throw new BatfishException(String.format("A Batfish %s must be a JSON string", expectedType.getName()));
            }
            Prefix.parse(value.textValue());
            break;
        case PREFIX_RANGE:
            if (!value.isTextual()) {
                throw new BatfishException(String.format("A Batfish %s must be a JSON string", expectedType.getName()));
            }
            PrefixRange.fromString(value.textValue());
            break;
        case QUESTION:
            // TODO: Implement
            break;
        case STRING:
            if (!value.isTextual()) {
                throw new BatfishException(String.format("A Batfish %s must be a JSON string", expectedType.getName()));
            }
            break;
        case SUBRANGE:
            if (!(value.isTextual() || value.isInt())) {
                throw new BatfishException(String.format("A Batfish %s must be a JSON string or " + "integer", expectedType.getName()));
            }
            Object actualValue = value.isTextual() ? value.textValue() : value.asInt();
            new SubRange(actualValue);
            break;
        case PROTOCOL:
            if (!value.isTextual()) {
                throw new BatfishException(String.format("A Batfish %s must be a JSON string", expectedType.getName()));
            }
            Protocol.fromString(value.textValue());
            break;
        case JSON_PATH:
            validateJsonPath(value);
            break;
        default:
            throw new BatfishException(String.format("Unsupported parameter type: %s", expectedType));
    }
}
Also used : IpWildcard(org.batfish.datamodel.IpWildcard) BatfishException(org.batfish.common.BatfishException) Variable(org.batfish.datamodel.questions.Question.InstanceData.Variable) Ip(org.batfish.datamodel.Ip) JSONObject(org.codehaus.jettison.json.JSONObject) SubRange(org.batfish.datamodel.SubRange) PatternSyntaxException(java.util.regex.PatternSyntaxException)

Example 2 with Variable

use of org.batfish.datamodel.questions.Question.InstanceData.Variable in project batfish by batfish.

the class Client method answer.

private boolean answer(String questionTemplateName, String paramsLine, boolean isDelta, FileWriter outWriter) {
    String questionContentUnmodified = _bfq.get(questionTemplateName.toLowerCase());
    if (questionContentUnmodified == null) {
        throw new BatfishException("Invalid question template name: '" + questionTemplateName + "'");
    }
    Map<String, JsonNode> parameters = parseParams(paramsLine);
    JSONObject questionJson;
    try {
        questionJson = new JSONObject(questionContentUnmodified);
    } catch (JSONException e) {
        throw new BatfishException("Question content is not valid JSON", e);
    }
    String questionName = DEFAULT_QUESTION_PREFIX + "_" + UUID.randomUUID();
    if (parameters.containsKey("questionName")) {
        questionName = parameters.get("questionName").asText();
        parameters.remove("questionName");
    }
    JSONObject instanceJson;
    try {
        instanceJson = questionJson.getJSONObject(BfConsts.PROP_INSTANCE);
        instanceJson.put(BfConsts.PROP_INSTANCE_NAME, questionName);
    } catch (JSONException e) {
        throw new BatfishException("Question is missing instance data", e);
    }
    String instanceDataStr = instanceJson.toString();
    InstanceData instanceData;
    try {
        instanceData = BatfishObjectMapper.mapper().readValue(instanceDataStr, new TypeReference<InstanceData>() {
        });
    } catch (IOException e) {
        throw new BatfishException("Invalid instance data (JSON)", e);
    }
    Map<String, Variable> variables = instanceData.getVariables();
    validateAndSet(parameters, variables);
    checkVariableState(variables);
    String modifiedInstanceDataStr;
    try {
        modifiedInstanceDataStr = BatfishObjectMapper.writePrettyString(instanceData);
        JSONObject modifiedInstanceData = new JSONObject(modifiedInstanceDataStr);
        questionJson.put(BfConsts.PROP_INSTANCE, modifiedInstanceData);
    } catch (JSONException | JsonProcessingException e) {
        throw new BatfishException("Could not process modified instance data", e);
    }
    String modifiedQuestionStr = questionJson.toString();
    boolean questionJsonDifferential = false;
    // check whether question is valid modulo instance data
    try {
        questionJsonDifferential = questionJson.has(BfConsts.PROP_DIFFERENTIAL) && questionJson.getBoolean(BfConsts.PROP_DIFFERENTIAL);
    } catch (JSONException e) {
        throw new BatfishException("Could not find whether question is explicitly differential", e);
    }
    if (questionJsonDifferential && (_currDeltaEnv == null || _currDeltaTestrig == null)) {
        _logger.output(DIFF_NOT_READY_MSG);
        return false;
    }
    Path questionFile = createTempFile(BfConsts.RELPATH_QUESTION_FILE, modifiedQuestionStr);
    questionFile.toFile().deleteOnExit();
    // upload the question
    boolean resultUpload = _workHelper.uploadQuestion(_currContainerName, isDelta ? _currDeltaTestrig : _currTestrig, questionName, questionFile.toAbsolutePath().toString());
    if (!resultUpload) {
        return false;
    }
    _logger.debug("Uploaded question. Answering now.\n");
    // delete the temporary params file
    if (questionFile != null) {
        CommonUtil.deleteIfExists(questionFile);
    }
    // answer the question
    WorkItem wItemAs = WorkItemBuilder.getWorkItemAnswerQuestion(questionName, _currContainerName, _currTestrig, _currEnv, _currDeltaTestrig, _currDeltaEnv, questionJsonDifferential, isDelta);
    return execute(wItemAs, outWriter);
}
Also used : Path(java.nio.file.Path) BatfishException(org.batfish.common.BatfishException) Variable(org.batfish.datamodel.questions.Question.InstanceData.Variable) JSONException(org.codehaus.jettison.json.JSONException) JsonNode(com.fasterxml.jackson.databind.JsonNode) IOException(java.io.IOException) WorkItem(org.batfish.common.WorkItem) JSONObject(org.codehaus.jettison.json.JSONObject) InstanceData(org.batfish.datamodel.questions.Question.InstanceData) TypeReference(com.fasterxml.jackson.core.type.TypeReference) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException)

Example 3 with Variable

use of org.batfish.datamodel.questions.Question.InstanceData.Variable in project batfish by batfish.

the class Client method validateInstanceData.

private static void validateInstanceData(InstanceData instanceData) {
    String description = instanceData.getDescription();
    String q = "Question: '" + instanceData.getInstanceName() + "'";
    if (description == null || description.length() == 0) {
        throw new BatfishException(q + " is missing question description");
    }
    for (Entry<String, Variable> e : instanceData.getVariables().entrySet()) {
        String variableName = e.getKey();
        Variable variable = e.getValue();
        String v = "Variable: '" + variableName + "' in " + q;
        String variableDescription = variable.getDescription();
        if (variableDescription == null || variableDescription.length() == 0) {
            throw new BatfishException(v + " is missing description");
        }
    }
}
Also used : BatfishException(org.batfish.common.BatfishException) Variable(org.batfish.datamodel.questions.Question.InstanceData.Variable)

Example 4 with Variable

use of org.batfish.datamodel.questions.Question.InstanceData.Variable in project batfish by batfish.

the class ClientTest method testValidIpProtocolValue.

@Test
public void testValidIpProtocolValue() throws IOException {
    JsonNode ipProtocolNode = _mapper.readTree("\"visa\"");
    Question.InstanceData.Variable variable = new Question.InstanceData.Variable();
    variable.setType(IP_PROTOCOL);
    Client.validateType(ipProtocolNode, variable);
}
Also used : Variable(org.batfish.datamodel.questions.Question.InstanceData.Variable) Variable(org.batfish.datamodel.questions.Question.InstanceData.Variable) JsonNode(com.fasterxml.jackson.databind.JsonNode) Question(org.batfish.datamodel.questions.Question) Test(org.junit.Test)

Example 5 with Variable

use of org.batfish.datamodel.questions.Question.InstanceData.Variable in project batfish by batfish.

the class ClientTest method testValidSubRangeStringValue.

@Test
public void testValidSubRangeStringValue() throws IOException {
    JsonNode subRangeNode = _mapper.readTree("\"10-50\"");
    Question.InstanceData.Variable variable = new Question.InstanceData.Variable();
    variable.setType(SUBRANGE);
    Client.validateType(subRangeNode, variable);
}
Also used : Variable(org.batfish.datamodel.questions.Question.InstanceData.Variable) Variable(org.batfish.datamodel.questions.Question.InstanceData.Variable) JsonNode(com.fasterxml.jackson.databind.JsonNode) Question(org.batfish.datamodel.questions.Question) Test(org.junit.Test)

Aggregations

Variable (org.batfish.datamodel.questions.Question.InstanceData.Variable)30 JsonNode (com.fasterxml.jackson.databind.JsonNode)25 Question (org.batfish.datamodel.questions.Question)24 Test (org.junit.Test)23 BatfishException (org.batfish.common.BatfishException)6 JSONObject (org.codehaus.jettison.json.JSONObject)3 IOException (java.io.IOException)2 TreeSet (java.util.TreeSet)2 JSONException (org.codehaus.jettison.json.JSONException)2 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)1 TypeReference (com.fasterxml.jackson.core.type.TypeReference)1 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)1 Path (java.nio.file.Path)1 HashMap (java.util.HashMap)1 PatternSyntaxException (java.util.regex.PatternSyntaxException)1 WorkItem (org.batfish.common.WorkItem)1 BatfishObjectMapper (org.batfish.common.util.BatfishObjectMapper)1 Ip (org.batfish.datamodel.Ip)1 IpWildcard (org.batfish.datamodel.IpWildcard)1 SubRange (org.batfish.datamodel.SubRange)1