/* Ċ Ġ* ĠCopyright Ġ 2 0 1 7 ĠNet flix , Ġ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 . spin n aker . or ca . q . handler Ċ Ċ import Ġcom . netflix . spect ator . api . Registry Ċ import Ġcom . netflix . spect ator . api . histogram . Percent ile Timer Ċ import Ġcom . netflix . spin n aker . or ca . api . pipeline . models . Execution Status Ċ import Ġcom . netflix . spin n aker . or ca . api . pipeline . models . Execution Status . C ANCE LED Ċ import Ġcom . netflix . spin n aker . or ca . api . pipeline . models . Execution Status . FAILED _ CONTINUE Ċ import Ġcom . netflix . spin n aker . or ca . api . pipeline . models . Execution Status . NOT _ STARTED Ċ import Ġcom . netflix . spin n aker . or ca . api . pipeline . models . Execution Status . RUNNING Ċ import Ġcom . netflix . spin n aker . or ca . api . pipeline . models . Execution Status . SKIP PED Ċ import Ġcom . netflix . spin n aker . or ca . api . pipeline . models . Execution Status . STOP PED Ċ import Ġcom . netflix . spin n aker . or ca . api . pipeline . models . Execution Status . SUCCEEDED Ċ import Ġcom . netflix . spin n aker . or ca . api . pipeline . models . Execution Status . TERMIN AL Ċ import Ġcom . netflix . spin n aker . or ca . api . pipeline . models . Stage Execution Ċ import Ġcom . netflix . spin n aker . or ca . api . pipeline . models . Task Execution Ċ import Ġcom . netflix . spin n aker . or ca . events . Stage Complete Ċ import Ġcom . netflix . spin n aker . or ca . exceptions . ExceptionHandler Ċ import Ġcom . netflix . spin n aker . or ca . ext . after Stages Ċ import Ġcom . netflix . spin n aker . or ca . ext . failure Status Ċ import Ġcom . netflix . spin n aker . or ca . ext . first After Stages Ċ import Ġcom . netflix . spin n aker . or ca . ext . synt hetic Stages Ċ import Ġcom . netflix . spin n aker . or ca . pipeline . Stage Definition BuilderFactory Ċ import Ġcom . netflix . spin n aker . or ca . pipeline . graph . Stage Graph Builder Impl Ċ import Ġcom . netflix . spin n aker . or ca . pipeline . persistence . Execution Repository Ċ import Ġcom . netflix . spin n aker . or ca . pipeline . util . Context Parameter Processor Ċ import Ġcom . netflix . spin n aker . or ca . pipeline . util . Stage Navigator Ċ import Ġcom . netflix . spin n aker . or ca . q . Cancel Stage Ċ import Ġcom . netflix . spin n aker . or ca . q . Complete Execution Ċ import Ġcom . netflix . spin n aker . or ca . q . Complete Stage Ċ import Ġcom . netflix . spin n aker . or ca . q . Start Stage Ċ import Ġcom . netflix . spin n aker . or ca . q . append After Stages Ċ import Ġcom . netflix . spin n aker . or ca . q . build After Stages Ċ import Ġcom . netflix . spin n aker . q . Queue Ċ import Ġjava . time . Clock Ċ import Ġjava . util . concurrent . TimeUnit Ċ import Ġkotlin . collections . List Ċ import Ġkotlin . collections . all Ċ import Ġkotlin . collections . any Ċ import Ġkotlin . collections . emptyList Ċ import Ġkotlin . collections . filter Ċ import Ġkotlin . collections . forEach Ċ import Ġkotlin . collections . forEach Indexed Ċ import Ġkotlin . collections . isNotEmpty Ċ import Ġkotlin . collections . listOf Ċ import Ġkotlin . collections . map Ċ import Ġkotlin . collections . minus Ċ import Ġkotlin . collections . plus Ċ import Ġkotlin . collections . set Ċ import Ġkotlin . collections . set Of Ċ import Ġkotlin . collections . toList Ċ import Ġorg . springframework . beans . factory . annotation . Qualifier Ċ import Ġorg . springframework . context . Application Event Publisher Ċ import Ġorg . springframework . stereotype . Component Ċ Ċ @ Component Ċ class ĠComplete Stage Handler ( ĊĠ Ġoverride Ġval Ġqueue : ĠQueue , ĊĠ Ġoverride Ġval Ġrepository : ĠExecution Repository , ĊĠ Ġoverride Ġval Ġstage Navigator : ĠStage Navigator , ĊĠ Ġ@ Qualifier (" queue Event Publisher ") Ġprivate Ġval Ġpublisher : ĠApplication Event Publisher , ĊĠ Ġprivate Ġval Ġclock : ĠClock , ĊĠ Ġprivate Ġval Ġexception Handlers : ĠList < ExceptionHandler >, ĊĠ Ġoverride Ġval Ġcontext Parameter Processor : ĠContext Parameter Processor , ĊĠ Ġprivate Ġval Ġregistry : ĠRegistry , ĊĠ Ġoverride Ġval Ġstage Definition BuilderFactory : ĠStage Definition BuilderFactory Ċ ) Ġ: ĠO rc a MessageHandler < Complete Stage >, ĠStage Builder Aware , ĠExpression Aware , ĠAuthentication Aware Ġ{ ĊĊĠ Ġoverride Ġfun Ġhandle ( message : ĠComplete Stage ) Ġ{ ĊĠĠĠ Ġmessage . with Stage Ġ{ Ġstage Ġ-> ĊĠĠĠĠĠ Ġif Ġ( stage . status Ġin Ġset Of ( RUNNING , ĠNOT _ STARTED )) Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġstatus Ġ= Ġstage . determine Status () ĊĠĠĠĠĠĠĠ Ġif Ġ( stage . should Fail On Failed Expression Evaluation ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġlog . warn ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Stage Ġ${ stage . id } Ġ(${ stage . type }) Ġof Ġ${ stage . execution . id } Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" is Ġset Ġto Ġfail Ġbecause Ġof Ġfailed Ġexpressions ." ĊĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠ Ġstatus Ġ= ĠTER MIN AL ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( status Ġin Ġset Of ( RUNNING , ĠNOT _ STARTED ) Ġ|| Ġ( status . is Complete Ġ&& Ġ! status . is H alt )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcheck Ġto Ġsee Ġif Ġthis Ġstage Ġhas Ġany Ġun pl anned Ġsynthetic Ġafter Ġstages ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġafter Stages Ġ= Ġstage . first After Stages () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( after Stages . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstage . with Auth Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstage . plan After Stages () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġafter Stages Ġ= Ġstage . first After Stages () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( after Stages . isNotEmpty () Ġ&& Ġafter Stages . any Ġ{ Ġit . status Ġ== ĠNOT _ STARTED Ġ}) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġafter Stages ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . status Ġ== ĠNOT _ STARTED Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. forEach Ġ{ Ġqueue . push ( Start Stage ( message , Ġit . id )) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ with Stage ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( status Ġ== ĠNOT _ STARTED ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġstage Ġhad Ġno Ġsynthetic Ġstages Ġor Ġtasks , Ġwhich Ġis Ġodd Ġbut Ġwhatever ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . warn (" Stage Ġ${ stage . id } Ġ(${ stage . type }) Ġof Ġ${ stage . execution . id } Ġhad Ġno Ġtasks Ġor Ġsynthetic Ġstages !") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstatus Ġ= ĠSKIP PED ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( status . is Failure ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġhas On Failure Stages Ġ= Ġfalse ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġstage . with Auth Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhas On Failure Stages Ġ= Ġstage . plan On Failure Stages () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( has On Failure Stages ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstage . first After Stages (). forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġqueue . push ( Start Stage ( it )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ with Stage ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠ Ġstage . status Ġ= Ġstatus ĊĠĠĠĠĠĠĠĠĠ Ġstage . endTime Ġ= Ġclock . millis () ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġlog . error (" Failed Ġto Ġconstruct Ġafter Ġstages Ġfor Ġ${ stage . name } Ġ${ stage . id }", Ġe ) ĊĊĠĠĠĠĠĠĠĠĠ Ġval Ġexception Details Ġ= Ġexception Handlers . should Retry ( e , Ġstage . name Ġ+ Ġ": Construct After Stages ") ĊĠĠĠĠĠĠĠĠĠ Ġstage . context [" exception "] Ġ= Ġexception Details ĊĠĠĠĠĠĠĠĠĠ Ġstage . status Ġ= ĠTER MIN AL ĊĠĠĠĠĠĠĠĠĠ Ġstage . endTime Ġ= Ġclock . millis () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġstage . include Expression Evaluation Summary () ĊĠĠĠĠĠĠĠ Ġrepository . store Stage ( stage ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠWhen Ġa Ġsynthetic Ġstage Ġends Ġwith ĠFAILED _ CONTINUE , Ġpropagate Ġthat Ġstatus Ġup Ġto Ġthe Ġstage 's ĊĠĠĠĠĠĠĠ Ġ// Ġparent Ġso Ġthat Ġno Ġmore Ġof Ġthe Ġparent 's Ġsynthetic Ġchildren Ġwill Ġrun . ĊĠĠĠĠĠĠĠ Ġif Ġ( stage . status Ġ== ĠFAILED _ CONTINUE Ġ&& Ġstage . synt hetic Stage Owner Ġ!= Ġnull Ġ&& Ġ! stage . allow Sibling Stages To Continue On Failure ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġqueue . push ( message . copy ( stage Id Ġ= Ġstage . parent Stage Id !! )) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( stage . status Ġin ĠlistOf ( SUCCEEDED , ĠFAILED _ CONTINUE , ĠSKIP PED )) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġstage . start Next () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġqueue . push ( Cancel Stage ( message )) ĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( stage . synt hetic Stage Owner Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . debug (" Stage Ġhas Ġno Ġsynthetic Ġowner Ġand Ġstatus Ġis Ġ'${ stage . status }', Ġcomplet ing Ġexecution Ġ( original Ġmessage : Ġ$ message )") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġqueue . push ( Complete Execution ( message )) ĊĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġqueue . push ( message . copy ( stage Id Ġ= Ġstage . parent Stage Id !! )) ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġpublisher . publish Event ( Stage Complete ( this , Ġstage )) ĊĠĠĠĠĠĠĠ Ġtrack Result ( stage ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġ// ĠTODO : Ġthis Ġshould Ġbe Ġdone Ġout Ġof Ġband Ġby Ġrespon ding Ġto Ġthe ĠStage Complete Ġevent ĊĠ Ġprivate Ġfun Ġtrack Result ( stage : ĠStage Execution ) Ġ{ ĊĠĠĠ Ġ// ĠWe Ġonly Ġwant Ġto Ġrecord Ġdur ations Ġof Ġparent - level Ġstages ; Ġnot Ġsynt het ics . ĊĠĠĠ Ġif Ġ( stage . parent Stage Id Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠ Ġreturn ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġid Ġ= Ġregistry . create Id (" stage . inv ocations . duration ") ĊĠĠĠĠĠ Ġ. with Tag (" status ", Ġstage . status . toString ()) ĊĠĠĠĠĠ Ġ. with Tag (" stage Type ", Ġstage . type ) ĊĠĠĠĠĠ Ġ. let Ġ{ Ġid Ġ-> ĊĠĠĠĠĠĠĠ Ġ// ĠTODO Ġr z Ġ- ĠNeed Ġto Ġcheck Ġsynt het ics Ġfor Ġtheir Ġcloud Provider . ĊĠĠĠĠĠĠĠ Ġstage . context [" cloud Provider "] ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġid . with Tag (" cloud Provider ", Ġit . toString ()) ĊĠĠĠĠĠĠĠ Ġ} Ġ?: Ġid ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠIf ĠstartTime Ġwas Ġnot Ġset , Ġthen Ġassume Ġthis Ġwas Ġinstant aneous . ĊĠĠĠ Ġ// ĠIn Ġpractice Ġ 0 Ġstart Times Ġcan Ġhappen Ġif Ġthere Ġis ĊĠĠĠ Ġ// Ġan Ġexception Ġin ĠStart Stage Handler Ġor Ġguard Ġcausing Ġskipping . ĊĠĠĠ Ġ// ĠWithout Ġa ĠstartTime , Ġwe Ġcannot Ġrecord Ġa Ġmeaningful Ġtime , ĊĠĠĠ Ġ// Ġand Ġassuming Ġa Ġstart Ġof Ġ 0 Ġmakes Ġthe Ġvalues Ġrid iculo us ly Ġlarge . ĊĠĠĠ Ġval ĠendTime Ġ= Ġstage . endTime Ġ?: Ġclock . millis () ĊĠĠĠ Ġval ĠstartTime Ġ= Ġstage . startTime Ġ?: ĠendTime ĊĊĠĠĠ ĠPercent ile Timer ĊĠĠĠĠĠ Ġ. get ( registry , Ġid ) ĊĠĠĠĠĠ Ġ. record ( endTime Ġ- ĠstartTime , ĠTimeUnit . MILLISECONDS ) ĊĠ Ġ} ĊĊĠ Ġoverride Ġval Ġmessage Type Ġ= ĠComplete Stage :: class . java ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠPlan Ġany Ġoutstanding Ġsynthetic Ġafter Ġstages . ĊĠĠ Ġ*/ ĊĠ Ġprivate Ġfun ĠStage Execution . plan After Stages () Ġ{ ĊĠĠĠ Ġvar Ġhas Pl anned Stages Ġ= Ġfalse ĊĊĠĠĠ Ġbuilder (). build After Stages ( this ) Ġ{ ĊĠĠĠĠĠ Ġrepository . add Stage ( it ) ĊĠĠĠĠĠ Ġhas Pl anned Stages Ġ= Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġif Ġ( has Pl anned Stages ) Ġ{ ĊĠĠĠĠĠ Ġthis . set Execution ( repository . retrieve ( this . execution . type , Ġthis . execution . id )) ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠPlan Ġany Ġoutstanding Ġsynthetic Ġon Ġfailure Ġstages . ĊĠĠ Ġ*/ ĊĠ Ġprivate Ġfun ĠStage Execution . plan On Failure Stages (): ĠBoolean Ġ{ ĊĠĠĠ Ġ// ĠAvoid Ġplanning Ġfailure Ġstages Ġif Ġ_ any _ Ġwith Ġthe Ġsame Ġname Ġare Ġalready Ġcomplete ĊĠĠĠ Ġval Ġpreviously Pl anned After Stage Names Ġ= Ġafter Stages (). filter Ġ{ Ġit . status . is Complete Ġ}. map Ġ{ Ġit . name Ġ} ĊĊĠĠĠ Ġval Ġgraph Ġ= ĠStage Graph Builder Impl . after Stages ( this ) ĊĠĠĠ Ġbuilder (). on Failure Stages ( this , Ġgraph ) ĊĊĠĠĠ Ġval Ġon Failure Stages Ġ= Ġgraph . build (). toList () ĊĠĠĠ Ġon Failure Stages . forEach Indexed Ġ{ Ġindex , Ġstage Ġ-> ĊĠĠĠĠĠ Ġif Ġ( index Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġall Ġon Ġfailure Ġstages Ġshould Ġbe Ġrun Ġlinear ly ĊĠĠĠĠĠĠĠ Ġgraph . connect ( on Failure Stages . get ( index Ġ- Ġ 1 ), Ġstage ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġalready Pl anned Ġ= Ġon Failure Stages . any Ġ{ Ġpreviously Pl anned After Stage Names . contains ( it . name ) Ġ} ĊĊĠĠĠ Ġreturn Ġif Ġ( already Pl anned Ġ|| Ġon Failure Stages . isEmpty ()) Ġ{ ĊĠĠĠĠĠ Ġfalse ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠ Ġremove Not Started Synt het ics () Ġ// Ġshould Ġbe Ġall Ġsynt het ics Ġ( nothing Ġshould Ġhave Ġbeen Ġstarted !) ĊĠĠĠĠĠ Ġappend After Stages ( on Failure Stages ) Ġ{ ĊĠĠĠĠĠĠĠ Ġrepository . add Stage ( it ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġtrue ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun ĠStage Execution . remove Not Started Synt het ics () Ġ{ ĊĠĠĠ Ġsynthetic Stages () ĊĠĠĠĠĠ Ġ. filter Ġ{ Ġit . status Ġ== ĠNOT _ STARTED Ġ} ĊĠĠĠĠĠ Ġ. forEach Ġ{ Ġstage Ġ-> ĊĠĠĠĠĠĠĠ Ġexecution ĊĠĠĠĠĠĠĠĠĠ Ġ. stages ĊĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . requis ite Stage Ref Ids . contains ( stage . id ) Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġ. forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . requis ite Stage Ref Ids Ġ= Ġit . requis ite Stage Ref Ids Ġ- Ġstage . id ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrepository . add Stage ( it ) ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġstage . remove Not Started Synt het ics () Ġ// Ġshould Ġbe Ġall Ġsynt het ics ! ĊĠĠĠĠĠĠĠ Ġrepository . remove Stage ( execution , Ġstage . id ) ĊĠĠĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun ĠStage Execution . determine Status (): ĠExecution Status Ġ{ ĊĠĠĠ Ġval Ġsynthetic Statuses Ġ= Ġsynthetic Stages (). map ( Stage Execution :: getStatus ) ĊĠĠĠ Ġval Ġtask Statuses Ġ= Ġtasks . map ( Task Execution :: getStatus ) ĊĠĠĠ Ġval Ġplanning Status Ġ= Ġif Ġ( has Pl anning Failure ()) ĠlistOf ( failure Status ()) Ġelse Ġempty List () ĊĠĠĠ Ġval Ġall Statuses Ġ= Ġsynthetic Statuses Ġ+ Ġtask Statuses Ġ+ Ġplanning Status ĊĠĠĠ Ġval Ġafter Stage Statuses Ġ= Ġafter Stages (). map ( Stage Execution :: getStatus ) ĊĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠ Ġall Statuses . isEmpty () Ġ-> ĠNOT _ STARTED ĊĠĠĠĠĠ Ġall Statuses . contains ( TERMIN AL ) Ġ-> Ġfailure Status () Ġ// Ġhandle Ġconfigured Ġ' if Ġstage Ġfails ' Ġoptions Ġcorrectly ĊĠĠĠĠĠ Ġall Statuses . contains ( STOP PED ) Ġ-> ĠSTOP PED ĊĠĠĠĠĠ Ġall Statuses . contains ( C ANCE LED ) Ġ-> ĠC ANCE LED ĊĠĠĠĠĠ Ġall Statuses . contains ( FAILED _ CONTINUE ) Ġ-> ĠFAILED _ CONTINUE ĊĠĠĠĠĠ Ġall Statuses . all Ġ{ Ġit Ġ== ĠSU CCEEDED Ġ|| Ġit Ġ== ĠSKIP PED Ġ} Ġ-> ĠSU CCEEDED ĊĠĠĠĠĠ Ġafter Stage Statuses . contains ( NOT _ STARTED ) Ġ-> ĠRUN NING Ġ// Ġafter Ġstages Ġwere Ġplanned Ġbut Ġnot Ġrun Ġyet ĊĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠ Ġlog . error (" Unhandled Ġcondition Ġfor Ġstage Ġ$ id Ġof Ġ${ execution . id }, Ġmarking Ġas ĠTER MIN AL . Ġsynthetic Statuses =$ synt hetic Statuses , Ġtask Statuses =$ task Statuses , Ġplanning Status =$ planning Status , Ġafter Stage Statuses =$ after Stage Statuses ") ĊĠĠĠĠĠĠĠ ĠTER MIN AL ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ } Ċ Ċ private Ġfun ĠStage Execution . has Pl anning Failure () Ġ= ĊĠ Ġcontext [" before Stage Pl anning Failed "] Ġ== Ġtrue Ċ