11package org.opensearch.commons.alerting.model
22
3+ import org.opensearch.Version
34import org.opensearch.common.lucene.uid.Versions
45import org.opensearch.commons.alerting.alerts.AlertError
6+ import org.opensearch.commons.alerting.model.Monitor.Companion.suppressWarning
57import org.opensearch.commons.alerting.util.IndexUtils.Companion.NO_SCHEMA_VERSION
68import org.opensearch.commons.alerting.util.instant
79import org.opensearch.commons.alerting.util.optionalTimeField
@@ -43,7 +45,12 @@ data class Alert(
4345 val aggregationResultBucket : AggregationResultBucket ? = null ,
4446 val executionId : String? = null ,
4547 val associatedAlertIds : List <String >,
46- val clusters : List <String >? = null
48+ val clusters : List <String >? = null ,
49+ // these fields are specifically used for PPL Monitors
50+ // for now, Query-Level Monitors can support including
51+ // query results in Alerts by using these fields
52+ val query : String? = null ,
53+ val queryResults : List <Map <String , Any ?>> = listOf()
4754) : Writeable, ToXContent {
4855
4956 init {
@@ -54,6 +61,64 @@ data class Alert(
5461 }
5562 }
5663
64+ constructor (
65+ id: String = NO_ID ,
66+ version: Long = NO_VERSION ,
67+ schemaVersion: Int = NO_SCHEMA_VERSION ,
68+ monitorId: String ,
69+ workflowId: String ,
70+ workflowName: String ,
71+ monitorName: String ,
72+ monitorVersion: Long ,
73+ monitorUser: User ? ,
74+ triggerId: String ,
75+ triggerName: String ,
76+ findingIds: List <String >,
77+ relatedDocIds: List <String >,
78+ state: State ,
79+ startTime: Instant ,
80+ endTime: Instant ? = null ,
81+ lastNotificationTime: Instant ? = null ,
82+ acknowledgedTime: Instant ? = null ,
83+ errorMessage: String? = null ,
84+ errorHistory: List <AlertError >,
85+ severity: String ,
86+ actionExecutionResults: List <ActionExecutionResult >,
87+ aggregationResultBucket: AggregationResultBucket ? = null ,
88+ executionId: String? = null ,
89+ associatedAlertIds: List <String >,
90+ clusters: List <String >? = null
91+ ) : this (
92+ id = id,
93+ version = version,
94+ schemaVersion = schemaVersion,
95+ monitorId = monitorId,
96+ workflowId = workflowId,
97+ workflowName = workflowName,
98+ monitorName = monitorName,
99+ monitorVersion = monitorVersion,
100+ monitorUser = monitorUser,
101+ triggerId = triggerId,
102+ triggerName = triggerName,
103+ findingIds = findingIds,
104+ relatedDocIds = relatedDocIds,
105+ state = state,
106+ startTime = startTime,
107+ endTime = endTime,
108+ lastNotificationTime = lastNotificationTime,
109+ acknowledgedTime = acknowledgedTime,
110+ errorMessage = errorMessage,
111+ errorHistory = errorHistory,
112+ severity = severity,
113+ actionExecutionResults = actionExecutionResults,
114+ aggregationResultBucket = aggregationResultBucket,
115+ executionId = executionId,
116+ associatedAlertIds = associatedAlertIds,
117+ clusters = clusters,
118+ query = null ,
119+ queryResults = listOf ()
120+ )
121+
57122 constructor (
58123 startTime: Instant ,
59124 lastNotificationTime: Instant ? ,
@@ -87,12 +152,16 @@ data class Alert(
87152 workflowId = workflow.id,
88153 workflowName = workflow.name,
89154 associatedAlertIds = associatedAlertIds,
90- clusters = clusters
155+ clusters = clusters,
156+ query = null ,
157+ queryResults = listOf ()
91158 )
92159
160+ // constructor for Alerts from QueryLevelMonitorRunner
161+ // this monitor runner runs Query-level, Cluster Metrics, and PPL Monitors
93162 constructor (
94163 monitor: Monitor ,
95- trigger: QueryLevelTrigger ,
164+ trigger: Trigger ,
96165 startTime: Instant ,
97166 lastNotificationTime: Instant ? ,
98167 state: State = State .ACTIVE ,
@@ -102,7 +171,9 @@ data class Alert(
102171 schemaVersion: Int = NO_SCHEMA_VERSION ,
103172 executionId: String? = null ,
104173 workflowId: String? = null ,
105- clusters: List <String >? = null
174+ clusters: List <String >? = null ,
175+ query: String? = null ,
176+ queryResults: List <Map <String , Any ?>> = listOf ()
106177 ) : this (
107178 monitorId = monitor.id,
108179 monitorName = monitor.name,
@@ -125,7 +196,9 @@ data class Alert(
125196 workflowId = workflowId ? : " " ,
126197 workflowName = " " ,
127198 associatedAlertIds = emptyList(),
128- clusters = clusters
199+ clusters = clusters,
200+ query = query,
201+ queryResults = queryResults
129202 )
130203
131204 constructor (
@@ -164,7 +237,9 @@ data class Alert(
164237 workflowId = workflowId ? : " " ,
165238 workflowName = " " ,
166239 associatedAlertIds = emptyList(),
167- clusters = clusters
240+ clusters = clusters,
241+ query = null ,
242+ queryResults = listOf ()
168243 )
169244
170245 constructor (
@@ -204,7 +279,9 @@ data class Alert(
204279 workflowId = workflowId ? : " " ,
205280 workflowName = " " ,
206281 associatedAlertIds = emptyList(),
207- clusters = clusters
282+ clusters = clusters,
283+ query = null ,
284+ queryResults = listOf ()
208285 )
209286
210287 constructor (
@@ -246,7 +323,9 @@ data class Alert(
246323 workflowId = workflowId ? : " " ,
247324 workflowName = " " ,
248325 associatedAlertIds = emptyList(),
249- clusters = clusters
326+ clusters = clusters,
327+ query = null ,
328+ queryResults = listOf ()
250329 )
251330
252331 constructor (
@@ -285,7 +364,9 @@ data class Alert(
285364 workflowId = workflowId ? : " " ,
286365 executionId = executionId,
287366 associatedAlertIds = emptyList(),
288- clusters = clusters
367+ clusters = clusters,
368+ query = null ,
369+ queryResults = listOf ()
289370 )
290371
291372 enum class State {
@@ -329,7 +410,17 @@ data class Alert(
329410 aggregationResultBucket = if (sin.readBoolean()) AggregationResultBucket (sin) else null ,
330411 executionId = sin.readOptionalString(),
331412 associatedAlertIds = sin.readStringList(),
332- clusters = sin.readOptionalStringList()
413+ clusters = sin.readOptionalStringList(),
414+ query = if (sin.version.onOrAfter(Version .V_3_5_0 )) {
415+ sin.readOptionalString()
416+ } else {
417+ null
418+ },
419+ queryResults = if (sin.version.onOrAfter(Version .V_3_5_0 )) {
420+ sin.readList { input -> suppressWarning(input.readMap()) }
421+ } else {
422+ listOf ()
423+ }
333424 )
334425
335426 fun isAcknowledged (): Boolean = (state == State .ACKNOWLEDGED )
@@ -368,6 +459,12 @@ data class Alert(
368459 out .writeOptionalString(executionId)
369460 out .writeStringCollection(associatedAlertIds)
370461 out .writeOptionalStringArray(clusters?.toTypedArray())
462+ if (out .version.onOrAfter(Version .V_3_5_0 )) {
463+ out .writeOptionalString(query)
464+ out .writeCollection(queryResults) { output, map ->
465+ output.writeMap(map)
466+ }
467+ }
371468 }
372469
373470 companion object {
@@ -399,6 +496,8 @@ data class Alert(
399496 const val BUCKET_KEYS = AggregationResultBucket .BUCKET_KEYS
400497 const val PARENTS_BUCKET_PATH = AggregationResultBucket .PARENTS_BUCKET_PATH
401498 const val CLUSTERS_FIELD = " clusters"
499+ const val QUERY_FIELD = " query"
500+ const val QUERY_RESULTS_FIELD = " query_results"
402501 const val NO_ID = " "
403502 const val NO_VERSION = Versions .NOT_FOUND
404503
@@ -430,6 +529,8 @@ data class Alert(
430529 var aggAlertBucket: AggregationResultBucket ? = null
431530 val associatedAlertIds = mutableListOf<String >()
432531 val clusters = mutableListOf<String >()
532+ var query: String? = null
533+ var queryResults: List <Map <String , Any ?>> = listOf ()
433534 ensureExpectedToken(XContentParser .Token .START_OBJECT , xcp.currentToken(), xcp)
434535 while (xcp.nextToken() != XContentParser .Token .END_OBJECT ) {
435536 val fieldName = xcp.currentName()
@@ -505,6 +606,19 @@ data class Alert(
505606 clusters.add(xcp.text())
506607 }
507608 }
609+ QUERY_FIELD -> {
610+ if (xcp.currentToken() != XContentParser .Token .VALUE_NULL ) {
611+ query = xcp.text()
612+ }
613+ }
614+ QUERY_RESULTS_FIELD -> {
615+ ensureExpectedToken(XContentParser .Token .START_ARRAY , xcp.currentToken(), xcp)
616+ val resultsList = mutableListOf<Map <String , Any ?>>()
617+ while (xcp.nextToken() != XContentParser .Token .END_ARRAY ) {
618+ resultsList.add(xcp.map())
619+ }
620+ queryResults = resultsList
621+ }
508622 }
509623 }
510624
@@ -534,7 +648,9 @@ data class Alert(
534648 workflowId = workflowId,
535649 workflowName = workflowName,
536650 associatedAlertIds = associatedAlertIds,
537- clusters = if (clusters.size > 0 ) clusters else null
651+ clusters = if (clusters.size > 0 ) clusters else null ,
652+ query = query,
653+ queryResults = queryResults
538654 )
539655 }
540656
@@ -587,6 +703,11 @@ data class Alert(
587703
588704 if (! clusters.isNullOrEmpty()) builder.field(CLUSTERS_FIELD , clusters.toTypedArray())
589705
706+ if (! query.isNullOrEmpty()) builder.field(QUERY_FIELD , query)
707+ if (queryResults.isNotEmpty()) {
708+ builder.field(QUERY_RESULTS_FIELD , queryResults.toTypedArray())
709+ }
710+
590711 builder.endObject()
591712 return builder
592713 }
@@ -611,7 +732,9 @@ data class Alert(
611732 PARENTS_BUCKET_PATH to aggregationResultBucket?.parentBucketPath,
612733 FINDING_IDS to findingIds.joinToString(" ," ),
613734 RELATED_DOC_IDS to relatedDocIds.joinToString(" ," ),
614- CLUSTERS_FIELD to clusters?.joinToString(" ," )
735+ CLUSTERS_FIELD to clusters?.joinToString(" ," ),
736+ QUERY_FIELD to query,
737+ QUERY_RESULTS_FIELD to queryResults
615738 )
616739 }
617740}
0 commit comments