From b83bac653126622ca4e8c5e86c82b77bb0a0de8c Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Fri, 22 Jul 2022 18:40:35 -0500 Subject: [PATCH] QQQ-28 updates for bulk actions --- pom.xml | 4 +- .../javalin/QJavalinProcessHandler.java | 49 +++++++++++++++++-- .../javalin/QJavalinImplementationTest.java | 3 +- 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index 70e32c14..f8d3c898 100644 --- a/pom.xml +++ b/pom.xml @@ -53,12 +53,12 @@ com.kingsrook.qqq qqq-backend-core - 0.2.0-SNAPSHOT + 0.2.0-20220722.233134-9 com.kingsrook.qqq qqq-backend-module-rdbms - 0.2.0-SNAPSHOT + 0.2.0-20220722.233524-9 test diff --git a/src/main/java/com/kingsrook/qqq/backend/javalin/QJavalinProcessHandler.java b/src/main/java/com/kingsrook/qqq/backend/javalin/QJavalinProcessHandler.java index 308634a9..60de405e 100644 --- a/src/main/java/com/kingsrook/qqq/backend/javalin/QJavalinProcessHandler.java +++ b/src/main/java/com/kingsrook/qqq/backend/javalin/QJavalinProcessHandler.java @@ -43,6 +43,7 @@ import com.kingsrook.qqq.backend.core.exceptions.QException; import com.kingsrook.qqq.backend.core.exceptions.QModuleDispatchException; import com.kingsrook.qqq.backend.core.exceptions.QUserFacingException; import com.kingsrook.qqq.backend.core.model.actions.processes.ProcessState; +import com.kingsrook.qqq.backend.core.model.actions.processes.QUploadedFile; import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessInput; import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessOutput; import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator; @@ -53,12 +54,16 @@ import com.kingsrook.qqq.backend.core.model.metadata.QInstance; import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData; import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData; import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; +import com.kingsrook.qqq.backend.core.state.StateType; +import com.kingsrook.qqq.backend.core.state.TempFileStateProvider; +import com.kingsrook.qqq.backend.core.state.UUIDAndTypeStateKey; import com.kingsrook.qqq.backend.core.utils.CollectionUtils; import com.kingsrook.qqq.backend.core.utils.ExceptionUtils; import com.kingsrook.qqq.backend.core.utils.JsonUtils; import com.kingsrook.qqq.backend.core.utils.StringUtils; import io.javalin.apibuilder.EndpointGroup; import io.javalin.http.Context; +import io.javalin.http.UploadedFile; import org.apache.commons.lang.NotImplementedException; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -216,7 +221,7 @@ public class QJavalinProcessHandler { Throwable rootException = ExceptionUtils.getRootException(exception); LOG.warn("Uncaught Exception in process", exception); - resultForCaller.put("error", "Original error message: " + rootException.getMessage()); + resultForCaller.put("error", "Error message: " + rootException.getMessage()); } } @@ -224,11 +229,14 @@ public class QJavalinProcessHandler /******************************************************************************* ** take values from query-string params, and put them into the run process request - ** todo - better from POST body, or with a "field-" type of prefix?? + ** todo - make query params have a "field-" type of prefix?? ** *******************************************************************************/ private static void populateRunProcessRequestWithValuesFromContext(Context context, RunProcessInput runProcessInput) throws IOException { + ////////////////////////// + // process query string // + ////////////////////////// for(Map.Entry> queryParam : context.queryParamMap().entrySet()) { String fieldName = queryParam.getKey(); @@ -239,6 +247,37 @@ public class QJavalinProcessHandler } } + //////////////////////////// + // process form/post body // + //////////////////////////// + for(Map.Entry> formParam : context.formParamMap().entrySet()) + { + String fieldName = formParam.getKey(); + List values = formParam.getValue(); + if(CollectionUtils.nullSafeHasContents(values)) + { + runProcessInput.addValue(fieldName, values.get(0)); + } + } + + //////////////////////////// + // process uploaded files // + //////////////////////////// + for(UploadedFile uploadedFile : context.uploadedFiles()) + { + QUploadedFile qUploadedFile = new QUploadedFile(); + qUploadedFile.setBytes(uploadedFile.getContent().readAllBytes()); + qUploadedFile.setFilename(uploadedFile.getFilename()); + + UUIDAndTypeStateKey key = new UUIDAndTypeStateKey(StateType.UPLOADED_FILE); + TempFileStateProvider.getInstance().put(key, qUploadedFile); + LOG.info("Stored uploaded file in TempFileStateProvider under key: " + key); + runProcessInput.addValue("uploadedFileKey", key); + } + + ///////////////////////////////////////////////////////////// + // deal with params that specify an initial-records filter // + ///////////////////////////////////////////////////////////// QQueryFilter initialRecordsFilter = buildProcessInitRecordsFilter(context, runProcessInput); if(initialRecordsFilter != null) { @@ -331,11 +370,12 @@ public class QJavalinProcessHandler *******************************************************************************/ public static void processStatus(Context context) { - Map resultForCaller = new HashMap<>(); - String processUUID = context.pathParam("processUUID"); String jobUUID = context.pathParam("jobUUID"); + Map resultForCaller = new HashMap<>(); + resultForCaller.put("processUUID", processUUID); + LOG.info("Request for status of process " + processUUID + ", job " + jobUUID); Optional optionalJobStatus = new AsyncJobManager().getJobStatus(jobUUID); if(optionalJobStatus.isEmpty()) @@ -412,6 +452,7 @@ public class QJavalinProcessHandler Map resultForCaller = new HashMap<>(); List recordPage = CollectionUtils.safelyGetPage(records, skip, limit); resultForCaller.put("records", recordPage); + resultForCaller.put("totalRecords", records.size()); context.result(JsonUtils.toJson(resultForCaller)); } catch(Exception e) diff --git a/src/test/java/com/kingsrook/qqq/backend/javalin/QJavalinImplementationTest.java b/src/test/java/com/kingsrook/qqq/backend/javalin/QJavalinImplementationTest.java index 459ff2bb..d0f7b78d 100644 --- a/src/test/java/com/kingsrook/qqq/backend/javalin/QJavalinImplementationTest.java +++ b/src/test/java/com/kingsrook/qqq/backend/javalin/QJavalinImplementationTest.java @@ -362,8 +362,7 @@ class QJavalinImplementationTest extends QJavalinTestBase JSONObject jsonObject = JsonUtils.toJSONObject(response.getBody()); assertNotNull(jsonObject); - assertEquals(1, jsonObject.getJSONArray("records").length()); - assertEquals(3, jsonObject.getJSONArray("records").getJSONObject(0).getJSONObject("values").getInt("id")); + assertEquals(1, jsonObject.getInt("deletedRecordCount")); TestUtils.runTestSql("SELECT id FROM person", (rs -> { int rowsFound = 0; while(rs.next())