Skip to content

Commit

Permalink
[DROOLS-7635] ansible-rulebook : Raise an error when a condition comp… (
Browse files Browse the repository at this point in the history
#117)

* [DROOLS-7635] ansible-rulebook : Raise an error when a condition compares incompatible types
- alpha index test, beta index test

beta index test fix

add negate test and any test

* refactor

* minor comment fix
  • Loading branch information
tkobayas authored Oct 11, 2024
1 parent 2d3e3ec commit 081fb11
Show file tree
Hide file tree
Showing 3 changed files with 339 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

import org.drools.model.ConstraintOperator;

import static org.drools.ansible.rulebook.integration.api.domain.constraints.RulebookConstraintOperator.isCompatibleType;

public class NegationOperator implements ConstraintOperator {

private final ConstraintOperator toBeNegated;
Expand All @@ -14,6 +16,16 @@ public NegationOperator(ConstraintOperator toBeNegated) {

@Override
public <T, V> BiPredicate<T, V> asPredicate() {
if (toBeNegated instanceof RulebookConstraintOperator rulebookConstraintOperator) {
return (t, v) -> {
// if not compatible type, return false. Use the operator to log the type check error
if (!isCompatibleType(t, v)) {
rulebookConstraintOperator.logTypeCheck(t, v);
return false;
}
return !toBeNegated.asPredicate().test(t, v);
};
}
return (t, v) -> !toBeNegated.asPredicate().test(t, v);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public RulebookConstraintOperator(Index.ConstraintType type) {
this.type = type;
}

@Override
public void setConditionContext(RuleGenerationContext ruleContext, Map<?, ?> expression) {
this.conditionContext = new ConditionContext(ruleContext.getRuleSetName(), ruleContext.getRuleName(), expression.toString());
}
Expand Down Expand Up @@ -64,6 +65,7 @@ public RulebookConstraintOperator negate() {
return this;
}

@Override
public boolean canInverse() {
switch (this.type) {
case EQUAL:
Expand Down Expand Up @@ -107,23 +109,35 @@ public <T, V> BiPredicate<T, V> asPredicate() {
}

private <T, V> boolean predicateWithTypeCheck(T t, V v, BiPredicate<T, V> predicate) {
if (t == null
|| v == null
|| t instanceof Number && v instanceof Number
|| t.getClass() == v.getClass()) {
if (isCompatibleType(t, v)) {
return predicate.test(t, v);
} else {
if (!typeCheckLogged) {
LOG.error("Cannot compare values of different types: {} and {}. RuleSet: {}. RuleName: {}. Condition: {}",
convertJavaClassToPythonClass(t.getClass()),
convertJavaClassToPythonClass(v.getClass()),
conditionContext.getRuleSet(), conditionContext.getRuleName(), conditionContext.getConditionExpression());
typeCheckLogged = true; // Log only once per constraint
}
return false; // Different types are never equal
logTypeCheck(t, v);
return false; // Different types evaluation always return false even if the operator is NOT_EQUAL
}
}

/*
* Log a type check error once per constraint
*/
<T, V> void logTypeCheck(T t, V v) {
if (!typeCheckLogged) {
LOG.error("Cannot compare values of different types: {} and {}. RuleSet: {}. RuleName: {}. Condition: {}",
convertJavaClassToPythonClass(t.getClass()),
convertJavaClassToPythonClass(v.getClass()),
conditionContext.getRuleSet(), conditionContext.getRuleName(), conditionContext.getConditionExpression());
typeCheckLogged = true; // Log only once per constraint
}
}

public static boolean isCompatibleType(Object t, Object v) {
return t == null
|| v == null
|| t instanceof Number && v instanceof Number
|| t.getClass() == v.getClass();
}

@Override
public RulebookConstraintOperator inverse() {
switch (this.type) {
case GREATER_THAN:
Expand Down
Loading

0 comments on commit 081fb11

Please sign in to comment.