Skip to content

Commit

Permalink
Merge pull request #45 from mkanoor/partial_retract_match
Browse files Browse the repository at this point in the history
Partial match, events ttl, session stats
  • Loading branch information
mkanoor committed Apr 18, 2023
2 parents b339a4c + 2552a50 commit b4504cb
Show file tree
Hide file tree
Showing 7 changed files with 234 additions and 2 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "drools_jpy"
version = "0.3.0"
version = "0.3.1"
authors = [
{ name="Madhu Kanoor", email="author@example.com" },
]
Expand Down
Binary file not shown.
32 changes: 31 additions & 1 deletion src/drools/ruleset.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import logging
import os
from dataclasses import dataclass, field
from typing import ClassVar, Dict
from typing import ClassVar, Dict, List

import jpyutil

Expand Down Expand Up @@ -173,6 +173,21 @@ def retract_fact(self, serialized_fact: str):
self._api.retractFact(self._session_id, serialized_fact)
)

def retract_matching_facts(
self, serialized_fact: str, partial: bool, exclude_keys: List[str]
):
return self._process_response(
self._api.retractMatchingFacts(
self._session_id, serialized_fact, partial, exclude_keys
)
)

def session_stats(self) -> Dict:
result = self._api.sessionStats(self._session_id)
if result:
return json.loads(result)
return {}

def advance_time(self, amount: int, units: str):
return self._api.advanceTime(self._session_id, amount, units)

Expand Down Expand Up @@ -294,10 +309,25 @@ def retract_fact(ruleset_name: str, serialized_fact: str):
)


def retract_matching_facts(
ruleset_name: str,
serialized_fact: str,
partial: bool,
exclude_keys: List[str],
):
return RulesetCollection.get(ruleset_name).retract_matching_facts(
_to_json(serialized_fact), partial, exclude_keys
)


def end_session(ruleset_name: str) -> Dict:
return RulesetCollection.get(ruleset_name).end_session()


def session_stats(ruleset_name: str) -> Dict:
return RulesetCollection.get(ruleset_name).session_stats()


def get_facts(ruleset_name: str):
return RulesetCollection.get(ruleset_name).get_facts()

Expand Down
44 changes: 44 additions & 0 deletions tests/asts/retract_matching_facts.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
- RuleSet:
hosts:
- all
name: example
rules:
- Rule:
actions:
- Action:
action: print_event
action_args:
pretty: true
condition:
AllCondition:
- GreaterThanExpression:
lhs:
Event: i
rhs:
Integer: 2
- GreaterThanExpression:
lhs:
Event: x
rhs:
Integer: 34
enabled: true
name: r1
- Rule:
actions:
- Action:
action: print_event
action_args:
pretty: true
condition:
AllCondition:
- IsNotDefinedExpression:
Event: i
enabled: true
name: r2
sources:
- EventSource:
name: range
source_args:
limit: 10
source_filters: []
source_name: range
34 changes: 34 additions & 0 deletions tests/asts/test_default_events_ttl.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
- RuleSet:
default_events_ttl: 16 seconds
hosts:
- all
name: Evict events which are partially matched
rules:
- Rule:
actions:
- Action:
action: print_event
action_args:
pretty: true
condition:
AllCondition:
- GreaterThanOrEqualToExpression:
lhs:
Event: i
rhs:
Integer: 0
- GreaterThanExpression:
lhs:
Event: x
rhs:
Integer: 34
enabled: true
name: r1
sources:
- EventSource:
name: range
source_args:
delay: 720
limit: 2
source_filters: []
source_name: range
50 changes: 50 additions & 0 deletions tests/asts/test_stats.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
- RuleSet:
hosts:
- localhost
name: Test Stats
rules:
- Rule:
action:
Action:
action: debug
action_args:
events_event: '{{events.first}}'
condition:
AllCondition:
- AssignmentExpression:
lhs:
Events: first
rhs:
EqualsExpression:
lhs:
Event: i
rhs:
Integer: 67
enabled: true
name: assignment
- Rule:
action:
Action:
action: debug
action_args:
events_event: '{{events.first}}'
condition:
AllCondition:
- AssignmentExpression:
lhs:
Events: first
rhs:
EqualsExpression:
lhs:
Event: i
rhs:
Integer: 67
enabled: false
name: disabled1
sources:
- EventSource:
name: range
source_args:
limit: 5
source_filters: []
source_name: range
74 changes: 74 additions & 0 deletions tests/test_ruleset.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,33 @@ def test_retract_fact():
assert len(response) == 0


def test_retract_matching_facts():
test_data = load_ast("asts/retract_matching_facts.yml")

my_callback1 = mock.Mock()
my_callback2 = mock.Mock()
result = Matches(data={"m": {"i": 67, "n": 239}})

ruleset_data = test_data[0]["RuleSet"]
rs = Ruleset(
name=ruleset_data["name"], serialized_ruleset=json.dumps(ruleset_data)
)
rs.add_rule(Rule("r1", my_callback1))
rs.add_rule(Rule("r2", my_callback2))

rs.assert_fact(json.dumps(dict(i=67, n=239)))
rs.assert_fact(json.dumps(dict(j=42)))
assert not my_callback1.called

assert (len(rs.get_facts())) == 1
rs.retract_matching_facts(json.dumps(dict(n=239)), True, [])

my_callback2.assert_called_with(result)
response = rs.get_facts()
rs.end_session()
assert len(response) == 0


def test_get_facts():
test_data = load_ast("asts/assert_fact.yml")

Expand Down Expand Up @@ -888,3 +915,50 @@ def test_integrated(rulebook):
assert cb.called

rs.end_session()


def test_default_events_ttl():
test_data = load_ast("asts/test_default_events_ttl.yml")
my_callback = mock.Mock()

ruleset_data = test_data[0]["RuleSet"]
rs = Ruleset(
name=ruleset_data["name"],
serialized_ruleset=json.dumps(ruleset_data),
)
rs.add_rule(Rule("r1", my_callback))

rs.assert_event(json.dumps(dict(i=42)))
assert (len(rs.get_facts())) == 1
rs.advance_time(40, "seconds")
rs.assert_event(json.dumps(dict(j=13)))
assert (len(rs.get_facts())) == 0

rs.end_session()

assert my_callback.call_count == 0


def test_session_stats():
test_data = load_ast("asts/test_stats.yml")
my_callback = mock.Mock()
result = Matches(data={"first": {"i": 67}})

ruleset_data = test_data[0]["RuleSet"]
rs = Ruleset(
name=ruleset_data["name"], serialized_ruleset=json.dumps(ruleset_data)
)
rs.add_rule(Rule("assignment", my_callback))

rs.assert_event(json.dumps(dict(i=67)))
rs.assert_event(json.dumps(dict(j=67)))
stats = rs.session_stats()

assert stats["rulesTriggered"] == 1
assert stats["numberOfRules"] == 1
assert stats["numberOfDisabledRules"] == 1
assert stats["eventsProcessed"] == 2
assert stats["eventsMatched"] == 1

rs.end_session()
my_callback.assert_called_with(result)

0 comments on commit b4504cb

Please sign in to comment.