Search in sources :

Example 16 with Variable

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

the class Question method preprocessQuestion.

private static String preprocessQuestion(String rawQuestionText) {
    try {
        JSONObject jobj = new JSONObject(rawQuestionText);
        if (jobj.has(BfConsts.PROP_INSTANCE) && !jobj.isNull(BfConsts.PROP_INSTANCE)) {
            String instanceDataStr = jobj.getString(BfConsts.PROP_INSTANCE);
            InstanceData instanceData = BatfishObjectMapper.mapper().readValue(instanceDataStr, new TypeReference<InstanceData>() {
            });
            for (Entry<String, Variable> e : instanceData.getVariables().entrySet()) {
                String varName = e.getKey();
                Variable variable = e.getValue();
                JsonNode value = variable.getValue();
                if (value == null) {
                    if (variable.getOptional()) {
                        /*
               * Recursively look for all key, value pairs and remove keys
               * whose value is "${varName}." Is this fragile?
               * To be doubly sure, we do only for keys whole parent object is a questions, which
               * we judge by it having a key "class" whose value starts with "org.batfish.question"
               */
                        recursivelyRemoveOptionalVar(jobj, varName);
                    } else {
                    // What to do here? For now, do nothing and assume that
                    // later validation will handle it.
                    }
                    continue;
                }
                if (variable.getType() == Variable.Type.QUESTION) {
                    if (variable.getMinElements() != null) {
                        if (!value.isArray()) {
                            throw new IllegalArgumentException("Expecting JSON array for array type");
                        }
                        JSONArray arr = new JSONArray();
                        for (int i = 0; i < value.size(); i++) {
                            String valueJsonString = new ObjectMapper().writeValueAsString(value.get(i));
                            arr.put(i, new JSONObject(preprocessQuestion(valueJsonString)));
                        }
                        jobj.put(varName, arr);
                    } else {
                        String valueJsonString = new ObjectMapper().writeValueAsString(value);
                        jobj.put(varName, new JSONObject(preprocessQuestion(valueJsonString)));
                    }
                }
            }
            String questionText = jobj.toString();
            for (Entry<String, Variable> e : instanceData.getVariables().entrySet()) {
                String varName = e.getKey();
                Variable variable = e.getValue();
                JsonNode value = variable.getValue();
                String valueJsonString = new ObjectMapper().writeValueAsString(value);
                boolean stringType = variable.getType().getStringType();
                boolean setType = variable.getMinElements() != null;
                if (value != null) {
                    String topLevelVarNameRegex = Pattern.quote("\"${" + varName + "}\"");
                    String inlineVarNameRegex = Pattern.quote("${" + varName + "}");
                    String topLevelReplacement = valueJsonString;
                    String inlineReplacement;
                    if (stringType && !setType) {
                        inlineReplacement = valueJsonString.substring(1, valueJsonString.length() - 1);
                    } else {
                        String quotedValueJsonString = JSONObject.quote(valueJsonString);
                        inlineReplacement = quotedValueJsonString.substring(1, quotedValueJsonString.length() - 1);
                    }
                    String inlineReplacementRegex = Matcher.quoteReplacement(inlineReplacement);
                    String topLevelReplacementRegex = Matcher.quoteReplacement(topLevelReplacement);
                    questionText = questionText.replaceAll(topLevelVarNameRegex, topLevelReplacementRegex);
                    questionText = questionText.replaceAll(inlineVarNameRegex, inlineReplacementRegex);
                }
            }
            return questionText;
        }
        return rawQuestionText;
    } catch (JSONException | IOException e) {
        throw new BatfishException(String.format("Could not convert raw question text [%s] to JSON", rawQuestionText), e);
    }
}
Also used : BatfishException(org.batfish.common.BatfishException) Variable(org.batfish.datamodel.questions.Question.InstanceData.Variable) JSONArray(org.codehaus.jettison.json.JSONArray) JSONException(org.codehaus.jettison.json.JSONException) JsonNode(com.fasterxml.jackson.databind.JsonNode) IOException(java.io.IOException) JSONObject(org.codehaus.jettison.json.JSONObject) BatfishObjectMapper(org.batfish.common.util.BatfishObjectMapper) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper)

Example 17 with Variable

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

the class Client method checkVariableState.

/**
 * Verify that every non-optional variable has value assigned to it.
 *
 * @throws BatfishException when there exists a missing parameter: it is not optional in {@code
 *     variable}, but the user failed to provide it.
 */
static void checkVariableState(Map<String, Variable> variables) throws BatfishException {
    for (Entry<String, Variable> e : variables.entrySet()) {
        String variableName = e.getKey();
        Variable variable = e.getValue();
        if (!variable.getOptional() && variable.getValue() == null) {
            throw new BatfishException(String.format("Missing parameter: %s", variableName));
        }
    }
}
Also used : BatfishException(org.batfish.common.BatfishException) Variable(org.batfish.datamodel.questions.Question.InstanceData.Variable)

Example 18 with Variable

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

the class Client method validateAndSet.

/**
 * For each key in {@code parameters}, validate that its value satisfies the requirements
 * specified by {@code variables} for that specific key. Set value to {@code variables} if
 * validation passed.
 *
 * @throws BatfishException if the key in parameters does not exist in variable, or the values in
 *     {@code parameters} do not match the requirements in {@code variables} for that specific
 *     key.
 */
static void validateAndSet(Map<String, JsonNode> parameters, Map<String, Variable> variables) throws BatfishException {
    for (Entry<String, JsonNode> e : parameters.entrySet()) {
        String parameterName = e.getKey();
        JsonNode value = e.getValue();
        Variable variable = variables.get(parameterName);
        if (variable == null) {
            throw new BatfishException("No variable named: '" + parameterName + "' in supplied question template");
        }
        if (variable.getMinElements() != null) {
            // Value is an array, check size and validate each elements in it
            if (!value.isArray() || value.size() < variable.getMinElements()) {
                throw new BatfishException(String.format("Invalid value for parameter %s: %s. " + "Expecting a JSON array of at least %d " + "elements", parameterName, value, variable.getMinElements()));
            }
            for (JsonNode node : value) {
                validateNode(node, variable, parameterName);
            }
        } else {
            validateNode(value, variable, parameterName);
        }
        // validation passed.
        variable.setValue(value);
    }
}
Also used : BatfishException(org.batfish.common.BatfishException) Variable(org.batfish.datamodel.questions.Question.InstanceData.Variable) JsonNode(com.fasterxml.jackson.databind.JsonNode)

Example 19 with Variable

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

the class ClientTest method testSatisfiedMinLengthValue.

@Test
public void testSatisfiedMinLengthValue() throws IOException {
    String longString = "\"long enough\"";
    Question.InstanceData.Variable variable = new Question.InstanceData.Variable();
    variable.setMinLength(8);
    variable.setType(STRING);
    Client.validateType(_mapper.readTree(longString), variable);
}
Also used : Variable(org.batfish.datamodel.questions.Question.InstanceData.Variable) Variable(org.batfish.datamodel.questions.Question.InstanceData.Variable) Question(org.batfish.datamodel.questions.Question) Test(org.junit.Test)

Example 20 with Variable

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

the class ClientTest method testValidateValidNode.

@Test
public void testValidateValidNode() throws IOException {
    String parameterName = "boolean";
    JsonNode invalidNode = _mapper.readTree("false");
    Question.InstanceData.Variable variable = new Question.InstanceData.Variable();
    variable.setType(BOOLEAN);
    SortedSet<String> allowedValues = new TreeSet<>();
    allowedValues.add("false");
    variable.setAllowedValues(allowedValues);
    Client.validateNode(invalidNode, variable, parameterName);
}
Also used : Variable(org.batfish.datamodel.questions.Question.InstanceData.Variable) TreeSet(java.util.TreeSet) 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