mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-19 13:40:44 +00:00
Merge branch 'feature/CTLE-433-cart-rover-now-extensiv-integration' into integration/sprint-26
This commit is contained in:
@ -52,6 +52,7 @@ 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.fields.AdornmentType;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.cache.CacheUseCase;
|
||||
@ -430,7 +431,7 @@ public class GetAction
|
||||
{
|
||||
returnRecord.removeValue(fieldName);
|
||||
}
|
||||
else if(field.getType() != null && field.getType().needsMasked())
|
||||
else if(getInput.getShouldMaskPasswords() && field.getType() != null && field.getType().needsMasked() && !field.hasAdornmentType(AdornmentType.REVEAL))
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// empty out the value completely first (which will remove from //
|
||||
|
@ -47,6 +47,7 @@ import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryOutput;
|
||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.AdornmentType;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.joins.JoinOn;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.joins.QJoinMetaData;
|
||||
@ -283,7 +284,7 @@ public class QueryAction
|
||||
{
|
||||
hiddenFields.add(fieldName);
|
||||
}
|
||||
else if(field.getType() != null && field.getType().needsMasked())
|
||||
else if(queryInput.getShouldMaskPasswords() && field.getType() != null && field.getType().needsMasked() && !field.hasAdornmentType(AdornmentType.REVEAL))
|
||||
{
|
||||
maskedFields.add(fieldName);
|
||||
}
|
||||
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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.backend.core.exceptions;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** User-facing exception for when user provided bad or missing data in their request
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class QBadRequestException extends QUserFacingException
|
||||
{
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Constructor of message
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QBadRequestException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Constructor of message & cause
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QBadRequestException(String message, Throwable cause)
|
||||
{
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
}
|
@ -67,6 +67,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.queues.SQSQueueProviderMeta
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.reporting.QReportDataSource;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.reporting.QReportField;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.reporting.QReportView;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.scheduleing.QScheduleMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.security.FieldSecurityLock;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.security.RecordSecurityLock;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.AssociatedScript;
|
||||
@ -1208,6 +1209,23 @@ public class QInstanceValidator
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// if the process has a schedule, make sure required schedule data populated //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
if(process.getSchedule() != null)
|
||||
{
|
||||
QScheduleMetaData schedule = process.getSchedule();
|
||||
assertCondition(schedule.getRepeatMillis() != null || schedule.getRepeatSeconds() != null, "Either repeat millis or repeat seconds must be set on schedule in process " + processName);
|
||||
|
||||
if(schedule.getBackendVariant() != null)
|
||||
{
|
||||
assertCondition(schedule.getVariantRunStrategy() != null, "A variant strategy was not set for " + schedule.getBackendVariant() + " on schedule in process " + processName);
|
||||
assertCondition(schedule.getVariantTableName() != null, "A variant table name was not set for " + schedule.getBackendVariant() + " on schedule in process " + processName);
|
||||
assertCondition(schedule.getVariantFieldName() != null, "A variant field name was not set for " + schedule.getBackendVariant() + " on schedule in process " + processName);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -43,6 +43,9 @@ public class QBackendMetaData
|
||||
private String name;
|
||||
private String backendType;
|
||||
|
||||
private Boolean usesVariants = false;
|
||||
private String variantOptionsTableName;
|
||||
|
||||
private Set<Capability> enabledCapabilities = new HashSet<>();
|
||||
private Set<Capability> disabledCapabilities = new HashSet<>();
|
||||
|
||||
@ -343,4 +346,67 @@ public class QBackendMetaData
|
||||
// noop in base class //
|
||||
////////////////////////
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for usesVariants
|
||||
*******************************************************************************/
|
||||
public Boolean getUsesVariants()
|
||||
{
|
||||
return (this.usesVariants);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for usesVariants
|
||||
*******************************************************************************/
|
||||
public void setUsesVariants(Boolean usesVariants)
|
||||
{
|
||||
this.usesVariants = usesVariants;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for usesVariants
|
||||
*******************************************************************************/
|
||||
public QBackendMetaData withUsesVariants(Boolean usesVariants)
|
||||
{
|
||||
this.usesVariants = usesVariants;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for variantsOptionTableName
|
||||
*******************************************************************************/
|
||||
public String getVariantOptionsTableName()
|
||||
{
|
||||
return (this.variantOptionsTableName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for variantsOptionTableName
|
||||
*******************************************************************************/
|
||||
public void setVariantOptionsTableName(String variantOptionsTableName)
|
||||
{
|
||||
this.variantOptionsTableName = variantOptionsTableName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for variantsOptionTableName
|
||||
*******************************************************************************/
|
||||
public QBackendMetaData withVariantsOptionTableName(String variantsOptionTableName)
|
||||
{
|
||||
this.variantOptionsTableName = variantsOptionTableName;
|
||||
return (this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -524,6 +524,25 @@ public class QFieldMetaData implements Cloneable
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** does this field have the given addornment
|
||||
**
|
||||
*******************************************************************************/
|
||||
public boolean hasAdornmentType(AdornmentType adornmentType)
|
||||
{
|
||||
for(FieldAdornment thisAdornment : CollectionUtils.nonNullList(this.adornments))
|
||||
{
|
||||
if(AdornmentType.REVEAL.equals(thisAdornment.getType()))
|
||||
{
|
||||
return (true);
|
||||
}
|
||||
}
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for adornments
|
||||
**
|
||||
|
@ -22,6 +22,9 @@
|
||||
package com.kingsrook.qqq.backend.core.model.metadata.scheduleing;
|
||||
|
||||
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Meta-data to define scheduled actions within QQQ.
|
||||
**
|
||||
@ -33,11 +36,22 @@ package com.kingsrook.qqq.backend.core.model.metadata.scheduleing;
|
||||
*******************************************************************************/
|
||||
public class QScheduleMetaData
|
||||
{
|
||||
public enum RunStrategy
|
||||
{PARALLEL, SERIAL}
|
||||
|
||||
|
||||
|
||||
private Integer repeatSeconds;
|
||||
private Integer repeatMillis;
|
||||
private Integer initialDelaySeconds;
|
||||
private Integer initialDelayMillis;
|
||||
|
||||
private RunStrategy variantRunStrategy;
|
||||
private String backendVariant;
|
||||
private String variantTableName;
|
||||
private QQueryFilter variantFilter;
|
||||
private String variantFieldName;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
@ -174,4 +188,159 @@ public class QScheduleMetaData
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for backendVariant
|
||||
*******************************************************************************/
|
||||
public String getBackendVariant()
|
||||
{
|
||||
return (this.backendVariant);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for backendVariant
|
||||
*******************************************************************************/
|
||||
public void setBackendVariant(String backendVariant)
|
||||
{
|
||||
this.backendVariant = backendVariant;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for backendVariant
|
||||
*******************************************************************************/
|
||||
public QScheduleMetaData withBackendVariant(String backendVariant)
|
||||
{
|
||||
this.backendVariant = backendVariant;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for variantTableName
|
||||
*******************************************************************************/
|
||||
public String getVariantTableName()
|
||||
{
|
||||
return (this.variantTableName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for variantTableName
|
||||
*******************************************************************************/
|
||||
public void setVariantTableName(String variantTableName)
|
||||
{
|
||||
this.variantTableName = variantTableName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for variantTableName
|
||||
*******************************************************************************/
|
||||
public QScheduleMetaData withVariantTableName(String variantTableName)
|
||||
{
|
||||
this.variantTableName = variantTableName;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for variantFilter
|
||||
*******************************************************************************/
|
||||
public QQueryFilter getVariantFilter()
|
||||
{
|
||||
return (this.variantFilter);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for variantFilter
|
||||
*******************************************************************************/
|
||||
public void setVariantFilter(QQueryFilter variantFilter)
|
||||
{
|
||||
this.variantFilter = variantFilter;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for variantFilter
|
||||
*******************************************************************************/
|
||||
public QScheduleMetaData withVariantFilter(QQueryFilter variantFilter)
|
||||
{
|
||||
this.variantFilter = variantFilter;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for variantFieldName
|
||||
*******************************************************************************/
|
||||
public String getVariantFieldName()
|
||||
{
|
||||
return (this.variantFieldName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for variantFieldName
|
||||
*******************************************************************************/
|
||||
public void setVariantFieldName(String variantFieldName)
|
||||
{
|
||||
this.variantFieldName = variantFieldName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for variantFieldName
|
||||
*******************************************************************************/
|
||||
public QScheduleMetaData withVariantFieldName(String variantFieldName)
|
||||
{
|
||||
this.variantFieldName = variantFieldName;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for variantRunStrategy
|
||||
*******************************************************************************/
|
||||
public RunStrategy getVariantRunStrategy()
|
||||
{
|
||||
return (this.variantRunStrategy);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for variantRunStrategy
|
||||
*******************************************************************************/
|
||||
public void setVariantRunStrategy(RunStrategy variantRunStrategy)
|
||||
{
|
||||
this.variantRunStrategy = variantRunStrategy;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for variantRunStrategy
|
||||
*******************************************************************************/
|
||||
public QScheduleMetaData withVariantRunStrategy(RunStrategy variantRunStrategy)
|
||||
{
|
||||
this.variantRunStrategy = variantRunStrategy;
|
||||
return (this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ import java.util.function.Consumer;
|
||||
import com.fasterxml.jackson.core.TreeNode;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import com.fasterxml.jackson.databind.node.BooleanNode;
|
||||
import com.fasterxml.jackson.databind.node.NullNode;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import com.fasterxml.jackson.databind.node.TextNode;
|
||||
@ -283,6 +284,10 @@ public class DeserializerUtils
|
||||
{
|
||||
setterMap.get(fieldName).accept(textNode.asText());
|
||||
}
|
||||
else if(fieldNode instanceof BooleanNode booleanNode)
|
||||
{
|
||||
setterMap.get(fieldName).accept(booleanNode);
|
||||
}
|
||||
else if(fieldNode instanceof ObjectNode)
|
||||
{
|
||||
setterMap.get(fieldName).accept(fieldNode);
|
||||
|
@ -47,8 +47,9 @@ public class QSession implements Serializable
|
||||
private QUser user;
|
||||
private String uuid;
|
||||
|
||||
private Map<String, List<Serializable>> securityKeyValues;
|
||||
private Set<String> permissions;
|
||||
private Map<String, List<Serializable>> securityKeyValues;
|
||||
private Map<String, Serializable> backendVariants;
|
||||
|
||||
// implementation-specific custom values
|
||||
private Map<String, String> values;
|
||||
@ -466,4 +467,35 @@ public class QSession implements Serializable
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for backendVariants
|
||||
*******************************************************************************/
|
||||
public Map<String, Serializable> getBackendVariants()
|
||||
{
|
||||
return (this.backendVariants);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for backendVariants
|
||||
*******************************************************************************/
|
||||
public void setBackendVariants(Map<String, Serializable> backendVariants)
|
||||
{
|
||||
this.backendVariants = backendVariants;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for backendVariants
|
||||
*******************************************************************************/
|
||||
public QSession withBackendVariants(Map<String, Serializable> backendVariants)
|
||||
{
|
||||
this.backendVariants = backendVariants;
|
||||
return (this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -232,25 +232,7 @@ public abstract class AbstractTableSyncTransformStep extends AbstractTransformSt
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// query to see if we already have those records in the destination (to determine insert/update) //
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Map<Serializable, QRecord> existingRecordsByForeignKey = Collections.emptyMap();
|
||||
if(!sourceKeyList.isEmpty())
|
||||
{
|
||||
QueryInput queryInput = new QueryInput();
|
||||
queryInput.setTableName(destinationTableName);
|
||||
getTransaction().ifPresent(queryInput::setTransaction);
|
||||
QQueryFilter filter = getExistingRecordQueryFilter(runBackendStepInput, sourceKeyList);
|
||||
queryInput.setFilter(filter);
|
||||
|
||||
Collection<String> associationNamesToInclude = getAssociationNamesToInclude();
|
||||
if(CollectionUtils.nullSafeHasContents(associationNamesToInclude))
|
||||
{
|
||||
queryInput.setIncludeAssociations(true);
|
||||
queryInput.setAssociationNamesToInclude(associationNamesToInclude);
|
||||
}
|
||||
|
||||
QueryOutput queryOutput = new QueryAction().execute(queryInput);
|
||||
existingRecordsByForeignKey = CollectionUtils.recordsToMap(queryOutput.getRecords(), destinationTableForeignKeyField);
|
||||
}
|
||||
Map<Serializable, QRecord> existingRecordsByForeignKey = getExistingRecordsByForeignKey(runBackendStepInput, destinationTableForeignKeyField, destinationTableName, sourceKeyList);
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// foreach source record, build the record we'll insert/update //
|
||||
@ -348,6 +330,35 @@ public abstract class AbstractTableSyncTransformStep extends AbstractTransformSt
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
protected Map<Serializable, QRecord> getExistingRecordsByForeignKey(RunBackendStepInput runBackendStepInput, String destinationTableForeignKeyField, String destinationTableName, List<Serializable> sourceKeyList) throws QException
|
||||
{
|
||||
Map<Serializable, QRecord> existingRecordsByForeignKey = Collections.emptyMap();
|
||||
if(!sourceKeyList.isEmpty())
|
||||
{
|
||||
QueryInput queryInput = new QueryInput();
|
||||
queryInput.setTableName(destinationTableName);
|
||||
getTransaction().ifPresent(queryInput::setTransaction);
|
||||
QQueryFilter filter = getExistingRecordQueryFilter(runBackendStepInput, sourceKeyList);
|
||||
queryInput.setFilter(filter);
|
||||
|
||||
Collection<String> associationNamesToInclude = getAssociationNamesToInclude();
|
||||
if(CollectionUtils.nullSafeHasContents(associationNamesToInclude))
|
||||
{
|
||||
queryInput.setIncludeAssociations(true);
|
||||
queryInput.setAssociationNamesToInclude(associationNamesToInclude);
|
||||
}
|
||||
|
||||
QueryOutput queryOutput = new QueryAction().execute(queryInput);
|
||||
existingRecordsByForeignKey = CollectionUtils.recordsToMap(queryOutput.getRecords(), destinationTableForeignKeyField);
|
||||
}
|
||||
return (existingRecordsByForeignKey);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
|
@ -34,7 +34,6 @@ import com.kingsrook.qqq.backend.core.actions.tables.GetAction;
|
||||
import com.kingsrook.qqq.backend.core.actions.tables.QueryAction;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QUserFacingException;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.AbstractActionInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.count.CountInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.count.CountOutput;
|
||||
@ -67,9 +66,9 @@ public class GeneralProcessUtils
|
||||
** e.g., for a list of orders (with a clientId field), build a map of client.id => client record
|
||||
** via getForeignRecordMap(input, orderList, "clientId", "client", "id")
|
||||
*******************************************************************************/
|
||||
public static Map<Serializable, QRecord> getForeignRecordMap(AbstractActionInput parentActionInput, List<QRecord> sourceRecords, String sourceTableForeignKeyFieldName, String foreignTableName, String foreignTablePrimaryKeyName) throws QException
|
||||
public static Map<Serializable, QRecord> getForeignRecordMap(List<QRecord> sourceRecords, String sourceTableForeignKeyFieldName, String foreignTableName, String foreignTablePrimaryKeyName) throws QException
|
||||
{
|
||||
return getForeignRecordMap(parentActionInput, sourceRecords, sourceTableForeignKeyFieldName, foreignTableName, foreignTablePrimaryKeyName, new QQueryFilter());
|
||||
return getForeignRecordMap(sourceRecords, sourceTableForeignKeyFieldName, foreignTableName, foreignTablePrimaryKeyName, new QQueryFilter());
|
||||
}
|
||||
|
||||
// todo not commit - clean up all method sigs
|
||||
@ -84,7 +83,7 @@ public class GeneralProcessUtils
|
||||
** e.g., for a list of orders (with a clientId field), build a map of client.id => client record
|
||||
** via getForeignRecordMap(input, orderList, "clientId", "client", "id")
|
||||
*******************************************************************************/
|
||||
public static Map<Serializable, QRecord> getForeignRecordMap(AbstractActionInput parentActionInput, List<QRecord> sourceRecords, String sourceTableForeignKeyFieldName, String foreignTableName, String foreignTablePrimaryKeyName, QQueryFilter additionalFilter) throws QException
|
||||
public static Map<Serializable, QRecord> getForeignRecordMap(List<QRecord> sourceRecords, String sourceTableForeignKeyFieldName, String foreignTableName, String foreignTablePrimaryKeyName, QQueryFilter additionalFilter) throws QException
|
||||
{
|
||||
Map<Serializable, QRecord> foreignRecordMap = new HashMap<>();
|
||||
QueryInput queryInput = new QueryInput();
|
||||
@ -112,7 +111,7 @@ public class GeneralProcessUtils
|
||||
** e.g., for a list of orders, build a ListingHash of order.id => List(OrderLine records)
|
||||
** via getForeignRecordListingHashMap(input, orderList, "id", "orderLine", "orderId")
|
||||
*******************************************************************************/
|
||||
public static ListingHash<Serializable, QRecord> getForeignRecordListingHashMap(AbstractActionInput parentActionInput, List<QRecord> sourceRecords, String sourceTableForeignKeyFieldName, String foreignTableName, String foreignTableForeignKeyName) throws QException
|
||||
public static ListingHash<Serializable, QRecord> getForeignRecordListingHashMap(List<QRecord> sourceRecords, String sourceTableForeignKeyFieldName, String foreignTableName, String foreignTableForeignKeyName) throws QException
|
||||
{
|
||||
ListingHash<Serializable, QRecord> foreignRecordMap = new ListingHash<>();
|
||||
QueryInput queryInput = new QueryInput();
|
||||
@ -139,9 +138,9 @@ public class GeneralProcessUtils
|
||||
** e.g., for a list of orders (with a clientId field), setValue("client", QRecord(client));
|
||||
** via addForeignRecordsToRecordList(input, orderList, "clientId", "client", "id")
|
||||
*******************************************************************************/
|
||||
public static void addForeignRecordsToRecordList(AbstractActionInput parentActionInput, List<QRecord> sourceRecords, String sourceTableForeignKeyFieldName, String foreignTableName, String foreignTablePrimaryKeyName) throws QException
|
||||
public static void addForeignRecordsToRecordList(List<QRecord> sourceRecords, String sourceTableForeignKeyFieldName, String foreignTableName, String foreignTablePrimaryKeyName) throws QException
|
||||
{
|
||||
Map<Serializable, QRecord> foreignRecordMap = getForeignRecordMap(parentActionInput, sourceRecords, sourceTableForeignKeyFieldName, foreignTableName, foreignTablePrimaryKeyName);
|
||||
Map<Serializable, QRecord> foreignRecordMap = getForeignRecordMap(sourceRecords, sourceTableForeignKeyFieldName, foreignTableName, foreignTablePrimaryKeyName);
|
||||
for(QRecord sourceRecord : sourceRecords)
|
||||
{
|
||||
QRecord foreignRecord = foreignRecordMap.get(sourceRecord.getValue(sourceTableForeignKeyFieldName));
|
||||
@ -159,9 +158,9 @@ public class GeneralProcessUtils
|
||||
** e.g., for a list of orders, setValue("orderLine", List(QRecord(orderLine)))
|
||||
** via addForeignRecordsListToRecordList(input, orderList, "id", "orderLine", "orderId")
|
||||
*******************************************************************************/
|
||||
public static void addForeignRecordsListToRecordList(AbstractActionInput parentActionInput, List<QRecord> sourceRecords, String sourceTableForeignKeyFieldName, String foreignTableName, String foreignTableForeignKeyName) throws QException
|
||||
public static void addForeignRecordsListToRecordList(List<QRecord> sourceRecords, String sourceTableForeignKeyFieldName, String foreignTableName, String foreignTableForeignKeyName) throws QException
|
||||
{
|
||||
ListingHash<Serializable, QRecord> foreignRecordMap = getForeignRecordListingHashMap(parentActionInput, sourceRecords, sourceTableForeignKeyFieldName, foreignTableName, foreignTableForeignKeyName);
|
||||
ListingHash<Serializable, QRecord> foreignRecordMap = getForeignRecordListingHashMap(sourceRecords, sourceTableForeignKeyFieldName, foreignTableName, foreignTableForeignKeyName);
|
||||
for(QRecord sourceRecord : sourceRecords)
|
||||
{
|
||||
List<QRecord> foreignRecordList = foreignRecordMap.get(sourceRecord.getValue(sourceTableForeignKeyFieldName));
|
||||
@ -185,7 +184,7 @@ public class GeneralProcessUtils
|
||||
** Run a query on tableName, for where fieldName equals fieldValue, and return
|
||||
** the list of QRecords.
|
||||
*******************************************************************************/
|
||||
public static List<QRecord> getRecordListByField(AbstractActionInput parentActionInput, String tableName, String fieldName, Serializable fieldValue) throws QException
|
||||
public static List<QRecord> getRecordListByField(String tableName, String fieldName, Serializable fieldValue) throws QException
|
||||
{
|
||||
QueryInput queryInput = new QueryInput();
|
||||
queryInput.setTableName(tableName);
|
||||
@ -201,7 +200,7 @@ public class GeneralProcessUtils
|
||||
** key, or any other field on the table. Note, if multiple rows do match the value,
|
||||
** only 1 (determined in an unspecified way) is returned.
|
||||
*******************************************************************************/
|
||||
public static Optional<QRecord> getRecordByField(AbstractActionInput parentActionInput, String tableName, String fieldName, Serializable fieldValue) throws QException
|
||||
public static Optional<QRecord> getRecordByField(String tableName, String fieldName, Serializable fieldValue) throws QException
|
||||
{
|
||||
if(fieldValue == null)
|
||||
{
|
||||
@ -222,9 +221,9 @@ public class GeneralProcessUtils
|
||||
** key, or any other field on the table. Note, if multiple rows do match the value,
|
||||
** only 1 (determined in an unspecified way) is returned.
|
||||
*******************************************************************************/
|
||||
public static <T extends QRecordEntity> Optional<T> getEntityByField(AbstractActionInput parentActionInput, String tableName, String fieldName, Serializable fieldValue, Class<T> entityClass) throws QException
|
||||
public static <T extends QRecordEntity> Optional<T> getEntityByField(String tableName, String fieldName, Serializable fieldValue, Class<T> entityClass) throws QException
|
||||
{
|
||||
Optional<QRecord> optionalQRecord = getRecordByField(parentActionInput, tableName, fieldName, fieldValue);
|
||||
Optional<QRecord> optionalQRecord = getRecordByField(tableName, fieldName, fieldValue);
|
||||
if(optionalQRecord.isPresent())
|
||||
{
|
||||
return (Optional.of(QRecordEntity.fromQRecord(entityClass, optionalQRecord.get())));
|
||||
@ -237,9 +236,9 @@ public class GeneralProcessUtils
|
||||
/*******************************************************************************
|
||||
** Query to get one record by a unique key value.
|
||||
*******************************************************************************/
|
||||
public static QRecord getRecordByFieldOrElseThrow(AbstractActionInput parentActionInput, String tableName, String fieldName, Serializable fieldValue) throws QException
|
||||
public static QRecord getRecordByFieldOrElseThrow(String tableName, String fieldName, Serializable fieldValue) throws QException
|
||||
{
|
||||
return getRecordByField(parentActionInput, tableName, fieldName, fieldValue)
|
||||
return getRecordByField(tableName, fieldName, fieldValue)
|
||||
.orElseThrow(() -> new QException(tableName + " with " + fieldName + " of " + fieldValue + " was not found."));
|
||||
}
|
||||
|
||||
@ -248,7 +247,7 @@ public class GeneralProcessUtils
|
||||
/*******************************************************************************
|
||||
** Query to get one record by its primary key value.
|
||||
*******************************************************************************/
|
||||
public static Optional<QRecord> getRecordByPrimaryKey(AbstractActionInput parentActionInput, String tableName, Serializable value) throws QException
|
||||
public static Optional<QRecord> getRecordByPrimaryKey(String tableName, Serializable value) throws QException
|
||||
{
|
||||
GetInput getInput = new GetInput();
|
||||
getInput.setTableName(tableName);
|
||||
@ -262,9 +261,9 @@ public class GeneralProcessUtils
|
||||
/*******************************************************************************
|
||||
** Query to get one record by its primary key value.
|
||||
*******************************************************************************/
|
||||
public static QRecord getRecordByPrimaryKeyOrElseThrow(AbstractActionInput parentActionInput, String tableName, Serializable value) throws QException
|
||||
public static QRecord getRecordByPrimaryKeyOrElseThrow(String tableName, Serializable value) throws QException
|
||||
{
|
||||
return getRecordByPrimaryKey(parentActionInput, tableName, value)
|
||||
return getRecordByPrimaryKey(tableName, value)
|
||||
.orElseThrow(() -> new QException(tableName + " with primary key of " + value + " was not found."));
|
||||
}
|
||||
|
||||
@ -276,7 +275,7 @@ public class GeneralProcessUtils
|
||||
** Note, this is inherently unsafe, if you were to call it on a table with
|
||||
** too many rows... Caveat emptor.
|
||||
*******************************************************************************/
|
||||
public static List<QRecord> loadTable(AbstractActionInput parentActionInput, String tableName) throws QException
|
||||
public static List<QRecord> loadTable(String tableName) throws QException
|
||||
{
|
||||
QueryInput queryInput = new QueryInput();
|
||||
queryInput.setTableName(tableName);
|
||||
@ -292,7 +291,7 @@ public class GeneralProcessUtils
|
||||
** Note, this is inherently unsafe, if you were to call it on a table with
|
||||
** too many rows... Caveat emptor.
|
||||
*******************************************************************************/
|
||||
public static <T extends QRecordEntity> List<T> loadTable(AbstractActionInput parentActionInput, String tableName, Class<T> entityClass) throws QException
|
||||
public static <T extends QRecordEntity> List<T> loadTable(String tableName, Class<T> entityClass) throws QException
|
||||
{
|
||||
QueryInput queryInput = new QueryInput();
|
||||
queryInput.setTableName(tableName);
|
||||
@ -320,9 +319,9 @@ public class GeneralProcessUtils
|
||||
** Also, note, this is inherently unsafe, if you were to call it on a table with
|
||||
** too many rows... Caveat emptor.
|
||||
*******************************************************************************/
|
||||
public static Map<Serializable, QRecord> loadTableToMap(AbstractActionInput parentActionInput, String tableName, String keyFieldName) throws QException
|
||||
public static Map<Serializable, QRecord> loadTableToMap(String tableName, String keyFieldName) throws QException
|
||||
{
|
||||
return (loadTableToMap(parentActionInput, tableName, keyFieldName, (QQueryFilter) null));
|
||||
return (loadTableToMap(tableName, keyFieldName, (QQueryFilter) null));
|
||||
}
|
||||
|
||||
|
||||
@ -335,7 +334,7 @@ public class GeneralProcessUtils
|
||||
** If multiple values are found for the key, they'll squash each other, and only
|
||||
** one (random) value will appear.
|
||||
*******************************************************************************/
|
||||
public static Map<Serializable, QRecord> loadTableToMap(AbstractActionInput parentActionInput, String tableName, String keyFieldName, QQueryFilter filter) throws QException
|
||||
public static Map<Serializable, QRecord> loadTableToMap(String tableName, String keyFieldName, QQueryFilter filter) throws QException
|
||||
{
|
||||
QueryInput queryInput = new QueryInput();
|
||||
queryInput.setTableName(tableName);
|
||||
@ -369,7 +368,7 @@ public class GeneralProcessUtils
|
||||
** Also, note, this is inherently unsafe, if you were to call it on a table with
|
||||
** too many rows... Caveat emptor.
|
||||
*******************************************************************************/
|
||||
public static <T extends Serializable> Map<T, QRecord> loadTableToMap(AbstractActionInput parentActionInput, String tableName, Class<T> keyType, String keyFieldName) throws QException
|
||||
public static <T extends Serializable> Map<T, QRecord> loadTableToMap(String tableName, Class<T> keyType, String keyFieldName) throws QException
|
||||
{
|
||||
QueryInput queryInput = new QueryInput();
|
||||
queryInput.setTableName(tableName);
|
||||
@ -394,7 +393,7 @@ public class GeneralProcessUtils
|
||||
/*******************************************************************************
|
||||
** Note - null values from the key field are NOT put in the map.
|
||||
*******************************************************************************/
|
||||
public static <T extends QRecordEntity> Map<Serializable, T> loadTableToMap(AbstractActionInput parentActionInput, String tableName, String keyFieldName, Class<T> entityClass) throws QException
|
||||
public static <T extends QRecordEntity> Map<Serializable, T> loadTableToMap(String tableName, String keyFieldName, Class<T> entityClass) throws QException
|
||||
{
|
||||
return (loadTableToMap(tableName, keyFieldName, entityClass, null));
|
||||
}
|
||||
@ -441,7 +440,7 @@ public class GeneralProcessUtils
|
||||
** Also, note, this is inherently unsafe, if you were to call it on a table with
|
||||
** too many rows... Caveat emptor.
|
||||
*******************************************************************************/
|
||||
public static ListingHash<Serializable, QRecord> loadTableToListingHash(AbstractActionInput parentActionInput, String tableName, String keyFieldName) throws QException
|
||||
public static ListingHash<Serializable, QRecord> loadTableToListingHash(String tableName, String keyFieldName) throws QException
|
||||
{
|
||||
QueryInput queryInput = new QueryInput();
|
||||
queryInput.setTableName(tableName);
|
||||
@ -514,7 +513,7 @@ public class GeneralProcessUtils
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static Integer count(AbstractActionInput input, String tableName, QQueryFilter filter) throws QException
|
||||
public static Integer count(String tableName, QQueryFilter filter) throws QException
|
||||
{
|
||||
CountInput countInput = new CountInput();
|
||||
countInput.setTableName(tableName);
|
||||
|
@ -83,7 +83,7 @@ public class RecordLookupHelper
|
||||
{
|
||||
if(disallowedOneOffLookups.isEmpty() || !disallowedOneOffLookups.contains(Pair.of(tableName, keyFieldName)))
|
||||
{
|
||||
Optional<QRecord> optRecord = GeneralProcessUtils.getRecordByField(null, tableName, keyFieldName, key);
|
||||
Optional<QRecord> optRecord = GeneralProcessUtils.getRecordByField(tableName, keyFieldName, key);
|
||||
recordMap.put(key, optRecord.orElse(null));
|
||||
}
|
||||
}
|
||||
@ -106,7 +106,7 @@ public class RecordLookupHelper
|
||||
String mapKey = tableName + "." + keyFieldName;
|
||||
if(!preloadedKeys.contains(mapKey))
|
||||
{
|
||||
Map<Serializable, QRecord> recordMap = GeneralProcessUtils.loadTableToMap(null, tableName, keyFieldName);
|
||||
Map<Serializable, QRecord> recordMap = GeneralProcessUtils.loadTableToMap(tableName, keyFieldName);
|
||||
recordMaps.put(mapKey, recordMap);
|
||||
preloadedKeys.add(mapKey);
|
||||
}
|
||||
@ -126,7 +126,7 @@ public class RecordLookupHelper
|
||||
{
|
||||
String mapKey = tableName + "." + keyFieldName;
|
||||
Map<Serializable, QRecord> tableMap = recordMaps.computeIfAbsent(mapKey, s -> new HashMap<>());
|
||||
tableMap.putAll(GeneralProcessUtils.loadTableToMap(null, tableName, keyFieldName, filter));
|
||||
tableMap.putAll(GeneralProcessUtils.loadTableToMap(tableName, keyFieldName, filter));
|
||||
}
|
||||
|
||||
|
||||
@ -148,7 +148,7 @@ public class RecordLookupHelper
|
||||
Map<Serializable, QRecord> tableMap = recordMaps.computeIfAbsent(mapKey, s -> new HashMap<>());
|
||||
|
||||
QQueryFilter filter = new QQueryFilter(new QFilterCriteria(keyFieldName, QCriteriaOperator.IN, inList));
|
||||
tableMap.putAll(GeneralProcessUtils.loadTableToMap(null, tableName, keyFieldName, filter));
|
||||
tableMap.putAll(GeneralProcessUtils.loadTableToMap(tableName, keyFieldName, filter));
|
||||
|
||||
QFieldType type = QContext.getQInstance().getTable(tableName).getField(keyFieldName).getType();
|
||||
for(Serializable keyValue : inList)
|
||||
|
@ -22,17 +22,25 @@
|
||||
package com.kingsrook.qqq.backend.core.scheduler;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Supplier;
|
||||
import com.kingsrook.qqq.backend.core.actions.automation.polling.PollingAutomationPerTableRunner;
|
||||
import com.kingsrook.qqq.backend.core.actions.processes.RunProcessAction;
|
||||
import com.kingsrook.qqq.backend.core.actions.queues.SQSQueuePoller;
|
||||
import com.kingsrook.qqq.backend.core.actions.tables.QueryAction;
|
||||
import com.kingsrook.qqq.backend.core.context.QContext;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||
import com.kingsrook.qqq.backend.core.instances.QMetaDataVariableInterpreter;
|
||||
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.tables.query.QueryInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryOutput;
|
||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.automation.QAutomationProviderMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData;
|
||||
@ -41,6 +49,8 @@ import com.kingsrook.qqq.backend.core.model.metadata.queues.QQueueProviderMetaDa
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.queues.SQSQueueProviderMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.scheduleing.QScheduleMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.session.QSession;
|
||||
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||
import com.kingsrook.qqq.backend.core.utils.collections.MapBuilder;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
@ -131,13 +141,71 @@ public class ScheduleManager
|
||||
{
|
||||
if(process.getSchedule() != null && allowedToStart(process.getName()))
|
||||
{
|
||||
startProcess(process);
|
||||
QScheduleMetaData scheduleMetaData = process.getSchedule();
|
||||
if(process.getSchedule().getBackendVariant() == null || QScheduleMetaData.RunStrategy.SERIAL.equals(process.getSchedule().getVariantRunStrategy()))
|
||||
{
|
||||
///////////////////////////////////////////////
|
||||
// if no variants, or variant is serial mode //
|
||||
///////////////////////////////////////////////
|
||||
startProcess(process, null);
|
||||
}
|
||||
else if(QScheduleMetaData.RunStrategy.PARALLEL.equals(process.getSchedule().getVariantRunStrategy()))
|
||||
{
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// if this a "parallel", which for example means we want to have a thread for each backend variant //
|
||||
// running at the same time, get the variant records and schedule each separately //
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
QContext.init(qInstance, sessionSupplier.get());
|
||||
for(QRecord qRecord : CollectionUtils.nonNullList(getBackendVariantFilteredRecords(process)))
|
||||
{
|
||||
try
|
||||
{
|
||||
startProcess(process, MapBuilder.of(scheduleMetaData.getBackendVariant(), qRecord.getValue(scheduleMetaData.getVariantFieldName())));
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
LOG.error("An error starting process [" + process.getLabel() + "], with backend variant data.", e, new LogPair("variantQRecord", qRecord));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG.error("Unsupported Schedule Run Strategy [" + process.getSchedule().getVariantFilter() + "] was provided.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private List<QRecord> getBackendVariantFilteredRecords(QProcessMetaData processMetaData)
|
||||
{
|
||||
List<QRecord> records = null;
|
||||
try
|
||||
{
|
||||
QScheduleMetaData scheduleMetaData = processMetaData.getSchedule();
|
||||
|
||||
QueryInput queryInput = new QueryInput();
|
||||
queryInput.setTableName(scheduleMetaData.getVariantTableName());
|
||||
queryInput.setFilter(scheduleMetaData.getVariantFilter());
|
||||
|
||||
QContext.init(qInstance, sessionSupplier.get());
|
||||
QueryOutput queryOutput = new QueryAction().execute(queryInput);
|
||||
records = queryOutput.getRecords();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
LOG.error("An error fetching variant data for process [" + processMetaData.getLabel() + "]", e);
|
||||
}
|
||||
|
||||
return (records);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@ -249,7 +317,7 @@ public class ScheduleManager
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private void startProcess(QProcessMetaData process)
|
||||
private void startProcess(QProcessMetaData process, Map<String, Serializable> backendVariantData)
|
||||
{
|
||||
Runnable runProcess = () ->
|
||||
{
|
||||
@ -257,18 +325,31 @@ public class ScheduleManager
|
||||
|
||||
try
|
||||
{
|
||||
QContext.init(qInstance, sessionSupplier.get());
|
||||
Thread.currentThread().setName("ScheduledProcess>" + process.getName());
|
||||
LOG.debug("Running Scheduled Process [" + process.getName() + "]");
|
||||
|
||||
RunProcessInput runProcessInput = new RunProcessInput();
|
||||
runProcessInput.setProcessName(process.getName());
|
||||
runProcessInput.setFrontendStepBehavior(RunProcessInput.FrontendStepBehavior.SKIP);
|
||||
|
||||
QContext.pushAction(runProcessInput);
|
||||
|
||||
RunProcessAction runProcessAction = new RunProcessAction();
|
||||
runProcessAction.execute(runProcessInput);
|
||||
if(process.getSchedule().getBackendVariant() == null || QScheduleMetaData.RunStrategy.PARALLEL.equals(process.getSchedule().getVariantRunStrategy()))
|
||||
{
|
||||
QContext.init(qInstance, sessionSupplier.get());
|
||||
executeSingleProcess(process, backendVariantData);
|
||||
}
|
||||
else if(QScheduleMetaData.RunStrategy.SERIAL.equals(process.getSchedule().getVariantRunStrategy()))
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// if this is "serial", which for example means we want to run each backend variant one after //
|
||||
// the other in the same thread so loop over these here so that they run in same lambda function //
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
for(QRecord qRecord : getBackendVariantFilteredRecords(process))
|
||||
{
|
||||
try
|
||||
{
|
||||
QContext.init(qInstance, sessionSupplier.get());
|
||||
QScheduleMetaData scheduleMetaData = process.getSchedule();
|
||||
executeSingleProcess(process, MapBuilder.of(scheduleMetaData.getBackendVariant(), qRecord.getValue(scheduleMetaData.getVariantFieldName())));
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
LOG.error("An error starting process [" + process.getLabel() + "], with backend variant data.", e, new LogPair("variantQRecord", qRecord));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
@ -294,6 +375,31 @@ public class ScheduleManager
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private static void executeSingleProcess(QProcessMetaData process, Map<String, Serializable> backendVariantData) throws QException
|
||||
{
|
||||
if(backendVariantData != null)
|
||||
{
|
||||
QContext.getQSession().setBackendVariants(backendVariantData);
|
||||
}
|
||||
|
||||
Thread.currentThread().setName("ScheduledProcess>" + process.getName());
|
||||
LOG.debug("Running Scheduled Process [" + process.getName() + "]");
|
||||
|
||||
RunProcessInput runProcessInput = new RunProcessInput();
|
||||
runProcessInput.setProcessName(process.getName());
|
||||
runProcessInput.setFrontendStepBehavior(RunProcessInput.FrontendStepBehavior.SKIP);
|
||||
|
||||
QContext.pushAction(runProcessInput);
|
||||
|
||||
RunProcessAction runProcessAction = new RunProcessAction();
|
||||
runProcessAction.execute(runProcessInput);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
|
Reference in New Issue
Block a user