Skip to content

Commit a40837c

Browse files
committed
Populate results and triggered docs in document level trigger execution context
Signed-off-by: Surya Sashank Nistala <[email protected]>
1 parent 9f3c393 commit a40837c

File tree

3 files changed

+98
-3
lines changed

3 files changed

+98
-3
lines changed

alerting/src/main/kotlin/org/opensearch/alerting/DocumentLevelMonitorRunner.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ object DocumentLevelMonitorRunner : MonitorRunner() {
222222
queryToDocIds: Map<DocLevelQuery, Set<String>>,
223223
dryrun: Boolean
224224
): DocumentLevelTriggerRunResult {
225-
val triggerCtx = DocumentLevelTriggerExecutionContext(monitor, trigger)
225+
val triggerCtx = DocumentLevelTriggerExecutionContext(monitor, trigger, monitorResult)
226226
val triggerResult = monitorCtx.triggerService!!.runDocLevelTrigger(monitor, trigger, queryToDocIds)
227227

228228
val findings = mutableListOf<String>()

alerting/src/main/kotlin/org/opensearch/alerting/script/DocumentLevelTriggerExecutionContext.kt

+6-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ package org.opensearch.alerting.script
77

88
import org.opensearch.alerting.model.Alert
99
import org.opensearch.alerting.model.DocumentLevelTrigger
10+
import org.opensearch.alerting.model.DocumentLevelTriggerRunResult
1011
import org.opensearch.alerting.model.Monitor
12+
import org.opensearch.alerting.model.MonitorRunResult
1113
import java.time.Instant
1214

1315
data class DocumentLevelTriggerExecutionContext(
@@ -25,10 +27,11 @@ data class DocumentLevelTriggerExecutionContext(
2527
constructor(
2628
monitor: Monitor,
2729
trigger: DocumentLevelTrigger,
30+
monitorRunResult: MonitorRunResult<DocumentLevelTriggerRunResult>,
2831
alerts: List<Alert> = listOf()
2932
) : this(
30-
monitor, trigger, emptyList(), Instant.now(), Instant.now(),
31-
alerts, emptyList(), emptyList(), null
33+
monitor, trigger, monitorRunResult.inputResults.results, monitorRunResult.periodStart, monitorRunResult.periodEnd,
34+
alerts, emptyList(), emptyList(), monitorRunResult.scriptContextError(trigger)
3235
)
3336

3437
/**
@@ -39,6 +42,7 @@ data class DocumentLevelTriggerExecutionContext(
3942
val tempArg = super.asTemplateArg().toMutableMap()
4043
tempArg["trigger"] = trigger.asTemplateArg()
4144
tempArg["alerts"] = alerts.map { it.asTemplateArg() }
45+
tempArg["triggeredDocs"] = triggeredDocs
4246
return tempArg
4347
}
4448
}

alerting/src/test/kotlin/org/opensearch/alerting/DocumentMonitorRunnerIT.kt

+91
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,97 @@ class DocumentMonitorRunnerIT : AlertingRestTestCase() {
9999
assertTrue("Incorrect search result", matchingDocsToQuery.contains("5|$testIndex"))
100100
}
101101

102+
fun `test execute monitor yields results in alert action context`() {
103+
104+
val testTime = DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(ZonedDateTime.now().truncatedTo(MILLIS))
105+
val testDoc = """{
106+
"message" : "This is an error from IAD region",
107+
"test_strict_date_time" : "$testTime",
108+
"test_field" : "us-west-2"
109+
}"""
110+
111+
val index = createTestIndex()
112+
113+
val docQuery = DocLevelQuery(query = "test_field:\"us-west-2\"", name = "3")
114+
val docLevelInput = DocLevelMonitorInput("description", listOf(index), listOf(docQuery))
115+
116+
val action = randomAction(template = randomTemplateScript("{{ctx.results.0}}"), destinationId = createDestination().id)
117+
val monitor = randomDocumentLevelMonitor(
118+
inputs = listOf(docLevelInput),
119+
triggers = listOf(randomDocumentLevelTrigger(condition = ALWAYS_RUN, actions = listOf(action)))
120+
)
121+
122+
indexDoc(index, "1", testDoc)
123+
124+
val response = executeMonitor(monitor, params = DRYRUN_MONITOR)
125+
126+
val output = entityAsMap(response)
127+
assertEquals(monitor.name, output["monitor_name"])
128+
129+
assertEquals(1, output.objectMap("trigger_results").values.size)
130+
131+
for (triggerResult in output.objectMap("trigger_results").values) {
132+
assertEquals(1, triggerResult.objectMap("action_results").values.size)
133+
for (alertActionResult in triggerResult.objectMap("action_results").values) {
134+
assertEquals(alertActionResult.values.size, 1)
135+
for (actionResult in alertActionResult.values) {
136+
@Suppress("UNCHECKED_CAST") val actionOutput = (actionResult as Map<String, Map<String, String>>)["output"]
137+
as Map<String, String>
138+
assertTrue(actionOutput["subject"].toString().contains(docQuery.id))
139+
assertTrue(actionOutput["message"].toString().contains(docQuery.id))
140+
}
141+
}
142+
}
143+
val alerts = searchAlerts(monitor)
144+
assertEquals("Alert saved for test monitor", 0, alerts.size)
145+
}
146+
147+
fun `test execute monitor yields triggeredDocs in alert action context`() {
148+
149+
val testTime = DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(ZonedDateTime.now().truncatedTo(MILLIS))
150+
val testDoc = """{
151+
"message" : "This is an error from IAD region",
152+
"test_strict_date_time" : "$testTime",
153+
"test_field" : "us-west-2"
154+
}"""
155+
156+
val index = createTestIndex()
157+
158+
val docQuery = DocLevelQuery(query = "test_field:\"us-west-2\"", name = "3")
159+
val docLevelInput = DocLevelMonitorInput("description", listOf(index), listOf(docQuery))
160+
161+
val action = randomAction(template = randomTemplateScript("{{ctx.triggeredDocs}}"), destinationId = createDestination().id)
162+
val monitor = randomDocumentLevelMonitor(
163+
inputs = listOf(docLevelInput),
164+
triggers = listOf(randomDocumentLevelTrigger(condition = ALWAYS_RUN, actions = listOf(action)))
165+
)
166+
167+
val id = "1"
168+
indexDoc(index, id, testDoc)
169+
170+
val response = executeMonitor(monitor, params = DRYRUN_MONITOR)
171+
172+
val output = entityAsMap(response)
173+
assertEquals(monitor.name, output["monitor_name"])
174+
175+
assertEquals(1, output.objectMap("trigger_results").values.size)
176+
177+
for (triggerResult in output.objectMap("trigger_results").values) {
178+
assertEquals(1, triggerResult.objectMap("action_results").values.size)
179+
for (alertActionResult in triggerResult.objectMap("action_results").values) {
180+
assertEquals(alertActionResult.values.size, 1)
181+
for (actionResult in alertActionResult.values) {
182+
@Suppress("UNCHECKED_CAST") val actionOutput = (actionResult as Map<String, Map<String, String>>)["output"]
183+
as Map<String, String>
184+
assertTrue(actionOutput["subject"].toString().contains("0=$id|$index"))
185+
assertTrue(actionOutput["subject"].toString().contains("0=$id|$index"))
186+
}
187+
}
188+
}
189+
val alerts = searchAlerts(monitor)
190+
assertEquals("Alert saved for test monitor", 0, alerts.size)
191+
}
192+
102193
fun `test execute monitor generates alerts and findings`() {
103194
val testIndex = createTestIndex()
104195
val testTime = DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(ZonedDateTime.now().truncatedTo(MILLIS))

0 commit comments

Comments
 (0)