diff --git a/src/main/kotlin/org/opensearch/commons/alerting/model/Workflow.kt b/src/main/kotlin/org/opensearch/commons/alerting/model/Workflow.kt index d2f2518d..4415695a 100644 --- a/src/main/kotlin/org/opensearch/commons/alerting/model/Workflow.kt +++ b/src/main/kotlin/org/opensearch/commons/alerting/model/Workflow.kt @@ -36,7 +36,8 @@ data class Workflow( val schemaVersion: Int = NO_SCHEMA_VERSION, val inputs: List, val owner: String? = DEFAULT_OWNER, - val triggers: List + val triggers: List, + val uiMetadata: Map, ) : ScheduledJob { override val type = WORKFLOW_TYPE @@ -69,8 +70,9 @@ data class Workflow( } else null, schemaVersion = sin.readInt(), inputs = sin.readList((WorkflowInput)::readFrom), + uiMetadata = Monitor.suppressWarning(sin.readMap()), owner = sin.readOptionalString(), - triggers = sin.readList((Trigger)::readFrom) + triggers = sin.readList((Trigger)::readFrom), ) // This enum classifies different workflows @@ -118,6 +120,7 @@ data class Workflow( .field(INPUTS_FIELD, inputs.toTypedArray()) .field(TRIGGERS_FIELD, triggers.toTypedArray()) .optionalTimeField(LAST_UPDATE_TIME_FIELD, lastUpdateTime) + if (uiMetadata.isNotEmpty()) builder.field(UI_METADATA_FIELD, uiMetadata) builder.field(OWNER_FIELD, owner) if (params.paramAsBoolean("with_type", false)) builder.endObject() return builder.endObject() @@ -149,6 +152,7 @@ data class Workflow( if (it is CompositeInput) out.writeEnum(WorkflowInput.Type.COMPOSITE_INPUT) it.writeTo(out) } + out.writeMap(uiMetadata) // Outputting type with each Trigger so that the generic Trigger.readFrom() can read it out.writeOptionalString(owner) out.writeVInt(triggers.size) @@ -176,6 +180,7 @@ data class Workflow( const val LAST_UPDATE_TIME_FIELD = "last_update_time" const val ENABLED_TIME_FIELD = "enabled_time" const val TRIGGERS_FIELD = "triggers" + const val UI_METADATA_FIELD = "ui_metadata" const val OWNER_FIELD = "owner" // This is defined here instead of in ScheduledJob to avoid having the ScheduledJob class know about all @@ -200,6 +205,7 @@ data class Workflow( var schemaVersion = NO_SCHEMA_VERSION val inputs: MutableList = mutableListOf() val triggers: MutableList = mutableListOf() + var uiMetadata: Map = mapOf() var owner = DEFAULT_OWNER XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_OBJECT, xcp.currentToken(), xcp) @@ -222,7 +228,7 @@ data class Workflow( } ENABLED_FIELD -> enabled = xcp.booleanValue() SCHEDULE_FIELD -> schedule = Schedule.parse(xcp) - Monitor.TRIGGERS_FIELD -> { + TRIGGERS_FIELD -> { XContentParserUtils.ensureExpectedToken( XContentParser.Token.START_ARRAY, xcp.currentToken(), @@ -245,6 +251,7 @@ data class Workflow( } ENABLED_TIME_FIELD -> enabledTime = xcp.instant() LAST_UPDATE_TIME_FIELD -> lastUpdateTime = xcp.instant() + UI_METADATA_FIELD -> uiMetadata = xcp.map() OWNER_FIELD -> { owner = if (xcp.currentToken() == XContentParser.Token.VALUE_NULL) owner else xcp.text() } @@ -272,7 +279,8 @@ data class Workflow( schemaVersion, inputs.toList(), owner, - triggers + triggers, + uiMetadata ) } diff --git a/src/test/kotlin/org/opensearch/commons/alerting/TestHelpers.kt b/src/test/kotlin/org/opensearch/commons/alerting/TestHelpers.kt index 14f62fbf..e7e6e192 100644 --- a/src/test/kotlin/org/opensearch/commons/alerting/TestHelpers.kt +++ b/src/test/kotlin/org/opensearch/commons/alerting/TestHelpers.kt @@ -173,6 +173,7 @@ fun randomWorkflow( enabledTime: Instant? = if (enabled) Instant.now().truncatedTo(ChronoUnit.MILLIS) else null, lastUpdateTime: Instant = Instant.now().truncatedTo(ChronoUnit.MILLIS), triggers: List = listOf(randomChainedAlertTrigger()), + withMetadata: Boolean = Random().nextBoolean() ): Workflow { val delegates = mutableListOf() if (!monitorIds.isNullOrEmpty()) { @@ -195,7 +196,7 @@ fun randomWorkflow( return Workflow( name = name, workflowType = Workflow.WorkflowType.COMPOSITE, enabled = enabled, inputs = input, schedule = schedule, enabledTime = enabledTime, lastUpdateTime = lastUpdateTime, user = user, - triggers = triggers + triggers = triggers, uiMetadata = if (withMetadata) mapOf("foo" to "bar") else mapOf() ) } @@ -208,11 +209,12 @@ fun randomWorkflowWithDelegates( enabledTime: Instant? = if (enabled) Instant.now().truncatedTo(ChronoUnit.MILLIS) else null, lastUpdateTime: Instant = Instant.now().truncatedTo(ChronoUnit.MILLIS), triggers: List = (1..RandomNumbers.randomIntBetween(Random(), 0, 10)).map { randomChainedAlertTrigger() }, + withMetadata: Boolean = Random().nextBoolean() ): Workflow { return Workflow( name = name, workflowType = Workflow.WorkflowType.COMPOSITE, enabled = enabled, inputs = input, schedule = schedule, enabledTime = enabledTime, lastUpdateTime = lastUpdateTime, user = user, - triggers = triggers + triggers = triggers, uiMetadata = if (withMetadata) mapOf("foo" to "bar") else mapOf() ) } diff --git a/src/test/kotlin/org/opensearch/commons/alerting/action/IndexWorkflowResponseTests.kt b/src/test/kotlin/org/opensearch/commons/alerting/action/IndexWorkflowResponseTests.kt index 8565d093..5d886437 100644 --- a/src/test/kotlin/org/opensearch/commons/alerting/action/IndexWorkflowResponseTests.kt +++ b/src/test/kotlin/org/opensearch/commons/alerting/action/IndexWorkflowResponseTests.kt @@ -32,7 +32,8 @@ class IndexWorkflowResponseTests { user = randomUser(), schemaVersion = 0, inputs = mutableListOf(), - triggers = listOf(randomChainedAlertTrigger()) + triggers = listOf(randomChainedAlertTrigger()), + uiMetadata = mutableMapOf(Pair("test", "test")) ) val req = IndexWorkflowResponse("1234", 1L, 2L, 0L, workflow) Assertions.assertNotNull(req) @@ -57,5 +58,6 @@ class IndexWorkflowResponseTests { (newReq.workflow.triggers.get(0) as ChainedAlertTrigger).condition.lang, (req.workflow.triggers.get(0) as ChainedAlertTrigger).condition.lang ) + Assertions.assertEquals(newReq.workflow.uiMetadata, req.workflow.uiMetadata) } }