Skip to content

Commit 356a511

Browse files
perf: Collect orgUnitGroups in RuleContextRequirements [DHIS2-21245]
1 parent 4ec44fb commit 356a511

5 files changed

Lines changed: 49 additions & 5 deletions

File tree

api/rule-engine.api

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,15 @@ public final class org/hisp/dhis/rules/api/ItemValueType : java/lang/Enum {
6565

6666
public final class org/hisp/dhis/rules/api/RuleContextRequirements {
6767
public static final field Companion Lorg/hisp/dhis/rules/api/RuleContextRequirements$Companion;
68-
public fun <init> (Z)V
68+
public fun <init> (ZLjava/util/Set;)V
69+
public synthetic fun <init> (ZLjava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
6970
public final fun component1 ()Z
70-
public final fun copy (Z)Lorg/hisp/dhis/rules/api/RuleContextRequirements;
71-
public static synthetic fun copy$default (Lorg/hisp/dhis/rules/api/RuleContextRequirements;ZILjava/lang/Object;)Lorg/hisp/dhis/rules/api/RuleContextRequirements;
71+
public final fun component2 ()Ljava/util/Set;
72+
public final fun copy (ZLjava/util/Set;)Lorg/hisp/dhis/rules/api/RuleContextRequirements;
73+
public static synthetic fun copy$default (Lorg/hisp/dhis/rules/api/RuleContextRequirements;ZLjava/util/Set;ILjava/lang/Object;)Lorg/hisp/dhis/rules/api/RuleContextRequirements;
7274
public fun equals (Ljava/lang/Object;)Z
7375
public final fun getNeedsAllEvents ()Z
76+
public final fun getOrgUnitGroups ()Ljava/util/Set;
7477
public fun hashCode ()I
7578
public fun toString ()Ljava/lang/String;
7679
}

gradle/libs.versions.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ sonarqube = "7.2.3.7755"
1010
kotlinxDatetime = "0.7.1"
1111
kotlinJsWrappers = "1.0.0-pre.830"
1212
slf4jApi = "1.7.36"
13-
expressionParser = "1.4.0"
13+
expressionParser = "1.4.1"
1414

1515
[libraries]
1616
kotlin-plugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" }

src/commonMain/kotlin/org/hisp/dhis/rules/api/RuleContextRequirements.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
package org.hisp.dhis.rules.api
22

3+
import kotlin.js.JsExport
4+
5+
@JsExport
36
data class RuleContextRequirements(
47
val needsAllEvents: Boolean,
8+
val orgUnitGroups: Set<String> = emptySet(),
59
) {
610
companion object {
711
val NONE = RuleContextRequirements(needsAllEvents = false)

src/commonMain/kotlin/org/hisp/dhis/rules/engine/RuleEngineAnalyzer.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,19 @@ internal object RuleEngineAnalyzer {
1616
): RuleContextRequirements {
1717
val envVars = mutableSetOf<String>()
1818
val referencedVarNames = mutableSetOf<String>()
19+
val orgUnitGroups = mutableSetOf<String>()
1920

2021
for (rule in rules) {
2122
rule.conditionExpression.getOrNull()?.let {
2223
envVars += it.collectProgramVariablesNames()
2324
referencedVarNames += it.collectProgramRuleVariableNames()
25+
orgUnitGroups += it.collectInOrgUnitGroups()
2426
}
2527
for (action in rule.actions) {
2628
action.dataExpression.getOrNull()?.let {
2729
envVars += it.collectProgramVariablesNames()
2830
referencedVarNames += it.collectProgramRuleVariableNames()
31+
orgUnitGroups += it.collectInOrgUnitGroups()
2932
}
3033
}
3134
}
@@ -39,6 +42,6 @@ internal object RuleEngineAnalyzer {
3942
v is RuleVariablePreviousEvent
4043
}
4144

42-
return RuleContextRequirements(needsAllEvents)
45+
return RuleContextRequirements(needsAllEvents, orgUnitGroups)
4346
}
4447
}

src/commonTest/kotlin/org/hisp/dhis/rules/RuleEngineAnalyzerTest.kt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,40 @@ class RuleEngineAnalyzerTest {
148148
assertFalse(RuleContextRequirements.NONE.needsAllEvents)
149149
}
150150

151+
// --- orgUnitGroups collection ---
152+
153+
@Test
154+
fun orgUnitGroupInConditionIsCollected() {
155+
val rules = listOf(rule("d2:inOrgUnitGroup('GroupA')"))
156+
val result = RuleEngineAnalyzer.analyzeContextRequirements(rules, emptyList())
157+
assertEquals(setOf("GroupA"), result.orgUnitGroups)
158+
}
159+
160+
@Test
161+
fun orgUnitGroupInActionDataIsCollected() {
162+
val rules = listOf(rule("true", "d2:inOrgUnitGroup('GroupB')"))
163+
val result = RuleEngineAnalyzer.analyzeContextRequirements(rules, emptyList())
164+
assertEquals(setOf("GroupB"), result.orgUnitGroups)
165+
}
166+
167+
@Test
168+
fun multipleOrgUnitGroupsAcrossRulesAreCollected() {
169+
val rules = listOf(
170+
rule("d2:inOrgUnitGroup('GroupA')"),
171+
rule("true", "d2:inOrgUnitGroup('GroupB')"),
172+
rule("d2:inOrgUnitGroup('GroupA') || d2:inOrgUnitGroup('GroupC')"),
173+
)
174+
val result = RuleEngineAnalyzer.analyzeContextRequirements(rules, emptyList())
175+
assertEquals(setOf("GroupA", "GroupB", "GroupC"), result.orgUnitGroups)
176+
}
177+
178+
@Test
179+
fun noOrgUnitGroupReturnsEmptySet() {
180+
val rules = listOf(rule("#{score} > 5"))
181+
val result = RuleEngineAnalyzer.analyzeContextRequirements(rules, emptyList())
182+
assertTrue(result.orgUnitGroups.isEmpty())
183+
}
184+
151185
// --- RuleEngine interface delegation ---
152186

153187
@Test

0 commit comments

Comments
 (0)