mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-19 21:50:45 +00:00
Initial implementation of api processes
This commit is contained in:
@ -30,14 +30,23 @@ import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import com.kingsrook.qqq.api.javalin.QBadRequestException;
|
||||
import com.kingsrook.qqq.api.model.APIVersion;
|
||||
import com.kingsrook.qqq.api.model.APIVersionRange;
|
||||
import com.kingsrook.qqq.api.model.metadata.ApiInstanceMetaData;
|
||||
import com.kingsrook.qqq.api.model.metadata.ApiOperation;
|
||||
import com.kingsrook.qqq.api.model.metadata.processes.ApiProcessCustomizers;
|
||||
import com.kingsrook.qqq.api.model.metadata.processes.ApiProcessMetaData;
|
||||
import com.kingsrook.qqq.api.model.metadata.processes.ApiProcessMetaDataContainer;
|
||||
import com.kingsrook.qqq.api.model.metadata.processes.PostRunApiProcessCustomizer;
|
||||
import com.kingsrook.qqq.api.model.metadata.processes.PreRunApiProcessCustomizer;
|
||||
import com.kingsrook.qqq.api.model.metadata.tables.ApiTableMetaData;
|
||||
import com.kingsrook.qqq.api.model.metadata.tables.ApiTableMetaDataContainer;
|
||||
import com.kingsrook.qqq.backend.core.actions.customizers.QCodeLoader;
|
||||
import com.kingsrook.qqq.backend.core.actions.permissions.PermissionsHelper;
|
||||
import com.kingsrook.qqq.backend.core.actions.permissions.TablePermissionSubType;
|
||||
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.DeleteAction;
|
||||
import com.kingsrook.qqq.backend.core.actions.tables.GetAction;
|
||||
@ -49,6 +58,8 @@ import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QNotFoundException;
|
||||
import com.kingsrook.qqq.backend.core.logging.LogPair;
|
||||
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.RunProcessOutput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.QInputSource;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.count.CountInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.count.CountOutput;
|
||||
@ -67,8 +78,10 @@ import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryOutput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.update.UpdateInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.update.UpdateOutput;
|
||||
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;
|
||||
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.model.statusmessages.BadInputStatusMessage;
|
||||
import com.kingsrook.qqq.backend.core.model.statusmessages.NotFoundStatusMessage;
|
||||
@ -96,10 +109,11 @@ public class ApiImplementation
|
||||
{
|
||||
private static final QLogger LOG = QLogger.getLogger(ApiImplementation.class);
|
||||
|
||||
/////////////////////////////////////
|
||||
// key: Pair<apiName, apiVersion> //
|
||||
/////////////////////////////////////
|
||||
private static Map<Pair<String, String>, Map<String, QTableMetaData>> tableApiNameMap = new HashMap<>();
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// key: Pair<apiName, apiVersion>, value: Map<name => metaData> //
|
||||
///////////////////////////////////////////////////////////////////
|
||||
private static Map<Pair<String, String>, Map<String, QTableMetaData>> tableApiNameMap = new HashMap<>();
|
||||
private static Map<Pair<String, String>, Map<String, QProcessMetaData>> processApiNameMap = new HashMap<>();
|
||||
|
||||
|
||||
|
||||
@ -896,6 +910,99 @@ public class ApiImplementation
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static Map<String, Serializable> runProcess(ApiInstanceMetaData apiInstanceMetaData, String version, String processApiName, Map<String, String> paramMap) throws QException
|
||||
{
|
||||
QProcessMetaData process = validateProcessAndVersion(apiInstanceMetaData, version, processApiName);
|
||||
String processName = process.getName();
|
||||
ApiProcessMetaData apiProcessMetaData = getApiProcessMetaDataIfProcessIsInApi(apiInstanceMetaData, process);
|
||||
|
||||
List<String> badRequestMessages = new ArrayList<>();
|
||||
Map<String, Serializable> output = new LinkedHashMap<>();
|
||||
|
||||
String processUUID = UUID.randomUUID().toString();
|
||||
|
||||
RunProcessInput runProcessInput = new RunProcessInput();
|
||||
runProcessInput.setProcessName(processName);
|
||||
runProcessInput.setFrontendStepBehavior(RunProcessInput.FrontendStepBehavior.SKIP);
|
||||
runProcessInput.setProcessUUID(processUUID);
|
||||
// todo i don't think runProcessInput.setCallback();
|
||||
// todo i don't think runProcessInput.setAsyncJobCallback();
|
||||
|
||||
//////////////////////
|
||||
// map input values //
|
||||
//////////////////////
|
||||
for(QFieldMetaData inputField : CollectionUtils.nonNullList(apiProcessMetaData.getInputFields()))
|
||||
{
|
||||
String value = paramMap.get(inputField.getName());
|
||||
if(!StringUtils.hasContent(value) && inputField.getIsRequired())
|
||||
{
|
||||
badRequestMessages.add("Missing value for required input field " + inputField.getName());
|
||||
continue;
|
||||
}
|
||||
|
||||
// todo - types?
|
||||
|
||||
runProcessInput.addValue(inputField.getName(), value);
|
||||
}
|
||||
|
||||
// todo! runProcessInput.setRecords(records);
|
||||
|
||||
/////////////////////////////////////////
|
||||
// throw if bad inputs have been noted //
|
||||
/////////////////////////////////////////
|
||||
if(!badRequestMessages.isEmpty())
|
||||
{
|
||||
if(badRequestMessages.size() == 1)
|
||||
{
|
||||
throw (new QBadRequestException(badRequestMessages.get(0)));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw (new QBadRequestException("Request failed with " + badRequestMessages.size() + " reasons: " + StringUtils.join(" \n", badRequestMessages)));
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////
|
||||
// run pre-customizer, if there is one //
|
||||
/////////////////////////////////////////
|
||||
Map<String, QCodeReference> customizers = apiProcessMetaData.getCustomizers();
|
||||
if(customizers != null && customizers.containsKey(ApiProcessCustomizers.PRE_RUN.getRole()))
|
||||
{
|
||||
PreRunApiProcessCustomizer preRunCustomizer = QCodeLoader.getAdHoc(PreRunApiProcessCustomizer.class, customizers.get(ApiProcessCustomizers.PRE_RUN.getRole()));
|
||||
preRunCustomizer.preApiRun(runProcessInput);
|
||||
}
|
||||
|
||||
/////////////////////
|
||||
// run the process //
|
||||
/////////////////////
|
||||
RunProcessAction runProcessAction = new RunProcessAction();
|
||||
RunProcessOutput runProcessOutput = runProcessAction.execute(runProcessInput);
|
||||
|
||||
/////////////////////////////////////////
|
||||
// run post-customizer, if there is one //
|
||||
/////////////////////////////////////////
|
||||
if(customizers != null && customizers.containsKey(ApiProcessCustomizers.POST_RUN.getRole()))
|
||||
{
|
||||
PostRunApiProcessCustomizer postRunCustomizer = QCodeLoader.getAdHoc(PostRunApiProcessCustomizer.class, customizers.get(ApiProcessCustomizers.POST_RUN.getRole()));
|
||||
postRunCustomizer.postApiRun(runProcessInput, runProcessOutput);
|
||||
}
|
||||
|
||||
///////////////////////
|
||||
// map output values //
|
||||
///////////////////////
|
||||
for(QFieldMetaData outputField : apiProcessMetaData.getOutputFields())
|
||||
{
|
||||
output.put(outputField.getName(), runProcessOutput.getValues().get(outputField.getName()));
|
||||
}
|
||||
|
||||
return (output);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@ -1078,14 +1185,14 @@ public class ApiImplementation
|
||||
ApiTableMetaDataContainer apiTableMetaDataContainer = ApiTableMetaDataContainer.of(table);
|
||||
if(apiTableMetaDataContainer == null)
|
||||
{
|
||||
LOG.info("404 because table apiMetaDataContainer is null", logPairs);
|
||||
LOG.info("404 because table apiTableMetaDataContainer is null", logPairs);
|
||||
throw (new QNotFoundException("Could not find a table named " + tableApiName + " in this api."));
|
||||
}
|
||||
|
||||
ApiTableMetaData apiTableMetaData = apiTableMetaDataContainer.getApiTableMetaData(apiInstanceMetaData.getName());
|
||||
if(apiTableMetaData == null)
|
||||
{
|
||||
LOG.info("404 because table apiMetaData is null", logPairs);
|
||||
LOG.info("404 because table apiTableMetaData is null", logPairs);
|
||||
throw (new QNotFoundException("Could not find a table named " + tableApiName + " in this api."));
|
||||
}
|
||||
|
||||
@ -1126,6 +1233,65 @@ public class ApiImplementation
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static QProcessMetaData validateProcessAndVersion(ApiInstanceMetaData apiInstanceMetaData, String version, String processApiName) throws QNotFoundException
|
||||
{
|
||||
QProcessMetaData process = getProcessByApiName(apiInstanceMetaData.getName(), version, processApiName);
|
||||
LogPair[] logPairs = new LogPair[] { logPair("apiName", apiInstanceMetaData.getName()), logPair("version", version), logPair("processApiName", processApiName) };
|
||||
|
||||
if(process == null)
|
||||
{
|
||||
LOG.info("404 because process is null (processApiName=" + processApiName + ")", logPairs);
|
||||
throw (new QNotFoundException("Could not find a process named " + processApiName + " in this api."));
|
||||
}
|
||||
|
||||
if(BooleanUtils.isTrue(process.getIsHidden()))
|
||||
{
|
||||
LOG.info("404 because process isHidden", logPairs);
|
||||
throw (new QNotFoundException("Could not find a process named " + processApiName + " in this api."));
|
||||
}
|
||||
|
||||
ApiProcessMetaDataContainer apiProcessMetaDataContainer = ApiProcessMetaDataContainer.of(process);
|
||||
if(apiProcessMetaDataContainer == null)
|
||||
{
|
||||
LOG.info("404 because process apiProcessMetaDataContainer is null", logPairs);
|
||||
throw (new QNotFoundException("Could not find a process named " + processApiName + " in this api."));
|
||||
}
|
||||
|
||||
ApiProcessMetaData apiProcessMetaData = apiProcessMetaDataContainer.getApiProcessMetaData(apiInstanceMetaData.getName());
|
||||
if(apiProcessMetaData == null)
|
||||
{
|
||||
LOG.info("404 because process apiProcessMetaData is null", logPairs);
|
||||
throw (new QNotFoundException("Could not find a process named " + processApiName + " in this api."));
|
||||
}
|
||||
|
||||
if(BooleanUtils.isTrue(apiProcessMetaData.getIsExcluded()))
|
||||
{
|
||||
LOG.info("404 because process is excluded", logPairs);
|
||||
throw (new QNotFoundException("Could not find a process named " + processApiName + " in this api."));
|
||||
}
|
||||
|
||||
APIVersion requestApiVersion = new APIVersion(version);
|
||||
List<APIVersion> supportedVersions = apiInstanceMetaData.getSupportedVersions();
|
||||
if(CollectionUtils.nullSafeIsEmpty(supportedVersions) || !supportedVersions.contains(requestApiVersion))
|
||||
{
|
||||
LOG.info("404 because requested version is not supported", logPairs);
|
||||
throw (new QNotFoundException(version + " is not a supported version in this api."));
|
||||
}
|
||||
|
||||
if(!apiProcessMetaData.getApiVersionRange().includes(requestApiVersion))
|
||||
{
|
||||
LOG.info("404 because process version range does not include requested version", logPairs);
|
||||
throw (new QNotFoundException(version + " is not a supported version for process " + processApiName + " in this api."));
|
||||
}
|
||||
|
||||
return (process);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@ -1167,6 +1333,100 @@ public class ApiImplementation
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private static QProcessMetaData getProcessByApiName(String apiName, String version, String processApiName)
|
||||
{
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// processApiNameMap is a map of (apiName,apiVersion) => Map<String, QProcessMetaData>. //
|
||||
// that is to say, a 2-level map. The first level is keyed by (apiName,apiVersion) pairs. //
|
||||
// the second level is keyed by processApiNames. //
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Pair<String, String> key = new Pair<>(apiName, version);
|
||||
if(processApiNameMap.get(key) == null)
|
||||
{
|
||||
Map<String, QProcessMetaData> map = new HashMap<>();
|
||||
|
||||
for(QProcessMetaData process : QContext.getQInstance().getProcesses().values())
|
||||
{
|
||||
ApiProcessMetaDataContainer apiProcessMetaDataContainer = ApiProcessMetaDataContainer.of(process);
|
||||
if(apiProcessMetaDataContainer != null)
|
||||
{
|
||||
ApiProcessMetaData apiProcessMetaData = apiProcessMetaDataContainer.getApiProcessMetaData(apiName);
|
||||
if(apiProcessMetaData != null)
|
||||
{
|
||||
String name = process.getName();
|
||||
if(StringUtils.hasContent(apiProcessMetaData.getApiProcessName()))
|
||||
{
|
||||
name = apiProcessMetaData.getApiProcessName();
|
||||
}
|
||||
map.put(name, process);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
processApiNameMap.put(key, map);
|
||||
}
|
||||
|
||||
return (processApiNameMap.get(key).get(processApiName));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static ApiProcessMetaData getApiProcessMetaDataIfProcessIsInApi(ApiInstanceMetaData apiInstanceMetaData, QProcessMetaData process)
|
||||
{
|
||||
if(BooleanUtils.isTrue(process.getIsHidden()))
|
||||
{
|
||||
LOG.trace("excluding process because it is hidden (process=" + process.getName() + ")");
|
||||
return (null);
|
||||
}
|
||||
|
||||
ApiProcessMetaDataContainer apiProcessMetaDataContainer = ApiProcessMetaDataContainer.of(process);
|
||||
if(apiProcessMetaDataContainer == null)
|
||||
{
|
||||
LOG.trace("excluding process because apiProcessMetaDataContainer is null (process=" + process.getName() + ")");
|
||||
return (null);
|
||||
}
|
||||
|
||||
ApiProcessMetaData apiProcessMetaData = apiProcessMetaDataContainer.getApiProcessMetaData(apiInstanceMetaData.getName());
|
||||
if(apiProcessMetaData == null)
|
||||
{
|
||||
LOG.trace("excluding process because apiProcessMetaData is null (process=" + process.getName() + ")");
|
||||
return (null);
|
||||
}
|
||||
|
||||
if(BooleanUtils.isTrue(apiProcessMetaData.getIsExcluded()))
|
||||
{
|
||||
LOG.trace("excluding process because is excluded (process=" + process.getName() + ")");
|
||||
return (null);
|
||||
}
|
||||
|
||||
boolean isProcessInAnySupportedVersions = false;
|
||||
List<APIVersion> supportedVersions = apiInstanceMetaData.getSupportedVersions();
|
||||
APIVersionRange apiVersionRange = apiProcessMetaData.getApiVersionRange();
|
||||
for(APIVersion supportedVersion : supportedVersions)
|
||||
{
|
||||
if(apiVersionRange.includes(supportedVersion))
|
||||
{
|
||||
isProcessInAnySupportedVersions = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!isProcessInAnySupportedVersions)
|
||||
{
|
||||
LOG.trace("excluding process because it is not in any supported versions (process=" + process.getName() + ")");
|
||||
return (null);
|
||||
}
|
||||
|
||||
return (apiProcessMetaData);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
|
@ -29,6 +29,7 @@ import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@ -43,8 +44,10 @@ import com.kingsrook.qqq.api.model.actions.GenerateOpenApiSpecOutput;
|
||||
import com.kingsrook.qqq.api.model.metadata.ApiInstanceMetaData;
|
||||
import com.kingsrook.qqq.api.model.metadata.ApiInstanceMetaDataContainer;
|
||||
import com.kingsrook.qqq.api.model.metadata.ApiInstanceMetaDataProvider;
|
||||
import com.kingsrook.qqq.api.model.metadata.processes.ApiProcessMetaData;
|
||||
import com.kingsrook.qqq.api.model.metadata.tables.ApiTableMetaData;
|
||||
import com.kingsrook.qqq.api.model.metadata.tables.ApiTableMetaDataContainer;
|
||||
import com.kingsrook.qqq.api.model.openapi.HttpMethod;
|
||||
import com.kingsrook.qqq.backend.core.actions.tables.GetAction;
|
||||
import com.kingsrook.qqq.backend.core.actions.tables.InsertAction;
|
||||
import com.kingsrook.qqq.backend.core.context.QContext;
|
||||
@ -54,6 +57,7 @@ import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QModuleDispatchException;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QNotFoundException;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QPermissionDeniedException;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QRuntimeException;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QUserFacingException;
|
||||
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.AbstractActionInput;
|
||||
@ -66,6 +70,8 @@ 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.authentication.Auth0AuthenticationMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.branding.QBrandingMetaData;
|
||||
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.model.session.QSession;
|
||||
import com.kingsrook.qqq.backend.core.model.session.QUser;
|
||||
@ -156,10 +162,43 @@ public class QJavalinApiHandler
|
||||
////////////////////////////////////////////
|
||||
ApiBuilder.get("/", context -> doSpecHtml(context, apiInstanceMetaData));
|
||||
|
||||
///////////////////////////////////////////
|
||||
// add known paths for specs & docs page //
|
||||
///////////////////////////////////////////
|
||||
ApiBuilder.get("/openapi.yaml", context -> doSpecYaml(context, apiInstanceMetaData));
|
||||
ApiBuilder.get("/openapi.json", context -> doSpecJson(context, apiInstanceMetaData));
|
||||
ApiBuilder.get("/openapi.html", context -> doSpecHtml(context, apiInstanceMetaData));
|
||||
|
||||
///////////////////
|
||||
// add processes //
|
||||
///////////////////
|
||||
for(QProcessMetaData process : qInstance.getProcesses().values())
|
||||
{
|
||||
ApiProcessMetaData apiProcessMetaData = ApiImplementation.getApiProcessMetaDataIfProcessIsInApi(apiInstanceMetaData, process);
|
||||
if(apiProcessMetaData != null)
|
||||
{
|
||||
String path = getProcessApiPath(process, apiProcessMetaData, apiInstanceMetaData);
|
||||
HttpMethod method = apiProcessMetaData.getMethod();
|
||||
switch(method)
|
||||
{
|
||||
case GET -> ApiBuilder.get(path, context -> runProcess(context, process, apiProcessMetaData, apiInstanceMetaData));
|
||||
case POST -> ApiBuilder.post(path, context -> runProcess(context, process, apiProcessMetaData, apiInstanceMetaData));
|
||||
case PUT -> ApiBuilder.put(path, context -> runProcess(context, process, apiProcessMetaData, apiInstanceMetaData));
|
||||
case PATCH -> ApiBuilder.patch(path, context -> runProcess(context, process, apiProcessMetaData, apiInstanceMetaData));
|
||||
case DELETE -> ApiBuilder.delete(path, context -> runProcess(context, process, apiProcessMetaData, apiInstanceMetaData));
|
||||
default -> throw (new QRuntimeException("Unrecognized http method [" + method + "] for process [" + process.getName() + "]"));
|
||||
}
|
||||
|
||||
if(doesProcessSupportAsync(apiInstanceMetaData, process))
|
||||
{
|
||||
ApiBuilder.get(path + "/status/{processId}", context -> getProcessStatus(context, apiInstanceMetaData));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////
|
||||
// add wildcard paths for tables //
|
||||
///////////////////////////////////
|
||||
ApiBuilder.path("/{tableName}", () ->
|
||||
{
|
||||
ApiBuilder.get("/openapi.yaml", context -> doSpecYaml(context, apiInstanceMetaData));
|
||||
@ -208,6 +247,104 @@ public class QJavalinApiHandler
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private void getProcessStatus(Context context, ApiInstanceMetaData apiInstanceMetaData)
|
||||
{
|
||||
// todo!
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@SuppressWarnings("checkstyle:indentation")
|
||||
private void runProcess(Context context, QProcessMetaData processMetaData, ApiProcessMetaData apiProcessMetaData, ApiInstanceMetaData apiInstanceMetaData)
|
||||
{
|
||||
String version = context.pathParam("version");
|
||||
APILog apiLog = newAPILog(context);
|
||||
|
||||
try
|
||||
{
|
||||
setupSession(context, null, version, apiInstanceMetaData);
|
||||
QJavalinAccessLogger.logStart("apiRunProcess", logPair("process", processMetaData.getName()));
|
||||
|
||||
Map<String, String> parameters = new LinkedHashMap<>();
|
||||
for(QFieldMetaData inputField : CollectionUtils.nonNullList(apiProcessMetaData.getInputFields()))
|
||||
{
|
||||
String value = switch(apiProcessMetaData.getMethod())
|
||||
{
|
||||
case GET -> context.queryParam(inputField.getName());
|
||||
// todo - other methods (all from a JSON body??)
|
||||
default -> throw new QException("Http method " + apiLog.getMethod() + " is not yet implemented for reading parameters");
|
||||
};
|
||||
parameters.put(inputField.getName(), value);
|
||||
}
|
||||
|
||||
Map<String, Serializable> outputRecord = ApiImplementation.runProcess(apiInstanceMetaData, version, apiProcessMetaData.getApiProcessName(), parameters);
|
||||
|
||||
QJavalinAccessLogger.logEndSuccess();
|
||||
String resultString = toJson(outputRecord);
|
||||
context.result(resultString);
|
||||
storeApiLog(apiLog.withStatusCode(context.statusCode()).withResponseBody(resultString));
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
QJavalinAccessLogger.logEndFail(e);
|
||||
handleException(context, e, apiLog);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private boolean doesProcessSupportAsync(ApiInstanceMetaData apiInstanceMetaData, QProcessMetaData process)
|
||||
{
|
||||
// todo - implement
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private String getProcessApiPath(QProcessMetaData process, ApiProcessMetaData apiProcessMetaData, ApiInstanceMetaData apiInstanceMetaData)
|
||||
{
|
||||
if(StringUtils.hasContent(apiProcessMetaData.getPath()))
|
||||
{
|
||||
return apiProcessMetaData.getPath() + "/" + apiProcessMetaData.getApiProcessName();
|
||||
}
|
||||
else if(StringUtils.hasContent(process.getTableName()))
|
||||
{
|
||||
QTableMetaData table = qInstance.getTable(process.getTableName());
|
||||
String tablePathPart = table.getName();
|
||||
ApiTableMetaDataContainer apiTableMetaDataContainer = ApiTableMetaDataContainer.of(table);
|
||||
if(apiTableMetaDataContainer != null)
|
||||
{
|
||||
ApiTableMetaData apiTableMetaData = apiTableMetaDataContainer.getApis().get(apiInstanceMetaData.getName());
|
||||
if(apiTableMetaData != null)
|
||||
{
|
||||
if(StringUtils.hasContent(apiTableMetaData.getApiTableName()))
|
||||
{
|
||||
tablePathPart = apiTableMetaData.getApiTableName();
|
||||
}
|
||||
}
|
||||
}
|
||||
return tablePathPart + "/" + apiProcessMetaData.getApiProcessName();
|
||||
}
|
||||
else
|
||||
{
|
||||
return apiProcessMetaData.getApiProcessName();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
|
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2022. 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.api.model.metadata.processes;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public enum ApiProcessCustomizers
|
||||
{
|
||||
PRE_RUN("preRun", PreRunApiProcessCustomizer.class),
|
||||
POST_RUN("postRun", PreRunApiProcessCustomizer.class);
|
||||
|
||||
private final String role;
|
||||
private final Class<?> expectedType;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
ApiProcessCustomizers(String role, Class<?> expectedType)
|
||||
{
|
||||
this.role = role;
|
||||
this.expectedType = expectedType;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Get the FilesystemTableCustomer for a given role (e.g., the role used in meta-data, not
|
||||
** the enum-constant name).
|
||||
*******************************************************************************/
|
||||
public static ApiProcessCustomizers forRole(String name)
|
||||
{
|
||||
for(ApiProcessCustomizers value : values())
|
||||
{
|
||||
if(value.role.equals(name))
|
||||
{
|
||||
return (value);
|
||||
}
|
||||
}
|
||||
|
||||
return (null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for role
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getRole()
|
||||
{
|
||||
return role;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for expectedType
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Class<?> getExpectedType()
|
||||
{
|
||||
return expectedType;
|
||||
}
|
||||
}
|
@ -0,0 +1,496 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2023. 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.api.model.metadata.processes;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import com.kingsrook.qqq.api.ApiSupplementType;
|
||||
import com.kingsrook.qqq.api.model.APIVersionRange;
|
||||
import com.kingsrook.qqq.api.model.metadata.fields.ApiFieldMetaData;
|
||||
import com.kingsrook.qqq.api.model.metadata.fields.ApiFieldMetaDataContainer;
|
||||
import com.kingsrook.qqq.api.model.openapi.HttpMethod;
|
||||
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.processes.QFrontendStepMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QStepMetaData;
|
||||
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class ApiProcessMetaData
|
||||
{
|
||||
private String initialVersion;
|
||||
private String finalVersion;
|
||||
|
||||
private String apiProcessName;
|
||||
private Boolean isExcluded;
|
||||
|
||||
private String path;
|
||||
private HttpMethod method;
|
||||
|
||||
private List<QFieldMetaData> inputFields;
|
||||
private List<QFieldMetaData> outputFields;
|
||||
|
||||
private Map<String, QCodeReference> customizers;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public ApiProcessMetaData withInferredInputFields(QProcessMetaData processMetaData)
|
||||
{
|
||||
inputFields = new ArrayList<>();
|
||||
for(QStepMetaData stepMetaData : CollectionUtils.nonNullList(processMetaData.getStepList()))
|
||||
{
|
||||
if(stepMetaData instanceof QFrontendStepMetaData frontendStep)
|
||||
{
|
||||
inputFields.addAll(frontendStep.getInputFields());
|
||||
}
|
||||
}
|
||||
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public ApiProcessMetaData withInferredOutputFields(QProcessMetaData processMetaData)
|
||||
{
|
||||
outputFields = new ArrayList<>();
|
||||
for(QStepMetaData stepMetaData : CollectionUtils.nonNullList(processMetaData.getStepList()))
|
||||
{
|
||||
if(stepMetaData instanceof QFrontendStepMetaData frontendStep)
|
||||
{
|
||||
outputFields.addAll(frontendStep.getOutputFields());
|
||||
}
|
||||
}
|
||||
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public APIVersionRange getApiVersionRange()
|
||||
{
|
||||
if(getInitialVersion() == null)
|
||||
{
|
||||
return APIVersionRange.none();
|
||||
}
|
||||
|
||||
return (getFinalVersion() != null
|
||||
? APIVersionRange.betweenAndIncluding(getInitialVersion(), getFinalVersion())
|
||||
: APIVersionRange.afterAndIncluding(getInitialVersion()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void enrich(String apiName, QProcessMetaData process)
|
||||
{
|
||||
if(!StringUtils.hasContent(getApiProcessName()))
|
||||
{
|
||||
setApiProcessName(process.getName());
|
||||
}
|
||||
|
||||
if(initialVersion != null)
|
||||
{
|
||||
///////////////////////////////////////////////////////////////
|
||||
// make sure all fields have at least an initial version set //
|
||||
///////////////////////////////////////////////////////////////
|
||||
for(QFieldMetaData field : CollectionUtils.mergeLists(getInputFields(), getOutputFields()))
|
||||
{
|
||||
ApiFieldMetaData apiFieldMetaData = ensureFieldHasApiSupplementalMetaData(apiName, field);
|
||||
if(apiFieldMetaData.getInitialVersion() == null)
|
||||
{
|
||||
apiFieldMetaData.setInitialVersion(initialVersion);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private static ApiFieldMetaData ensureFieldHasApiSupplementalMetaData(String apiName, QFieldMetaData field)
|
||||
{
|
||||
if(field.getSupplementalMetaData(ApiSupplementType.NAME) == null)
|
||||
{
|
||||
field.withSupplementalMetaData(new ApiFieldMetaDataContainer());
|
||||
}
|
||||
|
||||
ApiFieldMetaDataContainer apiFieldMetaDataContainer = ApiFieldMetaDataContainer.of(field);
|
||||
if(apiFieldMetaDataContainer.getApiFieldMetaData(apiName) == null)
|
||||
{
|
||||
apiFieldMetaDataContainer.withApiFieldMetaData(apiName, new ApiFieldMetaData());
|
||||
}
|
||||
|
||||
return (apiFieldMetaDataContainer.getApiFieldMetaData(apiName));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for a single outputField
|
||||
*******************************************************************************/
|
||||
public ApiProcessMetaData withOutputField(QFieldMetaData outputField)
|
||||
{
|
||||
if(this.outputFields == null)
|
||||
{
|
||||
this.outputFields = new ArrayList<>();
|
||||
}
|
||||
this.outputFields.add(outputField);
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for a single inputField
|
||||
*******************************************************************************/
|
||||
public ApiProcessMetaData withInputField(QFieldMetaData inputField)
|
||||
{
|
||||
if(this.inputFields == null)
|
||||
{
|
||||
this.inputFields = new ArrayList<>();
|
||||
}
|
||||
this.inputFields.add(inputField);
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for initialVersion
|
||||
*******************************************************************************/
|
||||
public String getInitialVersion()
|
||||
{
|
||||
return (this.initialVersion);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for initialVersion
|
||||
*******************************************************************************/
|
||||
public void setInitialVersion(String initialVersion)
|
||||
{
|
||||
this.initialVersion = initialVersion;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for initialVersion
|
||||
*******************************************************************************/
|
||||
public ApiProcessMetaData withInitialVersion(String initialVersion)
|
||||
{
|
||||
this.initialVersion = initialVersion;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for finalVersion
|
||||
*******************************************************************************/
|
||||
public String getFinalVersion()
|
||||
{
|
||||
return (this.finalVersion);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for finalVersion
|
||||
*******************************************************************************/
|
||||
public void setFinalVersion(String finalVersion)
|
||||
{
|
||||
this.finalVersion = finalVersion;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for finalVersion
|
||||
*******************************************************************************/
|
||||
public ApiProcessMetaData withFinalVersion(String finalVersion)
|
||||
{
|
||||
this.finalVersion = finalVersion;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for apiProcessName
|
||||
*******************************************************************************/
|
||||
public String getApiProcessName()
|
||||
{
|
||||
return (this.apiProcessName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for apiProcessName
|
||||
*******************************************************************************/
|
||||
public void setApiProcessName(String apiProcessName)
|
||||
{
|
||||
this.apiProcessName = apiProcessName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for apiProcessName
|
||||
*******************************************************************************/
|
||||
public ApiProcessMetaData withApiProcessName(String apiProcessName)
|
||||
{
|
||||
this.apiProcessName = apiProcessName;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for isExcluded
|
||||
*******************************************************************************/
|
||||
public Boolean getIsExcluded()
|
||||
{
|
||||
return (this.isExcluded);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for isExcluded
|
||||
*******************************************************************************/
|
||||
public void setIsExcluded(Boolean isExcluded)
|
||||
{
|
||||
this.isExcluded = isExcluded;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for isExcluded
|
||||
*******************************************************************************/
|
||||
public ApiProcessMetaData withIsExcluded(Boolean isExcluded)
|
||||
{
|
||||
this.isExcluded = isExcluded;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for method
|
||||
*******************************************************************************/
|
||||
public HttpMethod getMethod()
|
||||
{
|
||||
return (this.method);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for method
|
||||
*******************************************************************************/
|
||||
public void setMethod(HttpMethod method)
|
||||
{
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for method
|
||||
*******************************************************************************/
|
||||
public ApiProcessMetaData withMethod(HttpMethod method)
|
||||
{
|
||||
this.method = method;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for path
|
||||
*******************************************************************************/
|
||||
public String getPath()
|
||||
{
|
||||
return (this.path);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for path
|
||||
*******************************************************************************/
|
||||
public void setPath(String path)
|
||||
{
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for path
|
||||
*******************************************************************************/
|
||||
public ApiProcessMetaData withPath(String path)
|
||||
{
|
||||
this.path = path;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for inputFields
|
||||
*******************************************************************************/
|
||||
public List<QFieldMetaData> getInputFields()
|
||||
{
|
||||
return (this.inputFields);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for inputFields
|
||||
*******************************************************************************/
|
||||
public void setInputFields(List<QFieldMetaData> inputFields)
|
||||
{
|
||||
this.inputFields = inputFields;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for inputFields
|
||||
*******************************************************************************/
|
||||
public ApiProcessMetaData withInputFields(List<QFieldMetaData> inputFields)
|
||||
{
|
||||
this.inputFields = inputFields;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for outputFields
|
||||
*******************************************************************************/
|
||||
public List<QFieldMetaData> getOutputFields()
|
||||
{
|
||||
return (this.outputFields);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for outputFields
|
||||
*******************************************************************************/
|
||||
public void setOutputFields(List<QFieldMetaData> outputFields)
|
||||
{
|
||||
this.outputFields = outputFields;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for outputFields
|
||||
*******************************************************************************/
|
||||
public ApiProcessMetaData withOutputFields(List<QFieldMetaData> outputFields)
|
||||
{
|
||||
this.outputFields = outputFields;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for customizers
|
||||
*******************************************************************************/
|
||||
public Map<String, QCodeReference> getCustomizers()
|
||||
{
|
||||
return (this.customizers);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for customizers
|
||||
*******************************************************************************/
|
||||
public void setCustomizers(Map<String, QCodeReference> customizers)
|
||||
{
|
||||
this.customizers = customizers;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for customizers
|
||||
*******************************************************************************/
|
||||
public ApiProcessMetaData withCustomizers(Map<String, QCodeReference> customizers)
|
||||
{
|
||||
this.customizers = customizers;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public ApiProcessMetaData withCustomizer(String role, QCodeReference customizer)
|
||||
{
|
||||
if(this.customizers == null)
|
||||
{
|
||||
this.customizers = new HashMap<>();
|
||||
}
|
||||
|
||||
if(this.customizers.containsKey(role))
|
||||
{
|
||||
throw (new IllegalArgumentException("Attempt to add a second customizer with role [" + role + "] to apiProcess [" + apiProcessName + "]."));
|
||||
}
|
||||
this.customizers.put(role, customizer);
|
||||
return (this);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2023. 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.api.model.metadata.processes;
|
||||
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import com.kingsrook.qqq.api.ApiSupplementType;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QSupplementalProcessMetaData;
|
||||
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class ApiProcessMetaDataContainer extends QSupplementalProcessMetaData
|
||||
{
|
||||
private Map<String, ApiProcessMetaData> apis;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Constructor
|
||||
**
|
||||
*******************************************************************************/
|
||||
public ApiProcessMetaDataContainer()
|
||||
{
|
||||
setType("api");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static ApiProcessMetaDataContainer of(QProcessMetaData process)
|
||||
{
|
||||
return ((ApiProcessMetaDataContainer) process.getSupplementalMetaData(ApiSupplementType.NAME));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public void enrich(QProcessMetaData process)
|
||||
{
|
||||
super.enrich(process);
|
||||
|
||||
for(Map.Entry<String, ApiProcessMetaData> entry : CollectionUtils.nonNullMap(apis).entrySet())
|
||||
{
|
||||
entry.getValue().enrich(entry.getKey(), process);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for apis
|
||||
*******************************************************************************/
|
||||
public Map<String, ApiProcessMetaData> getApis()
|
||||
{
|
||||
return (this.apis);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for apis
|
||||
*******************************************************************************/
|
||||
public ApiProcessMetaData getApiProcessMetaData(String apiName)
|
||||
{
|
||||
if(this.apis == null)
|
||||
{
|
||||
return (null);
|
||||
}
|
||||
|
||||
return (this.apis.get(apiName));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for apis
|
||||
*******************************************************************************/
|
||||
public void setApis(Map<String, ApiProcessMetaData> apis)
|
||||
{
|
||||
this.apis = apis;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for apis
|
||||
*******************************************************************************/
|
||||
public ApiProcessMetaDataContainer withApis(Map<String, ApiProcessMetaData> apis)
|
||||
{
|
||||
this.apis = apis;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for apis
|
||||
*******************************************************************************/
|
||||
public ApiProcessMetaDataContainer withApiProcessMetaData(String apiName, ApiProcessMetaData apiProcessMetaData)
|
||||
{
|
||||
if(this.apis == null)
|
||||
{
|
||||
this.apis = new LinkedHashMap<>();
|
||||
}
|
||||
this.apis.put(apiName, apiProcessMetaData);
|
||||
return (this);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package com.kingsrook.qqq.api.model.metadata.processes;
|
||||
|
||||
|
||||
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;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public interface PostRunApiProcessCustomizer
|
||||
{
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
void postApiRun(RunProcessInput runProcessInput, RunProcessOutput runProcessOutput) throws QException;
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.kingsrook.qqq.api.model.metadata.processes;
|
||||
|
||||
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessInput;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public interface PreRunApiProcessCustomizer
|
||||
{
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
void preApiRun(RunProcessInput runProcessInput) throws QException;
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package com.kingsrook.qqq.api.model.openapi;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public enum HttpMethod
|
||||
{
|
||||
GET,
|
||||
POST,
|
||||
PUT,
|
||||
PATCH,
|
||||
DELETE
|
||||
}
|
Reference in New Issue
Block a user