QQQ-16 Checkpoint iteration on qqq processes

This commit is contained in:
2022-06-23 14:31:41 -05:00
parent bb2110ea08
commit 9de3300765
10 changed files with 255 additions and 46 deletions

View File

@ -37,7 +37,6 @@ import com.kingsrook.qqq.backend.core.model.metadata.QFieldMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.processes.QFunctionInputMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.processes.QFunctionMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.processes.QRecordListMetaData;
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
@ -56,7 +55,7 @@ public class RunFunctionAction
ActionHelper.validateSession(runFunctionRequest);
///////////////////////////////////////////////////////
// todo - shouldn't meta-data validation catch this? //
//
///////////////////////////////////////////////////////
QProcessMetaData process = runFunctionRequest.getInstance().getProcess(runFunctionRequest.getProcessName());
if(process == null)
@ -92,6 +91,10 @@ public class RunFunctionAction
private void ensureInputFieldsAreInRequest(RunFunctionRequest runFunctionRequest, QFunctionMetaData function)
{
QFunctionInputMetaData inputMetaData = function.getInputMetaData();
if (inputMetaData == null)
{
return;
}
List<QFieldMetaData> fieldsToGet = new ArrayList<>();
for(QFieldMetaData field : inputMetaData.getFieldList())
@ -124,8 +127,7 @@ public class RunFunctionAction
private void ensureRecordsAreInRequest(RunFunctionRequest runFunctionRequest, QFunctionMetaData function) throws QException
{
QFunctionInputMetaData inputMetaData = function.getInputMetaData();
QRecordListMetaData recordListMetaData = inputMetaData.getRecordListMetaData();
if(recordListMetaData != null)
if(inputMetaData != null && inputMetaData.getRecordListMetaData() != null)
{
if(CollectionUtils.nullSafeIsEmpty(runFunctionRequest.getRecords()))
{
@ -157,8 +159,8 @@ public class RunFunctionAction
{
runFunctionResult.seedFromRequest(runFunctionRequest);
Class<?> codeClass = Class.forName(code.getName());
Object codeObject = codeClass.getConstructor().newInstance();
Class<?> codeClass = Class.forName(code.getName());
Object codeObject = codeClass.getConstructor().newInstance();
if(!(codeObject instanceof FunctionBody functionBodyCodeObject))
{
throw (new QException("The supplied code [" + codeClass.getName() + "] is not an instance of FunctionBody"));

View File

@ -50,9 +50,6 @@ public class RunProcessAction
{
ActionHelper.validateSession(runProcessRequest);
///////////////////////////////////////////////////////
// todo - shouldn't meta-data validation catch this? //
///////////////////////////////////////////////////////
QProcessMetaData process = runProcessRequest.getInstance().getProcess(runProcessRequest.getProcessName());
if(process == null)
{
@ -61,7 +58,7 @@ public class RunProcessAction
RunProcessResult runProcessResult = new RunProcessResult();
UUIDStateKey stateKey = new UUIDStateKey();
UUIDStateKey stateKey = new UUIDStateKey();
RunFunctionResult lastFunctionResult = null;
// todo - custom routing?
@ -70,8 +67,18 @@ public class RunProcessAction
{
RunFunctionRequest runFunctionRequest = new RunFunctionRequest(runProcessRequest.getInstance());
if(lastFunctionResult != null)
if(lastFunctionResult == null)
{
///////////////////////////////////////////////////////////////////////////////////////////////////////
// for the first request, load state from the run process request to prime the run function request. //
///////////////////////////////////////////////////////////////////////////////////////////////////////
primeFunction(runProcessRequest, runFunctionRequest);
}
else
{
////////////////////////////////////////////////////////////////////////////////////////
// for functions after the first one, load from state management to prime the request //
////////////////////////////////////////////////////////////////////////////////////////
loadState(stateKey, runFunctionRequest);
}
@ -123,6 +130,17 @@ public class RunProcessAction
/*******************************************************************************
** Copy data (the state) down from the run-process request, down into the run-
** function request.
*******************************************************************************/
private void primeFunction(RunProcessRequest runProcessRequest, RunFunctionRequest runFunctionRequest)
{
runFunctionRequest.seedFromRunProcessRequest(runProcessRequest);
}
/*******************************************************************************
** Load the process state into a function request from the state provider
**

View File

@ -26,6 +26,8 @@ import java.util.Locale;
import com.kingsrook.qqq.backend.core.model.metadata.QFieldMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
import com.kingsrook.qqq.backend.core.model.metadata.QTableMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.processes.QFunctionMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData;
import com.kingsrook.qqq.backend.core.utils.StringUtils;
@ -41,10 +43,15 @@ public class QInstanceEnricher
*******************************************************************************/
public void enrich(QInstance qInstance)
{
if (qInstance.getTables() != null)
if(qInstance.getTables() != null)
{
qInstance.getTables().values().forEach(this::enrich);
}
if(qInstance.getProcesses() != null)
{
qInstance.getProcesses().values().forEach(this::enrich);
}
}
@ -59,7 +66,7 @@ public class QInstanceEnricher
table.setLabel(nameToLabel(table.getName()));
}
if (table.getFields() != null)
if(table.getFields() != null)
{
table.getFields().values().forEach(this::enrich);
}
@ -67,6 +74,40 @@ public class QInstanceEnricher
/*******************************************************************************
**
*******************************************************************************/
private void enrich(QProcessMetaData process)
{
if(!StringUtils.hasContent(process.getLabel()))
{
process.setLabel(nameToLabel(process.getName()));
}
if(process.getFunctionList() != null)
{
process.getFunctionList().forEach(this::enrich);
}
}
/*******************************************************************************
**
*******************************************************************************/
private void enrich(QFunctionMetaData function)
{
if(!StringUtils.hasContent(function.getLabel()))
{
function.setLabel(nameToLabel(function.getName()));
}
function.getInputFields().forEach(this::enrich);
function.getOutputFields().forEach(this::enrich);
}
/*******************************************************************************
**
*******************************************************************************/

View File

@ -22,6 +22,7 @@
package com.kingsrook.qqq.backend.core.interfaces;
import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.model.actions.processes.RunFunctionRequest;
import com.kingsrook.qqq.backend.core.model.actions.processes.RunFunctionResult;
@ -34,5 +35,5 @@ public interface FunctionBody
/*******************************************************************************
** TODO - document!
*******************************************************************************/
void run(RunFunctionRequest runFunctionRequest, RunFunctionResult runFunctionResult);
void run(RunFunctionRequest runFunctionRequest, RunFunctionResult runFunctionResult) throws QException;
}

View File

@ -24,6 +24,7 @@ package com.kingsrook.qqq.backend.core.model.actions.metadata;
import java.util.Map;
import com.kingsrook.qqq.backend.core.model.actions.AbstractQResult;
import com.kingsrook.qqq.backend.core.model.metadata.frontend.QFrontendProcessMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.frontend.QFrontendTableMetaData;
@ -33,7 +34,8 @@ import com.kingsrook.qqq.backend.core.model.metadata.frontend.QFrontendTableMeta
*******************************************************************************/
public class MetaDataResult extends AbstractQResult
{
Map<String, QFrontendTableMetaData> tables;
Map<String, QFrontendTableMetaData> tables;
Map<String, QFrontendProcessMetaData> processes;
@ -56,4 +58,26 @@ public class MetaDataResult extends AbstractQResult
{
this.tables = tables;
}
/*******************************************************************************
** Getter for processes
**
*******************************************************************************/
public Map<String, QFrontendProcessMetaData> getProcesses()
{
return processes;
}
/*******************************************************************************
** Setter for processes
**
*******************************************************************************/
public void setProcesses(Map<String, QFrontendProcessMetaData> processes)
{
this.processes = processes;
}
}

View File

@ -38,9 +38,9 @@ import com.kingsrook.qqq.backend.core.model.metadata.processes.QFunctionMetaData
*******************************************************************************/
public class RunFunctionRequest extends AbstractQRequest
{
private ProcessState processState;
private String processName;
private String functionName;
private ProcessState processState;
private String processName;
private String functionName;
private QProcessCallback callback;
@ -78,6 +78,16 @@ public class RunFunctionRequest extends AbstractQRequest
/*******************************************************************************
**
*******************************************************************************/
public void seedFromRunProcessRequest(RunProcessRequest runProcessRequest)
{
this.processState = runProcessRequest.getProcessState();
}
/*******************************************************************************
**
*******************************************************************************/

View File

@ -23,7 +23,6 @@ package com.kingsrook.qqq.backend.core.model.actions.processes;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.kingsrook.qqq.backend.core.callbacks.QProcessCallback;
@ -40,9 +39,8 @@ import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData;
public class RunProcessRequest extends AbstractQRequest
{
private String processName;
private List<QRecord> records;
private Map<String, Serializable> values;
private QProcessCallback callback;
private ProcessState processState;
@ -51,6 +49,7 @@ public class RunProcessRequest extends AbstractQRequest
*******************************************************************************/
public RunProcessRequest()
{
processState = new ProcessState();
}
@ -61,6 +60,7 @@ public class RunProcessRequest extends AbstractQRequest
public RunProcessRequest(QInstance instance)
{
super(instance);
processState = new ProcessState();
}
@ -115,7 +115,7 @@ public class RunProcessRequest extends AbstractQRequest
*******************************************************************************/
public List<QRecord> getRecords()
{
return records;
return processState.getRecords();
}
@ -126,7 +126,7 @@ public class RunProcessRequest extends AbstractQRequest
*******************************************************************************/
public void setRecords(List<QRecord> records)
{
this.records = records;
this.processState.setRecords(records);
}
@ -137,7 +137,7 @@ public class RunProcessRequest extends AbstractQRequest
*******************************************************************************/
public RunProcessRequest withRecords(List<QRecord> records)
{
this.records = records;
setRecords(records);
return (this);
}
@ -149,7 +149,7 @@ public class RunProcessRequest extends AbstractQRequest
*******************************************************************************/
public Map<String, Serializable> getValues()
{
return values;
return this.processState.getValues();
}
@ -160,7 +160,7 @@ public class RunProcessRequest extends AbstractQRequest
*******************************************************************************/
public void setValues(Map<String, Serializable> values)
{
this.values = values;
this.processState.setValues(values);
}
@ -171,7 +171,7 @@ public class RunProcessRequest extends AbstractQRequest
*******************************************************************************/
public RunProcessRequest withValues(Map<String, Serializable> values)
{
this.values = values;
this.processState.setValues(values);
return (this);
}
@ -183,11 +183,7 @@ public class RunProcessRequest extends AbstractQRequest
*******************************************************************************/
public RunProcessRequest addValue(String fieldName, Serializable value)
{
if(this.values == null)
{
this.values = new HashMap<>();
}
this.values.put(fieldName, value);
this.processState.getValues().put(fieldName, value);
return (this);
}
@ -233,11 +229,7 @@ public class RunProcessRequest extends AbstractQRequest
*******************************************************************************/
public Serializable getValue(String fieldName)
{
if(values == null)
{
return (null);
}
return (values.get(fieldName));
return (this.processState.getValues().get(fieldName));
}
@ -262,4 +254,15 @@ public class RunProcessRequest extends AbstractQRequest
return ((Integer) getValue(fieldName));
}
/*******************************************************************************
** Accessor for processState - protected, because we generally want to access
** its members through wrapper methods, we think
**
*******************************************************************************/
protected ProcessState getProcessState()
{
return processState;
}
}

View File

@ -22,7 +22,10 @@
package com.kingsrook.qqq.backend.core.model.metadata.processes;
import java.util.ArrayList;
import java.util.List;
import com.kingsrook.qqq.backend.core.model.metadata.QCodeReference;
import com.kingsrook.qqq.backend.core.model.metadata.QFieldMetaData;
/*******************************************************************************
@ -31,12 +34,12 @@ import com.kingsrook.qqq.backend.core.model.metadata.QCodeReference;
*******************************************************************************/
public class QFunctionMetaData
{
private String name;
private String label;
private QFunctionInputMetaData inputMetaData;
private String name;
private String label;
private QFunctionInputMetaData inputMetaData;
private QFunctionOutputMetaData outputMetaData;
private QCodeReference code;
private QOutputView outputView;
private QCodeReference code;
private QOutputView outputView;
@ -171,7 +174,7 @@ public class QFunctionMetaData
public QFunctionMetaData withOutputMetaData(QFunctionOutputMetaData outputMetaData)
{
this.outputMetaData = outputMetaData;
return(this);
return (this);
}
@ -241,4 +244,35 @@ public class QFunctionMetaData
this.outputView = outputView;
return (this);
}
/*******************************************************************************
** Get a list of all of the input fields used by this function
*******************************************************************************/
public List<QFieldMetaData> getInputFields()
{
List<QFieldMetaData> rs = new ArrayList<>();
if(inputMetaData != null && inputMetaData.getFieldList() != null)
{
rs.addAll(inputMetaData.getFieldList());
}
return (rs);
}
/*******************************************************************************
** Get a list of all of the output fields used by this function
*******************************************************************************/
public List<QFieldMetaData> getOutputFields()
{
List<QFieldMetaData> rs = new ArrayList<>();
if(outputMetaData != null && outputMetaData.getFieldList() != null)
{
rs.addAll(outputMetaData.getFieldList());
}
return (rs);
}
}

View File

@ -24,6 +24,7 @@ package com.kingsrook.qqq.backend.core.model.metadata.processes;
import java.util.ArrayList;
import java.util.List;
import com.kingsrook.qqq.backend.core.model.metadata.QFieldMetaData;
/*******************************************************************************
@ -32,8 +33,9 @@ import java.util.List;
*******************************************************************************/
public class QProcessMetaData
{
private String name;
private String tableName;
private String name;
private String label;
private String tableName;
private List<QFunctionMetaData> functionList;
@ -70,6 +72,42 @@ public class QProcessMetaData
return (this);
}
/*******************************************************************************
** Getter for label
**
*******************************************************************************/
public String getLabel()
{
return label;
}
/*******************************************************************************
** Setter for label
**
*******************************************************************************/
public void setLabel(String label)
{
this.label = label;
}
/*******************************************************************************
** Setter for label
**
*******************************************************************************/
public QProcessMetaData withLabel(String label)
{
this.label = label;
return (this);
}
/*******************************************************************************
** Getter for tableName
**
@ -169,4 +207,40 @@ public class QProcessMetaData
return (null);
}
/*******************************************************************************
** Get a list of all of the input fields used by all the functions in this process.
*******************************************************************************/
public List<QFieldMetaData> getInputFields()
{
List<QFieldMetaData> rs = new ArrayList<>();
if(functionList != null)
{
for(QFunctionMetaData function : functionList)
{
rs.addAll(function.getInputFields());
}
}
return (rs);
}
/*******************************************************************************
** Get a list of all of the output fields used by all the functions in this process.
*******************************************************************************/
public List<QFieldMetaData> getOutputFields()
{
List<QFieldMetaData> rs = new ArrayList<>();
if(functionList != null)
{
for(QFunctionMetaData function : functionList)
{
rs.addAll(function.getOutputFields());
}
}
return (rs);
}
}

View File

@ -51,6 +51,8 @@ import com.kingsrook.qqq.backend.core.modules.mock.MockAuthenticationModule;
*******************************************************************************/
public class TestUtils
{
public static String DEFAULT_BACKEND_NAME = "default";
/*******************************************************************************
** Define the instance used in standard tests.
**
@ -102,7 +104,7 @@ public class TestUtils
public static QBackendMetaData defineBackend()
{
return new QBackendMetaData()
.withName("default")
.withName(DEFAULT_BACKEND_NAME)
.withBackendType("mock");
}