mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-17 20:50:44 +00:00
CE-881 - support for streamed outputs, implemented for render saved reports process
This commit is contained in:
@ -22,20 +22,19 @@
|
||||
package com.kingsrook.qqq.api.implementations.savedreports;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.io.Serializable;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Map;
|
||||
import com.kingsrook.qqq.api.model.actions.HttpApiResponse;
|
||||
import com.kingsrook.qqq.api.model.metadata.processes.ApiProcessOutputInterface;
|
||||
import com.kingsrook.qqq.api.model.openapi.Content;
|
||||
import com.kingsrook.qqq.api.model.openapi.Response;
|
||||
import com.kingsrook.qqq.api.model.openapi.Schema;
|
||||
import com.kingsrook.qqq.backend.core.actions.tables.StorageAction;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||
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.reporting.ReportFormat;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.storage.StorageInput;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
|
||||
|
||||
@ -51,25 +50,10 @@ public class RenderSavedReportProcessApiProcessOutput implements ApiProcessOutpu
|
||||
@Override
|
||||
public Serializable getOutputForProcess(RunProcessInput runProcessInput, RunProcessOutput runProcessOutput) throws QException
|
||||
{
|
||||
try
|
||||
{
|
||||
ReportFormat reportFormat = ReportFormat.fromString(runProcessOutput.getValueString("reportFormat"));
|
||||
|
||||
String filePath = runProcessOutput.getValueString("serverFilePath");
|
||||
File file = new File(filePath);
|
||||
if(reportFormat.getIsBinary())
|
||||
{
|
||||
return FileUtils.readFileToByteArray(file);
|
||||
}
|
||||
else
|
||||
{
|
||||
return FileUtils.readFileToString(file, Charset.defaultCharset());
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
throw new QException("Error streaming report contents", e);
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// we don't use output like this - see customizeHttpApiResponse //
|
||||
//////////////////////////////////////////////////////////////////
|
||||
return (null);
|
||||
}
|
||||
|
||||
|
||||
@ -85,8 +69,18 @@ public class RenderSavedReportProcessApiProcessOutput implements ApiProcessOutpu
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
httpApiResponse.setNeedsFormattedAsJson(false);
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// set content type based on report format //
|
||||
/////////////////////////////////////////////
|
||||
ReportFormat reportFormat = ReportFormat.fromString(runProcessOutput.getValueString("reportFormat"));
|
||||
httpApiResponse.setContentType(reportFormat.getMimeType());
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// get an input stream from the backend where the report content is stored - send that down to the caller //
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
String storageTableName = runProcessOutput.getValueString("storageTableName");
|
||||
String storageReference = runProcessOutput.getValueString("storageReference");
|
||||
httpApiResponse.setInputStream(new StorageAction().getInputStream(new StorageInput(storageTableName).withReference(storageReference)));
|
||||
}
|
||||
|
||||
|
||||
|
@ -380,25 +380,36 @@ public class QJavalinApiHandler
|
||||
context.contentType(response.getContentType());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// else, try to return it raw - as byte[], or String, or as a converted-to-String //
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
Serializable result = Objects.requireNonNullElse(response.getResponseBodyObject(), "");
|
||||
if(result instanceof byte[] ba)
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// if there's an input stream in the response, just send that down to the client //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
if(response.getInputStream() != null)
|
||||
{
|
||||
context.result(ba);
|
||||
storeApiLog(apiLog.withStatusCode(context.statusCode()).withResponseBody("Byte array of length: " + ba.length));
|
||||
}
|
||||
else if(result instanceof String s)
|
||||
{
|
||||
context.result(s);
|
||||
storeApiLog(apiLog.withStatusCode(context.statusCode()).withResponseBody(s));
|
||||
context.result(response.getInputStream());
|
||||
storeApiLog(apiLog.withStatusCode(context.statusCode()).withResponseBody("Streamed result"));
|
||||
}
|
||||
else
|
||||
{
|
||||
String resultString = String.valueOf(result);
|
||||
context.result(resultString);
|
||||
storeApiLog(apiLog.withStatusCode(context.statusCode()).withResponseBody(resultString));
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// else, try to return it raw - as byte[], or String, or as a converted-to-String //
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
Serializable result = Objects.requireNonNullElse(response.getResponseBodyObject(), "");
|
||||
if(result instanceof byte[] ba)
|
||||
{
|
||||
context.result(ba);
|
||||
storeApiLog(apiLog.withStatusCode(context.statusCode()).withResponseBody("Byte array of length: " + ba.length));
|
||||
}
|
||||
else if(result instanceof String s)
|
||||
{
|
||||
context.result(s);
|
||||
storeApiLog(apiLog.withStatusCode(context.statusCode()).withResponseBody(s));
|
||||
}
|
||||
else
|
||||
{
|
||||
String resultString = String.valueOf(result);
|
||||
context.result(resultString);
|
||||
storeApiLog(apiLog.withStatusCode(context.statusCode()).withResponseBody(resultString));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
package com.kingsrook.qqq.api.model.actions;
|
||||
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
|
||||
@ -37,6 +38,8 @@ public class HttpApiResponse
|
||||
|
||||
private String contentType;
|
||||
|
||||
private InputStream inputStream;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// by default - QJavalinApiHandler will format the responseBodyObject as JSON. //
|
||||
// set this field to false if you don't want it to do that (e.g., if your response is, say, a byte[]) //
|
||||
@ -189,4 +192,35 @@ public class HttpApiResponse
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for inputStream
|
||||
*******************************************************************************/
|
||||
public InputStream getInputStream()
|
||||
{
|
||||
return (this.inputStream);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for inputStream
|
||||
*******************************************************************************/
|
||||
public void setInputStream(InputStream inputStream)
|
||||
{
|
||||
this.inputStream = inputStream;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for inputStream
|
||||
*******************************************************************************/
|
||||
public HttpApiResponse withInputStream(InputStream inputStream)
|
||||
{
|
||||
this.inputStream = inputStream;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -175,7 +175,7 @@ public class TestUtils
|
||||
private static void addSavedReports(QInstance qInstance) throws QException
|
||||
{
|
||||
qInstance.add(TablesPossibleValueSourceMetaDataProvider.defineTablesPossibleValueSource(qInstance));
|
||||
new SavedReportsMetaDataProvider().defineAll(qInstance, MEMORY_BACKEND_NAME, null);
|
||||
new SavedReportsMetaDataProvider().defineAll(qInstance, MEMORY_BACKEND_NAME, MEMORY_BACKEND_NAME, null);
|
||||
RenderSavedReportProcessApiMetaDataEnricher.setupProcessForApi(qInstance.getProcess(RenderSavedReportMetaDataProducer.NAME), API_NAME, V2022_Q4);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user