Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added validation on IndexWorkflowRequest class #405

Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ package org.opensearch.commons.alerting.action

import org.opensearch.action.ActionRequest
import org.opensearch.action.ActionRequestValidationException
import org.opensearch.action.ValidateActions
import org.opensearch.action.support.WriteRequest
import org.opensearch.common.io.stream.StreamInput
import org.opensearch.common.io.stream.StreamOutput
import org.opensearch.commons.alerting.model.CompositeInput
import org.opensearch.commons.alerting.model.Workflow
import org.opensearch.rest.RestRequest
import java.io.IOException
import java.util.stream.Collectors

class IndexWorkflowRequest : ActionRequest {
val workflowId: String
Expand All @@ -18,6 +21,8 @@ class IndexWorkflowRequest : ActionRequest {
var workflow: Workflow
val rbacRoles: List<String>?

private val MAX_DELEGATE_SIZE = 25

constructor(
workflowId: String,
seqNo: Long,
Expand Down Expand Up @@ -48,7 +53,75 @@ class IndexWorkflowRequest : ActionRequest {
)

override fun validate(): ActionRequestValidationException? {
return null
var validationException: ActionRequestValidationException? = null

if (workflow.inputs.isEmpty()) {
validationException = ValidateActions.addValidationError(
"Input list can not be empty.", validationException
)
return validationException
}
if (workflow.inputs.size > 1) {
validationException = ValidateActions.addValidationError(
"Input list can contain only one element.", validationException
)
return validationException
}
if (workflow.inputs[0] !is CompositeInput) {
validationException = ValidateActions.addValidationError(
"When creating a workflow input must be CompositeInput", validationException
)
}
val compositeInput = workflow.inputs[0] as CompositeInput
val monitorIds = compositeInput.sequence.delegates.stream().map { it.monitorId }.collect(Collectors.toList())

if (monitorIds.isNullOrEmpty()) {
validationException = ValidateActions.addValidationError(
"Delegates list can not be empty.", validationException
)
// Break the flow because next checks are dependant on non-null monitorIds
return validationException
}

if (monitorIds.size > MAX_DELEGATE_SIZE) {
validationException = ValidateActions.addValidationError(
"Delegates list can not be larger then $MAX_DELEGATE_SIZE.", validationException
)
}

if (monitorIds.toSet().size != monitorIds.size) {
validationException = ValidateActions.addValidationError(
"Duplicate delegates not allowed", validationException
)
}
val delegates = compositeInput.sequence.delegates
val orderSet = delegates.stream().filter { it.order > 0 }.map { it.order }.collect(Collectors.toSet())
if (orderSet.size != delegates.size) {
validationException = ValidateActions.addValidationError(
"Sequence ordering of delegate monitor shouldn't contain duplicate order values", validationException
)
}

val monitorIdOrderMap: Map<String, Int> = delegates.associate { it.monitorId to it.order }
delegates.forEach {
if (it.chainedMonitorFindings != null) {
if (monitorIdOrderMap.containsKey(it.chainedMonitorFindings!!.monitorId) == false) {
validationException = ValidateActions.addValidationError(
"Chained Findings Monitor ${it.chainedMonitorFindings!!.monitorId} doesn't exist in sequence",
validationException
)
// Break the flow because next check will generate the NPE
return validationException
}
if (it.order <= monitorIdOrderMap[it.chainedMonitorFindings!!.monitorId]!!) {
validationException = ValidateActions.addValidationError(
"Chained Findings Monitor ${it.chainedMonitorFindings!!.monitorId} should be executed before monitor ${it.monitorId}",
validationException
)
}
}
}
return validationException
}

@Throws(IOException::class)
Expand Down