From fb69c60e104e5b92680c0f062dccae52391d17f0 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Tue, 23 Jan 2024 14:44:10 -0600 Subject: [PATCH] CE-781 - Add option to set secuirty key values in importFile & importRecord records dynamically through a QCodeReference to a Function --- ...esystemImporterProcessMetaDataBuilder.java | 14 ++++++ .../importer/FilesystemImporterStep.java | 39 +++++++++++++-- .../importer/FilesystemImporterStepTest.java | 50 +++++++++++++++++++ 3 files changed, 99 insertions(+), 4 deletions(-) diff --git a/qqq-backend-module-filesystem/src/main/java/com/kingsrook/qqq/backend/module/filesystem/processes/implementations/filesystem/importer/FilesystemImporterProcessMetaDataBuilder.java b/qqq-backend-module-filesystem/src/main/java/com/kingsrook/qqq/backend/module/filesystem/processes/implementations/filesystem/importer/FilesystemImporterProcessMetaDataBuilder.java index d90992a2..96e8c95b 100644 --- a/qqq-backend-module-filesystem/src/main/java/com/kingsrook/qqq/backend/module/filesystem/processes/implementations/filesystem/importer/FilesystemImporterProcessMetaDataBuilder.java +++ b/qqq-backend-module-filesystem/src/main/java/com/kingsrook/qqq/backend/module/filesystem/processes/implementations/filesystem/importer/FilesystemImporterProcessMetaDataBuilder.java @@ -23,6 +23,8 @@ package com.kingsrook.qqq.backend.module.filesystem.processes.implementations.fi import java.io.Serializable; +import java.util.function.Function; +import com.kingsrook.qqq.backend.core.model.data.QRecord; import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference; import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData; import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldType; @@ -62,6 +64,7 @@ public class FilesystemImporterProcessMetaDataBuilder extends AbstractProcessMet .withField(new QFieldMetaData(FilesystemImporterStep.FIELD_ARCHIVE_PATH, QFieldType.STRING)) .withField(new QFieldMetaData(FilesystemImporterStep.FIELD_IMPORT_SECURITY_FIELD_NAME, QFieldType.STRING)) .withField(new QFieldMetaData(FilesystemImporterStep.FIELD_IMPORT_SECURITY_FIELD_VALUE, QFieldType.STRING)) + .withField(new QFieldMetaData(FilesystemImporterStep.FIELD_IMPORT_SECURITY_VALUE_SUPPLIER, QFieldType.STRING)) // actually, QCodeReference, of type Function ))); } @@ -186,4 +189,15 @@ public class FilesystemImporterProcessMetaDataBuilder extends AbstractProcessMet return (this); } + + + /******************************************************************************* + ** + *******************************************************************************/ + public FilesystemImporterProcessMetaDataBuilder withImportSecurityValueSupplierFunction(Class> supplierFunction) + { + setInputFieldDefaultValue(FilesystemImporterStep.FIELD_IMPORT_SECURITY_VALUE_SUPPLIER, new QCodeReference(supplierFunction)); + return (this); + } + } diff --git a/qqq-backend-module-filesystem/src/main/java/com/kingsrook/qqq/backend/module/filesystem/processes/implementations/filesystem/importer/FilesystemImporterStep.java b/qqq-backend-module-filesystem/src/main/java/com/kingsrook/qqq/backend/module/filesystem/processes/implementations/filesystem/importer/FilesystemImporterStep.java index 5537c9fd..a8361281 100644 --- a/qqq-backend-module-filesystem/src/main/java/com/kingsrook/qqq/backend/module/filesystem/processes/implementations/filesystem/importer/FilesystemImporterStep.java +++ b/qqq-backend-module-filesystem/src/main/java/com/kingsrook/qqq/backend/module/filesystem/processes/implementations/filesystem/importer/FilesystemImporterStep.java @@ -33,7 +33,9 @@ import java.util.Map; import java.util.Objects; import java.util.TreeMap; import java.util.UUID; +import java.util.function.Function; import com.kingsrook.qqq.backend.core.actions.QBackendTransaction; +import com.kingsrook.qqq.backend.core.actions.customizers.QCodeLoader; import com.kingsrook.qqq.backend.core.actions.processes.BackendStep; import com.kingsrook.qqq.backend.core.actions.tables.InsertAction; import com.kingsrook.qqq.backend.core.actions.tables.QueryAction; @@ -41,6 +43,7 @@ import com.kingsrook.qqq.backend.core.adapters.CsvToQRecordAdapter; import com.kingsrook.qqq.backend.core.adapters.JsonToQRecordAdapter; import com.kingsrook.qqq.backend.core.context.QContext; import com.kingsrook.qqq.backend.core.exceptions.QException; +import com.kingsrook.qqq.backend.core.exceptions.QRuntimeException; import com.kingsrook.qqq.backend.core.logging.QLogger; import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput; import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutput; @@ -53,6 +56,7 @@ import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryInput; import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryOutput; import com.kingsrook.qqq.backend.core.model.data.QRecord; import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData; +import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference; import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; import com.kingsrook.qqq.backend.core.modules.backend.QBackendModuleDispatcher; import com.kingsrook.qqq.backend.core.utils.CollectionUtils; @@ -83,8 +87,9 @@ public class FilesystemImporterStep implements BackendStep public static final String FIELD_IMPORT_FILE_TABLE = "importFileTable"; public static final String FIELD_IMPORT_RECORD_TABLE = "importRecordTable"; - public static final String FIELD_IMPORT_SECURITY_FIELD_NAME = "importSecurityFieldName"; - public static final String FIELD_IMPORT_SECURITY_FIELD_VALUE = "importSecurityFieldValue"; + public static final String FIELD_IMPORT_SECURITY_FIELD_NAME = "importSecurityFieldName"; + public static final String FIELD_IMPORT_SECURITY_FIELD_VALUE = "importSecurityFieldValue"; + public static final String FIELD_IMPORT_SECURITY_VALUE_SUPPLIER = "importSecurityFieldSupplier"; public static final String FIELD_ARCHIVE_FILE_ENABLED = "archiveFileEnabled"; public static final String FIELD_ARCHIVE_TABLE_NAME = "archiveTableName"; @@ -93,6 +98,7 @@ public class FilesystemImporterStep implements BackendStep public static final String FIELD_UPDATE_FILE_IF_NAME_EXISTS = "updateFileIfNameExists"; + private Function securitySupplier = null; /******************************************************************************* @@ -267,9 +273,34 @@ public class FilesystemImporterStep implements BackendStep *******************************************************************************/ private void addSecurityValue(RunBackendStepInput runBackendStepInput, QRecord record) { - String securityField = runBackendStepInput.getValueString(FIELD_IMPORT_SECURITY_FIELD_NAME); - Serializable securityValue = runBackendStepInput.getValue(FIELD_IMPORT_SECURITY_FIELD_VALUE); + String securityField = runBackendStepInput.getValueString(FIELD_IMPORT_SECURITY_FIELD_NAME); + ///////////////////////////////////////////////////////////// + // if we're using a security supplier function, load it up // + ///////////////////////////////////////////////////////////// + QCodeReference securitySupplierReference = (QCodeReference) runBackendStepInput.getValue(FIELD_IMPORT_SECURITY_VALUE_SUPPLIER); + try + { + if(securitySupplierReference != null && securitySupplier == null) + { + securitySupplier = QCodeLoader.getAdHoc(Function.class, securitySupplierReference); + } + } + catch(Exception e) + { + throw (new QRuntimeException("Error loading Security Supplier Function from QCodeReference [" + securitySupplierReference + "]", e)); + } + + /////////////////////////////////////////////////////////////////////////////////////// + // either get the security value from the supplier, or the field value field's value // + /////////////////////////////////////////////////////////////////////////////////////// + Serializable securityValue = securitySupplier != null + ? securitySupplier.apply(record) + : runBackendStepInput.getValue(FIELD_IMPORT_SECURITY_FIELD_VALUE); + + //////////////////////////////////////////////////////////////////// + // if we have a field name and a value, then add it to the record // + //////////////////////////////////////////////////////////////////// if(StringUtils.hasContent(securityField) && securityValue != null) { record.setValue(securityField, securityValue); diff --git a/qqq-backend-module-filesystem/src/test/java/com/kingsrook/qqq/backend/module/filesystem/processes/implementations/filesystem/importer/FilesystemImporterStepTest.java b/qqq-backend-module-filesystem/src/test/java/com/kingsrook/qqq/backend/module/filesystem/processes/implementations/filesystem/importer/FilesystemImporterStepTest.java index 89801686..a4a36da5 100644 --- a/qqq-backend-module-filesystem/src/test/java/com/kingsrook/qqq/backend/module/filesystem/processes/implementations/filesystem/importer/FilesystemImporterStepTest.java +++ b/qqq-backend-module-filesystem/src/test/java/com/kingsrook/qqq/backend/module/filesystem/processes/implementations/filesystem/importer/FilesystemImporterStepTest.java @@ -23,7 +23,9 @@ package com.kingsrook.qqq.backend.module.filesystem.processes.implementations.fi import java.io.File; +import java.io.Serializable; import java.time.LocalDateTime; +import java.util.function.Function; import com.kingsrook.qqq.backend.core.actions.processes.RunProcessAction; import com.kingsrook.qqq.backend.core.actions.tables.CountAction; import com.kingsrook.qqq.backend.core.actions.tables.GetAction; @@ -33,6 +35,7 @@ import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessInput; import com.kingsrook.qqq.backend.core.model.actions.tables.count.CountInput; import com.kingsrook.qqq.backend.core.model.actions.tables.get.GetInput; import com.kingsrook.qqq.backend.core.model.data.QRecord; +import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference; import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData; import com.kingsrook.qqq.backend.core.modules.backend.implementations.memory.MemoryRecordStore; import com.kingsrook.qqq.backend.module.filesystem.TestUtils; @@ -261,4 +264,51 @@ class FilesystemImporterStepTest extends FilesystemActionTest assertEquals(47, recordRecord.getValue("customerId")); } + + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void testSecuritySupplier() throws QException + { + ////////////////////////////////////////////// + // Add a security name/value to our process // + ////////////////////////////////////////////// + QProcessMetaData process = QContext.getQInstance().getProcess(TestUtils.LOCAL_PERSON_CSV_FILE_IMPORTER_PROCESS_NAME); + process.getInputFields().stream().filter(f -> f.getName().equals(FilesystemImporterStep.FIELD_IMPORT_SECURITY_FIELD_NAME)).findFirst().get().setDefaultValue("customerId"); + process.getInputFields().stream().filter(f -> f.getName().equals(FilesystemImporterStep.FIELD_IMPORT_SECURITY_VALUE_SUPPLIER)).findFirst().get().setDefaultValue(new QCodeReference(SecuritySupplier.class)); + + RunProcessInput runProcessInput = new RunProcessInput(); + runProcessInput.setProcessName(TestUtils.LOCAL_PERSON_CSV_FILE_IMPORTER_PROCESS_NAME); + new RunProcessAction().execute(runProcessInput); + + //////////////////////////////////////////////////////////////////////////////////////////// + // assert the security field gets its value on both the importFile & importRecord records // + //////////////////////////////////////////////////////////////////////////////////////////// + String importBaseName = "personImporter"; + QRecord fileRecord = new GetAction().executeForRecord(new GetInput(importBaseName + FilesystemImporterMetaDataTemplate.IMPORT_FILE_TABLE_SUFFIX).withPrimaryKey(1)); + assertEquals(1701, fileRecord.getValue("customerId")); + + QRecord recordRecord = new GetAction().executeForRecord(new GetInput(importBaseName + FilesystemImporterMetaDataTemplate.IMPORT_RECORD_TABLE_SUFFIX).withPrimaryKey(1)); + assertEquals(1701, recordRecord.getValue("customerId")); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + public static class SecuritySupplier implements Function + { + /******************************************************************************* + ** + *******************************************************************************/ + @Override + public Serializable apply(QRecord qRecord) + { + return (1701); + } + } + } \ No newline at end of file