From 9de330076554035b8c0009f632d7335ce5be8655 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Thu, 23 Jun 2022 14:31:41 -0500 Subject: [PATCH] QQQ-16 Checkpoint iteration on qqq processes --- .../core/actions/RunFunctionAction.java | 14 ++-- .../core/actions/RunProcessAction.java | 28 +++++-- .../core/instances/QInstanceEnricher.java | 45 ++++++++++- .../backend/core/interfaces/FunctionBody.java | 3 +- .../actions/metadata/MetaDataResult.java | 26 ++++++- .../actions/processes/RunFunctionRequest.java | 16 +++- .../actions/processes/RunProcessRequest.java | 41 +++++----- .../metadata/processes/QFunctionMetaData.java | 46 +++++++++-- .../metadata/processes/QProcessMetaData.java | 78 ++++++++++++++++++- .../qqq/backend/core/utils/TestUtils.java | 4 +- 10 files changed, 255 insertions(+), 46 deletions(-) diff --git a/src/main/java/com/kingsrook/qqq/backend/core/actions/RunFunctionAction.java b/src/main/java/com/kingsrook/qqq/backend/core/actions/RunFunctionAction.java index a47a7661..d91e2238 100644 --- a/src/main/java/com/kingsrook/qqq/backend/core/actions/RunFunctionAction.java +++ b/src/main/java/com/kingsrook/qqq/backend/core/actions/RunFunctionAction.java @@ -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 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")); diff --git a/src/main/java/com/kingsrook/qqq/backend/core/actions/RunProcessAction.java b/src/main/java/com/kingsrook/qqq/backend/core/actions/RunProcessAction.java index d74c1fdb..a3a595b3 100644 --- a/src/main/java/com/kingsrook/qqq/backend/core/actions/RunProcessAction.java +++ b/src/main/java/com/kingsrook/qqq/backend/core/actions/RunProcessAction.java @@ -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 ** diff --git a/src/main/java/com/kingsrook/qqq/backend/core/instances/QInstanceEnricher.java b/src/main/java/com/kingsrook/qqq/backend/core/instances/QInstanceEnricher.java index 8de70ac9..12b74f4f 100644 --- a/src/main/java/com/kingsrook/qqq/backend/core/instances/QInstanceEnricher.java +++ b/src/main/java/com/kingsrook/qqq/backend/core/instances/QInstanceEnricher.java @@ -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); + } + + + /******************************************************************************* ** *******************************************************************************/ diff --git a/src/main/java/com/kingsrook/qqq/backend/core/interfaces/FunctionBody.java b/src/main/java/com/kingsrook/qqq/backend/core/interfaces/FunctionBody.java index 2f0b6865..ab720fe3 100644 --- a/src/main/java/com/kingsrook/qqq/backend/core/interfaces/FunctionBody.java +++ b/src/main/java/com/kingsrook/qqq/backend/core/interfaces/FunctionBody.java @@ -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; } diff --git a/src/main/java/com/kingsrook/qqq/backend/core/model/actions/metadata/MetaDataResult.java b/src/main/java/com/kingsrook/qqq/backend/core/model/actions/metadata/MetaDataResult.java index 3ec4e6f0..7d11645c 100644 --- a/src/main/java/com/kingsrook/qqq/backend/core/model/actions/metadata/MetaDataResult.java +++ b/src/main/java/com/kingsrook/qqq/backend/core/model/actions/metadata/MetaDataResult.java @@ -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 tables; + Map tables; + Map processes; @@ -56,4 +58,26 @@ public class MetaDataResult extends AbstractQResult { this.tables = tables; } + + + + /******************************************************************************* + ** Getter for processes + ** + *******************************************************************************/ + public Map getProcesses() + { + return processes; + } + + + + /******************************************************************************* + ** Setter for processes + ** + *******************************************************************************/ + public void setProcesses(Map processes) + { + this.processes = processes; + } } diff --git a/src/main/java/com/kingsrook/qqq/backend/core/model/actions/processes/RunFunctionRequest.java b/src/main/java/com/kingsrook/qqq/backend/core/model/actions/processes/RunFunctionRequest.java index 67420b8a..6b8701b7 100644 --- a/src/main/java/com/kingsrook/qqq/backend/core/model/actions/processes/RunFunctionRequest.java +++ b/src/main/java/com/kingsrook/qqq/backend/core/model/actions/processes/RunFunctionRequest.java @@ -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(); + } + + + /******************************************************************************* ** *******************************************************************************/ diff --git a/src/main/java/com/kingsrook/qqq/backend/core/model/actions/processes/RunProcessRequest.java b/src/main/java/com/kingsrook/qqq/backend/core/model/actions/processes/RunProcessRequest.java index 17daab53..07bc1d18 100644 --- a/src/main/java/com/kingsrook/qqq/backend/core/model/actions/processes/RunProcessRequest.java +++ b/src/main/java/com/kingsrook/qqq/backend/core/model/actions/processes/RunProcessRequest.java @@ -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 records; - private Map 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 getRecords() { - return records; + return processState.getRecords(); } @@ -126,7 +126,7 @@ public class RunProcessRequest extends AbstractQRequest *******************************************************************************/ public void setRecords(List records) { - this.records = records; + this.processState.setRecords(records); } @@ -137,7 +137,7 @@ public class RunProcessRequest extends AbstractQRequest *******************************************************************************/ public RunProcessRequest withRecords(List records) { - this.records = records; + setRecords(records); return (this); } @@ -149,7 +149,7 @@ public class RunProcessRequest extends AbstractQRequest *******************************************************************************/ public Map getValues() { - return values; + return this.processState.getValues(); } @@ -160,7 +160,7 @@ public class RunProcessRequest extends AbstractQRequest *******************************************************************************/ public void setValues(Map values) { - this.values = values; + this.processState.setValues(values); } @@ -171,7 +171,7 @@ public class RunProcessRequest extends AbstractQRequest *******************************************************************************/ public RunProcessRequest withValues(Map 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; + } + } \ No newline at end of file diff --git a/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/processes/QFunctionMetaData.java b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/processes/QFunctionMetaData.java index 13cd4cde..40980c33 100644 --- a/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/processes/QFunctionMetaData.java +++ b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/processes/QFunctionMetaData.java @@ -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 getInputFields() + { + List 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 getOutputFields() + { + List rs = new ArrayList<>(); + if(outputMetaData != null && outputMetaData.getFieldList() != null) + { + rs.addAll(outputMetaData.getFieldList()); + } + return (rs); + } + } diff --git a/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/processes/QProcessMetaData.java b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/processes/QProcessMetaData.java index 5dd45167..52a7cd32 100644 --- a/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/processes/QProcessMetaData.java +++ b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/processes/QProcessMetaData.java @@ -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 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 getInputFields() + { + List 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 getOutputFields() + { + List rs = new ArrayList<>(); + if(functionList != null) + { + for(QFunctionMetaData function : functionList) + { + rs.addAll(function.getOutputFields()); + } + } + return (rs); + } } diff --git a/src/test/java/com/kingsrook/qqq/backend/core/utils/TestUtils.java b/src/test/java/com/kingsrook/qqq/backend/core/utils/TestUtils.java index 2e353096..d15e4b65 100644 --- a/src/test/java/com/kingsrook/qqq/backend/core/utils/TestUtils.java +++ b/src/test/java/com/kingsrook/qqq/backend/core/utils/TestUtils.java @@ -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"); }