mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 05:01:07 +00:00
Update processBasedRouters to use different handlers for processing the javalin context - with a new default implementation that makes available the request body as a string
This commit is contained in:
@ -25,8 +25,10 @@ package com.kingsrook.qqq.backend.javalin;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
import com.kingsrook.qqq.backend.core.instances.QInstanceValidator;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QSupplementalInstanceMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.QSupplementalInstanceMetaData;
|
||||||
|
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||||
import com.kingsrook.qqq.middleware.javalin.metadata.JavalinRouteProviderMetaData;
|
import com.kingsrook.qqq.middleware.javalin.metadata.JavalinRouteProviderMetaData;
|
||||||
import org.apache.logging.log4j.Level;
|
import org.apache.logging.log4j.Level;
|
||||||
|
|
||||||
@ -329,4 +331,16 @@ public class QJavalinMetaData implements QSupplementalInstanceMetaData
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public void validate(QInstance qInstance, QInstanceValidator validator)
|
||||||
|
{
|
||||||
|
for(JavalinRouteProviderMetaData routeProviderMetaData : CollectionUtils.nonNullList(routeProviders))
|
||||||
|
{
|
||||||
|
routeProviderMetaData.validate(qInstance, validator);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,13 @@ package com.kingsrook.qqq.middleware.javalin.metadata;
|
|||||||
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import com.kingsrook.qqq.backend.core.instances.QInstanceValidator;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QMetaDataObject;
|
import com.kingsrook.qqq.backend.core.model.metadata.QMetaDataObject;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
||||||
|
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
||||||
|
import com.kingsrook.qqq.middleware.javalin.routeproviders.authentication.RouteAuthenticatorInterface;
|
||||||
|
import com.kingsrook.qqq.middleware.javalin.routeproviders.contexthandlers.RouteProviderContextHandlerInterface;
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -32,6 +37,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public class JavalinRouteProviderMetaData implements QMetaDataObject
|
public class JavalinRouteProviderMetaData implements QMetaDataObject
|
||||||
{
|
{
|
||||||
|
private String name;
|
||||||
private String hostedPath;
|
private String hostedPath;
|
||||||
|
|
||||||
private String fileSystemPath;
|
private String fileSystemPath;
|
||||||
@ -40,6 +46,7 @@ public class JavalinRouteProviderMetaData implements QMetaDataObject
|
|||||||
private List<String> methods;
|
private List<String> methods;
|
||||||
|
|
||||||
private QCodeReference routeAuthenticator;
|
private QCodeReference routeAuthenticator;
|
||||||
|
private QCodeReference contextHandler;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -206,4 +213,90 @@ public class JavalinRouteProviderMetaData implements QMetaDataObject
|
|||||||
return (this);
|
return (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for contextHandler
|
||||||
|
*******************************************************************************/
|
||||||
|
public QCodeReference getContextHandler()
|
||||||
|
{
|
||||||
|
return (this.contextHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for contextHandler
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setContextHandler(QCodeReference contextHandler)
|
||||||
|
{
|
||||||
|
this.contextHandler = contextHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for contextHandler
|
||||||
|
*******************************************************************************/
|
||||||
|
public JavalinRouteProviderMetaData withContextHandler(QCodeReference contextHandler)
|
||||||
|
{
|
||||||
|
this.contextHandler = contextHandler;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for name
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getName()
|
||||||
|
{
|
||||||
|
return (this.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for name
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setName(String name)
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for name
|
||||||
|
*******************************************************************************/
|
||||||
|
public JavalinRouteProviderMetaData withName(String name)
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
public void validate(QInstance qInstance, QInstanceValidator validator)
|
||||||
|
{
|
||||||
|
String prefix = "In javalinRouteProvider '" + name + "', ";
|
||||||
|
if(StringUtils.hasContent(processName))
|
||||||
|
{
|
||||||
|
validator.assertCondition(qInstance.getProcesses().containsKey(processName), prefix + "unrecognized process name: " + processName + " in a javalinRouteProvider");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(routeAuthenticator != null)
|
||||||
|
{
|
||||||
|
validator.validateSimpleCodeReference(prefix + "routeAuthenticator ", routeAuthenticator, RouteAuthenticatorInterface.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(contextHandler != null)
|
||||||
|
{
|
||||||
|
validator.validateSimpleCodeReference(prefix + "contextHandler ", contextHandler, RouteProviderContextHandlerInterface.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,34 +22,27 @@
|
|||||||
package com.kingsrook.qqq.middleware.javalin.routeproviders;
|
package com.kingsrook.qqq.middleware.javalin.routeproviders;
|
||||||
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import com.kingsrook.qqq.backend.core.actions.customizers.QCodeLoader;
|
import com.kingsrook.qqq.backend.core.actions.customizers.QCodeLoader;
|
||||||
import com.kingsrook.qqq.backend.core.actions.processes.RunProcessAction;
|
import com.kingsrook.qqq.backend.core.actions.processes.RunProcessAction;
|
||||||
import com.kingsrook.qqq.backend.core.actions.tables.StorageAction;
|
|
||||||
import com.kingsrook.qqq.backend.core.context.QContext;
|
import com.kingsrook.qqq.backend.core.context.QContext;
|
||||||
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessInput;
|
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.processes.RunProcessOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.storage.StorageInput;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
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.code.QCodeReference;
|
||||||
import com.kingsrook.qqq.backend.core.model.session.QSystemUserSession;
|
import com.kingsrook.qqq.backend.core.model.session.QSystemUserSession;
|
||||||
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||||
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
|
||||||
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
|
|
||||||
import com.kingsrook.qqq.backend.javalin.QJavalinImplementation;
|
import com.kingsrook.qqq.backend.javalin.QJavalinImplementation;
|
||||||
import com.kingsrook.qqq.backend.javalin.QJavalinUtils;
|
import com.kingsrook.qqq.backend.javalin.QJavalinUtils;
|
||||||
import com.kingsrook.qqq.middleware.javalin.QJavalinRouteProviderInterface;
|
import com.kingsrook.qqq.middleware.javalin.QJavalinRouteProviderInterface;
|
||||||
import com.kingsrook.qqq.middleware.javalin.metadata.JavalinRouteProviderMetaData;
|
import com.kingsrook.qqq.middleware.javalin.metadata.JavalinRouteProviderMetaData;
|
||||||
import com.kingsrook.qqq.middleware.javalin.routeproviders.authentication.RouteAuthenticatorInterface;
|
import com.kingsrook.qqq.middleware.javalin.routeproviders.authentication.RouteAuthenticatorInterface;
|
||||||
|
import com.kingsrook.qqq.middleware.javalin.routeproviders.contexthandlers.DefaultRouteProviderContextHandler;
|
||||||
|
import com.kingsrook.qqq.middleware.javalin.routeproviders.contexthandlers.RouteProviderContextHandlerInterface;
|
||||||
import io.javalin.apibuilder.ApiBuilder;
|
import io.javalin.apibuilder.ApiBuilder;
|
||||||
import io.javalin.apibuilder.EndpointGroup;
|
import io.javalin.apibuilder.EndpointGroup;
|
||||||
import io.javalin.http.Context;
|
import io.javalin.http.Context;
|
||||||
import io.javalin.http.HttpStatus;
|
|
||||||
import static com.kingsrook.qqq.backend.core.logging.LogUtils.logPair;
|
import static com.kingsrook.qqq.backend.core.logging.LogUtils.logPair;
|
||||||
|
|
||||||
|
|
||||||
@ -65,6 +58,7 @@ public class ProcessBasedRouter implements QJavalinRouteProviderInterface
|
|||||||
private final List<String> methods;
|
private final List<String> methods;
|
||||||
|
|
||||||
private QCodeReference routeAuthenticator;
|
private QCodeReference routeAuthenticator;
|
||||||
|
private QCodeReference contextHandler;
|
||||||
|
|
||||||
private QInstance qInstance;
|
private QInstance qInstance;
|
||||||
|
|
||||||
@ -88,6 +82,7 @@ public class ProcessBasedRouter implements QJavalinRouteProviderInterface
|
|||||||
{
|
{
|
||||||
this(routeProvider.getHostedPath(), routeProvider.getProcessName(), routeProvider.getMethods());
|
this(routeProvider.getHostedPath(), routeProvider.getProcessName(), routeProvider.getMethods());
|
||||||
setRouteAuthenticator(routeProvider.getRouteAuthenticator());
|
setRouteAuthenticator(routeProvider.getRouteAuthenticator());
|
||||||
|
setContextHandler(routeProvider.getContextHandler());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -188,72 +183,27 @@ public class ProcessBasedRouter implements QJavalinRouteProviderInterface
|
|||||||
{
|
{
|
||||||
LOG.info("Running process to serve route", logPair("processName", processName), logPair("path", context.path()));
|
LOG.info("Running process to serve route", logPair("processName", processName), logPair("path", context.path()));
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// handle request (either using route's specific context handler, or a default one) //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
RouteProviderContextHandlerInterface contextHandler = createContextHandler();
|
||||||
|
contextHandler.handleRequest(context, input);
|
||||||
|
|
||||||
|
// todo - make the inputStream available to the process to stream results?
|
||||||
|
// maybe via the callback object??? input.setCallback(new QProcessCallback() {});
|
||||||
|
// context.resultInputStream();
|
||||||
|
|
||||||
/////////////////////
|
/////////////////////
|
||||||
// run the process //
|
// run the process //
|
||||||
/////////////////////
|
/////////////////////
|
||||||
input.setFrontendStepBehavior(RunProcessInput.FrontendStepBehavior.SKIP);
|
input.setFrontendStepBehavior(RunProcessInput.FrontendStepBehavior.SKIP);
|
||||||
input.addValue("path", context.path());
|
|
||||||
input.addValue("method", context.method());
|
|
||||||
input.addValue("pathParams", new HashMap<>(context.pathParamMap()));
|
|
||||||
input.addValue("queryParams", new HashMap<>(context.queryParamMap()));
|
|
||||||
input.addValue("formParams", new HashMap<>(context.formParamMap()));
|
|
||||||
input.addValue("cookies", new HashMap<>(context.cookieMap()));
|
|
||||||
input.addValue("requestHeaders", new HashMap<>(context.headerMap()));
|
|
||||||
|
|
||||||
RunProcessOutput runProcessOutput = new RunProcessAction().execute(input);
|
RunProcessOutput runProcessOutput = new RunProcessAction().execute(input);
|
||||||
|
|
||||||
/////////////////
|
/////////////////////
|
||||||
// headers map //
|
// handle response //
|
||||||
/////////////////
|
/////////////////////
|
||||||
Serializable headers = runProcessOutput.getValue("responseHeaders");
|
if(contextHandler.handleResponse(context, runProcessOutput))
|
||||||
if(headers instanceof Map headersMap)
|
|
||||||
{
|
{
|
||||||
for(Object key : headersMap.keySet())
|
|
||||||
{
|
|
||||||
context.header(ValueUtils.getValueAsString(key), ValueUtils.getValueAsString(headersMap.get(key)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo - make the inputStream available to the process
|
|
||||||
// maybe via the callback object??? input.setCallback(new QProcessCallback() {});
|
|
||||||
// context.resultInputStream();
|
|
||||||
|
|
||||||
//////////////
|
|
||||||
// response //
|
|
||||||
//////////////
|
|
||||||
Integer statusCode = runProcessOutput.getValueInteger("statusCode");
|
|
||||||
String redirectURL = runProcessOutput.getValueString("redirectURL");
|
|
||||||
String responseString = runProcessOutput.getValueString("responseString");
|
|
||||||
byte[] responseBytes = runProcessOutput.getValueByteArray("responseBytes");
|
|
||||||
StorageInput responseStorageInput = (StorageInput) runProcessOutput.getValue("responseStorageInput");
|
|
||||||
|
|
||||||
if(StringUtils.hasContent(redirectURL))
|
|
||||||
{
|
|
||||||
context.redirect(redirectURL, statusCode == null ? HttpStatus.FOUND : HttpStatus.forStatus(statusCode));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(statusCode != null)
|
|
||||||
{
|
|
||||||
context.status(statusCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(StringUtils.hasContent(responseString))
|
|
||||||
{
|
|
||||||
context.result(responseString);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(responseBytes != null && responseBytes.length > 0)
|
|
||||||
{
|
|
||||||
context.result(responseBytes);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(responseStorageInput != null)
|
|
||||||
{
|
|
||||||
InputStream inputStream = new StorageAction().getInputStream(responseStorageInput);
|
|
||||||
context.result(inputStream);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,6 +221,23 @@ public class ProcessBasedRouter implements QJavalinRouteProviderInterface
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
private RouteProviderContextHandlerInterface createContextHandler()
|
||||||
|
{
|
||||||
|
if(contextHandler != null)
|
||||||
|
{
|
||||||
|
return QCodeLoader.getAdHoc(RouteProviderContextHandlerInterface.class, this.contextHandler);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (new DefaultRouteProviderContextHandler());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Getter for routeAuthenticator
|
** Getter for routeAuthenticator
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@ -300,4 +267,35 @@ public class ProcessBasedRouter implements QJavalinRouteProviderInterface
|
|||||||
return (this);
|
return (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for contextHandler
|
||||||
|
*******************************************************************************/
|
||||||
|
public QCodeReference getContextHandler()
|
||||||
|
{
|
||||||
|
return (this.contextHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for contextHandler
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setContextHandler(QCodeReference contextHandler)
|
||||||
|
{
|
||||||
|
this.contextHandler = contextHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for contextHandler
|
||||||
|
*******************************************************************************/
|
||||||
|
public ProcessBasedRouter withContextHandler(QCodeReference contextHandler)
|
||||||
|
{
|
||||||
|
this.contextHandler = contextHandler;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,7 @@ public class ProcessBasedRouterPayload extends QProcessPayload
|
|||||||
private Map<String, List<String>> queryParams;
|
private Map<String, List<String>> queryParams;
|
||||||
private Map<String, List<String>> formParams;
|
private Map<String, List<String>> formParams;
|
||||||
private Map<String, String> cookies;
|
private Map<String, String> cookies;
|
||||||
|
private String bodyString;
|
||||||
|
|
||||||
private Integer statusCode;
|
private Integer statusCode;
|
||||||
private String redirectURL;
|
private String redirectURL;
|
||||||
@ -410,4 +411,35 @@ public class ProcessBasedRouterPayload extends QProcessPayload
|
|||||||
return (this);
|
return (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for bodyString
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getBodyString()
|
||||||
|
{
|
||||||
|
return (this.bodyString);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for bodyString
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setBodyString(String bodyString)
|
||||||
|
{
|
||||||
|
this.bodyString = bodyString;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for bodyString
|
||||||
|
*******************************************************************************/
|
||||||
|
public ProcessBasedRouterPayload withBodyString(String bodyString)
|
||||||
|
{
|
||||||
|
this.bodyString = bodyString;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,159 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2025. Kingsrook, LLC
|
||||||
|
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||||
|
* contact@kingsrook.com
|
||||||
|
* https://github.com/Kingsrook/
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.kingsrook.qqq.middleware.javalin.routeproviders.contexthandlers;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
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.tables.storage.StorageInput;
|
||||||
|
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
||||||
|
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
|
||||||
|
import io.javalin.http.Context;
|
||||||
|
import io.javalin.http.HttpStatus;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** default implementation of this interface. reads the request body as a string
|
||||||
|
*******************************************************************************/
|
||||||
|
public class DefaultRouteProviderContextHandler implements RouteProviderContextHandlerInterface
|
||||||
|
{
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public void handleRequest(Context context, RunProcessInput input)
|
||||||
|
{
|
||||||
|
input.addValue("path", context.path());
|
||||||
|
input.addValue("method", context.method());
|
||||||
|
input.addValue("pathParams", new HashMap<>(context.pathParamMap()));
|
||||||
|
input.addValue("queryParams", new HashMap<>(context.queryParamMap()));
|
||||||
|
input.addValue("cookies", new HashMap<>(context.cookieMap()));
|
||||||
|
input.addValue("requestHeaders", new HashMap<>(context.headerMap()));
|
||||||
|
|
||||||
|
handleRequestBody(context, input);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
protected void handleRequestBody(Context context, RunProcessInput input)
|
||||||
|
{
|
||||||
|
input.addValue("formParams", new HashMap<>(context.formParamMap()));
|
||||||
|
input.addValue("bodyString", context.body());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public boolean handleResponse(Context context, RunProcessOutput runProcessOutput) throws QException
|
||||||
|
{
|
||||||
|
handleResponseHeaders(context, runProcessOutput);
|
||||||
|
|
||||||
|
//////////////
|
||||||
|
// response //
|
||||||
|
//////////////
|
||||||
|
Integer statusCode = runProcessOutput.getValueInteger("statusCode");
|
||||||
|
String redirectURL = runProcessOutput.getValueString("redirectURL");
|
||||||
|
|
||||||
|
if(StringUtils.hasContent(redirectURL))
|
||||||
|
{
|
||||||
|
context.redirect(redirectURL, statusCode == null ? HttpStatus.FOUND : HttpStatus.forStatus(statusCode));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(statusCode != null)
|
||||||
|
{
|
||||||
|
context.status(statusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(handleResponseBody(context, runProcessOutput))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
protected void handleResponseHeaders(Context context, RunProcessOutput runProcessOutput)
|
||||||
|
{
|
||||||
|
/////////////////
|
||||||
|
// headers map //
|
||||||
|
/////////////////
|
||||||
|
Serializable headers = runProcessOutput.getValue("responseHeaders");
|
||||||
|
if(headers instanceof Map headersMap)
|
||||||
|
{
|
||||||
|
for(Object key : headersMap.keySet())
|
||||||
|
{
|
||||||
|
context.header(ValueUtils.getValueAsString(key), ValueUtils.getValueAsString(headersMap.get(key)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
protected boolean handleResponseBody(Context context, RunProcessOutput runProcessOutput) throws QException
|
||||||
|
{
|
||||||
|
String responseString = runProcessOutput.getValueString("responseString");
|
||||||
|
byte[] responseBytes = runProcessOutput.getValueByteArray("responseBytes");
|
||||||
|
StorageInput responseStorageInput = (StorageInput) runProcessOutput.getValue("responseStorageInput");
|
||||||
|
if(StringUtils.hasContent(responseString))
|
||||||
|
{
|
||||||
|
context.result(responseString);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(responseBytes != null && responseBytes.length > 0)
|
||||||
|
{
|
||||||
|
context.result(responseBytes);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(responseStorageInput != null)
|
||||||
|
{
|
||||||
|
InputStream inputStream = new StorageAction().getInputStream(responseStorageInput);
|
||||||
|
context.result(inputStream);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2025. Kingsrook, LLC
|
||||||
|
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||||
|
* contact@kingsrook.com
|
||||||
|
* https://github.com/Kingsrook/
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.kingsrook.qqq.middleware.javalin.routeproviders.contexthandlers;
|
||||||
|
|
||||||
|
|
||||||
|
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 io.javalin.http.Context;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** interface for how to handle the javalin context for a process based route provider.
|
||||||
|
** e.g., taking things like query params and the request body into the process input
|
||||||
|
** and similarly for the http response from the process output..
|
||||||
|
*******************************************************************************/
|
||||||
|
public interface RouteProviderContextHandlerInterface
|
||||||
|
{
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
void handleRequest(Context context, RunProcessInput runProcessInput);
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
boolean handleResponse(Context context, RunProcessOutput runProcessOutput) throws QException;
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user