All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.nflow.tests.demo.workflow.ProcessCreditApplicationWorkflow Maven / Gradle / Ivy

The newest version!
package io.nflow.tests.demo.workflow;

import static io.nflow.engine.workflow.definition.NextAction.moveToState;
import static io.nflow.engine.workflow.definition.NextAction.moveToStateAfter;
import static io.nflow.engine.workflow.definition.NextAction.retryAfter;
import static io.nflow.engine.workflow.definition.WorkflowStateType.end;
import static io.nflow.engine.workflow.definition.WorkflowStateType.manual;
import static io.nflow.engine.workflow.definition.WorkflowStateType.start;
import static io.nflow.tests.demo.workflow.CreditDecisionWorkflow.APPROVED;
import static io.nflow.tests.demo.workflow.CreditDecisionWorkflow.CREDIT_DECISION_TYPE;
import static io.nflow.tests.demo.workflow.CreditDecisionWorkflow.REJECTED;
import static io.nflow.tests.demo.workflow.CreditDecisionWorkflow.VAR_REQUEST_DATA;
import static org.joda.time.DateTime.now;

import org.springframework.stereotype.Component;

import io.nflow.engine.workflow.curated.State;
import io.nflow.engine.workflow.definition.Mutable;
import io.nflow.engine.workflow.definition.NextAction;
import io.nflow.engine.workflow.definition.StateExecution;
import io.nflow.engine.workflow.definition.StateVar;
import io.nflow.engine.workflow.definition.WorkflowDefinition;
import io.nflow.engine.workflow.definition.WorkflowState;
import io.nflow.engine.workflow.instance.WorkflowInstance;
import io.nflow.tests.demo.domain.CreateCreditApplicationRequest;
import io.nflow.tests.demo.domain.CreateLoanResponse;
import io.nflow.tests.demo.domain.CreditDecisionData;
import io.nflow.tests.demo.domain.QueryCreditApplicationResponse;

@Component
public class ProcessCreditApplicationWorkflow extends WorkflowDefinition {

  private static final String CREDIT_APPLICATION_KEY = "credit_application_key";
  private static final String LOAN_KEY = "loan_key";
  private static final String CREDIT_DECISION_RESULT = "credit_decision_result";

  private static final WorkflowState CREATE_CREDIT_APPLICATION = new State("createCreditApplication", start,
      "Create new credit application");
  private static final WorkflowState START_CREDIT_DECISION_WORKFLOW = new State("startCreditDecisionWorkflow",
      "Start credit decision workflow");
  private static final WorkflowState WAIT_CREDIT_DECISION_WORKFLOW = new State("waitCreditDecisionWorkflow",
      "Poll for result of credit decision process");
  private static final WorkflowState CREATE_LOAN = new State("createLoan", "Create the loan based on application");
  private static final WorkflowState TRANSFER_MONEY = new State("transferMoney", "Transfer money to deposit account");
  private static final WorkflowState TRANSFER_MONEY_FAILED = new State("transferMoneyFailed",
      "Transfering money failed, reverse creating loan");
  private static final WorkflowState UPDATE_CREDIT_APPLICATION = new State("updateCreditApplication",
      "Update the credit application state");
  private static final WorkflowState MANUAL_PROCESSING = new State("manualProcessing", manual,
      "Process must be handled manually because of an unexpected situation");
  private static final WorkflowState DONE = new State("done", end, "Credit application has been completed.");

  @SuppressWarnings("this-escape")
  public ProcessCreditApplicationWorkflow() {
    super("processCreditApplication", CREATE_CREDIT_APPLICATION, MANUAL_PROCESSING);
    setName("Process credit application");
    setDescription("Makes credit decision, creates loan, deposits the money and updates credit application");
    permit(CREATE_CREDIT_APPLICATION, START_CREDIT_DECISION_WORKFLOW);
    permit(START_CREDIT_DECISION_WORKFLOW, WAIT_CREDIT_DECISION_WORKFLOW);
    permit(WAIT_CREDIT_DECISION_WORKFLOW, CREATE_LOAN);
    permit(WAIT_CREDIT_DECISION_WORKFLOW, UPDATE_CREDIT_APPLICATION);
    permit(CREATE_LOAN, TRANSFER_MONEY);
    permit(TRANSFER_MONEY, UPDATE_CREDIT_APPLICATION, TRANSFER_MONEY_FAILED);
    permit(TRANSFER_MONEY_FAILED, MANUAL_PROCESSING);
    permit(UPDATE_CREDIT_APPLICATION, DONE);
  }

  public NextAction createCreditApplication(StateExecution execution,
      @StateVar(readOnly = true, value = "requestData") CreateCreditApplicationRequest request,
      @StateVar(value = CREDIT_APPLICATION_KEY) Mutable application) {
    request.processWorkflowId = execution.getWorkflowInstanceId();
    application.setVal(new QueryCreditApplicationResponse());
    return moveToState(START_CREDIT_DECISION_WORKFLOW, "Credit application created");
  }

  public NextAction startCreditDecisionWorkflow(StateExecution execution,
      @StateVar(value = CREDIT_APPLICATION_KEY) QueryCreditApplicationResponse application) {
    CreditDecisionData creditDecisionData = new CreditDecisionData();
    creditDecisionData.clientId = application.clientId;
    creditDecisionData.amount = application.amount;
    execution.addChildWorkflows(execution.workflowInstanceBuilder().setType(CREDIT_DECISION_TYPE)
        .setBusinessKey(application.applicationId).putStateVariable(VAR_REQUEST_DATA, creditDecisionData).build());
    return moveToStateAfter(WAIT_CREDIT_DECISION_WORKFLOW, now().plusMonths(1), "Credit decision request submitted");
  }

  public NextAction waitCreditDecisionWorkflow(StateExecution execution,
      @StateVar(value = CREDIT_DECISION_RESULT) Mutable creditDecisionResult) {
    WorkflowInstance decisionWorkflow = execution.getAllChildWorkflows().get(0);
    creditDecisionResult.setVal(decisionWorkflow.state);
    if (APPROVED.name().equals(decisionWorkflow.state)) {
      return moveToState(CREATE_LOAN, "Credit decision approved");
    }
    if (REJECTED.name().equals(decisionWorkflow.state)) {
      return moveToState(UPDATE_CREDIT_APPLICATION, "Credit decision rejected");
    }
    return retryAfter(now().plusSeconds(20), "Credit decision workflow in state " + decisionWorkflow.state);
  }

  public NextAction createLoan(@SuppressWarnings("unused") StateExecution execution,
      @StateVar(value = LOAN_KEY) Mutable loan) {
    CreateLoanResponse response = new CreateLoanResponse();
    response.success = true;
    loan.setVal(response);
    return moveToState(TRANSFER_MONEY, "Loan created");
  }

  public NextAction transferMoney(@SuppressWarnings("unused") StateExecution execution) {
    return moveToState(UPDATE_CREDIT_APPLICATION, "Money transferred");
  }

  public NextAction updateCreditApplication(@SuppressWarnings("unused") StateExecution execution) {
    return moveToState(DONE, "Credit application updated");
  }

  public NextAction transferMoneyFailed(@SuppressWarnings("unused") StateExecution execution) {
    return moveToState(MANUAL_PROCESSING, "Loan cancelled");
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy