forked from opensearch-project/common-utils
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds Chained alerts triggers for workflows (opensearch-project#456) (o…
…pensearch-project#457) * adds models for chained alert trigger and chained alerts (opensearch-project#426) Signed-off-by: Surya Sashank Nistala <[email protected]> * fix execution id field in alerts (opensearch-project#429) Signed-off-by: Surya Sashank Nistala <[email protected]> * accept workflow argument in chained alert constructor (opensearch-project#435) Signed-off-by: Surya Sashank Nistala <[email protected]> * add tests for chained alert Signed-off-by: Surya Sashank Nistala <[email protected]> --------- Signed-off-by: Surya Sashank Nistala <[email protected]> (cherry picked from commit 5ef9b55) Co-authored-by: Surya Sashank Nistala <[email protected]> Signed-off-by: AWSHurneyt <[email protected]>
- Loading branch information
1 parent
4fba3f3
commit 5ef7ce4
Showing
11 changed files
with
311 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
150 changes: 150 additions & 0 deletions
150
src/main/kotlin/org/opensearch/commons/alerting/model/ChainedAlertTrigger.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
package org.opensearch.commons.alerting.model | ||
|
||
import org.opensearch.common.CheckedFunction | ||
import org.opensearch.common.UUIDs | ||
import org.opensearch.common.io.stream.StreamInput | ||
import org.opensearch.common.io.stream.StreamOutput | ||
import org.opensearch.common.xcontent.XContentParserUtils | ||
import org.opensearch.commons.alerting.model.Trigger.Companion.ACTIONS_FIELD | ||
import org.opensearch.commons.alerting.model.Trigger.Companion.ID_FIELD | ||
import org.opensearch.commons.alerting.model.Trigger.Companion.NAME_FIELD | ||
import org.opensearch.commons.alerting.model.Trigger.Companion.SEVERITY_FIELD | ||
import org.opensearch.commons.alerting.model.action.Action | ||
import org.opensearch.core.ParseField | ||
import org.opensearch.core.xcontent.NamedXContentRegistry | ||
import org.opensearch.core.xcontent.ToXContent | ||
import org.opensearch.core.xcontent.XContentBuilder | ||
import org.opensearch.core.xcontent.XContentParser | ||
import org.opensearch.script.Script | ||
import java.io.IOException | ||
|
||
data class ChainedAlertTrigger( | ||
override val id: String = UUIDs.base64UUID(), | ||
override val name: String, | ||
override val severity: String, | ||
override val actions: List<Action>, | ||
val condition: Script | ||
) : Trigger { | ||
|
||
@Throws(IOException::class) | ||
constructor(sin: StreamInput) : this( | ||
sin.readString(), // id | ||
sin.readString(), // name | ||
sin.readString(), // severity | ||
sin.readList(::Action), // actions | ||
Script(sin) | ||
) | ||
|
||
override fun toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder { | ||
builder.startObject() | ||
.startObject(CHAINED_ALERT_TRIGGER_FIELD) | ||
.field(ID_FIELD, id) | ||
.field(NAME_FIELD, name) | ||
.field(SEVERITY_FIELD, severity) | ||
.startObject(CONDITION_FIELD) | ||
.field(SCRIPT_FIELD, condition) | ||
.endObject() | ||
.field(ACTIONS_FIELD, actions.toTypedArray()) | ||
.endObject() | ||
.endObject() | ||
return builder | ||
} | ||
|
||
override fun name(): String { | ||
return CHAINED_ALERT_TRIGGER_FIELD | ||
} | ||
|
||
/** Returns a representation of the trigger suitable for passing into painless and mustache scripts. */ | ||
fun asTemplateArg(): Map<String, Any> { | ||
return mapOf( | ||
ID_FIELD to id, | ||
NAME_FIELD to name, | ||
SEVERITY_FIELD to severity, | ||
ACTIONS_FIELD to actions.map { it.asTemplateArg() } | ||
) | ||
} | ||
|
||
@Throws(IOException::class) | ||
override fun writeTo(out: StreamOutput) { | ||
out.writeString(id) | ||
out.writeString(name) | ||
out.writeString(severity) | ||
out.writeCollection(actions) | ||
condition.writeTo(out) | ||
} | ||
|
||
companion object { | ||
const val CHAINED_ALERT_TRIGGER_FIELD = "chained_alert_trigger" | ||
const val CONDITION_FIELD = "condition" | ||
const val SCRIPT_FIELD = "script" | ||
const val QUERY_IDS_FIELD = "query_ids" | ||
|
||
val XCONTENT_REGISTRY = NamedXContentRegistry.Entry( | ||
Trigger::class.java, | ||
ParseField(CHAINED_ALERT_TRIGGER_FIELD), | ||
CheckedFunction { parseInner(it) } | ||
) | ||
|
||
@JvmStatic | ||
@Throws(IOException::class) | ||
fun parseInner(xcp: XContentParser): ChainedAlertTrigger { | ||
var id = UUIDs.base64UUID() // assign a default triggerId if one is not specified | ||
lateinit var name: String | ||
lateinit var severity: String | ||
lateinit var condition: Script | ||
val actions: MutableList<Action> = mutableListOf() | ||
|
||
if (xcp.currentToken() != XContentParser.Token.START_OBJECT && xcp.currentToken() != XContentParser.Token.FIELD_NAME) { | ||
XContentParserUtils.throwUnknownToken(xcp.currentToken(), xcp.tokenLocation) | ||
} | ||
|
||
// If the parser began on START_OBJECT, move to the next token so that the while loop enters on | ||
// the fieldName (or END_OBJECT if it's empty). | ||
if (xcp.currentToken() == XContentParser.Token.START_OBJECT) xcp.nextToken() | ||
|
||
while (xcp.currentToken() != XContentParser.Token.END_OBJECT) { | ||
val fieldName = xcp.currentName() | ||
|
||
xcp.nextToken() | ||
when (fieldName) { | ||
ID_FIELD -> id = xcp.text() | ||
NAME_FIELD -> name = xcp.text() | ||
SEVERITY_FIELD -> severity = xcp.text() | ||
CONDITION_FIELD -> { | ||
xcp.nextToken() | ||
condition = Script.parse(xcp) | ||
require(condition.lang == Script.DEFAULT_SCRIPT_LANG) { | ||
"Invalid script language. Allowed languages are [${Script.DEFAULT_SCRIPT_LANG}]" | ||
} | ||
xcp.nextToken() | ||
} | ||
ACTIONS_FIELD -> { | ||
XContentParserUtils.ensureExpectedToken( | ||
XContentParser.Token.START_ARRAY, | ||
xcp.currentToken(), | ||
xcp | ||
) | ||
while (xcp.nextToken() != XContentParser.Token.END_ARRAY) { | ||
actions.add(Action.parse(xcp)) | ||
} | ||
} | ||
} | ||
xcp.nextToken() | ||
} | ||
|
||
return ChainedAlertTrigger( | ||
name = requireNotNull(name) { "Trigger name is null" }, | ||
severity = requireNotNull(severity) { "Trigger severity is null" }, | ||
condition = requireNotNull(condition) { "Trigger condition is null" }, | ||
actions = requireNotNull(actions) { "Trigger actions are null" }, | ||
id = requireNotNull(id) { "Trigger id is null." } | ||
) | ||
} | ||
|
||
@JvmStatic | ||
@Throws(IOException::class) | ||
fun readFrom(sin: StreamInput): ChainedAlertTrigger { | ||
return ChainedAlertTrigger(sin) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.