CE-1180 Better built-in support for processes with dynamic flows - that is:

- in a backendStepOutput, you can set overrideLastStepName and call updateStepList
- those values then flow through RunProcessAction to the runProcessOutput, then out through the javalin to the frontend.
This commit is contained in:
2024-05-10 15:16:59 -05:00
parent f009d50631
commit 889697f86f
6 changed files with 522 additions and 10 deletions

View File

@ -190,7 +190,25 @@ public class RunProcessAction
// Run backend steps //
///////////////////////
LOG.debug("Running backend step [" + step.getName() + "] in process [" + process.getName() + "]");
runBackendStep(runProcessInput, process, runProcessOutput, stateKey, backendStepMetaData, process, processState);
RunBackendStepOutput runBackendStepOutput = runBackendStep(runProcessInput, process, runProcessOutput, stateKey, backendStepMetaData, process, processState);
/////////////////////////////////////////////////////////////////////////////////////////
// if the step returned an override lastStepName, use that to determine how we proceed //
/////////////////////////////////////////////////////////////////////////////////////////
if(runBackendStepOutput.getOverrideLastStepName() != null)
{
LOG.debug("Process step [" + lastStepName + "] returned an overrideLastStepName [" + runBackendStepOutput.getOverrideLastStepName() + "]!");
lastStepName = runBackendStepOutput.getOverrideLastStepName();
}
/////////////////////////////////////////////////////////////////////////////////////////////
// similarly, if the step produced an updatedFrontendStepList, propagate that data outward //
/////////////////////////////////////////////////////////////////////////////////////////////
if(runBackendStepOutput.getUpdatedFrontendStepList() != null)
{
LOG.debug("Process step [" + lastStepName + "] generated an updatedFrontendStepList [" + runBackendStepOutput.getUpdatedFrontendStepList().stream().map(s -> s.getName()).toList() + "]!");
runProcessOutput.setUpdatedFrontendStepList(runBackendStepOutput.getUpdatedFrontendStepList());
}
}
else
{
@ -339,7 +357,7 @@ public class RunProcessAction
/*******************************************************************************
** Run a single backend step.
*******************************************************************************/
private void runBackendStep(RunProcessInput runProcessInput, QProcessMetaData process, RunProcessOutput runProcessOutput, UUIDAndTypeStateKey stateKey, QBackendStepMetaData backendStep, QProcessMetaData qProcessMetaData, ProcessState processState) throws Exception
private RunBackendStepOutput runBackendStep(RunProcessInput runProcessInput, QProcessMetaData process, RunProcessOutput runProcessOutput, UUIDAndTypeStateKey stateKey, QBackendStepMetaData backendStep, QProcessMetaData qProcessMetaData, ProcessState processState) throws Exception
{
RunBackendStepInput runBackendStepInput = new RunBackendStepInput(processState);
runBackendStepInput.setProcessName(process.getName());
@ -368,14 +386,16 @@ public class RunProcessAction
runBackendStepInput.setBasepullLastRunTime((Instant) runProcessInput.getValues().get(BASEPULL_LAST_RUNTIME_KEY));
}
RunBackendStepOutput lastFunctionResult = new RunBackendStepAction().execute(runBackendStepInput);
storeState(stateKey, lastFunctionResult.getProcessState());
RunBackendStepOutput runBackendStepOutput = new RunBackendStepAction().execute(runBackendStepInput);
storeState(stateKey, runBackendStepOutput.getProcessState());
if(lastFunctionResult.getException() != null)
if(runBackendStepOutput.getException() != null)
{
runProcessOutput.setException(lastFunctionResult.getException());
throw (lastFunctionResult.getException());
runProcessOutput.setException(runBackendStepOutput.getException());
throw (runBackendStepOutput.getException());
}
return (runBackendStepOutput);
}

View File

@ -27,10 +27,14 @@ import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.kingsrook.qqq.backend.core.context.QContext;
import com.kingsrook.qqq.backend.core.exceptions.QRuntimeException;
import com.kingsrook.qqq.backend.core.model.actions.AbstractActionOutput;
import com.kingsrook.qqq.backend.core.model.actions.audits.AuditInput;
import com.kingsrook.qqq.backend.core.model.actions.audits.AuditSingleInput;
import com.kingsrook.qqq.backend.core.model.data.QRecord;
import com.kingsrook.qqq.backend.core.model.metadata.processes.QFrontendStepMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData;
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
@ -40,9 +44,14 @@ import com.kingsrook.qqq.backend.core.utils.ValueUtils;
*******************************************************************************/
public class RunBackendStepOutput extends AbstractActionOutput implements Serializable
{
private String processName;
private ProcessState processState;
private Exception exception; // todo - make optional
private String overrideLastStepName;
private List<QFrontendStepMetaData> updatedFrontendStepList = null;
private List<AuditInput> auditInputList = new ArrayList<>();
@ -78,6 +87,7 @@ public class RunBackendStepOutput extends AbstractActionOutput implements Serial
public void seedFromRequest(RunBackendStepInput runBackendStepInput)
{
this.processState = runBackendStepInput.getProcessState();
this.processName = runBackendStepInput.getProcessName();
}
@ -312,4 +322,122 @@ public class RunBackendStepOutput extends AbstractActionOutput implements Serial
auditInput.addAuditSingleInput(auditSingleInput);
}
/*******************************************************************************
** Getter for overrideLastStepName
*******************************************************************************/
public String getOverrideLastStepName()
{
return (this.overrideLastStepName);
}
/*******************************************************************************
** Setter for overrideLastStepName
*******************************************************************************/
public void setOverrideLastStepName(String overrideLastStepName)
{
this.overrideLastStepName = overrideLastStepName;
}
/*******************************************************************************
** Fluent setter for overrideLastStepName
*******************************************************************************/
public RunBackendStepOutput withOverrideLastStepName(String overrideLastStepName)
{
this.overrideLastStepName = overrideLastStepName;
return (this);
}
/*******************************************************************************
**
*******************************************************************************/
public void updateStepList(List<String> stepList)
{
getProcessState().setStepList(stepList);
if(processName == null)
{
throw (new QRuntimeException("ProcessName was not set in this object, therefore updateStepList cannot complete successfully. Try to manually call setProcessName as a work around."));
}
QProcessMetaData processMetaData = QContext.getQInstance().getProcess(processName);
ArrayList<QFrontendStepMetaData> updatedFrontendStepList = new ArrayList<>(stepList.stream()
.map(name -> processMetaData.getStep(name))
.filter(step -> step instanceof QFrontendStepMetaData)
.map(step -> (QFrontendStepMetaData) step)
.toList());
setUpdatedFrontendStepList(updatedFrontendStepList);
}
/*******************************************************************************
** Getter for processName
*******************************************************************************/
public String getProcessName()
{
return (this.processName);
}
/*******************************************************************************
** Setter for processName
*******************************************************************************/
public void setProcessName(String processName)
{
this.processName = processName;
}
/*******************************************************************************
** Fluent setter for processName
*******************************************************************************/
public RunBackendStepOutput withProcessName(String processName)
{
this.processName = processName;
return (this);
}
/*******************************************************************************
** Getter for updatedFrontendStepList
*******************************************************************************/
public List<QFrontendStepMetaData> getUpdatedFrontendStepList()
{
return (this.updatedFrontendStepList);
}
/*******************************************************************************
** Setter for updatedFrontendStepList
*******************************************************************************/
public void setUpdatedFrontendStepList(List<QFrontendStepMetaData> updatedFrontendStepList)
{
this.updatedFrontendStepList = updatedFrontendStepList;
}
/*******************************************************************************
** Fluent setter for updatedFrontendStepList
*******************************************************************************/
public RunBackendStepOutput withUpdatedFrontendStepList(List<QFrontendStepMetaData> updatedFrontendStepList)
{
this.updatedFrontendStepList = updatedFrontendStepList;
return (this);
}
}

View File

@ -32,6 +32,7 @@ import java.util.Map;
import java.util.Optional;
import com.kingsrook.qqq.backend.core.model.actions.AbstractActionOutput;
import com.kingsrook.qqq.backend.core.model.data.QRecord;
import com.kingsrook.qqq.backend.core.model.metadata.processes.QFrontendStepMetaData;
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
@ -45,6 +46,8 @@ public class RunProcessOutput extends AbstractActionOutput implements Serializab
private String processUUID;
private Optional<Exception> exception = Optional.empty();
private List<QFrontendStepMetaData> updatedFrontendStepList = null;
/*******************************************************************************
@ -327,4 +330,36 @@ public class RunProcessOutput extends AbstractActionOutput implements Serializab
{
return exception;
}
/*******************************************************************************
** Getter for updatedFrontendStepList
*******************************************************************************/
public List<QFrontendStepMetaData> getUpdatedFrontendStepList()
{
return (this.updatedFrontendStepList);
}
/*******************************************************************************
** Setter for updatedFrontendStepList
*******************************************************************************/
public void setUpdatedFrontendStepList(List<QFrontendStepMetaData> updatedFrontendStepList)
{
this.updatedFrontendStepList = updatedFrontendStepList;
}
/*******************************************************************************
** Fluent setter for updatedFrontendStepList
*******************************************************************************/
public RunProcessOutput withUpdatedFrontendStepList(List<QFrontendStepMetaData> updatedFrontendStepList)
{
this.updatedFrontendStepList = updatedFrontendStepList;
return (this);
}
}