From 93f27cca937ff4b4411ce046ee662dba615a47d1 Mon Sep 17 00:00:00 2001 From: dzhengg <53837320+dzhengg@users.noreply.github.com> Date: Fri, 17 Jan 2025 09:47:22 -0800 Subject: [PATCH] perf(pipeline): Improve execution times for dense pipeline graphs (#4824) * test(pipeline): Define StartStageHandler performance when given a complex pipeline with multiple layers of upstream stages * fix(pipeline): Memoize anyUpstreamStagesFailed results This turns the anyUpstreamStagesFailed calculation from one that scales exponentially based on the number of (branches+downstream stages) in a pipeline to one that scales linearly based on the total number of stages in a pipeline. This is a significant performance improvement, especially for very large and complicated pipelines * refactor(stage): Move anyUpstreamStagesFailed to StartStageHandler since that's the only place where it gets used * fix(stage): Avoid using a ConcurrentHashMap for memoization. The recursive anyUpstreamStagesFailed(StageExecution) function runs in a single thread, so ConcurrentHashMap is not necessary here * docs(test): Use a more concise test name * perf(stage): First check if a stage has been visited before checking for parent stages. stage.getRequisiteStageRefIds is a more expensive call because the underlying implementation creates a copy of a List. Therefore, start with the cheaper operation first hoping to short-circuit and avoid the more expensive check * perf(stage): Filter out non-synthetic stages The javadocs state that the syntheticStageOwner property is null for non-synthetic stages. Use this information to filter out non-synthetic stages before attempting a potentially expensive operation to check for synthetic parents of previousStages * perf(stage): Precompute requisiteStageRefIds StageExecutionImpl.getRequisiteStageRefIds() returns a copy of a Set. This is a costly operation that has the potential to get repeated for every unvisited stage. To avoid this, compute the value before entering a loop * perf(stage): Only use withAuth when needed withAuth is only necessary when starting a stage. Since withAuth is very computationally expensive for complex pipelines, only call it when it is absolutely necessary. * perf(stage): Remove duplicate call to withStage StartStageHandler already makes a call to message.withStage at the beginning of the handle() method. Therefore, this call within the catch block is unnecessary * chore(import): Clean up unused imports --------- Co-authored-by: Daniel Zheng --- .../model/StageExecutionInternals.java | 7 +- .../com/netflix/spinnaker/orca/ext/Stage.kt | 4 - .../spinnaker/orca/q/ComplexPipeline.kt | 549 ++++++++++++++++++ .../orca/q/handler/StartStageHandler.kt | 82 ++- .../orca/q/handler/StartStageHandlerTest.kt | 36 ++ 5 files changed, 644 insertions(+), 34 deletions(-) create mode 100644 orca-queue-tck/src/main/kotlin/com/netflix/spinnaker/orca/q/ComplexPipeline.kt diff --git a/orca-core/src/main/java/com/netflix/spinnaker/orca/pipeline/model/StageExecutionInternals.java b/orca-core/src/main/java/com/netflix/spinnaker/orca/pipeline/model/StageExecutionInternals.java index 5241e2b156..e55a0ed09a 100644 --- a/orca-core/src/main/java/com/netflix/spinnaker/orca/pipeline/model/StageExecutionInternals.java +++ b/orca-core/src/main/java/com/netflix/spinnaker/orca/pipeline/model/StageExecutionInternals.java @@ -22,6 +22,7 @@ import com.netflix.spinnaker.orca.api.pipeline.SyntheticStageOwner; import com.netflix.spinnaker.orca.api.pipeline.models.StageExecution; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.Set; @@ -41,15 +42,17 @@ static List getAncestorsImpl( StageExecution stage, Set visited, boolean directParentOnly) { visited.add(stage.getRefId()); - if (!stage.getRequisiteStageRefIds().isEmpty() && !directParentOnly) { + if (!directParentOnly && !stage.getRequisiteStageRefIds().isEmpty()) { // Get stages this stage depends on via requisiteStageRefIds: + Collection requisiteStageRefIds = stage.getRequisiteStageRefIds(); List previousStages = stage.getExecution().getStages().stream() - .filter(it -> stage.getRequisiteStageRefIds().contains(it.getRefId())) .filter(it -> !visited.contains(it.getRefId())) + .filter(it -> requisiteStageRefIds.contains(it.getRefId())) .collect(toList()); List syntheticStages = stage.getExecution().getStages().stream() + .filter(s -> s.getSyntheticStageOwner() != null) .filter( s -> previousStages.stream() diff --git a/orca-kotlin/src/main/kotlin/com/netflix/spinnaker/orca/ext/Stage.kt b/orca-kotlin/src/main/kotlin/com/netflix/spinnaker/orca/ext/Stage.kt index 2e7eca9a45..49aa49c37d 100644 --- a/orca-kotlin/src/main/kotlin/com/netflix/spinnaker/orca/ext/Stage.kt +++ b/orca-kotlin/src/main/kotlin/com/netflix/spinnaker/orca/ext/Stage.kt @@ -21,7 +21,6 @@ import com.netflix.spinnaker.orca.api.pipeline.SyntheticStageOwner.STAGE_BEFORE import com.netflix.spinnaker.orca.api.pipeline.models.ExecutionStatus import com.netflix.spinnaker.orca.api.pipeline.models.ExecutionStatus.CANCELED import com.netflix.spinnaker.orca.api.pipeline.models.ExecutionStatus.FAILED_CONTINUE -import com.netflix.spinnaker.orca.api.pipeline.models.ExecutionStatus.NOT_STARTED import com.netflix.spinnaker.orca.api.pipeline.models.ExecutionStatus.SKIPPED import com.netflix.spinnaker.orca.api.pipeline.models.ExecutionStatus.STOPPED import com.netflix.spinnaker.orca.api.pipeline.models.ExecutionStatus.SUCCEEDED @@ -83,9 +82,6 @@ fun StageExecution.upstreamStages(): List = fun StageExecution.allUpstreamStagesComplete(): Boolean = upstreamStages().all { it.status in listOf(SUCCEEDED, FAILED_CONTINUE, SKIPPED) } -fun StageExecution.anyUpstreamStagesFailed(): Boolean = - upstreamStages().any { it.status in listOf(TERMINAL, STOPPED, CANCELED) || it.status == NOT_STARTED && it.anyUpstreamStagesFailed() } - fun StageExecution.syntheticStages(): List = execution.stages.filter { it.parentStageId == id } diff --git a/orca-queue-tck/src/main/kotlin/com/netflix/spinnaker/orca/q/ComplexPipeline.kt b/orca-queue-tck/src/main/kotlin/com/netflix/spinnaker/orca/q/ComplexPipeline.kt new file mode 100644 index 0000000000..157194cce3 --- /dev/null +++ b/orca-queue-tck/src/main/kotlin/com/netflix/spinnaker/orca/q/ComplexPipeline.kt @@ -0,0 +1,549 @@ +/* + * Copyright 2025 Salesforce, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.netflix.spinnaker.orca.q + +import com.netflix.spinnaker.orca.api.test.pipeline +import com.netflix.spinnaker.orca.api.test.stage +import com.netflix.spinnaker.orca.api.pipeline.models.ExecutionStatus.NOT_STARTED +import com.netflix.spinnaker.orca.api.pipeline.models.ExecutionStatus.SUCCEEDED +import com.netflix.spinnaker.orca.api.pipeline.models.PipelineExecution + +/** + * Complex pipeline to test queue performance. + * + * The pipeline has the following structure: + * An initial stage named "Initial", followed by 10 layers of parallel stages, with 10 stages in each layer. + * The stage IDs are in the format "ID: -", where is the layer in the pipeline (0-9), + * and is the stage in the layer (0-9). + * Each stage in a particular layer is dependent on every stage in every previous layer, plus the initial stage. + * The end of the pipeline is a final stage named "Final", which depends on every stage in every layer. + * + * The current state of the pipeline is: the initial stage and half of the stages in layer 0 have succeeded. The + * remaining stages have not been started + */ +val complexPipeline : PipelineExecution = pipeline { + stage { + refId = "Initial" + requisiteStageRefIds = setOf() + status = SUCCEEDED + } + stage { + refId = "ID: 0-0" + requisiteStageRefIds = setOf("Initial") + status = SUCCEEDED + } + stage { + refId = "ID: 0-1" + requisiteStageRefIds = setOf("Initial") + status = SUCCEEDED + } + stage { + refId = "ID: 0-2" + requisiteStageRefIds = setOf("Initial") + status = SUCCEEDED + } + stage { + refId = "ID: 0-3" + requisiteStageRefIds = setOf("Initial") + status = SUCCEEDED + } + stage { + refId = "ID: 0-4" + requisiteStageRefIds = setOf("Initial") + status = SUCCEEDED + } + stage { + refId = "ID: 0-5" + requisiteStageRefIds = setOf("Initial") + status = NOT_STARTED + } + stage { + refId = "ID: 0-6" + requisiteStageRefIds = setOf("Initial") + status = NOT_STARTED + } + stage { + refId = "ID: 0-7" + requisiteStageRefIds = setOf("Initial") + status = NOT_STARTED + } + stage { + refId = "ID: 0-8" + requisiteStageRefIds = setOf("Initial") + status = NOT_STARTED + } + stage { + refId = "ID: 0-9" + requisiteStageRefIds = setOf("Initial") + status = NOT_STARTED + } + stage { + refId = "ID: 1-0" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9") + status = NOT_STARTED + } + stage { + refId = "ID: 1-1" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9") + status = NOT_STARTED + } + stage { + refId = "ID: 1-2" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9") + status = NOT_STARTED + } + stage { + refId = "ID: 1-3" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9") + status = NOT_STARTED + } + stage { + refId = "ID: 1-4" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9") + status = NOT_STARTED + } + stage { + refId = "ID: 1-5" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9") + status = NOT_STARTED + } + stage { + refId = "ID: 1-6" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9") + status = NOT_STARTED + } + stage { + refId = "ID: 1-7" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9") + status = NOT_STARTED + } + stage { + refId = "ID: 1-8" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9") + status = NOT_STARTED + } + stage { + refId = "ID: 1-9" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9") + status = NOT_STARTED + } + stage { + refId = "ID: 2-0" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9") + status = NOT_STARTED + } + stage { + refId = "ID: 2-1" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9") + status = NOT_STARTED + } + stage { + refId = "ID: 2-2" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9") + status = NOT_STARTED + } + stage { + refId = "ID: 2-3" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9") + status = NOT_STARTED + } + stage { + refId = "ID: 2-4" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9") + status = NOT_STARTED + } + stage { + refId = "ID: 2-5" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9") + status = NOT_STARTED + } + stage { + refId = "ID: 2-6" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9") + status = NOT_STARTED + } + stage { + refId = "ID: 2-7" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9") + status = NOT_STARTED + } + stage { + refId = "ID: 2-8" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9") + status = NOT_STARTED + } + stage { + refId = "ID: 2-9" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9") + status = NOT_STARTED + } + stage { + refId = "ID: 3-0" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9") + status = NOT_STARTED + } + stage { + refId = "ID: 3-1" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9") + status = NOT_STARTED + } + stage { + refId = "ID: 3-2" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9") + status = NOT_STARTED + } + stage { + refId = "ID: 3-3" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9") + status = NOT_STARTED + } + stage { + refId = "ID: 3-4" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9") + status = NOT_STARTED + } + stage { + refId = "ID: 3-5" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9") + status = NOT_STARTED + } + stage { + refId = "ID: 3-6" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9") + status = NOT_STARTED + } + stage { + refId = "ID: 3-7" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9") + status = NOT_STARTED + } + stage { + refId = "ID: 3-8" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9") + status = NOT_STARTED + } + stage { + refId = "ID: 3-9" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9") + status = NOT_STARTED + } + stage { + refId = "ID: 4-0" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9") + status = NOT_STARTED + } + stage { + refId = "ID: 4-1" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9") + status = NOT_STARTED + } + stage { + refId = "ID: 4-2" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9") + status = NOT_STARTED + } + stage { + refId = "ID: 4-3" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9") + status = NOT_STARTED + } + stage { + refId = "ID: 4-4" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9") + status = NOT_STARTED + } + stage { + refId = "ID: 4-5" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9") + status = NOT_STARTED + } + stage { + refId = "ID: 4-6" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9") + status = NOT_STARTED + } + stage { + refId = "ID: 4-7" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9") + status = NOT_STARTED + } + stage { + refId = "ID: 4-8" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9") + status = NOT_STARTED + } + stage { + refId = "ID: 4-9" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9") + status = NOT_STARTED + } + stage { + refId = "ID: 5-0" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9") + status = NOT_STARTED + } + stage { + refId = "ID: 5-1" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9") + status = NOT_STARTED + } + stage { + refId = "ID: 5-2" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9") + status = NOT_STARTED + } + stage { + refId = "ID: 5-3" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9") + status = NOT_STARTED + } + stage { + refId = "ID: 5-4" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9") + status = NOT_STARTED + } + stage { + refId = "ID: 5-5" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9") + status = NOT_STARTED + } + stage { + refId = "ID: 5-6" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9") + status = NOT_STARTED + } + stage { + refId = "ID: 5-7" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9") + status = NOT_STARTED + } + stage { + refId = "ID: 5-8" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9") + status = NOT_STARTED + } + stage { + refId = "ID: 5-9" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9") + status = NOT_STARTED + } + stage { + refId = "ID: 6-0" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9") + status = NOT_STARTED + } + stage { + refId = "ID: 6-1" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9") + status = NOT_STARTED + } + stage { + refId = "ID: 6-2" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9") + status = NOT_STARTED + } + stage { + refId = "ID: 6-3" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9") + status = NOT_STARTED + } + stage { + refId = "ID: 6-4" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9") + status = NOT_STARTED + } + stage { + refId = "ID: 6-5" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9") + status = NOT_STARTED + } + stage { + refId = "ID: 6-6" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9") + status = NOT_STARTED + } + stage { + refId = "ID: 6-7" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9") + status = NOT_STARTED + } + stage { + refId = "ID: 6-8" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9") + status = NOT_STARTED + } + stage { + refId = "ID: 6-9" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9") + status = NOT_STARTED + } + stage { + refId = "ID: 7-0" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9", "ID: 6-0", "ID: 6-1", "ID: 6-2", "ID: 6-3", "ID: 6-4", "ID: 6-5", "ID: 6-6", "ID: 6-7", "ID: 6-8", "ID: 6-9") + status = NOT_STARTED + } + stage { + refId = "ID: 7-1" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9", "ID: 6-0", "ID: 6-1", "ID: 6-2", "ID: 6-3", "ID: 6-4", "ID: 6-5", "ID: 6-6", "ID: 6-7", "ID: 6-8", "ID: 6-9") + status = NOT_STARTED + } + stage { + refId = "ID: 7-2" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9", "ID: 6-0", "ID: 6-1", "ID: 6-2", "ID: 6-3", "ID: 6-4", "ID: 6-5", "ID: 6-6", "ID: 6-7", "ID: 6-8", "ID: 6-9") + status = NOT_STARTED + } + stage { + refId = "ID: 7-3" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9", "ID: 6-0", "ID: 6-1", "ID: 6-2", "ID: 6-3", "ID: 6-4", "ID: 6-5", "ID: 6-6", "ID: 6-7", "ID: 6-8", "ID: 6-9") + status = NOT_STARTED + } + stage { + refId = "ID: 7-4" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9", "ID: 6-0", "ID: 6-1", "ID: 6-2", "ID: 6-3", "ID: 6-4", "ID: 6-5", "ID: 6-6", "ID: 6-7", "ID: 6-8", "ID: 6-9") + status = NOT_STARTED + } + stage { + refId = "ID: 7-5" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9", "ID: 6-0", "ID: 6-1", "ID: 6-2", "ID: 6-3", "ID: 6-4", "ID: 6-5", "ID: 6-6", "ID: 6-7", "ID: 6-8", "ID: 6-9") + status = NOT_STARTED + } + stage { + refId = "ID: 7-6" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9", "ID: 6-0", "ID: 6-1", "ID: 6-2", "ID: 6-3", "ID: 6-4", "ID: 6-5", "ID: 6-6", "ID: 6-7", "ID: 6-8", "ID: 6-9") + status = NOT_STARTED + } + stage { + refId = "ID: 7-7" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9", "ID: 6-0", "ID: 6-1", "ID: 6-2", "ID: 6-3", "ID: 6-4", "ID: 6-5", "ID: 6-6", "ID: 6-7", "ID: 6-8", "ID: 6-9") + status = NOT_STARTED + } + stage { + refId = "ID: 7-8" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9", "ID: 6-0", "ID: 6-1", "ID: 6-2", "ID: 6-3", "ID: 6-4", "ID: 6-5", "ID: 6-6", "ID: 6-7", "ID: 6-8", "ID: 6-9") + status = NOT_STARTED + } + stage { + refId = "ID: 7-9" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9", "ID: 6-0", "ID: 6-1", "ID: 6-2", "ID: 6-3", "ID: 6-4", "ID: 6-5", "ID: 6-6", "ID: 6-7", "ID: 6-8", "ID: 6-9") + status = NOT_STARTED + } + stage { + refId = "ID: 8-0" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9", "ID: 6-0", "ID: 6-1", "ID: 6-2", "ID: 6-3", "ID: 6-4", "ID: 6-5", "ID: 6-6", "ID: 6-7", "ID: 6-8", "ID: 6-9", "ID: 7-0", "ID: 7-1", "ID: 7-2", "ID: 7-3", "ID: 7-4", "ID: 7-5", "ID: 7-6", "ID: 7-7", "ID: 7-8", "ID: 7-9") + status = NOT_STARTED + } + stage { + refId = "ID: 8-1" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9", "ID: 6-0", "ID: 6-1", "ID: 6-2", "ID: 6-3", "ID: 6-4", "ID: 6-5", "ID: 6-6", "ID: 6-7", "ID: 6-8", "ID: 6-9", "ID: 7-0", "ID: 7-1", "ID: 7-2", "ID: 7-3", "ID: 7-4", "ID: 7-5", "ID: 7-6", "ID: 7-7", "ID: 7-8", "ID: 7-9") + status = NOT_STARTED + } + stage { + refId = "ID: 8-2" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9", "ID: 6-0", "ID: 6-1", "ID: 6-2", "ID: 6-3", "ID: 6-4", "ID: 6-5", "ID: 6-6", "ID: 6-7", "ID: 6-8", "ID: 6-9", "ID: 7-0", "ID: 7-1", "ID: 7-2", "ID: 7-3", "ID: 7-4", "ID: 7-5", "ID: 7-6", "ID: 7-7", "ID: 7-8", "ID: 7-9") + status = NOT_STARTED + } + stage { + refId = "ID: 8-3" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9", "ID: 6-0", "ID: 6-1", "ID: 6-2", "ID: 6-3", "ID: 6-4", "ID: 6-5", "ID: 6-6", "ID: 6-7", "ID: 6-8", "ID: 6-9", "ID: 7-0", "ID: 7-1", "ID: 7-2", "ID: 7-3", "ID: 7-4", "ID: 7-5", "ID: 7-6", "ID: 7-7", "ID: 7-8", "ID: 7-9") + status = NOT_STARTED + } + stage { + refId = "ID: 8-4" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9", "ID: 6-0", "ID: 6-1", "ID: 6-2", "ID: 6-3", "ID: 6-4", "ID: 6-5", "ID: 6-6", "ID: 6-7", "ID: 6-8", "ID: 6-9", "ID: 7-0", "ID: 7-1", "ID: 7-2", "ID: 7-3", "ID: 7-4", "ID: 7-5", "ID: 7-6", "ID: 7-7", "ID: 7-8", "ID: 7-9") + status = NOT_STARTED + } + stage { + refId = "ID: 8-5" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9", "ID: 6-0", "ID: 6-1", "ID: 6-2", "ID: 6-3", "ID: 6-4", "ID: 6-5", "ID: 6-6", "ID: 6-7", "ID: 6-8", "ID: 6-9", "ID: 7-0", "ID: 7-1", "ID: 7-2", "ID: 7-3", "ID: 7-4", "ID: 7-5", "ID: 7-6", "ID: 7-7", "ID: 7-8", "ID: 7-9") + status = NOT_STARTED + } + stage { + refId = "ID: 8-6" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9", "ID: 6-0", "ID: 6-1", "ID: 6-2", "ID: 6-3", "ID: 6-4", "ID: 6-5", "ID: 6-6", "ID: 6-7", "ID: 6-8", "ID: 6-9", "ID: 7-0", "ID: 7-1", "ID: 7-2", "ID: 7-3", "ID: 7-4", "ID: 7-5", "ID: 7-6", "ID: 7-7", "ID: 7-8", "ID: 7-9") + status = NOT_STARTED + } + stage { + refId = "ID: 8-7" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9", "ID: 6-0", "ID: 6-1", "ID: 6-2", "ID: 6-3", "ID: 6-4", "ID: 6-5", "ID: 6-6", "ID: 6-7", "ID: 6-8", "ID: 6-9", "ID: 7-0", "ID: 7-1", "ID: 7-2", "ID: 7-3", "ID: 7-4", "ID: 7-5", "ID: 7-6", "ID: 7-7", "ID: 7-8", "ID: 7-9") + status = NOT_STARTED + } + stage { + refId = "ID: 8-8" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9", "ID: 6-0", "ID: 6-1", "ID: 6-2", "ID: 6-3", "ID: 6-4", "ID: 6-5", "ID: 6-6", "ID: 6-7", "ID: 6-8", "ID: 6-9", "ID: 7-0", "ID: 7-1", "ID: 7-2", "ID: 7-3", "ID: 7-4", "ID: 7-5", "ID: 7-6", "ID: 7-7", "ID: 7-8", "ID: 7-9") + status = NOT_STARTED + } + stage { + refId = "ID: 8-9" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9", "ID: 6-0", "ID: 6-1", "ID: 6-2", "ID: 6-3", "ID: 6-4", "ID: 6-5", "ID: 6-6", "ID: 6-7", "ID: 6-8", "ID: 6-9", "ID: 7-0", "ID: 7-1", "ID: 7-2", "ID: 7-3", "ID: 7-4", "ID: 7-5", "ID: 7-6", "ID: 7-7", "ID: 7-8", "ID: 7-9") + status = NOT_STARTED + } + stage { + refId = "ID: 9-0" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9", "ID: 6-0", "ID: 6-1", "ID: 6-2", "ID: 6-3", "ID: 6-4", "ID: 6-5", "ID: 6-6", "ID: 6-7", "ID: 6-8", "ID: 6-9", "ID: 7-0", "ID: 7-1", "ID: 7-2", "ID: 7-3", "ID: 7-4", "ID: 7-5", "ID: 7-6", "ID: 7-7", "ID: 7-8", "ID: 7-9", "ID: 8-0", "ID: 8-1", "ID: 8-2", "ID: 8-3", "ID: 8-4", "ID: 8-5", "ID: 8-6", "ID: 8-7", "ID: 8-8", "ID: 8-9") + status = NOT_STARTED + } + stage { + refId = "ID: 9-1" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9", "ID: 6-0", "ID: 6-1", "ID: 6-2", "ID: 6-3", "ID: 6-4", "ID: 6-5", "ID: 6-6", "ID: 6-7", "ID: 6-8", "ID: 6-9", "ID: 7-0", "ID: 7-1", "ID: 7-2", "ID: 7-3", "ID: 7-4", "ID: 7-5", "ID: 7-6", "ID: 7-7", "ID: 7-8", "ID: 7-9", "ID: 8-0", "ID: 8-1", "ID: 8-2", "ID: 8-3", "ID: 8-4", "ID: 8-5", "ID: 8-6", "ID: 8-7", "ID: 8-8", "ID: 8-9") + status = NOT_STARTED + } + stage { + refId = "ID: 9-2" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9", "ID: 6-0", "ID: 6-1", "ID: 6-2", "ID: 6-3", "ID: 6-4", "ID: 6-5", "ID: 6-6", "ID: 6-7", "ID: 6-8", "ID: 6-9", "ID: 7-0", "ID: 7-1", "ID: 7-2", "ID: 7-3", "ID: 7-4", "ID: 7-5", "ID: 7-6", "ID: 7-7", "ID: 7-8", "ID: 7-9", "ID: 8-0", "ID: 8-1", "ID: 8-2", "ID: 8-3", "ID: 8-4", "ID: 8-5", "ID: 8-6", "ID: 8-7", "ID: 8-8", "ID: 8-9") + status = NOT_STARTED + } + stage { + refId = "ID: 9-3" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9", "ID: 6-0", "ID: 6-1", "ID: 6-2", "ID: 6-3", "ID: 6-4", "ID: 6-5", "ID: 6-6", "ID: 6-7", "ID: 6-8", "ID: 6-9", "ID: 7-0", "ID: 7-1", "ID: 7-2", "ID: 7-3", "ID: 7-4", "ID: 7-5", "ID: 7-6", "ID: 7-7", "ID: 7-8", "ID: 7-9", "ID: 8-0", "ID: 8-1", "ID: 8-2", "ID: 8-3", "ID: 8-4", "ID: 8-5", "ID: 8-6", "ID: 8-7", "ID: 8-8", "ID: 8-9") + status = NOT_STARTED + } + stage { + refId = "ID: 9-4" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9", "ID: 6-0", "ID: 6-1", "ID: 6-2", "ID: 6-3", "ID: 6-4", "ID: 6-5", "ID: 6-6", "ID: 6-7", "ID: 6-8", "ID: 6-9", "ID: 7-0", "ID: 7-1", "ID: 7-2", "ID: 7-3", "ID: 7-4", "ID: 7-5", "ID: 7-6", "ID: 7-7", "ID: 7-8", "ID: 7-9", "ID: 8-0", "ID: 8-1", "ID: 8-2", "ID: 8-3", "ID: 8-4", "ID: 8-5", "ID: 8-6", "ID: 8-7", "ID: 8-8", "ID: 8-9") + status = NOT_STARTED + } + stage { + refId = "ID: 9-5" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9", "ID: 6-0", "ID: 6-1", "ID: 6-2", "ID: 6-3", "ID: 6-4", "ID: 6-5", "ID: 6-6", "ID: 6-7", "ID: 6-8", "ID: 6-9", "ID: 7-0", "ID: 7-1", "ID: 7-2", "ID: 7-3", "ID: 7-4", "ID: 7-5", "ID: 7-6", "ID: 7-7", "ID: 7-8", "ID: 7-9", "ID: 8-0", "ID: 8-1", "ID: 8-2", "ID: 8-3", "ID: 8-4", "ID: 8-5", "ID: 8-6", "ID: 8-7", "ID: 8-8", "ID: 8-9") + status = NOT_STARTED + } + stage { + refId = "ID: 9-6" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9", "ID: 6-0", "ID: 6-1", "ID: 6-2", "ID: 6-3", "ID: 6-4", "ID: 6-5", "ID: 6-6", "ID: 6-7", "ID: 6-8", "ID: 6-9", "ID: 7-0", "ID: 7-1", "ID: 7-2", "ID: 7-3", "ID: 7-4", "ID: 7-5", "ID: 7-6", "ID: 7-7", "ID: 7-8", "ID: 7-9", "ID: 8-0", "ID: 8-1", "ID: 8-2", "ID: 8-3", "ID: 8-4", "ID: 8-5", "ID: 8-6", "ID: 8-7", "ID: 8-8", "ID: 8-9") + status = NOT_STARTED + } + stage { + refId = "ID: 9-7" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9", "ID: 6-0", "ID: 6-1", "ID: 6-2", "ID: 6-3", "ID: 6-4", "ID: 6-5", "ID: 6-6", "ID: 6-7", "ID: 6-8", "ID: 6-9", "ID: 7-0", "ID: 7-1", "ID: 7-2", "ID: 7-3", "ID: 7-4", "ID: 7-5", "ID: 7-6", "ID: 7-7", "ID: 7-8", "ID: 7-9", "ID: 8-0", "ID: 8-1", "ID: 8-2", "ID: 8-3", "ID: 8-4", "ID: 8-5", "ID: 8-6", "ID: 8-7", "ID: 8-8", "ID: 8-9") + status = NOT_STARTED + } + stage { + refId = "ID: 9-8" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9", "ID: 6-0", "ID: 6-1", "ID: 6-2", "ID: 6-3", "ID: 6-4", "ID: 6-5", "ID: 6-6", "ID: 6-7", "ID: 6-8", "ID: 6-9", "ID: 7-0", "ID: 7-1", "ID: 7-2", "ID: 7-3", "ID: 7-4", "ID: 7-5", "ID: 7-6", "ID: 7-7", "ID: 7-8", "ID: 7-9", "ID: 8-0", "ID: 8-1", "ID: 8-2", "ID: 8-3", "ID: 8-4", "ID: 8-5", "ID: 8-6", "ID: 8-7", "ID: 8-8", "ID: 8-9") + status = NOT_STARTED + } + stage { + refId = "ID: 9-9" + requisiteStageRefIds = setOf("Initial", "ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9", "ID: 6-0", "ID: 6-1", "ID: 6-2", "ID: 6-3", "ID: 6-4", "ID: 6-5", "ID: 6-6", "ID: 6-7", "ID: 6-8", "ID: 6-9", "ID: 7-0", "ID: 7-1", "ID: 7-2", "ID: 7-3", "ID: 7-4", "ID: 7-5", "ID: 7-6", "ID: 7-7", "ID: 7-8", "ID: 7-9", "ID: 8-0", "ID: 8-1", "ID: 8-2", "ID: 8-3", "ID: 8-4", "ID: 8-5", "ID: 8-6", "ID: 8-7", "ID: 8-8", "ID: 8-9") + status = NOT_STARTED + } + stage { + refId = "Final" + requisiteStageRefIds = setOf("ID: 0-0", "ID: 0-1", "ID: 0-2", "ID: 0-3", "ID: 0-4", "ID: 0-5", "ID: 0-6", "ID: 0-7", "ID: 0-8", "ID: 0-9", "ID: 1-0", "ID: 1-1", "ID: 1-2", "ID: 1-3", "ID: 1-4", "ID: 1-5", "ID: 1-6", "ID: 1-7", "ID: 1-8", "ID: 1-9", "ID: 2-0", "ID: 2-1", "ID: 2-2", "ID: 2-3", "ID: 2-4", "ID: 2-5", "ID: 2-6", "ID: 2-7", "ID: 2-8", "ID: 2-9", "ID: 3-0", "ID: 3-1", "ID: 3-2", "ID: 3-3", "ID: 3-4", "ID: 3-5", "ID: 3-6", "ID: 3-7", "ID: 3-8", "ID: 3-9", "ID: 4-0", "ID: 4-1", "ID: 4-2", "ID: 4-3", "ID: 4-4", "ID: 4-5", "ID: 4-6", "ID: 4-7", "ID: 4-8", "ID: 4-9", "ID: 5-0", "ID: 5-1", "ID: 5-2", "ID: 5-3", "ID: 5-4", "ID: 5-5", "ID: 5-6", "ID: 5-7", "ID: 5-8", "ID: 5-9", "ID: 6-0", "ID: 6-1", "ID: 6-2", "ID: 6-3", "ID: 6-4", "ID: 6-5", "ID: 6-6", "ID: 6-7", "ID: 6-8", "ID: 6-9", "ID: 7-0", "ID: 7-1", "ID: 7-2", "ID: 7-3", "ID: 7-4", "ID: 7-5", "ID: 7-6", "ID: 7-7", "ID: 7-8", "ID: 7-9", "ID: 8-0", "ID: 8-1", "ID: 8-2", "ID: 8-3", "ID: 8-4", "ID: 8-5", "ID: 8-6", "ID: 8-7", "ID: 8-8", "ID: 8-9", "ID: 9-0", "ID: 9-1", "ID: 9-2", "ID: 9-3", "ID: 9-4", "ID: 9-5", "ID: 9-6", "ID: 9-7", "ID: 9-8", "ID: 9-9") + status = NOT_STARTED + } +} diff --git a/orca-queue/src/main/kotlin/com/netflix/spinnaker/orca/q/handler/StartStageHandler.kt b/orca-queue/src/main/kotlin/com/netflix/spinnaker/orca/q/handler/StartStageHandler.kt index 3a18214ff1..e1cefed868 100644 --- a/orca-queue/src/main/kotlin/com/netflix/spinnaker/orca/q/handler/StartStageHandler.kt +++ b/orca-queue/src/main/kotlin/com/netflix/spinnaker/orca/q/handler/StartStageHandler.kt @@ -19,6 +19,7 @@ package com.netflix.spinnaker.orca.q.handler import com.fasterxml.jackson.databind.ObjectMapper import com.netflix.spectator.api.Registry import com.netflix.spinnaker.orca.TaskImplementationResolver +import com.netflix.spinnaker.orca.api.pipeline.models.ExecutionStatus import com.netflix.spinnaker.orca.api.pipeline.models.ExecutionStatus.NOT_STARTED import com.netflix.spinnaker.orca.api.pipeline.models.ExecutionStatus.RUNNING import com.netflix.spinnaker.orca.api.pipeline.models.ExecutionType.PIPELINE @@ -26,10 +27,10 @@ import com.netflix.spinnaker.orca.api.pipeline.models.StageExecution import com.netflix.spinnaker.orca.events.StageStarted import com.netflix.spinnaker.orca.exceptions.ExceptionHandler import com.netflix.spinnaker.orca.ext.allUpstreamStagesComplete -import com.netflix.spinnaker.orca.ext.anyUpstreamStagesFailed import com.netflix.spinnaker.orca.ext.firstAfterStages import com.netflix.spinnaker.orca.ext.firstBeforeStages import com.netflix.spinnaker.orca.ext.firstTask +import com.netflix.spinnaker.orca.ext.upstreamStages import com.netflix.spinnaker.orca.pipeline.StageDefinitionBuilderFactory import com.netflix.spinnaker.orca.pipeline.expressions.PipelineExpressionEvaluator import com.netflix.spinnaker.orca.pipeline.model.OptionalStageSupport @@ -78,20 +79,20 @@ class StartStageHandler( override fun handle(message: StartStage) { message.withStage { stage -> try { - stage.withAuth { - if (stage.anyUpstreamStagesFailed()) { - // this only happens in restart scenarios - log.warn("Tried to start stage ${stage.id} but something upstream had failed (executionId: ${message.executionId})") - queue.push(CompleteExecution(message)) - } else if (stage.allUpstreamStagesComplete()) { - if (stage.status != NOT_STARTED) { - log.warn("Ignoring $message as stage is already ${stage.status}") - } else if (stage.shouldSkip()) { - queue.push(SkipStage(message)) - } else if (stage.isAfterStartTimeExpiry()) { - log.warn("Stage is being skipped because its start time is after TTL (stageId: ${stage.id}, executionId: ${message.executionId})") - queue.push(SkipStage(stage)) - } else { + if (stage.anyUpstreamStagesFailed()) { + // this only happens in restart scenarios + log.warn("Tried to start stage ${stage.id} but something upstream had failed (executionId: ${message.executionId})") + queue.push(CompleteExecution(message)) + } else if (stage.allUpstreamStagesComplete()) { + if (stage.status != NOT_STARTED) { + log.warn("Ignoring $message as stage is already ${stage.status}") + } else if (stage.shouldSkip()) { + queue.push(SkipStage(message)) + } else if (stage.isAfterStartTimeExpiry()) { + log.warn("Stage is being skipped because its start time is after TTL (stageId: ${stage.id}, executionId: ${message.executionId})") + queue.push(SkipStage(stage)) + } else { + stage.withAuth { try { // Set the startTime in case we throw an exception. stage.startTime = clock.millis() @@ -122,24 +123,23 @@ class StartStageHandler( } } } - } else { - log.info("Re-queuing $message as upstream stages are not yet complete") - queue.push(message, retryDelay) } + } else { + log.info("Re-queuing $message as upstream stages are not yet complete") + queue.push(message, retryDelay) } - } catch (e: Exception) { - message.withStage { stage -> - log.error("Error running ${stage.type}[${stage.id}] stage for ${message.executionType}[${message.executionId}]", e) - stage.apply { - val exceptionDetails = exceptionHandlers.shouldRetry(e, stage.name) - context["exception"] = exceptionDetails - context["beforeStagePlanningFailed"] = true - } + } catch (e: Exception) { + log.error("Error running ${stage.type}[${stage.id}] stage for ${message.executionType}[${message.executionId}]", e) - repository.storeStage(stage) - queue.push(CompleteStage(message)) + stage.apply { + val exceptionDetails = exceptionHandlers.shouldRetry(e, stage.name) + context["exception"] = exceptionDetails + context["beforeStagePlanningFailed"] = true } + + repository.storeStage(stage) + queue.push(CompleteStage(message)) } } } @@ -168,6 +168,32 @@ class StartStageHandler( override val messageType = StartStage::class.java + private fun StageExecution.anyUpstreamStagesFailed(): Boolean { + // Memoized map of stageId to the result of anyUpstreamStagesFailed() for each stage + val memo = HashMap() + + fun anyUpstreamStagesFailed(stage: StageExecution): Boolean { + val stageId = stage.id + if (memo.containsKey(stageId)) { + return memo[stageId]!! + } + for (upstreamStage in stage.upstreamStages()) { + if (upstreamStage.status in listOf(ExecutionStatus.TERMINAL, ExecutionStatus.STOPPED, ExecutionStatus.CANCELED)) { + memo[stageId] = true + return true + } + if (upstreamStage.status == NOT_STARTED && anyUpstreamStagesFailed(upstreamStage)) { + memo[stageId] = true + return true + } + } + memo[stageId] = false + return false + } + + return anyUpstreamStagesFailed(this) + } + private fun StageExecution.plan() { builder().let { builder -> // if we have a top level stage, ensure that context expressions are processed diff --git a/orca-queue/src/test/kotlin/com/netflix/spinnaker/orca/q/handler/StartStageHandlerTest.kt b/orca-queue/src/test/kotlin/com/netflix/spinnaker/orca/q/handler/StartStageHandlerTest.kt index adb4886e2c..592385fe8b 100644 --- a/orca-queue/src/test/kotlin/com/netflix/spinnaker/orca/q/handler/StartStageHandlerTest.kt +++ b/orca-queue/src/test/kotlin/com/netflix/spinnaker/orca/q/handler/StartStageHandlerTest.kt @@ -51,6 +51,7 @@ import com.netflix.spinnaker.orca.q.StartStage import com.netflix.spinnaker.orca.q.StartTask import com.netflix.spinnaker.orca.q.buildBeforeStages import com.netflix.spinnaker.orca.q.buildTasks +import com.netflix.spinnaker.orca.q.complexPipeline import com.netflix.spinnaker.orca.q.failPlanningStage import com.netflix.spinnaker.orca.q.get import com.netflix.spinnaker.orca.q.multiTaskStage @@ -72,6 +73,7 @@ import com.nhaarman.mockito_kotlin.argumentCaptor import com.nhaarman.mockito_kotlin.check import com.nhaarman.mockito_kotlin.doReturn import com.nhaarman.mockito_kotlin.doThrow +import com.nhaarman.mockito_kotlin.eq import com.nhaarman.mockito_kotlin.isA import com.nhaarman.mockito_kotlin.mock import com.nhaarman.mockito_kotlin.never @@ -91,6 +93,9 @@ import org.jetbrains.spek.api.dsl.on import org.jetbrains.spek.api.lifecycle.CachingMode.GROUP import org.jetbrains.spek.subject.SubjectSpek import org.springframework.context.ApplicationEventPublisher +import java.util.concurrent.Executors +import java.util.concurrent.TimeUnit +import java.util.concurrent.TimeoutException object StartStageHandlerTest : SubjectSpek({ @@ -549,6 +554,37 @@ object StartStageHandlerTest : SubjectSpek({ } } + given("the stage has multiple layers of upstream stages") { + val pipeline = complexPipeline + val message = StartStage(pipeline.type, pipeline.id, "foo", pipeline.stageByRef("Final").id) + fun withTimeout(timeoutMs: Long, block: () -> Unit) { + val executor = Executors.newSingleThreadExecutor() + val future = executor.submit(block) + + try { + future.get(timeoutMs, TimeUnit.MILLISECONDS) + } catch (e: TimeoutException) { + future.cancel(true) // Force interruption + throw RuntimeException("Task timed out!") + } finally { + executor.shutdownNow() + } + } + + beforeGroup { + whenever(repository.retrieve(PIPELINE, message.executionId)) doReturn pipeline + } + + afterGroup(::resetMocks) + + it("handles a message in a timely manner") { + withTimeout(5000) { + subject.handle(message) + verify(queue).push(eq(message), any()) + } + } + } + given("the stage has an execution window") { and("synthetic before stages") { val pipeline = pipeline {