From 3914670988115968444f0bcc1671d09864ec5ef8 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Mon, 1 Apr 2024 12:53:02 -0500 Subject: [PATCH] CE-881 - Update RenderSavedReport process to stream results to a backend through new StorageAction. --- .../SavedReportsMetaDataProvider.java | 64 +++++++++- .../RenderSavedReportExecuteStep.java | 39 +++--- .../RenderSavedReportMetaDataProducer.java | 10 +- .../RenderSavedReportPreStep.java | 33 +++++- .../RenderSavedReportProcessTest.java | 112 +++++++++++------- .../GenerateReportActionRDBMSTest.java | 14 ++- 6 files changed, 197 insertions(+), 75 deletions(-) diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/savedreports/SavedReportsMetaDataProvider.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/savedreports/SavedReportsMetaDataProvider.java index dfdb8c57..b5eac877 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/savedreports/SavedReportsMetaDataProvider.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/savedreports/SavedReportsMetaDataProvider.java @@ -24,13 +24,21 @@ package com.kingsrook.qqq.backend.core.model.savedreports; import java.util.List; import java.util.function.Consumer; +import com.kingsrook.qqq.backend.core.actions.dashboard.widgets.DefaultWidgetRenderer; import com.kingsrook.qqq.backend.core.exceptions.QException; import com.kingsrook.qqq.backend.core.model.actions.reporting.ReportFormatPossibleValueEnum; +import com.kingsrook.qqq.backend.core.model.dashboard.widgets.WidgetType; import com.kingsrook.qqq.backend.core.model.metadata.QInstance; +import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference; +import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaData; +import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaDataInterface; import com.kingsrook.qqq.backend.core.model.metadata.fields.AdornmentType; import com.kingsrook.qqq.backend.core.model.metadata.fields.FieldAdornment; +import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData; +import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldType; import com.kingsrook.qqq.backend.core.model.metadata.layout.QIcon; import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValueSource; +import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData; import com.kingsrook.qqq.backend.core.model.metadata.tables.QFieldSection; import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; import com.kingsrook.qqq.backend.core.model.metadata.tables.Tier; @@ -42,17 +50,66 @@ import com.kingsrook.qqq.backend.core.processes.implementations.savedreports.Ren *******************************************************************************/ public class SavedReportsMetaDataProvider { + public static final String REPORT_STORAGE_TABLE_NAME = "reportStorage"; + /******************************************************************************* ** *******************************************************************************/ - public void defineAll(QInstance instance, String backendName, Consumer backendDetailEnricher) throws QException + public void defineAll(QInstance instance, String recordTablesBackendName, String reportStorageBackendName, Consumer backendDetailEnricher) throws QException { - instance.addTable(defineSavedReportTable(backendName, backendDetailEnricher)); + instance.addTable(defineSavedReportTable(recordTablesBackendName, backendDetailEnricher)); instance.addPossibleValueSource(QPossibleValueSource.newForTable(SavedReport.TABLE_NAME)); instance.addPossibleValueSource(QPossibleValueSource.newForEnum(ReportFormatPossibleValueEnum.NAME, ReportFormatPossibleValueEnum.values())); - instance.addProcess(new RenderSavedReportMetaDataProducer().produce(instance)); + + instance.addTable(defineReportStorageTable(reportStorageBackendName, backendDetailEnricher)); + + QProcessMetaData renderSavedReportProcess = new RenderSavedReportMetaDataProducer().produce(instance); + instance.addProcess(renderSavedReportProcess); + renderSavedReportProcess.getInputFields().stream() + .filter(f -> RenderSavedReportMetaDataProducer.FIELD_NAME_STORAGE_TABLE_NAME.equals(f.getName())) + .findFirst() + .ifPresent(f -> f.setDefaultValue(REPORT_STORAGE_TABLE_NAME)); + + instance.addWidget(defineReportSetupWidget()); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + private QTableMetaData defineReportStorageTable(String backendName, Consumer backendDetailEnricher) + { + QTableMetaData table = new QTableMetaData() + .withName(REPORT_STORAGE_TABLE_NAME) + .withBackendName(backendName) + .withPrimaryKeyField("reference") + .withField(new QFieldMetaData("reference", QFieldType.STRING)) + .withField(new QFieldMetaData("contents", QFieldType.BLOB)); + + if(backendDetailEnricher != null) + { + backendDetailEnricher.accept(table); + } + + return (table); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + private QWidgetMetaDataInterface defineReportSetupWidget() + { + return new QWidgetMetaData() + .withName("reportSetupWidget") + .withLabel("Report Setup") + .withIsCard(true) + .withType(WidgetType.REPORT_SETUP.getType()) + .withCodeReference(new QCodeReference(DefaultWidgetRenderer.class)); } @@ -73,6 +130,7 @@ public class SavedReportsMetaDataProvider .withFieldsFromEntity(SavedReport.class) .withSection(new QFieldSection("identity", new QIcon().withName("badge"), Tier.T1, List.of("id", "label"))) .withSection(new QFieldSection("settings", new QIcon().withName("settings"), Tier.T2, List.of("tableName"))) + .withSection(new QFieldSection("reportSetup", new QIcon().withName("table_chart"), Tier.T2).withWidgetName("reportSetupWidget")) .withSection(new QFieldSection("data", new QIcon().withName("text_snippet"), Tier.T2, List.of("queryFilterJson", "columnsJson", "pivotTableJson"))) .withSection(new QFieldSection("hidden", new QIcon().withName("text_snippet"), Tier.T2, List.of("inputFieldsJson", "userId")).withIsHidden(true)) .withSection(new QFieldSection("dates", new QIcon().withName("calendar_month"), Tier.T3, List.of("createDate", "modifyDate"))); diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/savedreports/RenderSavedReportExecuteStep.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/savedreports/RenderSavedReportExecuteStep.java index 0fd11194..a6d99954 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/savedreports/RenderSavedReportExecuteStep.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/savedreports/RenderSavedReportExecuteStep.java @@ -22,15 +22,16 @@ package com.kingsrook.qqq.backend.core.processes.implementations.savedreports; -import java.io.File; -import java.io.FileOutputStream; +import java.io.OutputStream; import java.io.Serializable; import java.time.Instant; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.Map; +import java.util.UUID; import com.kingsrook.qqq.backend.core.actions.processes.BackendStep; import com.kingsrook.qqq.backend.core.actions.reporting.GenerateReportAction; +import com.kingsrook.qqq.backend.core.actions.tables.StorageAction; import com.kingsrook.qqq.backend.core.exceptions.QException; import com.kingsrook.qqq.backend.core.logging.QLogger; import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput; @@ -38,6 +39,7 @@ import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutp import com.kingsrook.qqq.backend.core.model.actions.reporting.ReportDestination; import com.kingsrook.qqq.backend.core.model.actions.reporting.ReportFormat; import com.kingsrook.qqq.backend.core.model.actions.reporting.ReportInput; +import com.kingsrook.qqq.backend.core.model.actions.tables.storage.StorageInput; import com.kingsrook.qqq.backend.core.model.metadata.reporting.QReportMetaData; import com.kingsrook.qqq.backend.core.model.savedreports.SavedReport; import com.kingsrook.qqq.backend.core.utils.StringUtils; @@ -60,32 +62,33 @@ public class RenderSavedReportExecuteStep implements BackendStep { try { - ReportFormat reportFormat = ReportFormat.fromString(runBackendStepInput.getValueString("reportFormat")); + String storageTableName = runBackendStepInput.getValueString(RenderSavedReportMetaDataProducer.FIELD_NAME_STORAGE_TABLE_NAME); + ReportFormat reportFormat = ReportFormat.fromString(runBackendStepInput.getValueString(RenderSavedReportMetaDataProducer.FIELD_NAME_REPORT_FORMAT)); - SavedReport savedReport = new SavedReport(runBackendStepInput.getRecords().get(0)); - File tmpFile = File.createTempFile("SavedReport" + savedReport.getId(), "." + reportFormat.getExtension(), new File("/tmp/")); + SavedReport savedReport = new SavedReport(runBackendStepInput.getRecords().get(0)); + String downloadFileBaseName = getDownloadFileBaseName(runBackendStepInput, savedReport); + String storageReference = UUID.randomUUID() + "/" + downloadFileBaseName + "." + reportFormat.getExtension(); + + OutputStream outputStream = new StorageAction().createOutputStream(new StorageInput(storageTableName).withReference(storageReference)); runBackendStepInput.getAsyncJobCallback().updateStatus("Generating Report"); QReportMetaData reportMetaData = new SavedReportToReportMetaDataAdapter().adapt(savedReport, reportFormat); - try(FileOutputStream reportOutputStream = new FileOutputStream(tmpFile)) - { - ReportInput reportInput = new ReportInput(); - reportInput.setReportMetaData(reportMetaData); - reportInput.setReportDestination(new ReportDestination() - .withReportFormat(reportFormat) - .withReportOutputStream(reportOutputStream)); + ReportInput reportInput = new ReportInput(); + reportInput.setReportMetaData(reportMetaData); + reportInput.setReportDestination(new ReportDestination() + .withReportFormat(reportFormat) + .withReportOutputStream(outputStream)); - Map values = runBackendStepInput.getValues(); - reportInput.setInputValues(values); + Map values = runBackendStepInput.getValues(); + reportInput.setInputValues(values); - new GenerateReportAction().execute(reportInput); - } + new GenerateReportAction().execute(reportInput); - String downloadFileBaseName = getDownloadFileBaseName(runBackendStepInput, savedReport); runBackendStepOutput.addValue("downloadFileName", downloadFileBaseName + "." + reportFormat.getExtension()); - runBackendStepOutput.addValue("serverFilePath", tmpFile.getCanonicalPath()); + runBackendStepOutput.addValue("storageTableName", storageTableName); + runBackendStepOutput.addValue("storageReference", storageReference); } catch(Exception e) { diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/savedreports/RenderSavedReportMetaDataProducer.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/savedreports/RenderSavedReportMetaDataProducer.java index dfe1cd31..729edbc5 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/savedreports/RenderSavedReportMetaDataProducer.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/savedreports/RenderSavedReportMetaDataProducer.java @@ -47,6 +47,9 @@ public class RenderSavedReportMetaDataProducer implements MetaDataProducerInterf { public static final String NAME = "renderSavedReport"; + public static final String FIELD_NAME_STORAGE_TABLE_NAME = "storageTableName"; + public static final String FIELD_NAME_REPORT_FORMAT = "reportFormat"; + /******************************************************************************* @@ -61,13 +64,14 @@ public class RenderSavedReportMetaDataProducer implements MetaDataProducerInterf .withIcon(new QIcon().withName("print")) .addStep(new QBackendStepMetaData() .withName("pre") - .withInputData(new QFunctionInputMetaData().withRecordListMetaData(new QRecordListMetaData() - .withTableName(SavedReport.TABLE_NAME))) + .withInputData(new QFunctionInputMetaData() + .withField(new QFieldMetaData(FIELD_NAME_STORAGE_TABLE_NAME, QFieldType.STRING)) + .withRecordListMetaData(new QRecordListMetaData().withTableName(SavedReport.TABLE_NAME))) .withCode(new QCodeReference(RenderSavedReportPreStep.class))) .addStep(new QFrontendStepMetaData() .withName("input") .withComponent(new QFrontendComponentMetaData().withType(QComponentType.EDIT_FORM)) - .withFormField(new QFieldMetaData("reportFormat", QFieldType.STRING) + .withFormField(new QFieldMetaData(FIELD_NAME_REPORT_FORMAT, QFieldType.STRING) .withPossibleValueSourceName(ReportFormatPossibleValueEnum.NAME) .withIsRequired(true))) .addStep(new QBackendStepMetaData() diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/savedreports/RenderSavedReportPreStep.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/savedreports/RenderSavedReportPreStep.java index 277bc431..a6ab1442 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/savedreports/RenderSavedReportPreStep.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/savedreports/RenderSavedReportPreStep.java @@ -22,10 +22,17 @@ package com.kingsrook.qqq.backend.core.processes.implementations.savedreports; +import java.util.List; import com.kingsrook.qqq.backend.core.actions.processes.BackendStep; +import com.kingsrook.qqq.backend.core.context.QContext; import com.kingsrook.qqq.backend.core.exceptions.QException; +import com.kingsrook.qqq.backend.core.exceptions.QUserFacingException; import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput; import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutput; +import com.kingsrook.qqq.backend.core.model.data.QRecord; +import com.kingsrook.qqq.backend.core.model.savedreports.SavedReport; +import com.kingsrook.qqq.backend.core.utils.CollectionUtils; +import com.kingsrook.qqq.backend.core.utils.StringUtils; /******************************************************************************* @@ -40,8 +47,30 @@ public class RenderSavedReportPreStep implements BackendStep @Override public void run(RunBackendStepInput runBackendStepInput, RunBackendStepOutput runBackendStepOutput) throws QException { - // todo - verify ran on 1 - // todo - load the SavedReport + String storageTableName = runBackendStepInput.getValueString(RenderSavedReportMetaDataProducer.FIELD_NAME_STORAGE_TABLE_NAME); + if(!StringUtils.hasContent(storageTableName)) + { + throw (new QUserFacingException("Process configuration error: Missing value for storageTableName.")); + } + + if(QContext.getQInstance().getTable(storageTableName) == null) + { + throw (new QUserFacingException("Process configuration error: Unrecognized value for storageTableName - no table named [" + storageTableName + "] was found in the instance.")); + } + + List records = runBackendStepInput.getRecords(); + if(!CollectionUtils.nullSafeHasContents(records)) + { + throw (new QUserFacingException("No report was selected or found to be rendered.")); + } + + if(records.size() > 1) + { + throw (new QUserFacingException("You may only render 1 report at a time.")); + } + + SavedReport savedReport = new SavedReport(records.get(0)); + // todo - check for inputs - set up the input screen... } diff --git a/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/processes/implementations/savedreports/RenderSavedReportProcessTest.java b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/processes/implementations/savedreports/RenderSavedReportProcessTest.java index a52577ff..3e6efae7 100644 --- a/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/processes/implementations/savedreports/RenderSavedReportProcessTest.java +++ b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/processes/implementations/savedreports/RenderSavedReportProcessTest.java @@ -23,6 +23,9 @@ package com.kingsrook.qqq.backend.core.processes.implementations.savedreports; import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; import java.math.BigDecimal; import java.nio.charset.StandardCharsets; import java.util.List; @@ -42,14 +45,17 @@ import com.kingsrook.qqq.backend.core.model.actions.reporting.pivottable.PivotTa import com.kingsrook.qqq.backend.core.model.actions.reporting.pivottable.PivotTableValue; import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertInput; import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter; +import com.kingsrook.qqq.backend.core.model.actions.tables.storage.StorageInput; import com.kingsrook.qqq.backend.core.model.data.QRecord; import com.kingsrook.qqq.backend.core.model.savedreports.ReportColumns; import com.kingsrook.qqq.backend.core.model.savedreports.SavedReport; import com.kingsrook.qqq.backend.core.model.savedreports.SavedReportsMetaDataProvider; +import com.kingsrook.qqq.backend.core.modules.backend.implementations.memory.MemoryStorageAction; import com.kingsrook.qqq.backend.core.utils.JsonUtils; import com.kingsrook.qqq.backend.core.utils.LocalMacDevUtils; +import com.kingsrook.qqq.backend.core.utils.StringUtils; import com.kingsrook.qqq.backend.core.utils.TestUtils; -import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; import org.json.JSONArray; import org.json.JSONObject; import org.junit.jupiter.api.BeforeEach; @@ -57,7 +63,6 @@ import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; /******************************************************************************* @@ -71,7 +76,7 @@ class RenderSavedReportProcessTest extends BaseTest @BeforeEach void beforeEach() throws Exception { - new SavedReportsMetaDataProvider().defineAll(QContext.getQInstance(), TestUtils.MEMORY_BACKEND_NAME, null); + new SavedReportsMetaDataProvider().defineAll(QContext.getQInstance(), TestUtils.MEMORY_BACKEND_NAME, TestUtils.MEMORY_BACKEND_NAME, null); GenerateReportActionTest.insertPersonRecords(QContext.getQInstance()); } @@ -131,17 +136,14 @@ class RenderSavedReportProcessTest extends BaseTest RunProcessOutput runProcessOutput = runRenderReportProcess(savedReport, ReportFormatPossibleValueEnum.CSV); String downloadFileName = runProcessOutput.getValueString("downloadFileName"); - String serverFilePath = runProcessOutput.getValueString("serverFilePath"); - assertThat(downloadFileName) .startsWith(label + " - ") .matches(".*\\d\\d\\d\\d-\\d\\d-\\d\\d-\\d\\d\\d\\d.*") .endsWith(".csv"); - File serverFile = new File(serverFilePath); - assertTrue(serverFile.exists()); + InputStream inputStream = getInputStream(runProcessOutput); + List lines = IOUtils.readLines(inputStream, StandardCharsets.UTF_8); - List lines = FileUtils.readLines(serverFile); assertEquals(""" "Id","First Name","Last Name" """.trim(), lines.get(0)); @@ -149,7 +151,41 @@ class RenderSavedReportProcessTest extends BaseTest "1","Darin","Jonson" """.trim(), lines.get(1)); - LocalMacDevUtils.openFile(serverFilePath); + writeTmpFileAndOpen(inputStream, ".csv"); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + private static InputStream getInputStream(RunProcessOutput runProcessOutput) throws QException + { + String storageTableName = runProcessOutput.getValueString("storageTableName"); + String storageReference = runProcessOutput.getValueString("storageReference"); + InputStream inputStream = new MemoryStorageAction().getInputStream(new StorageInput(storageTableName).withReference(storageReference)); + return inputStream; + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + private void writeTmpFileAndOpen(InputStream inputStream, String suffix) throws IOException + { + // LocalMacDevUtils.mayOpenFiles = true; + if(LocalMacDevUtils.mayOpenFiles) + { + inputStream.reset(); + + File tmpFile = File.createTempFile(getClass().getName(), suffix, new File("/tmp/")); + FileOutputStream fileOutputStream = new FileOutputStream(tmpFile); + inputStream.transferTo(fileOutputStream); + fileOutputStream.close(); + + LocalMacDevUtils.openFile(tmpFile.getAbsolutePath()); + } } @@ -203,14 +239,8 @@ class RenderSavedReportProcessTest extends BaseTest QRecord savedReport = insertBasicSavedPivotReport(label); RunProcessOutput runProcessOutput = runRenderReportProcess(savedReport, ReportFormatPossibleValueEnum.XLSX); - String serverFilePath = runProcessOutput.getValueString("serverFilePath"); - System.out.println(serverFilePath); - - File serverFile = new File(serverFilePath); - assertTrue(serverFile.exists()); - - LocalMacDevUtils.mayOpenFiles = true; - LocalMacDevUtils.openFile(serverFilePath, "/Applications/Numbers.app"); + InputStream inputStream = getInputStream(runProcessOutput); + writeTmpFileAndOpen(inputStream, ".xlsx"); } @@ -225,14 +255,9 @@ class RenderSavedReportProcessTest extends BaseTest QRecord savedReport = insertBasicSavedPivotReport(label); RunProcessOutput runProcessOutput = runRenderReportProcess(savedReport, ReportFormatPossibleValueEnum.JSON); - String serverFilePath = runProcessOutput.getValueString("serverFilePath"); - System.out.println(serverFilePath); - - File serverFile = new File(serverFilePath); - assertTrue(serverFile.exists()); - - String json = FileUtils.readFileToString(serverFile, StandardCharsets.UTF_8); - System.out.println(json); + InputStream inputStream = getInputStream(runProcessOutput); + String json = StringUtils.join("\n", IOUtils.readLines(inputStream, StandardCharsets.UTF_8)); + printReport(json); JSONArray jsonArray = new JSONArray(json); assertEquals(2, jsonArray.length()); @@ -262,6 +287,16 @@ class RenderSavedReportProcessTest extends BaseTest + /******************************************************************************* + ** + *******************************************************************************/ + private void printReport(String report) + { + // System.out.println(report); + } + + + /******************************************************************************* ** *******************************************************************************/ @@ -272,13 +307,8 @@ class RenderSavedReportProcessTest extends BaseTest QRecord savedReport = insertBasicSavedPivotReport(label); RunProcessOutput runProcessOutput = runRenderReportProcess(savedReport, ReportFormatPossibleValueEnum.CSV); - String serverFilePath = runProcessOutput.getValueString("serverFilePath"); - System.out.println(serverFilePath); - - File serverFile = new File(serverFilePath); - assertTrue(serverFile.exists()); - - List csv = FileUtils.readLines(serverFile, StandardCharsets.UTF_8); + InputStream inputStream = getInputStream(runProcessOutput); + List csv = IOUtils.readLines(inputStream, StandardCharsets.UTF_8); System.out.println(csv); assertEquals(""" @@ -316,6 +346,7 @@ class RenderSavedReportProcessTest extends BaseTest } + /******************************************************************************* ** *******************************************************************************/ @@ -329,12 +360,8 @@ class RenderSavedReportProcessTest extends BaseTest String serverFilePath = runProcessOutput.getValueString("serverFilePath"); System.out.println(serverFilePath); - File serverFile = new File(serverFilePath); - assertTrue(serverFile.exists()); - - // LocalMacDevUtils.mayOpenFiles = true; - LocalMacDevUtils.openFile(serverFilePath, "/Applications/Numbers.app"); - LocalMacDevUtils.openFile(serverFilePath); + InputStream inputStream = getInputStream(runProcessOutput); + writeTmpFileAndOpen(inputStream, ".xlsx"); } @@ -349,13 +376,8 @@ class RenderSavedReportProcessTest extends BaseTest QRecord savedReport = insertSavedPivotReportWithAllFunctions(label); RunProcessOutput runProcessOutput = runRenderReportProcess(savedReport, ReportFormatPossibleValueEnum.CSV); - String serverFilePath = runProcessOutput.getValueString("serverFilePath"); - System.out.println(serverFilePath); - - File serverFile = new File(serverFilePath); - assertTrue(serverFile.exists()); - - List csv = FileUtils.readLines(serverFile, StandardCharsets.UTF_8); + InputStream inputStream = getInputStream(runProcessOutput); + List csv = IOUtils.readLines(inputStream, StandardCharsets.UTF_8); System.out.println(csv); assertEquals(""" diff --git a/qqq-backend-module-rdbms/src/test/java/com/kingsrook/qqq/backend/module/rdbms/reporting/GenerateReportActionRDBMSTest.java b/qqq-backend-module-rdbms/src/test/java/com/kingsrook/qqq/backend/module/rdbms/reporting/GenerateReportActionRDBMSTest.java index c85aa6fb..f9d545a9 100644 --- a/qqq-backend-module-rdbms/src/test/java/com/kingsrook/qqq/backend/module/rdbms/reporting/GenerateReportActionRDBMSTest.java +++ b/qqq-backend-module-rdbms/src/test/java/com/kingsrook/qqq/backend/module/rdbms/reporting/GenerateReportActionRDBMSTest.java @@ -23,7 +23,7 @@ package com.kingsrook.qqq.backend.module.rdbms.reporting; import java.io.ByteArrayOutputStream; -import java.io.File; +import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.List; import com.kingsrook.qqq.backend.core.actions.processes.QProcessCallbackFactory; @@ -44,6 +44,7 @@ import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterOrderBy; import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter; import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryJoin; +import com.kingsrook.qqq.backend.core.model.actions.tables.storage.StorageInput; import com.kingsrook.qqq.backend.core.model.data.QRecord; import com.kingsrook.qqq.backend.core.model.metadata.QInstance; import com.kingsrook.qqq.backend.core.model.metadata.reporting.QReportDataSource; @@ -55,11 +56,12 @@ import com.kingsrook.qqq.backend.core.model.savedreports.ReportColumns; import com.kingsrook.qqq.backend.core.model.savedreports.SavedReport; import com.kingsrook.qqq.backend.core.model.savedreports.SavedReportsMetaDataProvider; import com.kingsrook.qqq.backend.core.model.session.QSession; +import com.kingsrook.qqq.backend.core.modules.backend.implementations.memory.MemoryStorageAction; import com.kingsrook.qqq.backend.core.processes.implementations.savedreports.RenderSavedReportMetaDataProducer; import com.kingsrook.qqq.backend.core.utils.JsonUtils; import com.kingsrook.qqq.backend.module.rdbms.TestUtils; import com.kingsrook.qqq.backend.module.rdbms.actions.RDBMSActionTest; -import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -220,7 +222,7 @@ public class GenerateReportActionRDBMSTest extends RDBMSActionTest { newSavedReport.setLabel("Test Report"); QContext.setQSession(new QSession().withSecurityKeyValue(TestUtils.SECURITY_KEY_STORE_ALL_ACCESS, true)); - new SavedReportsMetaDataProvider().defineAll(QContext.getQInstance(), TestUtils.MEMORY_BACKEND_NAME, null); + new SavedReportsMetaDataProvider().defineAll(QContext.getQInstance(), TestUtils.MEMORY_BACKEND_NAME, TestUtils.MEMORY_BACKEND_NAME, null); QRecord savedReport = new InsertAction().execute(new InsertInput(SavedReport.TABLE_NAME).withRecordEntity(newSavedReport)).getRecords().get(0); @@ -231,7 +233,11 @@ public class GenerateReportActionRDBMSTest extends RDBMSActionTest input.addValue("reportFormat", ReportFormatPossibleValueEnum.CSV.getPossibleValueId()); RunProcessOutput runProcessOutput = new RunProcessAction().execute(input); - return (FileUtils.readLines(new File(runProcessOutput.getValueString("serverFilePath")), StandardCharsets.UTF_8)); + String storageTableName = runProcessOutput.getValueString("storageTableName"); + String storageReference = runProcessOutput.getValueString("storageReference"); + InputStream inputStream = new MemoryStorageAction().getInputStream(new StorageInput(storageTableName).withReference(storageReference)); + + return (IOUtils.readLines(inputStream, StandardCharsets.UTF_8)); }