AlarmExpression { public boolean evaluate(Map<AlarmSubExpression, Boolean> subExpressionValues) { Stack<Object> stack = new Stack<Object>(); for (Object element : elements) { if (element instanceof AlarmSubExpression) { Boolean value = subExpressionValues.get(element); if (value == null) throw new IllegalArgumentException("Expected sub-expression was not found for " + element); stack.push(value); } else { BooleanOperator operator = (BooleanOperator) element; Boolean operandA = (Boolean) stack.pop(); Boolean operandB = (Boolean) stack.pop(); stack.push(operator.evaluate(operandA, operandB)); } } return (Boolean) stack.pop(); } AlarmExpression(String expression); @JsonCreator static AlarmExpression of(String expression); @Override boolean equals(Object obj); boolean evaluate(Map<AlarmSubExpression, Boolean> subExpressionValues); @JsonIgnore String getExpression(); @JsonIgnore Object getExpressionTree(); List<AlarmSubExpression> getSubExpressions(); boolean isDeterministic(); @Override int hashCode(); @Override String toString();  }
@Test(expectedExceptions = IllegalArgumentException.class) public void shouldThrowOnEvaluateInvalidSubExpressions() { AlarmExpression expr = new AlarmExpression( "avg(hpcs.compute{instance_id=5,metric_name=cpu,device=2}, 1) > 5 times 3 and avg(hpcs.compute{flavor_id=3,metric_name=mem}, 2) < 4 times 3"); expr.evaluate(ImmutableMap.<AlarmSubExpression, Boolean>builder() .put( new AlarmSubExpression(AggregateFunction.AVG, new MetricDefinition("hpcs.compute", ImmutableMap .<String, String>builder() .put("flavor_id", "3") .put("metric_name", "mem") .build()), AlarmOperator.LT, 4, 2, 3), true) .build()); }