mirror of
https://github.com/elastic/logstash.git
synced 2025-04-24 06:37:19 -04:00
parent
c431aba536
commit
8dc46bece1
2 changed files with 266 additions and 267 deletions
|
@ -4,15 +4,16 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import org.jruby.RubyInteger;
|
||||
import org.jruby.RubyNumeric;
|
||||
import java.util.function.Predicate;
|
||||
import org.jruby.RubyString;
|
||||
import org.jruby.runtime.builtin.IRubyObject;
|
||||
import org.jruby.util.ByteList;
|
||||
import org.logstash.ConvertedList;
|
||||
import org.logstash.ConvertedMap;
|
||||
import org.logstash.Event;
|
||||
import org.logstash.FieldReference;
|
||||
import org.logstash.RubyUtil;
|
||||
import org.logstash.Rubyfier;
|
||||
import org.logstash.Valuefier;
|
||||
import org.logstash.config.ir.expression.BinaryBooleanExpression;
|
||||
import org.logstash.config.ir.expression.BooleanExpression;
|
||||
|
@ -55,15 +56,13 @@ public interface EventCondition {
|
|||
*/
|
||||
final class Compiler {
|
||||
|
||||
/**
|
||||
* {@link EventCondition} that is always {@code true}.
|
||||
*/
|
||||
private static final EventCondition TRUE = event -> true;
|
||||
private static final Predicate<Integer> LESS_THAN = i -> i < 0;
|
||||
|
||||
/**
|
||||
* {@link EventCondition} that is always {@code false}.
|
||||
*/
|
||||
private static final EventCondition FALSE = event -> false;
|
||||
private static final Predicate<Integer> LESS_OR_EQUAL_THAN = i -> i <= 0;
|
||||
|
||||
private static final Predicate<Integer> GREATER_THAN = i -> i > 0;
|
||||
|
||||
private static final Predicate<Integer> GREATER_OR_EQUAL_THAN = i -> i >= 0;
|
||||
|
||||
/**
|
||||
* Cache of all compiled {@link EventCondition}.
|
||||
|
@ -96,24 +95,17 @@ public interface EventCondition {
|
|||
condition = regex((RegexEq) expression);
|
||||
} else if (expression instanceof In) {
|
||||
condition = in((In) expression);
|
||||
} else if (expression instanceof Or) {
|
||||
condition = or(booleanPair((BinaryBooleanExpression) expression));
|
||||
} else if (expression instanceof Or || expression instanceof And) {
|
||||
condition = booleanCondition((BinaryBooleanExpression) expression);
|
||||
} else if (expression instanceof Truthy) {
|
||||
condition = truthy((Truthy) expression);
|
||||
} else if (expression instanceof Not) {
|
||||
condition = not((Not) expression);
|
||||
} else if (expression instanceof Gt) {
|
||||
condition = gt((Gt) expression);
|
||||
} else if (expression instanceof Gte) {
|
||||
condition = gte((Gte) expression);
|
||||
} else if (expression instanceof Lt) {
|
||||
condition = lt((Lt) expression);
|
||||
} else if (expression instanceof Lte) {
|
||||
condition = lte((Lte) expression);
|
||||
} else if (expression instanceof And) {
|
||||
condition = and(booleanPair((BinaryBooleanExpression) expression));
|
||||
} else if (expression instanceof Gt || expression instanceof Gte
|
||||
|| expression instanceof Lt || expression instanceof Lte) {
|
||||
condition = comparison((BinaryBooleanExpression) expression);
|
||||
} else if (expression instanceof Neq) {
|
||||
condition = neq((Neq) expression);
|
||||
condition = not(eq((BinaryBooleanExpression) expression));
|
||||
} else {
|
||||
throw new EventCondition.Compiler.UnexpectedTypeException(expression);
|
||||
}
|
||||
|
@ -122,7 +114,7 @@ public interface EventCondition {
|
|||
}
|
||||
}
|
||||
|
||||
private EventCondition[] booleanPair(final BinaryBooleanExpression expression) {
|
||||
private EventCondition booleanCondition(final BinaryBooleanExpression expression) {
|
||||
final Expression left = expression.getLeft();
|
||||
final Expression right = expression.getRight();
|
||||
final EventCondition first;
|
||||
|
@ -143,7 +135,13 @@ public interface EventCondition {
|
|||
} else {
|
||||
throw new EventCondition.Compiler.UnexpectedTypeException(left, right);
|
||||
}
|
||||
return new EventCondition[]{first, second};
|
||||
if (expression instanceof And) {
|
||||
return event -> first.fulfilled(event) && second.fulfilled(event);
|
||||
} else if (expression instanceof Or) {
|
||||
return event -> first.fulfilled(event) || second.fulfilled(event);
|
||||
} else {
|
||||
throw new EventCondition.Compiler.UnexpectedTypeException(expression);
|
||||
}
|
||||
}
|
||||
|
||||
private EventCondition not(final Not not) {
|
||||
|
@ -186,18 +184,6 @@ public interface EventCondition {
|
|||
expression.getRight() instanceof EventValueExpression;
|
||||
}
|
||||
|
||||
private static EventCondition neq(final Neq neq) {
|
||||
final EventCondition condition;
|
||||
final Expression uleft = neq.getLeft();
|
||||
final Expression uright = neq.getRight();
|
||||
if (eAndV(neq)) {
|
||||
condition = not(eq((EventValueExpression) uleft, (ValueExpression) uright));
|
||||
} else {
|
||||
throw new EventCondition.Compiler.UnexpectedTypeException(uleft, uright);
|
||||
}
|
||||
return condition;
|
||||
}
|
||||
|
||||
private static EventCondition truthy(final Truthy truthy) {
|
||||
final EventCondition condition;
|
||||
final Expression inner = truthy.getExpression();
|
||||
|
@ -224,42 +210,43 @@ public interface EventCondition {
|
|||
return condition;
|
||||
}
|
||||
|
||||
private static EventCondition gte(final Gte gte) {
|
||||
final EventCondition condition;
|
||||
final Expression uleft = gte.getLeft();
|
||||
final Expression uright = gte.getRight();
|
||||
if (eAndV(gte)) {
|
||||
final EventValueExpression left = (EventValueExpression) uleft;
|
||||
final ValueExpression right = (ValueExpression) uright;
|
||||
condition = or(gt(left, right), eq(left, right));
|
||||
private static EventCondition comparison(final BinaryBooleanExpression expression) {
|
||||
final Predicate<Integer> conditional;
|
||||
final Predicate<Integer> converse;
|
||||
if (expression instanceof Gte) {
|
||||
conditional = GREATER_OR_EQUAL_THAN;
|
||||
converse = LESS_OR_EQUAL_THAN;
|
||||
} else if (expression instanceof Lte) {
|
||||
conditional = LESS_OR_EQUAL_THAN;
|
||||
converse = GREATER_OR_EQUAL_THAN;
|
||||
} else if (expression instanceof Lt) {
|
||||
conditional = LESS_THAN;
|
||||
converse = GREATER_THAN;
|
||||
} else if (expression instanceof Gt) {
|
||||
conditional = GREATER_THAN;
|
||||
converse = LESS_THAN;
|
||||
} else {
|
||||
throw new EventCondition.Compiler.UnexpectedTypeException(uleft, uright);
|
||||
throw new EventCondition.Compiler.UnexpectedTypeException(expression);
|
||||
}
|
||||
return condition;
|
||||
}
|
||||
|
||||
private static EventCondition lte(final Lte lte) {
|
||||
final EventCondition condition;
|
||||
final Expression uleft = lte.getLeft();
|
||||
final Expression uright = lte.getRight();
|
||||
if (eAndV(lte)) {
|
||||
condition = not(gt((EventValueExpression) uleft, (ValueExpression) uright));
|
||||
final Expression uleft = expression.getLeft();
|
||||
final Expression uright = expression.getRight();
|
||||
if (eAndV(expression)) {
|
||||
condition = compareFieldToConstant(
|
||||
(EventValueExpression) uleft, (ValueExpression) uright, conditional
|
||||
);
|
||||
} else if (vAndE(expression)) {
|
||||
condition = compareFieldToConstant(
|
||||
(EventValueExpression) uright, (ValueExpression) uleft, converse
|
||||
);
|
||||
} else if (vAndV(expression)) {
|
||||
return compareConstants(
|
||||
(ValueExpression) uleft, (ValueExpression) uright, conditional
|
||||
);
|
||||
} else {
|
||||
throw new EventCondition.Compiler.UnexpectedTypeException(uleft, uright);
|
||||
}
|
||||
return condition;
|
||||
}
|
||||
|
||||
private static EventCondition lt(final Lt lt) {
|
||||
final EventCondition condition;
|
||||
final Expression uleft = lt.getLeft();
|
||||
final Expression uright = lt.getRight();
|
||||
if (eAndV(lt)) {
|
||||
final EventValueExpression left = (EventValueExpression) uleft;
|
||||
final ValueExpression right = (ValueExpression) uright;
|
||||
condition = not(or(gt(left, right), eq(left, right)));
|
||||
} else {
|
||||
throw new EventCondition.Compiler.UnexpectedTypeException(uleft, uright);
|
||||
return compareFields(
|
||||
(EventValueExpression) uleft, (EventValueExpression) uright, conditional
|
||||
);
|
||||
}
|
||||
return condition;
|
||||
}
|
||||
|
@ -306,27 +293,27 @@ public interface EventCondition {
|
|||
|
||||
/**
|
||||
* Compiles a constant (due to both of its sides being constant {@link ValueExpression})
|
||||
* conditional into either {@link EventCondition.Compiler#TRUE} or
|
||||
* {@link EventCondition.Compiler#FALSE}.
|
||||
* conditional.
|
||||
* @param left Constant left side {@link ValueExpression}
|
||||
* @param right Constant right side {@link ValueExpression}
|
||||
* @return Either {@link EventCondition.Compiler#TRUE} or
|
||||
* {@link EventCondition.Compiler#FALSE}
|
||||
* @return Constant {@link EventCondition}
|
||||
*/
|
||||
private static EventCondition in(final ValueExpression left, final ValueExpression right) {
|
||||
final Object found = right.get();
|
||||
final Object other = left.get();
|
||||
final boolean res;
|
||||
if (found instanceof ConvertedList && other instanceof RubyString) {
|
||||
return ((ConvertedList) found).stream().anyMatch(item -> item.toString()
|
||||
.equals(other.toString())) ? TRUE : FALSE;
|
||||
res = ((ConvertedList) found).stream().anyMatch(item -> item.toString()
|
||||
.equals(other.toString()));
|
||||
} else if (found instanceof RubyString && other instanceof RubyString) {
|
||||
return found.toString().contains(other.toString()) ? TRUE : FALSE;
|
||||
res = found.toString().contains(other.toString());
|
||||
} else if (found instanceof RubyString && other instanceof ConvertedList) {
|
||||
return ((ConvertedList) other).stream()
|
||||
.anyMatch(item -> item.toString().equals(found.toString())) ? TRUE : FALSE;
|
||||
res = ((ConvertedList) other).stream()
|
||||
.anyMatch(item -> item.toString().equals(found.toString()));
|
||||
} else {
|
||||
return found != null && other != null && found.equals(other) ? TRUE : FALSE;
|
||||
res = found != null && found.equals(other);
|
||||
}
|
||||
return constant(res);
|
||||
}
|
||||
|
||||
private static boolean listValueRight(final In in) {
|
||||
|
@ -345,22 +332,16 @@ public interface EventCondition {
|
|||
);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static EventCondition eq(final EventValueExpression evalE,
|
||||
final ValueExpression valE) {
|
||||
final Object value = valE.get();
|
||||
final String field = evalE.getFieldName();
|
||||
if (value instanceof String) {
|
||||
return new EventCondition.Compiler.FieldEqualsString(field, (String) value);
|
||||
} else if (value instanceof Long || value instanceof Integer ||
|
||||
value instanceof Short) {
|
||||
return new EventCondition.Compiler.FieldEqualsLong(
|
||||
field, ((Number) value).longValue()
|
||||
);
|
||||
}
|
||||
throw new EventCondition.Compiler.UnexpectedTypeException(value);
|
||||
return rubyFieldEquals(
|
||||
(Comparable<IRubyObject>) Rubyfier.deep(RubyUtil.RUBY, valE.get()),
|
||||
evalE.getFieldName()
|
||||
);
|
||||
}
|
||||
|
||||
private static EventCondition eq(final Eq equals) {
|
||||
private static EventCondition eq(final BinaryBooleanExpression equals) {
|
||||
final Expression left = equals.getLeft();
|
||||
final Expression right = equals.getRight();
|
||||
final EventCondition condition;
|
||||
|
@ -370,47 +351,20 @@ public interface EventCondition {
|
|||
condition = eq((EventValueExpression) right, (ValueExpression) left);
|
||||
} else if (eAndE(equals)) {
|
||||
condition = eq((EventValueExpression) left, (EventValueExpression) right);
|
||||
} else if (vAndV(equals)) {
|
||||
condition = ((ValueExpression) left).get()
|
||||
.equals(((ValueExpression) right).get()) ? TRUE : FALSE;
|
||||
} else {
|
||||
throw new EventCondition.Compiler.UnexpectedTypeException(left, right);
|
||||
condition = constant(
|
||||
((ValueExpression) left).get().equals(((ValueExpression) right).get())
|
||||
);
|
||||
}
|
||||
return condition;
|
||||
}
|
||||
|
||||
private static EventCondition eq(final EventValueExpression first,
|
||||
final EventValueExpression second) {
|
||||
return new EventCondition.Compiler.FieldEqualsField(
|
||||
FieldReference.from(first.getFieldName()), FieldReference.from(second.getFieldName())
|
||||
);
|
||||
}
|
||||
|
||||
private static EventCondition gt(final Gt greater) {
|
||||
final EventCondition condition;
|
||||
final Expression left = greater.getLeft();
|
||||
final Expression right = greater.getRight();
|
||||
if (eAndV(greater)) {
|
||||
condition = gt((EventValueExpression) left, (ValueExpression) right);
|
||||
} else {
|
||||
throw new EventCondition.Compiler.UnexpectedTypeException(left, right);
|
||||
}
|
||||
return condition;
|
||||
}
|
||||
|
||||
private static EventCondition gt(final EventValueExpression left,
|
||||
final ValueExpression right) {
|
||||
final Object value = right.get();
|
||||
final String field = left.getFieldName();
|
||||
if (value instanceof String) {
|
||||
return new EventCondition.Compiler.FieldGreaterThanString(field, (String) value);
|
||||
} else if (value instanceof Long || value instanceof Integer ||
|
||||
value instanceof Short) {
|
||||
return new EventCondition.Compiler.FieldGreaterThanNumber(
|
||||
field, RubyUtil.RUBY.newFixnum(((Number) value).longValue())
|
||||
);
|
||||
}
|
||||
throw new EventCondition.Compiler.UnexpectedTypeException(value);
|
||||
final FieldReference field1 = FieldReference.from(first.getFieldName());
|
||||
final FieldReference field2 = FieldReference.from(second.getFieldName());
|
||||
return event -> event.getEvent().getUnconvertedField(field1)
|
||||
.equals(event.getEvent().getUnconvertedField(field2));
|
||||
}
|
||||
|
||||
private static EventCondition truthy(final EventValueExpression evalE) {
|
||||
|
@ -418,15 +372,46 @@ public interface EventCondition {
|
|||
}
|
||||
|
||||
private static EventCondition not(final EventCondition condition) {
|
||||
return new EventCondition.Compiler.Negated(condition);
|
||||
return event -> !condition.fulfilled(event);
|
||||
}
|
||||
|
||||
private static EventCondition or(final EventCondition... conditions) {
|
||||
return new EventCondition.Compiler.OrCondition(conditions[0], conditions[1]);
|
||||
private static EventCondition compareConstants(final ValueExpression left,
|
||||
final ValueExpression right, final Predicate<Integer> operator) {
|
||||
return constant(operator.test(compare(left.get(), right.get())));
|
||||
}
|
||||
|
||||
private static EventCondition and(final EventCondition... conditions) {
|
||||
return new EventCondition.Compiler.AndCondition(conditions[0], conditions[1]);
|
||||
private static EventCondition compareFields(final EventValueExpression left,
|
||||
final EventValueExpression right, final Predicate<Integer> operator) {
|
||||
final FieldReference one = FieldReference.from(left.getFieldName());
|
||||
final FieldReference other = FieldReference.from(right.getFieldName());
|
||||
return event -> {
|
||||
final Event javaEvent = event.getEvent();
|
||||
return operator.test(
|
||||
compare(
|
||||
javaEvent.getUnconvertedField(one), javaEvent.getUnconvertedField(other)
|
||||
)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static EventCondition compareFieldToConstant(final EventValueExpression left,
|
||||
final ValueExpression right, final Predicate<Integer> operator) {
|
||||
final FieldReference one = FieldReference.from(left.getFieldName());
|
||||
final Comparable<IRubyObject> other =
|
||||
(Comparable<IRubyObject>) Rubyfier.deep(RubyUtil.RUBY, right.get());
|
||||
return event -> {
|
||||
final Event javaEvent = event.getEvent();
|
||||
return operator.test(compare(javaEvent.getUnconvertedField(one), other));
|
||||
};
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static int compare(final Object left, final Object right) {
|
||||
if (left instanceof Comparable<?>) {
|
||||
return ((Comparable) left).compareTo(right);
|
||||
}
|
||||
throw new EventCondition.Compiler.UnexpectedTypeException(left, right);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -444,144 +429,15 @@ public interface EventCondition {
|
|||
return false;
|
||||
}
|
||||
|
||||
private static final class Negated implements EventCondition {
|
||||
|
||||
private final EventCondition condition;
|
||||
|
||||
Negated(final EventCondition condition) {
|
||||
this.condition = condition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fulfilled(final JrubyEventExtLibrary.RubyEvent event) {
|
||||
return !condition.fulfilled(event);
|
||||
}
|
||||
private static EventCondition rubyFieldEquals(final Comparable<IRubyObject> left,
|
||||
final String field) {
|
||||
final FieldReference reference = FieldReference.from(field);
|
||||
return event ->
|
||||
left.equals((IRubyObject) event.getEvent().getUnconvertedField(reference));
|
||||
}
|
||||
|
||||
private static final class AndCondition implements EventCondition {
|
||||
|
||||
private final EventCondition first;
|
||||
|
||||
private final EventCondition second;
|
||||
|
||||
AndCondition(final EventCondition first, final EventCondition second) {
|
||||
this.first = first;
|
||||
this.second = second;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fulfilled(final JrubyEventExtLibrary.RubyEvent event) {
|
||||
return first.fulfilled(event) && second.fulfilled(event);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class OrCondition implements EventCondition {
|
||||
|
||||
private final EventCondition first;
|
||||
|
||||
private final EventCondition second;
|
||||
|
||||
OrCondition(final EventCondition first, final EventCondition second) {
|
||||
this.first = first;
|
||||
this.second = second;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fulfilled(final JrubyEventExtLibrary.RubyEvent event) {
|
||||
return first.fulfilled(event) || second.fulfilled(event);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class FieldGreaterThanString implements EventCondition {
|
||||
|
||||
private final FieldReference field;
|
||||
|
||||
private final RubyString value;
|
||||
|
||||
private FieldGreaterThanString(final String field, final String value) {
|
||||
this.field = FieldReference.from(field);
|
||||
this.value = RubyUtil.RUBY.newString(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fulfilled(final JrubyEventExtLibrary.RubyEvent event) {
|
||||
return value.compareTo(
|
||||
(IRubyObject) event.getEvent().getUnconvertedField(field)
|
||||
) < 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class FieldGreaterThanNumber implements EventCondition {
|
||||
|
||||
private final FieldReference field;
|
||||
|
||||
private final RubyNumeric value;
|
||||
|
||||
private FieldGreaterThanNumber(final String field, final RubyNumeric value) {
|
||||
this.field = FieldReference.from(field);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fulfilled(final JrubyEventExtLibrary.RubyEvent event) {
|
||||
return value.compareTo(
|
||||
(IRubyObject) event.getEvent().getUnconvertedField(field)
|
||||
) < 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class FieldEqualsString implements EventCondition {
|
||||
|
||||
private final FieldReference field;
|
||||
|
||||
private final RubyString value;
|
||||
|
||||
private FieldEqualsString(final String field, final String value) {
|
||||
this.field = FieldReference.from(field);
|
||||
this.value = RubyUtil.RUBY.newString(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fulfilled(final JrubyEventExtLibrary.RubyEvent event) {
|
||||
final Object val = event.getEvent().getUnconvertedField(field);
|
||||
return value.equals(val);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class FieldEqualsLong implements EventCondition {
|
||||
|
||||
private final FieldReference field;
|
||||
|
||||
private final long value;
|
||||
|
||||
private FieldEqualsLong(final String field, final long value) {
|
||||
this.field = FieldReference.from(field);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fulfilled(final JrubyEventExtLibrary.RubyEvent event) {
|
||||
final Object val = event.getEvent().getUnconvertedField(field);
|
||||
return val instanceof RubyInteger && ((RubyInteger) val).getLongValue() == value;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class FieldEqualsField implements EventCondition {
|
||||
|
||||
private final FieldReference one;
|
||||
|
||||
private final FieldReference other;
|
||||
|
||||
private FieldEqualsField(final FieldReference one, final FieldReference other) {
|
||||
this.one = one;
|
||||
this.other = other;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fulfilled(final JrubyEventExtLibrary.RubyEvent event) {
|
||||
return event.getEvent().getUnconvertedField(one)
|
||||
.equals(event.getEvent().getUnconvertedField(other));
|
||||
}
|
||||
private static EventCondition constant(final boolean value) {
|
||||
return value ? event -> true : event -> false;
|
||||
}
|
||||
|
||||
private static final class FieldMatches implements EventCondition {
|
||||
|
@ -687,7 +543,7 @@ public interface EventCondition {
|
|||
} else if (rfound instanceof ConvertedList) {
|
||||
return contains((ConvertedList) rfound, lfound);
|
||||
} else {
|
||||
return lfound != null && rfound != null && lfound.equals(rfound);
|
||||
return lfound != null && lfound.equals(rfound);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -749,6 +605,14 @@ public interface EventCondition {
|
|||
UnexpectedTypeException(final Object inner) {
|
||||
super(String.format("Unexpected input type %s", inner.getClass()));
|
||||
}
|
||||
|
||||
UnexpectedTypeException(final Object left, final Object right) {
|
||||
super(
|
||||
String.format(
|
||||
"Unexpected input type combination %s %s", left.getClass(), right.getClass()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.junit.Before;
|
|||
import org.junit.Test;
|
||||
import org.logstash.Event;
|
||||
import org.logstash.RubyUtil;
|
||||
import org.logstash.common.IncompleteSourceWithMetadataException;
|
||||
import org.logstash.config.ir.compiler.AbstractOutputDelegatorExt;
|
||||
import org.logstash.config.ir.compiler.FilterDelegatorExt;
|
||||
import org.logstash.config.ir.compiler.RubyIntegration;
|
||||
|
@ -155,6 +156,90 @@ public final class CompiledPipelineTest extends RubyEnvTestCase {
|
|||
MatcherAssert.assertThat(outputEvents.contains(testEvent), CoreMatchers.is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void correctlyCompilesEquals() throws Exception {
|
||||
final String eq = "==";
|
||||
assertCorrectFieldComparison(eq, 6, false);
|
||||
assertCorrectFieldComparison(eq, 7, true);
|
||||
assertCorrectFieldComparison(eq, 8, false);
|
||||
assertCorrectValueComparison(eq, 6, false);
|
||||
assertCorrectValueComparison(eq, 7, true);
|
||||
assertCorrectValueComparison(eq, 8, false);
|
||||
assertCorrectFieldToFieldComparison(eq, 7, 6, false);
|
||||
assertCorrectFieldToFieldComparison(eq, 7, 7, true);
|
||||
assertCorrectFieldToFieldComparison(eq, 7, 8, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void correctlyCompilesNotEquals() throws Exception {
|
||||
final String eq = "!=";
|
||||
assertCorrectFieldComparison(eq, 6, true);
|
||||
assertCorrectFieldComparison(eq, 7, false);
|
||||
assertCorrectFieldComparison(eq, 8, true);
|
||||
assertCorrectValueComparison(eq, 6, true);
|
||||
assertCorrectValueComparison(eq, 7, false);
|
||||
assertCorrectValueComparison(eq, 8, true);
|
||||
assertCorrectFieldToFieldComparison(eq, 7, 6, true);
|
||||
assertCorrectFieldToFieldComparison(eq, 7, 7, false);
|
||||
assertCorrectFieldToFieldComparison(eq, 7, 8, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void correctlyCompilesGreaterThan() throws Exception {
|
||||
final String gt = ">";
|
||||
assertCorrectFieldComparison(gt, 6, true);
|
||||
assertCorrectFieldComparison(gt, 7, false);
|
||||
assertCorrectFieldComparison(gt, 8, false);
|
||||
assertCorrectValueComparison(gt, 6, true);
|
||||
assertCorrectValueComparison(gt, 7, false);
|
||||
assertCorrectValueComparison(gt, 8, false);
|
||||
assertCorrectFieldToFieldComparison(gt, 7, 6, true);
|
||||
assertCorrectFieldToFieldComparison(gt, 7, 7, false);
|
||||
assertCorrectFieldToFieldComparison(gt, 7, 8, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void correctlyCompilesLessThan() throws Exception {
|
||||
final String lt = "<";
|
||||
assertCorrectFieldComparison(lt, 6, false);
|
||||
assertCorrectFieldComparison(lt, 7, false);
|
||||
assertCorrectFieldComparison(lt, 8, true);
|
||||
assertCorrectValueComparison(lt, 6, false);
|
||||
assertCorrectValueComparison(lt, 7, false);
|
||||
assertCorrectValueComparison(lt, 8, true);
|
||||
assertCorrectFieldToFieldComparison(lt, 7, 6, false);
|
||||
assertCorrectFieldToFieldComparison(lt, 7, 7, false);
|
||||
assertCorrectFieldToFieldComparison(lt, 7, 8, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void correctlyCompilesLessOrEqualThan() throws Exception {
|
||||
final String lte = "<=";
|
||||
assertCorrectFieldComparison(lte, 6, false);
|
||||
assertCorrectFieldComparison(lte, 7, true);
|
||||
assertCorrectFieldComparison(lte, 8, true);
|
||||
assertCorrectValueComparison(lte, 6, false);
|
||||
assertCorrectValueComparison(lte, 7, true);
|
||||
assertCorrectValueComparison(lte, 8, true);
|
||||
assertCorrectFieldToFieldComparison(lte, 7, 6, false);
|
||||
assertCorrectFieldToFieldComparison(lte, 7, 7, true);
|
||||
assertCorrectFieldToFieldComparison(lte, 7, 8, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void correctlyCompilesGreaterOrEqualThan() throws Exception {
|
||||
final String gte = ">=";
|
||||
assertCorrectFieldComparison(gte, 6, true);
|
||||
assertCorrectFieldComparison(gte, 7, true);
|
||||
assertCorrectFieldComparison(gte, 8, false);
|
||||
assertCorrectValueComparison(gte, 6, true);
|
||||
assertCorrectValueComparison(gte, 7, true);
|
||||
assertCorrectValueComparison(gte, 8, false);
|
||||
assertCorrectFieldToFieldComparison(gte, 7, 6, true);
|
||||
assertCorrectFieldToFieldComparison(gte, 7, 7, true);
|
||||
assertCorrectFieldToFieldComparison(gte, 7, 8, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void conditionalNestedMetaFieldPipeline() throws Exception {
|
||||
final PipelineIR pipelineIR = ConfigCompiler.configToPipelineIR(
|
||||
|
@ -212,6 +297,56 @@ public final class CompiledPipelineTest extends RubyEnvTestCase {
|
|||
MatcherAssert.assertThat(outputEvents.contains(testEvent), CoreMatchers.is(true));
|
||||
}
|
||||
|
||||
private void assertCorrectValueComparison(final String op, final int value,
|
||||
final boolean expected) throws Exception {
|
||||
final Event event = new Event();
|
||||
verifyComparison(expected, String.format("7 %s %d ", op, value), event);
|
||||
}
|
||||
|
||||
private void assertCorrectFieldComparison(final String op, final int value,
|
||||
final boolean expected) throws Exception {
|
||||
final Event event = new Event();
|
||||
event.setField("baz", value);
|
||||
verifyComparison(expected, String.format("7 %s [baz]", op), event);
|
||||
}
|
||||
|
||||
private void assertCorrectFieldToFieldComparison(final String op, final int value1,
|
||||
final int value2, final boolean expected) throws Exception {
|
||||
final Event event = new Event();
|
||||
event.setField("brr", value1);
|
||||
event.setField("baz", value2);
|
||||
verifyComparison(expected, String.format("[brr] %s [baz]", op), event);
|
||||
}
|
||||
|
||||
private void verifyComparison(final boolean expected, final String conditional,
|
||||
final Event event) throws IncompleteSourceWithMetadataException {
|
||||
final JrubyEventExtLibrary.RubyEvent testEvent =
|
||||
JrubyEventExtLibrary.RubyEvent.newRubyEvent(RubyUtil.RUBY, event);
|
||||
new CompiledPipeline(
|
||||
ConfigCompiler.configToPipelineIR(
|
||||
"input {mockinput{}} filter { " +
|
||||
String.format("if %s { ", conditional) +
|
||||
" mockaddfilter {} " +
|
||||
"} " +
|
||||
"} output {mockoutput{} }",
|
||||
false
|
||||
),
|
||||
new CompiledPipelineTest.MockPluginFactory(
|
||||
Collections.singletonMap("mockinput", () -> null),
|
||||
Collections.singletonMap("mockaddfilter", () -> ADD_FIELD_FILTER),
|
||||
Collections.singletonMap("mockoutput", mockOutputSupplier())
|
||||
)
|
||||
).buildExecution()
|
||||
.compute(RubyUtil.RUBY.newArray(testEvent), false, false);
|
||||
final Collection<JrubyEventExtLibrary.RubyEvent> outputEvents = EVENT_SINKS.get(runId);
|
||||
MatcherAssert.assertThat(outputEvents.size(), CoreMatchers.is(1));
|
||||
MatcherAssert.assertThat(outputEvents.contains(testEvent), CoreMatchers.is(true));
|
||||
MatcherAssert.assertThat(
|
||||
event.getField("foo"), CoreMatchers.is(expected ? "bar" : null)
|
||||
);
|
||||
outputEvents.clear();
|
||||
}
|
||||
|
||||
private Supplier<Consumer<Collection<JrubyEventExtLibrary.RubyEvent>>> mockOutputSupplier() {
|
||||
return () -> events -> events.forEach(
|
||||
event -> EVENT_SINKS.get(runId).add((JrubyEventExtLibrary.RubyEvent) event)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue