Skip to content

Commit

Permalink
- support alpha index
Browse files Browse the repository at this point in the history
- support node sharing (but not merging error messages)
- WIP: need more assertions
  • Loading branch information
tkobayas committed Sep 27, 2024
1 parent ab2d146 commit d4a3d35
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import org.drools.ansible.rulebook.integration.api.domain.RuleGenerationContext;
import org.drools.model.ConstraintOperator;
import org.drools.model.Index;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -13,52 +14,52 @@

public class RulebookConstraintOperator implements ConstraintOperator {

enum RulebookConstraintOperatorType {
EQUAL,
NOT_EQUAL,
GREATER_THAN,
GREATER_OR_EQUAL,
LESS_THAN,
LESS_OR_EQUAL,
UNKNOWN;
}

private static final Logger LOG = LoggerFactory.getLogger(RulebookConstraintOperator.class);

private RulebookConstraintOperatorType type;
private Index.ConstraintType type;
private ConditionContext conditionContext;
private boolean typeCheckLogged = false;

public RulebookConstraintOperator(RulebookConstraintOperatorType type) {
public RulebookConstraintOperator(Index.ConstraintType type) {
this.type = type;
}

public void setConditionContext(RuleGenerationContext ruleContext, Map<?, ?> expression) {
this.conditionContext = new ConditionContext(ruleContext.getRuleSetName(), ruleContext.getRuleName(), expression.toString());
}

@Override
public boolean containsConstraintType() {
return true;
}

@Override
public Index.ConstraintType getConstraintType() {
return type;
}

public RulebookConstraintOperator negate() {
switch (this.type) {
case EQUAL:
this.type = RulebookConstraintOperatorType.NOT_EQUAL;
this.type = Index.ConstraintType.NOT_EQUAL;
return this;
case NOT_EQUAL:
this.type = RulebookConstraintOperatorType.EQUAL;
this.type = Index.ConstraintType.EQUAL;
return this;
case GREATER_THAN:
this.type = RulebookConstraintOperatorType.LESS_OR_EQUAL;
this.type = Index.ConstraintType.LESS_OR_EQUAL;
return this;
case GREATER_OR_EQUAL:
this.type = RulebookConstraintOperatorType.LESS_THAN;
this.type = Index.ConstraintType.LESS_THAN;
return this;
case LESS_OR_EQUAL:
this.type = RulebookConstraintOperatorType.GREATER_THAN;
this.type = Index.ConstraintType.GREATER_THAN;
return this;
case LESS_THAN:
this.type = RulebookConstraintOperatorType.GREATER_OR_EQUAL;
this.type = Index.ConstraintType.GREATER_OR_EQUAL;
return this;
}
this.type = RulebookConstraintOperatorType.UNKNOWN;
this.type = Index.ConstraintType.UNKNOWN;
return this;
}

Expand Down Expand Up @@ -124,16 +125,16 @@ private <T, V> boolean predicateWithTypeCheck(T t, V v, BiPredicate<T, V> predic
public RulebookConstraintOperator inverse() {
switch (this.type) {
case GREATER_THAN:
this.type = RulebookConstraintOperatorType.LESS_THAN;
this.type = Index.ConstraintType.LESS_THAN;
return this;
case GREATER_OR_EQUAL:
this.type = RulebookConstraintOperatorType.LESS_OR_EQUAL;
this.type = Index.ConstraintType.LESS_OR_EQUAL;
return this;
case LESS_THAN:
this.type = RulebookConstraintOperatorType.GREATER_THAN;
this.type = Index.ConstraintType.GREATER_THAN;
return this;
case LESS_OR_EQUAL:
this.type = RulebookConstraintOperatorType.GREATER_OR_EQUAL;
this.type = Index.ConstraintType.GREATER_OR_EQUAL;
return this;
default:
return this;
Expand All @@ -145,11 +146,11 @@ public boolean isComparison() {
}

public boolean isAscending() {
return this.type == RulebookConstraintOperatorType.GREATER_THAN || this.type == RulebookConstraintOperatorType.GREATER_OR_EQUAL;
return this.type == Index.ConstraintType.GREATER_THAN || this.type == Index.ConstraintType.GREATER_OR_EQUAL;
}

public boolean isDescending() {
return this.type == RulebookConstraintOperatorType.LESS_THAN || this.type == RulebookConstraintOperatorType.LESS_OR_EQUAL;
return this.type == Index.ConstraintType.LESS_THAN || this.type == Index.ConstraintType.LESS_OR_EQUAL;
}

private class ConditionContext {
Expand All @@ -176,4 +177,10 @@ public String getConditionExpression() {
return conditionExpression;
}
}

@Override
public String toString() {
// works for node sharing
return type.toString();
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package org.drools.ansible.rulebook.integration.api.domain.constraints;

import org.drools.ansible.rulebook.integration.api.domain.RuleGenerationContext;
import org.drools.model.ConstraintOperator;

import java.util.Map;
import java.util.function.BiPredicate;

import org.drools.ansible.rulebook.integration.api.domain.RuleGenerationContext;
import org.drools.model.ConstraintOperator;
import org.drools.model.Index;

public interface RulebookOperator extends ConstraintOperator {

default boolean canInverse() {
Expand All @@ -21,35 +22,34 @@ default ConstraintOperator asConstraintOperator() {
}

static RulebookOperator newEqual() {
return new OperatorWrapper(new RulebookConstraintOperator(RulebookConstraintOperator.RulebookConstraintOperatorType.EQUAL));
return new OperatorWrapper(new RulebookConstraintOperator(Index.ConstraintType.EQUAL));
}

static RulebookOperator newNotEqual() {
return new OperatorWrapper(new RulebookConstraintOperator(RulebookConstraintOperator.RulebookConstraintOperatorType.NOT_EQUAL));
return new OperatorWrapper(new RulebookConstraintOperator(Index.ConstraintType.NOT_EQUAL));
}

static RulebookOperator newGreaterThan() {
return new OperatorWrapper(new RulebookConstraintOperator(RulebookConstraintOperator.RulebookConstraintOperatorType.GREATER_THAN));
return new OperatorWrapper(new RulebookConstraintOperator(Index.ConstraintType.GREATER_THAN));
}

static RulebookOperator newGreaterOrEqual() {
return new OperatorWrapper(new RulebookConstraintOperator(RulebookConstraintOperator.RulebookConstraintOperatorType.GREATER_OR_EQUAL));
return new OperatorWrapper(new RulebookConstraintOperator(Index.ConstraintType.GREATER_OR_EQUAL));
}

static RulebookOperator newLessThan() {
return new OperatorWrapper(new RulebookConstraintOperator(RulebookConstraintOperator.RulebookConstraintOperatorType.LESS_THAN));
return new OperatorWrapper(new RulebookConstraintOperator(Index.ConstraintType.LESS_THAN));
}

static RulebookOperator newLessOrEqual() {
return new OperatorWrapper(new RulebookConstraintOperator(RulebookConstraintOperator.RulebookConstraintOperatorType.LESS_OR_EQUAL));
return new OperatorWrapper(new RulebookConstraintOperator(Index.ConstraintType.LESS_OR_EQUAL));
}

default void setConditionContext(RuleGenerationContext ruleContext, Map<?, ?> expression) {
if (this instanceof OperatorWrapper operatorWrapper) {
operatorWrapper.setConditionContext(ruleContext, expression);
} else {
// do nothing
return;
}
}

Expand Down Expand Up @@ -80,6 +80,7 @@ public ConstraintOperator asConstraintOperator() {
return delegate;
}

@Override
public void setConditionContext(RuleGenerationContext ruleContext, Map<?, ?> expression) {
delegate.setConditionContext(ruleContext, expression);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
package org.drools.ansible.rulebook.integration.api;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import org.drools.base.reteoo.InitialFactImpl;
import org.junit.Test;
import org.kie.api.prototype.PrototypeFactInstance;
import org.kie.api.runtime.rule.Match;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

public class TypeMismatchTest {

Expand Down Expand Up @@ -86,6 +81,7 @@ public void mapAndString() {
// mera.headers is a map, not a string
List<Match> matchedRules = rulesExecutor.processEvents("{ \"meta\": {\"headers\": {\"Content-Length\": \"36\"}} } }").join();
// When comparing mismatched types, the rule should not match (even r2). Logs error for 2 rules.
// TODO: Add log assertion
assertEquals(0, matchedRules.size());

// One more time
Expand Down Expand Up @@ -143,4 +139,108 @@ public void stringAndInteger() {

rulesExecutor.dispose();
}


@Test
public void typeMismatchWithNodeSharing() {
String json =
"""
{
"rules": [
{
"Rule": {
"name": "r1",
"condition": {
"AllCondition": [
{
"AndExpression": {
"lhs": {
"EqualsExpression": {
"lhs": {
"Event": "i"
},
"rhs": {
"Integer": 1
}
}
},
"rhs": {
"EqualsExpression": {
"lhs": {
"Event": "j"
},
"rhs": {
"Integer": 1
}
}
}
}
}
]
},
"actions": [
{
"Action": {
"action": "debug",
"action_args": {}
}
}
],
"enabled": true
}
},
{
"Rule": {
"name": "r2",
"condition": {
"AllCondition": [
{
"AndExpression": {
"lhs": {
"EqualsExpression": {
"lhs": {
"Event": "i"
},
"rhs": {
"Integer": 1
}
}
},
"rhs": {
"EqualsExpression": {
"lhs": {
"Event": "j"
},
"rhs": {
"Integer": 2
}
}
}
}
}
]
},
"actions": [
{
"Action": {
"action": "debug",
"action_args": {}
}
}
],
"enabled": true
}
}
]
}
""";

RulesExecutor rulesExecutor = RulesExecutorFactory.createFromJson(json);

// TODO: add node sharing assertion

// i is a string, not an integer
List<Match> matchedRules = rulesExecutor.processEvents("{ \"i\": \"1\", \"j\": 1 }").join();
assertEquals(0, matchedRules.size());
}
}

0 comments on commit d4a3d35

Please sign in to comment.