Search in sources :

Example 1 with Expression

use of org.opennms.netmgt.measurements.model.Expression in project opennms by OpenNMS.

the class JEXLExpressionEngine method applyExpressions.

/**
     * {@inheritDoc}
     */
@Override
public void applyExpressions(final QueryRequest request, final FetchResults results) throws ExpressionException {
    Preconditions.checkNotNull(request, "request argument");
    Preconditions.checkNotNull(results, "results argument");
    final int numExpressions = request.getExpressions().size();
    // Don't do anything if there are no expressions
    if (numExpressions < 1) {
        return;
    }
    // Use to keep track of transient expression so that we don't
    // allocate memory to store their results
    int numNonTransientExpression = 0;
    boolean[] transientFlags = new boolean[numExpressions];
    // Compile the expressions
    int j, k = 0;
    final LinkedHashMap<String, org.apache.commons.jexl2.Expression> expressions = Maps.newLinkedHashMap();
    for (final Expression e : request.getExpressions()) {
        // Populate the transientFlags array
        transientFlags[k] = e.getTransient();
        if (!transientFlags[k]) {
            numNonTransientExpression++;
        }
        k++;
        try {
            expressions.put(e.getLabel(), jexl.createExpression(e.getExpression()));
        } catch (JexlException ex) {
            throw new ExpressionException(ex, "Failed to parse expression label '{}'.", e.getLabel());
        }
    }
    // Prepare the JEXL context
    final Map<String, Object> jexlValues = Maps.newHashMap();
    final JexlContext context = new MapContext(jexlValues);
    // Add constants (i.e. values from strings.properties) retrieved by the fetch operation
    jexlValues.putAll(results.getConstants());
    LOG.debug("JEXL context constants: {}", jexlValues);
    // Add some additional constants for ease of use
    jexlValues.put("__inf", Double.POSITIVE_INFINITY);
    jexlValues.put("__neg_inf", Double.NEGATIVE_INFINITY);
    jexlValues.put("NaN", Double.NaN);
    final long[] timestamps = results.getTimestamps();
    final Map<String, double[]> columns = results.getColumns();
    final int numRows = timestamps.length;
    // Calculate the time span
    jexlValues.put("__diff_time", numRows < 1 ? 0d : timestamps[numRows - 1] - timestamps[0]);
    final double[][] expressionValues = new double[numNonTransientExpression][numRows];
    // Iterate through all of the rows, apply the expressions
    for (int i = 0; i < numRows; i++) {
        // Evaluate every expression, in the same order as which they appeared in the query
        j = k = 0;
        for (final Map.Entry<String, org.apache.commons.jexl2.Expression> expressionEntry : expressions.entrySet()) {
            // Update the timestamp
            jexlValues.put("timestamp", timestamps[i]);
            // overwriting values from the last loop
            for (final String sourceLabel : columns.keySet()) {
                jexlValues.put(sourceLabel, columns.get(sourceLabel)[i]);
            }
            // Evaluate the expression
            try {
                Object derived = expressionEntry.getValue().evaluate(context);
                double derivedAsDouble = Utils.toDouble(derived);
                // Only store the values for non-transient expressions
                if (!transientFlags[j++]) {
                    expressionValues[k++][i] = derivedAsDouble;
                }
                // Store the result back in the context, so that it can be referenced
                // by subsequent expression in the row
                jexlValues.put(expressionEntry.getKey(), derivedAsDouble);
            } catch (NullPointerException | NumberFormatException e) {
                throw new ExpressionException(e, "The return value from expression with label '" + expressionEntry.getKey() + "' could not be cast to a Double.");
            } catch (JexlException e) {
                throw new ExpressionException(e, "Failed to evaluate expression with label '" + expressionEntry.getKey() + "'.");
            }
        }
    }
    // Store the results
    j = k = 0;
    for (final String expressionLabel : expressions.keySet()) {
        if (!transientFlags[j++]) {
            columns.put(expressionLabel, expressionValues[k++]);
        }
    }
}
Also used : JexlException(org.apache.commons.jexl2.JexlException) MapContext(org.apache.commons.jexl2.MapContext) ExpressionException(org.opennms.netmgt.measurements.api.exceptions.ExpressionException) Expression(org.opennms.netmgt.measurements.model.Expression) JexlContext(org.apache.commons.jexl2.JexlContext) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

Example 2 with Expression

use of org.opennms.netmgt.measurements.model.Expression in project opennms by OpenNMS.

the class MeasurementsWrapper method computeUtilization.

/**
     * This method computes the utilization of a given interface resource. The method returns two double values
     * encapsulated in a list. It uses the HC attributes for the computation and non-HC as fallback attributes.
     *
     * @param resource the resource for which the utilization must be computed
     * @param start the start timestamp
     * @param end the end timestamp
     * @param step the step size
     * @param aggregation the aggregation function
     * @return a list containing two double values for the in/out percentage utilization
     */
public List<Double> computeUtilization(final String resource, final long start, final long end, final long step, final String aggregation) throws MeasurementException {
    QueryRequest request = new QueryRequest();
    request.setRelaxed(true);
    request.setStart(start);
    request.setEnd(end);
    request.setStep(step);
    Source sourceIn = new Source();
    sourceIn.setAggregation(aggregation);
    sourceIn.setTransient(true);
    sourceIn.setAttribute("ifHCInOctets");
    // using non-HC attributes as fallback
    sourceIn.setFallbackAttribute("ifInOctets");
    sourceIn.setResourceId(resource);
    sourceIn.setLabel("ifInOctets");
    Source sourceOut = new Source();
    sourceOut.setAggregation(aggregation);
    sourceOut.setTransient(true);
    sourceOut.setAttribute("ifHCOutOctets");
    // using non-HC attributes as fallback
    sourceOut.setFallbackAttribute("ifOutOctets");
    sourceOut.setResourceId(resource);
    sourceOut.setLabel("ifOutOctets");
    request.setExpressions(Arrays.asList(new Expression("ifInPercent", "(8 * ifInOctects / 1000000) / ifInOctets.ifHighSpeed * 100", false), new Expression("ifOutPercent", "(8 * ifOutOctects / 1000000) / ifOutOctets.ifHighSpeed * 100", false)));
    request.setSources(Arrays.asList(sourceIn, sourceOut));
    QueryResponse.WrappedPrimitive[] columns = measurementsService.query(request).getColumns();
    double[] values1 = columns[0].getList();
    double[] values2 = columns[1].getList();
    for (int i = values1.length - 1; i >= 0; i--) {
        if (!Double.isNaN(values1[i]) && !Double.isNaN(values2[i])) {
            return Arrays.asList(values1[i], values2[i]);
        }
    }
    return Arrays.asList(Double.NaN, Double.NaN);
}
Also used : QueryRequest(org.opennms.netmgt.measurements.model.QueryRequest) Expression(org.opennms.netmgt.measurements.model.Expression) Source(org.opennms.netmgt.measurements.model.Source)

Example 3 with Expression

use of org.opennms.netmgt.measurements.model.Expression in project opennms by OpenNMS.

the class MeasurementsRestServiceWithJrbIT method canPerformExpressions.

@Test
public void canPerformExpressions() {
    QueryRequest request = new QueryRequest();
    request.setStart(1414602000000L);
    request.setEnd(1417046400000L);
    request.setStep(1000L);
    request.setMaxRows(700);
    Source ifInOctets = new Source();
    ifInOctets.setResourceId("node[1].interfaceSnmp[eth0-04013f75f101]");
    ifInOctets.setAttribute("ifInOctets");
    ifInOctets.setAggregation("MAX");
    ifInOctets.setLabel("ifInOctets");
    request.setSources(Lists.newArrayList(ifInOctets));
    Expression scale = new Expression();
    scale.setLabel("ifUsage");
    // References a variable from strings.properties
    scale.setExpression("ifInOctets * 8 / ifInOctets.ifSpeed");
    request.setExpressions(Lists.newArrayList(scale));
    QueryResponse response = m_svc.query(request);
    final int idx = 3;
    final Map<String, double[]> columns = response.columnsWithLabels();
    assertEquals(975.3053156146178, columns.get("ifInOctets")[idx], 0.0001);
    assertEquals(975.3053156146178 * 8d / 1000.0d, columns.get("ifUsage")[idx], 0.0001);
}
Also used : QueryRequest(org.opennms.netmgt.measurements.model.QueryRequest) Expression(org.opennms.netmgt.measurements.model.Expression) QueryResponse(org.opennms.netmgt.measurements.model.QueryResponse) Source(org.opennms.netmgt.measurements.model.Source) Test(org.junit.Test)

Example 4 with Expression

use of org.opennms.netmgt.measurements.model.Expression in project opennms by OpenNMS.

the class JEXLExpressionEngineTest method performExpression.

private double[] performExpression(String expression, Map<String, Object> constants) throws ExpressionException {
    // Build a simple request with the given expression
    QueryRequest request = new QueryRequest();
    Source constant = new Source();
    constant.setLabel("x");
    request.setSources(Lists.newArrayList(constant));
    Expression exp = new Expression();
    exp.setLabel("y");
    exp.setExpression(expression);
    request.setExpressions(Lists.newArrayList(exp));
    // Build the fetch results with known values
    final int N = 100;
    long[] timestamps = new long[N];
    double[] xValues = new double[N];
    for (int i = 0; i < N; i++) {
        timestamps[i] = i * 1000;
        xValues[i] = Double.valueOf(i);
    }
    Map<String, double[]> values = Maps.newHashMap();
    values.put("x", xValues);
    FetchResults results = new FetchResults(timestamps, values, 1, constants);
    // Use the engine to evaluate the expression
    jexlExpressionEngine.applyExpressions(request, results);
    // Retrieve the results
    return results.getColumns().get("y");
}
Also used : QueryRequest(org.opennms.netmgt.measurements.model.QueryRequest) Expression(org.opennms.netmgt.measurements.model.Expression) FetchResults(org.opennms.netmgt.measurements.api.FetchResults) Source(org.opennms.netmgt.measurements.model.Source)

Example 5 with Expression

use of org.opennms.netmgt.measurements.model.Expression in project opennms by OpenNMS.

the class QueryRequestValidator method validate.

public void validate(QueryRequest request) throws ValidationException {
    if (request.getEnd() < 0) {
        throw new ValidationException("Query end must be >= 0: {}", request.getEnd());
    }
    if (request.getStep() <= 0) {
        throw new ValidationException("Query step must be > 0: {}", request.getStep());
    }
    if ((request.getHeartbeat() == null && request.getInterval() != null) || (request.getHeartbeat() != null && request.getInterval() == null)) {
        throw new ValidationException("If either the heartbeat or the interval are set, then both must be set.");
    }
    if (request.getHeartbeat() != null && request.getInterval() != null) {
        if (request.getHeartbeat() <= 0) {
            throw new ValidationException("Heartbeat must be positive: {}", request.getHeartbeat());
        }
        if (request.getInterval() <= 0) {
            throw new ValidationException("Interval must be positive: {}", request.getInterval());
        }
        if (request.getStep() % request.getInterval() != 0) {
            throw new ValidationException("Step must be a multiple of the interval. Step: {}, Interval: {}", request.getStep(), request.getInterval());
        }
        if (request.getHeartbeat() % request.getInterval() != 0) {
            throw new ValidationException("Heartbeat must be a multiple of the interval. Interval: {} Heartbeat: {}", request.getInterval(), request.getHeartbeat());
        }
    }
    final Map<String, String> labels = new HashMap<>();
    for (final Source source : request.getSources()) {
        if (source.getResourceId() == null || source.getAttribute() == null || source.getLabel() == null || source.getAggregation() == null) {
            throw new ValidationException("Query source fields must be set: {}", source);
        }
        if (labels.containsKey(source.getLabel())) {
            throw new ValidationException("Query source label '{}' conflict: source with that label is already defined.", source.getLabel());
        } else {
            labels.put(source.getLabel(), "source");
        }
    }
    for (final Expression expression : request.getExpressions()) {
        if (expression.getExpression() == null || expression.getLabel() == null) {
            throw new ValidationException("Query expression fields must be set: {}", expression);
        }
        if (labels.containsKey(expression.getLabel())) {
            final String type = labels.get(expression.getLabel());
            throw new ValidationException("Query expression label '{}' conflict: {} with that label is already defined.", expression.getLabel(), type);
        } else {
            labels.put(expression.getLabel(), "expression");
        }
    }
    List<FilterDef> filters = request.getFilters();
    if (filters.size() > 0) {
        for (FilterDef filter : filters) {
            if (filter.getName() == null) {
                throw new ValidationException("Filter name must be set: {}", filter);
            }
        }
    }
}
Also used : ValidationException(org.opennms.netmgt.measurements.api.exceptions.ValidationException) FilterDef(org.opennms.netmgt.measurements.model.FilterDef) HashMap(java.util.HashMap) Expression(org.opennms.netmgt.measurements.model.Expression) Source(org.opennms.netmgt.measurements.model.Source)

Aggregations

Expression (org.opennms.netmgt.measurements.model.Expression)5 Source (org.opennms.netmgt.measurements.model.Source)4 QueryRequest (org.opennms.netmgt.measurements.model.QueryRequest)3 HashMap (java.util.HashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 Map (java.util.Map)1 JexlContext (org.apache.commons.jexl2.JexlContext)1 JexlException (org.apache.commons.jexl2.JexlException)1 MapContext (org.apache.commons.jexl2.MapContext)1 Test (org.junit.Test)1 FetchResults (org.opennms.netmgt.measurements.api.FetchResults)1 ExpressionException (org.opennms.netmgt.measurements.api.exceptions.ExpressionException)1 ValidationException (org.opennms.netmgt.measurements.api.exceptions.ValidationException)1 FilterDef (org.opennms.netmgt.measurements.model.FilterDef)1 QueryResponse (org.opennms.netmgt.measurements.model.QueryResponse)1