Skip to content

Commit

Permalink
✨ : update workflow with PENDING states
Browse files Browse the repository at this point in the history
  • Loading branch information
juwit committed Oct 23, 2020
1 parent c37dc1f commit b5d2867
Show file tree
Hide file tree
Showing 29 changed files with 545 additions and 192 deletions.
40 changes: 23 additions & 17 deletions src/main/java/io/gaia_app/runner/RunnerController.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ResponseStatusException;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Stack;

/**
* Controller for the operations that are called by the runner only
Expand Down Expand Up @@ -55,12 +55,7 @@ public Map<String, Object> findFirstRunnableJob() {

// get the workflow
var workflow = new JobWorkflow(job);
// start the workflow
var step = workflow.startWorkflow();

// saving the job
this.jobRepository.save(job);
this.stepRepository.save(step);
var step = workflow.getCurrentStep();

var script = "";
// generate the script
Expand Down Expand Up @@ -111,18 +106,29 @@ public void updateLogs(@PathVariable String stepId, @RequestBody String logs) {
*/
@PutMapping("/steps/{stepId}/status")
public void updateStepStatus(@PathVariable String stepId, @RequestBody int status) {
var step = this.stepRepository.findById(stepId).orElseThrow();
// getting jobId
var jobId = this.stepRepository.findById(stepId).orElseThrow().getJobId();

// reload the job to check workflow status
var job = this.jobRepository.findById(step.getJobId()).orElseThrow();
var job = this.jobRepository.findById(jobId).orElseThrow();

// rebuild the workflow
var workflow = new JobWorkflow(job);
workflow.setCurrentStep(step);
workflow.next(status);
workflow.end(status);

var stack = this.stackRepository.findById(job.getStackId()).orElseThrow();
if(job.getStatus() == JobStatus.APPLY_FINISHED) {
if(job.getType() == JobType.RUN){
stack.setState(StackState.RUNNING);
}
else{
stack.setState(StackState.STOPPED);
}
}
this.stackRepository.save(stack);

// save the job & step to update their status
this.stepRepository.save(step);
this.stepRepository.saveAll(job.getSteps());
this.jobRepository.save(job);
}

Expand All @@ -131,18 +137,18 @@ public void updateStepStatus(@PathVariable String stepId, @RequestBody int statu
*/
@PutMapping("/steps/{stepId}/start")
public void startStep(@PathVariable String stepId) {
// getting step
var step = this.stepRepository.findById(stepId).orElseThrow();
// getting jobId
var jobId = this.stepRepository.findById(stepId).orElseThrow().getJobId();

// reload the job to check workflow status
var job = this.jobRepository.findById(step.getJobId()).orElseThrow();
var job = this.jobRepository.findById(jobId).orElseThrow();

// rebuild the workflow and start it
var workflow = new JobWorkflow(job);
workflow.startWorkflow();
workflow.start();

// save the job & step to update their status
this.stepRepository.save(step);
this.stepRepository.saveAll(job.getSteps());
this.jobRepository.save(job);
}
}
2 changes: 1 addition & 1 deletion src/main/java/io/gaia_app/stacks/bo/Step.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class Step {
private LocalDateTime endDateTime;
private Long executionTime;
private StepType type;
private StepStatus status;
private StepStatus status = StepStatus.PENDING;
private List<String> logs = new LinkedList<>();

public Step() {
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/io/gaia_app/stacks/bo/StepStatus.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package io.gaia_app.stacks.bo;

public enum StepStatus {
STARTED, FINISHED, FAILED
PENDING, STARTED, FINISHED, FAILED
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,28 @@ class JobRestController(
val workflow = JobWorkflow(job)
workflow.plan()
jobRepository.save(job)
stepRepository.save(workflow.currentStep)
}

@PostMapping("/{id}/apply")
fun apply(@PathVariable id: String) {
val job = jobRepository.findById(id).orElseThrow { JobNotFoundException() }
job.status = JobStatus.APPLY_PENDING
val workflow = JobWorkflow(job)
workflow.apply()
jobRepository.save(job)
stepRepository.save(workflow.currentStep)
}

@PostMapping("/{id}/retry")
fun retry(@PathVariable id: String) {
val job = jobRepository.findById(id).orElseThrow { JobNotFoundException() }

stepRepository.deleteByJobId(id)

val workflow = JobWorkflow(job)
workflow.retry()
jobRepository.save(job)
stepRepository.save(workflow.currentStep)
}

@DeleteMapping("/{id}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,6 @@ public Map<String, String> launchJob(@PathVariable String id, @PathVariable JobT

// create a new job
var job = new Job(jobType, id, user);
// setting the status to pending
job.setStatus(JobStatus.PLAN_PENDING);

job.setTerraformImage(stack.getModule().getTerraformImage());
if(stack.getCredentialsId() != null){
this.credentialsRepository.findById(stack.getCredentialsId())
Expand Down
60 changes: 27 additions & 33 deletions src/main/java/io/gaia_app/stacks/workflow/JobWorkflow.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import io.gaia_app.stacks.bo.*;
import io.gaia_app.stacks.workflow.state.*;
import io.gaia_app.stacks.workflow.state.*;

import java.util.Objects;

Expand All @@ -11,8 +10,7 @@
*/
public class JobWorkflow {

private Job job;
private Step currentStep;
private final Job job;
private JobState state;

public JobWorkflow(Job job) {
Expand All @@ -28,14 +26,6 @@ public void apply() {
this.state.apply(this);
}

public void end() {
this.state.end(this);
}

public void fail() {
this.state.fail(this);
}

public void retry() {
this.state.retry(this);
}
Expand All @@ -45,11 +35,20 @@ public Job getJob() {
}

public Step getCurrentStep() {
return currentStep;
}

public void setCurrentStep(Step currentStep) {
this.currentStep = currentStep;
// calculating current step depending on the state
switch (this.job.getStatus()){
case PLAN_PENDING:
case PLAN_STARTED:
case PLAN_FINISHED:
case PLAN_FAILED:
return this.job.getSteps().get(0);
case APPLY_PENDING:
case APPLY_STARTED:
case APPLY_FAILED:
case APPLY_FINISHED:
return this.job.getSteps().get(1);
}
return null;
}

public JobState getState() {
Expand All @@ -72,6 +71,9 @@ JobState evalInitialState(JobStatus jobStatus) {
return result;
}
switch (jobStatus) {
case PLAN_PENDING:
result = new PlanPendingState();
break;
case PLAN_STARTED:
result = new PlanStartedState();
break;
Expand All @@ -82,7 +84,7 @@ JobState evalInitialState(JobStatus jobStatus) {
result = new PlanFailedState();
break;
case APPLY_PENDING:
result = new PlanFinishedState();
result = new ApplyPendingState();
break;
case APPLY_STARTED:
result = new ApplyStartedState();
Expand All @@ -97,21 +99,15 @@ JobState evalInitialState(JobStatus jobStatus) {
return result;
}

public Step startWorkflow() {
if(this.job.getStatus() == JobStatus.PLAN_PENDING){
this.state.plan(this);
}
else if(this.job.getStatus() == JobStatus.APPLY_PENDING) {
this.state.apply(this);
}
return this.currentStep;
public void start() {
this.state.start(this);
}

/**
* Updates workflow to next status depending of the result code
* @param stepResultCode
*/
public void next(int stepResultCode) {
public void end(int stepResultCode) {
if(this.job.getStatus() == JobStatus.PLAN_STARTED){
this.managePlanResult(stepResultCode);
}
Expand All @@ -121,22 +117,20 @@ else if(this.job.getStatus() == JobStatus.APPLY_STARTED) {
}

private void managePlanResult(int result) {
if (result == 0) {
if (result == 0 || result == 2) {
// diff is empty
this.end();
} else if (result == 2) {
this.end();
this.state.end(this);
} else {
// error
this.fail();
this.state.fail(this);
}
}

private void managerApplyResult(int result){
if (result == 0) {
this.end();
this.state.end(this);
} else {
this.fail();
this.state.fail(this);;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
/**
* Describes a job which apply has been failed
*/
public class ApplyFailedState implements RetryableState {
public class ApplyFailedState extends RetryableState {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.gaia_app.stacks.workflow.state;

import io.gaia_app.stacks.bo.JobStatus;
import io.gaia_app.stacks.workflow.JobWorkflow;

public class ApplyPendingState implements JobState {

@Override
public void start(JobWorkflow jobWorkflow) {
var job = jobWorkflow.getJob();

job.proceed(JobStatus.APPLY_STARTED);
jobWorkflow.setState(new ApplyStartedState());

jobWorkflow.getCurrentStep().start();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,17 @@
public class ApplyStartedState implements JobState {
@Override
public void end(JobWorkflow jobWorkflow) {
jobWorkflow.getCurrentStep().end();
jobWorkflow.getJob().end(JobStatus.APPLY_FINISHED);
jobWorkflow.setState(new ApplyFinishedState());

jobWorkflow.getCurrentStep().end();
}

@Override
public void fail(JobWorkflow jobWorkflow) {
jobWorkflow.getCurrentStep().fail();
jobWorkflow.getJob().end(JobStatus.APPLY_FAILED);
jobWorkflow.setState(new ApplyFailedState());

jobWorkflow.getCurrentStep().fail();
}
}
5 changes: 5 additions & 0 deletions src/main/java/io/gaia_app/stacks/workflow/state/JobState.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
* Describe the state of job and its possible actions
*/
public interface JobState {

default void start(JobWorkflow jobWorkflow){
throw new UnsupportedOperationException();
}

default void plan(JobWorkflow jobWorkflow) {
throw new UnsupportedOperationException();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package io.gaia_app.stacks.workflow.state;

import io.gaia_app.stacks.bo.Step;
import io.gaia_app.stacks.bo.StepType;
import io.gaia_app.stacks.bo.*;
import io.gaia_app.stacks.workflow.JobWorkflow;
import io.gaia_app.stacks.bo.Step;
import io.gaia_app.stacks.bo.StepType;
Expand All @@ -14,13 +13,12 @@ public class NotStartedState implements JobState {
@Override
public void plan(JobWorkflow jobWorkflow) {
var job = jobWorkflow.getJob();
job.start();
job.setStatus(JobStatus.PLAN_PENDING);

// creating the PLAN step
var step = new Step(StepType.PLAN, job.getId());
job.getSteps().add(step);
jobWorkflow.setCurrentStep(step);
step.start();

jobWorkflow.setState(new PlanStartedState());
jobWorkflow.setState(new PlanPendingState());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
/**
* Describes a job which plan has been failed
*/
public class PlanFailedState implements RetryableState {
public class PlanFailedState extends RetryableState {
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,11 @@
public class PlanFinishedState implements JobState {
@Override
public void apply(JobWorkflow jobWorkflow) {
jobWorkflow.setState(new ApplyPendingState());
var job = jobWorkflow.getJob();
job.proceed(JobStatus.APPLY_STARTED);
job.setStatus(JobStatus.APPLY_PENDING);

var step = new Step(StepType.APPLY, job.getId());
job.getSteps().add(step);
jobWorkflow.setCurrentStep(step);
step.start();

jobWorkflow.setState(new ApplyStartedState());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.gaia_app.stacks.workflow.state;

import io.gaia_app.stacks.bo.JobStatus;
import io.gaia_app.stacks.workflow.JobWorkflow;

/**
* Describes a job which plan has not been started yet
*/
public class PlanPendingState implements JobState {

@Override
public void start(JobWorkflow jobWorkflow) {
var job = jobWorkflow.getJob();

job.start();
jobWorkflow.setState(new PlanStartedState());

jobWorkflow.getCurrentStep().start();
}
}

0 comments on commit b5d2867

Please sign in to comment.