mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 13:10:44 +00:00
Merge branch 'feature/CTLE-436-move-to-integration-per-client' into integration/sprint-28
This commit is contained in:
@ -1224,11 +1224,10 @@ public class QInstanceValidator
|
|||||||
QScheduleMetaData schedule = process.getSchedule();
|
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);
|
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)
|
if(schedule.getVariantBackend() != null)
|
||||||
{
|
{
|
||||||
assertCondition(schedule.getVariantRunStrategy() != null, "A variant strategy was not set for " + schedule.getBackendVariant() + " on schedule in process " + processName);
|
assertCondition(qInstance.getBackend(schedule.getVariantBackend()) != null, "A variant backend was not found for " + schedule.getVariantBackend());
|
||||||
assertCondition(schedule.getVariantTableName() != null, "A variant table name was not set for " + schedule.getBackendVariant() + " on schedule in process " + processName);
|
assertCondition(schedule.getVariantRunStrategy() != null, "A variant run strategy was not set for " + schedule.getVariantBackend() + " on schedule in process " + processName);
|
||||||
assertCondition(schedule.getVariantFieldName() != null, "A variant field name was not set for " + schedule.getBackendVariant() + " on schedule in process " + processName);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,12 +42,19 @@ public class QBackendMetaData
|
|||||||
private String name;
|
private String name;
|
||||||
private String backendType;
|
private String backendType;
|
||||||
|
|
||||||
private Boolean usesVariants = false;
|
|
||||||
private String variantOptionsTableName;
|
|
||||||
|
|
||||||
private Set<Capability> enabledCapabilities = new HashSet<>();
|
private Set<Capability> enabledCapabilities = new HashSet<>();
|
||||||
private Set<Capability> disabledCapabilities = new HashSet<>();
|
private Set<Capability> disabledCapabilities = new HashSet<>();
|
||||||
|
|
||||||
|
private Boolean usesVariants = false;
|
||||||
|
private String variantOptionsTableIdField;
|
||||||
|
private String variantOptionsTableNameField;
|
||||||
|
private String variantOptionsTableTypeField;
|
||||||
|
private String variantOptionsTableTypeValue;
|
||||||
|
private String variantOptionsTableUsernameField;
|
||||||
|
private String variantOptionsTablePasswordField;
|
||||||
|
private String variantOptionsTableApiKeyField;
|
||||||
|
private String variantOptionsTableName;
|
||||||
|
|
||||||
// todo - at some point, we may want to apply this to secret properties on subclasses?
|
// todo - at some point, we may want to apply this to secret properties on subclasses?
|
||||||
// @JsonFilter("secretsFilter")
|
// @JsonFilter("secretsFilter")
|
||||||
|
|
||||||
@ -398,7 +405,224 @@ public class QBackendMetaData
|
|||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Getter for variantsOptionTableName
|
** Getter for variantOptionsTableIdField
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getVariantOptionsTableIdField()
|
||||||
|
{
|
||||||
|
return (this.variantOptionsTableIdField);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for variantOptionsTableIdField
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setVariantOptionsTableIdField(String variantOptionsTableIdField)
|
||||||
|
{
|
||||||
|
this.variantOptionsTableIdField = variantOptionsTableIdField;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for variantOptionsTableIdField
|
||||||
|
*******************************************************************************/
|
||||||
|
public QBackendMetaData withVariantOptionsTableIdField(String variantOptionsTableIdField)
|
||||||
|
{
|
||||||
|
this.variantOptionsTableIdField = variantOptionsTableIdField;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for variantOptionsTableNameField
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getVariantOptionsTableNameField()
|
||||||
|
{
|
||||||
|
return (this.variantOptionsTableNameField);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for variantOptionsTableNameField
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setVariantOptionsTableNameField(String variantOptionsTableNameField)
|
||||||
|
{
|
||||||
|
this.variantOptionsTableNameField = variantOptionsTableNameField;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for variantOptionsTableNameField
|
||||||
|
*******************************************************************************/
|
||||||
|
public QBackendMetaData withVariantOptionsTableNameField(String variantOptionsTableNameField)
|
||||||
|
{
|
||||||
|
this.variantOptionsTableNameField = variantOptionsTableNameField;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for variantOptionsTableTypeField
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getVariantOptionsTableTypeField()
|
||||||
|
{
|
||||||
|
return (this.variantOptionsTableTypeField);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for variantOptionsTableTypeField
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setVariantOptionsTableTypeField(String variantOptionsTableTypeField)
|
||||||
|
{
|
||||||
|
this.variantOptionsTableTypeField = variantOptionsTableTypeField;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for variantOptionsTableTypeField
|
||||||
|
*******************************************************************************/
|
||||||
|
public QBackendMetaData withVariantOptionsTableTypeField(String variantOptionsTableTypeField)
|
||||||
|
{
|
||||||
|
this.variantOptionsTableTypeField = variantOptionsTableTypeField;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for variantOptionsTableTypeValue
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getVariantOptionsTableTypeValue()
|
||||||
|
{
|
||||||
|
return (this.variantOptionsTableTypeValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for variantOptionsTableTypeValue
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setVariantOptionsTableTypeValue(String variantOptionsTableTypeValue)
|
||||||
|
{
|
||||||
|
this.variantOptionsTableTypeValue = variantOptionsTableTypeValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for variantOptionsTableTypeValue
|
||||||
|
*******************************************************************************/
|
||||||
|
public QBackendMetaData withVariantOptionsTableTypeValue(String variantOptionsTableTypeValue)
|
||||||
|
{
|
||||||
|
this.variantOptionsTableTypeValue = variantOptionsTableTypeValue;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for variantOptionsTableUsernameField
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getVariantOptionsTableUsernameField()
|
||||||
|
{
|
||||||
|
return (this.variantOptionsTableUsernameField);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for variantOptionsTableUsernameField
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setVariantOptionsTableUsernameField(String variantOptionsTableUsernameField)
|
||||||
|
{
|
||||||
|
this.variantOptionsTableUsernameField = variantOptionsTableUsernameField;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for variantOptionsTableUsernameField
|
||||||
|
*******************************************************************************/
|
||||||
|
public QBackendMetaData withVariantOptionsTableUsernameField(String variantOptionsTableUsernameField)
|
||||||
|
{
|
||||||
|
this.variantOptionsTableUsernameField = variantOptionsTableUsernameField;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for variantOptionsTablePasswordField
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getVariantOptionsTablePasswordField()
|
||||||
|
{
|
||||||
|
return (this.variantOptionsTablePasswordField);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for variantOptionsTablePasswordField
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setVariantOptionsTablePasswordField(String variantOptionsTablePasswordField)
|
||||||
|
{
|
||||||
|
this.variantOptionsTablePasswordField = variantOptionsTablePasswordField;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for variantOptionsTablePasswordField
|
||||||
|
*******************************************************************************/
|
||||||
|
public QBackendMetaData withVariantOptionsTablePasswordField(String variantOptionsTablePasswordField)
|
||||||
|
{
|
||||||
|
this.variantOptionsTablePasswordField = variantOptionsTablePasswordField;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for variantOptionsTableApiKeyField
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getVariantOptionsTableApiKeyField()
|
||||||
|
{
|
||||||
|
return (this.variantOptionsTableApiKeyField);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for variantOptionsTableApiKeyField
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setVariantOptionsTableApiKeyField(String variantOptionsTableApiKeyField)
|
||||||
|
{
|
||||||
|
this.variantOptionsTableApiKeyField = variantOptionsTableApiKeyField;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for variantOptionsTableApiKeyField
|
||||||
|
*******************************************************************************/
|
||||||
|
public QBackendMetaData withVariantOptionsTableApiKeyField(String variantOptionsTableApiKeyField)
|
||||||
|
{
|
||||||
|
this.variantOptionsTableApiKeyField = variantOptionsTableApiKeyField;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for variantOptionsTableName
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public String getVariantOptionsTableName()
|
public String getVariantOptionsTableName()
|
||||||
{
|
{
|
||||||
@ -408,7 +632,7 @@ public class QBackendMetaData
|
|||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Setter for variantsOptionTableName
|
** Setter for variantOptionsTableName
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public void setVariantOptionsTableName(String variantOptionsTableName)
|
public void setVariantOptionsTableName(String variantOptionsTableName)
|
||||||
{
|
{
|
||||||
@ -418,11 +642,11 @@ public class QBackendMetaData
|
|||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Fluent setter for variantsOptionTableName
|
** Fluent setter for variantOptionsTableName
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public QBackendMetaData withVariantsOptionTableName(String variantsOptionTableName)
|
public QBackendMetaData withVariantOptionsTableName(String variantOptionsTableName)
|
||||||
{
|
{
|
||||||
this.variantOptionsTableName = variantsOptionTableName;
|
this.variantOptionsTableName = variantOptionsTableName;
|
||||||
return (this);
|
return (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +72,9 @@ public class QFrontendTableMetaData
|
|||||||
private boolean editPermission;
|
private boolean editPermission;
|
||||||
private boolean deletePermission;
|
private boolean deletePermission;
|
||||||
|
|
||||||
|
private boolean usesVariants;
|
||||||
|
private String variantTableLabel;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
// do not add setters. take values from the source-object in the constructor!! //
|
// do not add setters. take values from the source-object in the constructor!! //
|
||||||
//////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -135,6 +138,13 @@ public class QFrontendTableMetaData
|
|||||||
insertPermission = PermissionsHelper.hasTablePermission(actionInput, tableMetaData.getName(), TablePermissionSubType.INSERT);
|
insertPermission = PermissionsHelper.hasTablePermission(actionInput, tableMetaData.getName(), TablePermissionSubType.INSERT);
|
||||||
editPermission = PermissionsHelper.hasTablePermission(actionInput, tableMetaData.getName(), TablePermissionSubType.EDIT);
|
editPermission = PermissionsHelper.hasTablePermission(actionInput, tableMetaData.getName(), TablePermissionSubType.EDIT);
|
||||||
deletePermission = PermissionsHelper.hasTablePermission(actionInput, tableMetaData.getName(), TablePermissionSubType.DELETE);
|
deletePermission = PermissionsHelper.hasTablePermission(actionInput, tableMetaData.getName(), TablePermissionSubType.DELETE);
|
||||||
|
|
||||||
|
QBackendMetaData backend = actionInput.getInstance().getBackend(tableMetaData.getBackendName());
|
||||||
|
if(backend != null && backend.getUsesVariants())
|
||||||
|
{
|
||||||
|
usesVariants = true;
|
||||||
|
variantTableLabel = actionInput.getInstance().getTable(backend.getVariantOptionsTableName()).getLabel();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -294,6 +304,17 @@ public class QFrontendTableMetaData
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for usesVariants
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public boolean getUsesVariants()
|
||||||
|
{
|
||||||
|
return usesVariants;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Getter for exposedJoins
|
** Getter for exposedJoins
|
||||||
**
|
**
|
||||||
@ -302,4 +323,15 @@ public class QFrontendTableMetaData
|
|||||||
{
|
{
|
||||||
return exposedJoins;
|
return exposedJoins;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for variantTableLabel
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getVariantTableLabel()
|
||||||
|
{
|
||||||
|
return (this.variantTableLabel);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
* 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.backend.core.model.metadata.frontend;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Version of a variant for a frontend to see
|
||||||
|
*******************************************************************************/
|
||||||
|
public class QFrontendVariant
|
||||||
|
{
|
||||||
|
private Serializable id;
|
||||||
|
private String name;
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for id
|
||||||
|
*******************************************************************************/
|
||||||
|
public Serializable getId()
|
||||||
|
{
|
||||||
|
return (this.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for id
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setId(Serializable id)
|
||||||
|
{
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for id
|
||||||
|
*******************************************************************************/
|
||||||
|
public QFrontendVariant withId(Serializable id)
|
||||||
|
{
|
||||||
|
this.id = id;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for name
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getName()
|
||||||
|
{
|
||||||
|
return (this.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for name
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setName(String name)
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for name
|
||||||
|
*******************************************************************************/
|
||||||
|
public QFrontendVariant withName(String name)
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for type
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getType()
|
||||||
|
{
|
||||||
|
return (this.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for type
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setType(String type)
|
||||||
|
{
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for type
|
||||||
|
*******************************************************************************/
|
||||||
|
public QFrontendVariant withType(String type)
|
||||||
|
{
|
||||||
|
this.type = type;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -22,9 +22,6 @@
|
|||||||
package com.kingsrook.qqq.backend.core.model.metadata.scheduleing;
|
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.
|
** Meta-data to define scheduled actions within QQQ.
|
||||||
**
|
**
|
||||||
@ -46,11 +43,8 @@ public class QScheduleMetaData
|
|||||||
private Integer initialDelaySeconds;
|
private Integer initialDelaySeconds;
|
||||||
private Integer initialDelayMillis;
|
private Integer initialDelayMillis;
|
||||||
|
|
||||||
private RunStrategy variantRunStrategy;
|
private RunStrategy variantRunStrategy;
|
||||||
private String backendVariant;
|
private String variantBackend;
|
||||||
private String variantTableName;
|
|
||||||
private QQueryFilter variantFilter;
|
|
||||||
private String variantFieldName;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -191,124 +185,31 @@ public class QScheduleMetaData
|
|||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Getter for backendVariant
|
** Getter for variantBackend
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public String getBackendVariant()
|
public String getVariantBackend()
|
||||||
{
|
{
|
||||||
return (this.backendVariant);
|
return (this.variantBackend);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Setter for backendVariant
|
** Setter for variantBackend
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public void setBackendVariant(String backendVariant)
|
public void setVariantBackend(String variantBackend)
|
||||||
{
|
{
|
||||||
this.backendVariant = backendVariant;
|
this.variantBackend = variantBackend;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Fluent setter for backendVariant
|
** Fluent setter for variantBackend
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public QScheduleMetaData withBackendVariant(String backendVariant)
|
public QScheduleMetaData withBackendVariant(String backendVariant)
|
||||||
{
|
{
|
||||||
this.backendVariant = backendVariant;
|
this.variantBackend = 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);
|
return (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,9 +38,13 @@ import com.kingsrook.qqq.backend.core.instances.QMetaDataVariableInterpreter;
|
|||||||
import com.kingsrook.qqq.backend.core.logging.LogPair;
|
import com.kingsrook.qqq.backend.core.logging.LogPair;
|
||||||
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessInput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessInput;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria;
|
||||||
|
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.QueryInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryOutput;
|
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.data.QRecord;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.automation.QAutomationProviderMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.automation.QAutomationProviderMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData;
|
||||||
@ -131,7 +135,7 @@ public class ScheduleManager
|
|||||||
if(process.getSchedule() != null && allowedToStart(process.getName()))
|
if(process.getSchedule() != null && allowedToStart(process.getName()))
|
||||||
{
|
{
|
||||||
QScheduleMetaData scheduleMetaData = process.getSchedule();
|
QScheduleMetaData scheduleMetaData = process.getSchedule();
|
||||||
if(process.getSchedule().getBackendVariant() == null || QScheduleMetaData.RunStrategy.SERIAL.equals(process.getSchedule().getVariantRunStrategy()))
|
if(process.getSchedule().getVariantBackend() == null || QScheduleMetaData.RunStrategy.SERIAL.equals(process.getSchedule().getVariantRunStrategy()))
|
||||||
{
|
{
|
||||||
///////////////////////////////////////////////
|
///////////////////////////////////////////////
|
||||||
// if no variants, or variant is serial mode //
|
// if no variants, or variant is serial mode //
|
||||||
@ -145,11 +149,12 @@ public class ScheduleManager
|
|||||||
// running at the same time, get the variant records and schedule each separately //
|
// running at the same time, get the variant records and schedule each separately //
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
QContext.init(qInstance, sessionSupplier.get());
|
QContext.init(qInstance, sessionSupplier.get());
|
||||||
|
QBackendMetaData backendMetaData = qInstance.getBackend(scheduleMetaData.getVariantBackend());
|
||||||
for(QRecord qRecord : CollectionUtils.nonNullList(getBackendVariantFilteredRecords(process)))
|
for(QRecord qRecord : CollectionUtils.nonNullList(getBackendVariantFilteredRecords(process)))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
startProcess(process, MapBuilder.of(scheduleMetaData.getBackendVariant(), qRecord.getValue(scheduleMetaData.getVariantFieldName())));
|
startProcess(process, MapBuilder.of(backendMetaData.getVariantOptionsTableTypeValue(), qRecord.getValue(backendMetaData.getVariantOptionsTableIdField())));
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch(Exception e)
|
||||||
{
|
{
|
||||||
@ -159,7 +164,7 @@ public class ScheduleManager
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG.error("Unsupported Schedule Run Strategy [" + process.getSchedule().getVariantFilter() + "] was provided.");
|
LOG.error("Unsupported Schedule Run Strategy [" + process.getSchedule().getVariantRunStrategy() + "] was provided.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -176,10 +181,11 @@ public class ScheduleManager
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
QScheduleMetaData scheduleMetaData = processMetaData.getSchedule();
|
QScheduleMetaData scheduleMetaData = processMetaData.getSchedule();
|
||||||
|
QBackendMetaData backendMetaData = qInstance.getBackend(scheduleMetaData.getVariantBackend());
|
||||||
|
|
||||||
QueryInput queryInput = new QueryInput();
|
QueryInput queryInput = new QueryInput();
|
||||||
queryInput.setTableName(scheduleMetaData.getVariantTableName());
|
queryInput.setTableName(backendMetaData.getVariantOptionsTableName());
|
||||||
queryInput.setFilter(scheduleMetaData.getVariantFilter());
|
queryInput.setFilter(new QQueryFilter(new QFilterCriteria(backendMetaData.getVariantOptionsTableTypeField(), QCriteriaOperator.EQUALS, backendMetaData.getVariantOptionsTableTypeValue())));
|
||||||
|
|
||||||
QContext.init(qInstance, sessionSupplier.get());
|
QContext.init(qInstance, sessionSupplier.get());
|
||||||
QueryOutput queryOutput = new QueryAction().execute(queryInput);
|
QueryOutput queryOutput = new QueryAction().execute(queryInput);
|
||||||
@ -314,7 +320,7 @@ public class ScheduleManager
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(process.getSchedule().getBackendVariant() == null || QScheduleMetaData.RunStrategy.PARALLEL.equals(process.getSchedule().getVariantRunStrategy()))
|
if(process.getSchedule().getVariantBackend() == null || QScheduleMetaData.RunStrategy.PARALLEL.equals(process.getSchedule().getVariantRunStrategy()))
|
||||||
{
|
{
|
||||||
QContext.init(qInstance, sessionSupplier.get());
|
QContext.init(qInstance, sessionSupplier.get());
|
||||||
executeSingleProcess(process, backendVariantData);
|
executeSingleProcess(process, backendVariantData);
|
||||||
@ -331,7 +337,8 @@ public class ScheduleManager
|
|||||||
{
|
{
|
||||||
QContext.init(qInstance, sessionSupplier.get());
|
QContext.init(qInstance, sessionSupplier.get());
|
||||||
QScheduleMetaData scheduleMetaData = process.getSchedule();
|
QScheduleMetaData scheduleMetaData = process.getSchedule();
|
||||||
executeSingleProcess(process, MapBuilder.of(scheduleMetaData.getBackendVariant(), qRecord.getValue(scheduleMetaData.getVariantFieldName())));
|
QBackendMetaData backendMetaData = qInstance.getBackend(scheduleMetaData.getVariantBackend());
|
||||||
|
executeSingleProcess(process, MapBuilder.of(backendMetaData.getVariantOptionsTableTypeValue(), qRecord.getValue(backendMetaData.getVariantOptionsTableIdField())));
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch(Exception e)
|
||||||
{
|
{
|
||||||
|
@ -32,6 +32,7 @@ import java.util.Base64;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import com.kingsrook.qqq.backend.core.actions.tables.GetAction;
|
||||||
import com.kingsrook.qqq.backend.core.actions.tables.InsertAction;
|
import com.kingsrook.qqq.backend.core.actions.tables.InsertAction;
|
||||||
import com.kingsrook.qqq.backend.core.context.QContext;
|
import com.kingsrook.qqq.backend.core.context.QContext;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
@ -624,28 +625,57 @@ public class BaseAPIActionUtil
|
|||||||
**
|
**
|
||||||
** Can be overridden if an API uses an authorization type we don't natively support.
|
** Can be overridden if an API uses an authorization type we don't natively support.
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
protected void setupAuthorizationInRequest(HttpRequestBase request) throws QException
|
public void setupAuthorizationInRequest(HttpRequestBase request) throws QException
|
||||||
{
|
{
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// if backend specifies that it uses variants, look for that data in the session //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
if(backendMetaData.getUsesVariants())
|
||||||
|
{
|
||||||
|
QSession session = QContext.getQSession();
|
||||||
|
if(session.getBackendVariants() == null || !session.getBackendVariants().containsKey(backendMetaData.getVariantOptionsTableTypeValue()))
|
||||||
|
{
|
||||||
|
throw (new QException("Could not find Backend Variant information for Backend '" + backendMetaData.getName() + "'"));
|
||||||
|
}
|
||||||
|
|
||||||
|
Serializable variantId = session.getBackendVariants().get(backendMetaData.getVariantOptionsTableTypeValue());
|
||||||
|
GetInput getInput = new GetInput();
|
||||||
|
getInput.setShouldMaskPasswords(false);
|
||||||
|
getInput.setTableName(backendMetaData.getVariantOptionsTableName());
|
||||||
|
getInput.setPrimaryKey(variantId);
|
||||||
|
GetOutput getOutput = new GetAction().execute(getInput);
|
||||||
|
|
||||||
|
QRecord record = getOutput.getRecord();
|
||||||
|
if(record == null)
|
||||||
|
{
|
||||||
|
throw (new QException("Could not find Backend Variant in table " + backendMetaData.getVariantOptionsTableName() + " with id '" + variantId + "'"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(backendMetaData.getAuthorizationType().equals(AuthorizationType.BASIC_AUTH_USERNAME_PASSWORD))
|
||||||
|
{
|
||||||
|
request.addHeader("Authorization", getBasicAuthenticationHeader(record.getValueString(backendMetaData.getVariantOptionsTableUsernameField()), record.getValueString(backendMetaData.getVariantOptionsTablePasswordField())));
|
||||||
|
}
|
||||||
|
else if(backendMetaData.getAuthorizationType().equals(AuthorizationType.API_KEY_HEADER))
|
||||||
|
{
|
||||||
|
request.addHeader("API-Key", record.getValueString(backendMetaData.getVariantOptionsTableApiKeyField()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw (new IllegalArgumentException("Unexpected variant authorization type specified: " + backendMetaData.getAuthorizationType()));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// if not using variants, the authorization data will be in the backend meta data object //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
switch(backendMetaData.getAuthorizationType())
|
switch(backendMetaData.getAuthorizationType())
|
||||||
{
|
{
|
||||||
case BASIC_AUTH_API_KEY:
|
case BASIC_AUTH_API_KEY -> request.addHeader("Authorization", getBasicAuthenticationHeader(backendMetaData.getApiKey()));
|
||||||
request.addHeader("Authorization", getBasicAuthenticationHeader(backendMetaData.getApiKey()));
|
case BASIC_AUTH_USERNAME_PASSWORD -> request.addHeader("Authorization", getBasicAuthenticationHeader(backendMetaData.getUsername(), backendMetaData.getPassword()));
|
||||||
break;
|
case API_KEY_HEADER -> request.addHeader("API-Key", backendMetaData.getApiKey());
|
||||||
|
case OAUTH2 -> request.setHeader("Authorization", "Bearer " + getOAuth2Token());
|
||||||
case BASIC_AUTH_USERNAME_PASSWORD:
|
default -> throw new IllegalArgumentException("Unexpected authorization type: " + backendMetaData.getAuthorizationType());
|
||||||
request.addHeader("Authorization", getBasicAuthenticationHeader(backendMetaData.getUsername(), backendMetaData.getPassword()));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case API_KEY_HEADER:
|
|
||||||
request.addHeader("API-Key", backendMetaData.getApiKey());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OAUTH2:
|
|
||||||
request.setHeader("Authorization", "Bearer " + getOAuth2Token());
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException("Unexpected authorization type: " + backendMetaData.getAuthorizationType());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -757,7 +787,7 @@ public class BaseAPIActionUtil
|
|||||||
** Helper method to create a value for an Authentication header, using just a
|
** Helper method to create a value for an Authentication header, using just a
|
||||||
** username & password - encoded as Basic + base64(username:password)
|
** username & password - encoded as Basic + base64(username:password)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
protected String getBasicAuthenticationHeader(String username, String password)
|
public String getBasicAuthenticationHeader(String username, String password)
|
||||||
{
|
{
|
||||||
return "Basic " + Base64.getEncoder().encodeToString((username + ":" + password).getBytes());
|
return "Basic " + Base64.getEncoder().encodeToString((username + ":" + password).getBytes());
|
||||||
}
|
}
|
||||||
|
@ -66,6 +66,8 @@ public class TestUtils
|
|||||||
qInstance.addBackend(defineEasypostBackend());
|
qInstance.addBackend(defineEasypostBackend());
|
||||||
qInstance.addTable(defineTableEasypostTracker());
|
qInstance.addTable(defineTableEasypostTracker());
|
||||||
|
|
||||||
|
qInstance.addTable(defineVariant());
|
||||||
|
|
||||||
return (qInstance);
|
return (qInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,6 +153,29 @@ public class TestUtils
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
private static QTableMetaData defineVariant()
|
||||||
|
{
|
||||||
|
return (new QTableMetaData()
|
||||||
|
.withName("variant")
|
||||||
|
.withBackendName(MEMORY_BACKEND_NAME)
|
||||||
|
.withField(new QFieldMetaData("id", QFieldType.INTEGER))
|
||||||
|
.withField(new QFieldMetaData("type", QFieldType.STRING))
|
||||||
|
.withField(new QFieldMetaData("apiKey", QFieldType.STRING))
|
||||||
|
.withField(new QFieldMetaData("username", QFieldType.STRING))
|
||||||
|
.withField(new QFieldMetaData("password", QFieldType.STRING))
|
||||||
|
.withPrimaryKeyField("id")
|
||||||
|
.withBackendDetails(new APITableBackendDetails()
|
||||||
|
.withTablePath("variant")
|
||||||
|
.withTableWrapperObjectName("variant")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
@ -22,12 +22,14 @@
|
|||||||
package com.kingsrook.qqq.backend.module.api.actions;
|
package com.kingsrook.qqq.backend.module.api.actions;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import com.kingsrook.qqq.backend.core.actions.tables.CountAction;
|
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;
|
import com.kingsrook.qqq.backend.core.actions.tables.GetAction;
|
||||||
import com.kingsrook.qqq.backend.core.actions.tables.InsertAction;
|
import com.kingsrook.qqq.backend.core.actions.tables.InsertAction;
|
||||||
import com.kingsrook.qqq.backend.core.actions.tables.QueryAction;
|
import com.kingsrook.qqq.backend.core.actions.tables.QueryAction;
|
||||||
@ -36,6 +38,7 @@ import com.kingsrook.qqq.backend.core.context.QContext;
|
|||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.count.CountInput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.count.CountInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.count.CountOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.count.CountOutput;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.tables.delete.DeleteInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.get.GetInput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.get.GetInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.get.GetOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.get.GetOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertInput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertInput;
|
||||||
@ -59,6 +62,7 @@ import com.kingsrook.qqq.backend.module.api.model.OutboundAPILog;
|
|||||||
import com.kingsrook.qqq.backend.module.api.model.OutboundAPILogMetaDataProvider;
|
import com.kingsrook.qqq.backend.module.api.model.OutboundAPILogMetaDataProvider;
|
||||||
import com.kingsrook.qqq.backend.module.api.model.metadata.APIBackendMetaData;
|
import com.kingsrook.qqq.backend.module.api.model.metadata.APIBackendMetaData;
|
||||||
import org.apache.http.Header;
|
import org.apache.http.Header;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
@ -81,11 +85,21 @@ class BaseAPIActionUtilTest extends BaseTest
|
|||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void beforeEach()
|
void beforeEach() throws QException
|
||||||
{
|
{
|
||||||
mockApiUtilsHelper = new MockApiUtilsHelper();
|
mockApiUtilsHelper = new MockApiUtilsHelper();
|
||||||
mockApiUtilsHelper.setUseMock(true);
|
mockApiUtilsHelper.setUseMock(true);
|
||||||
MockApiActionUtils.mockApiUtilsHelper = mockApiUtilsHelper;
|
MockApiActionUtils.mockApiUtilsHelper = mockApiUtilsHelper;
|
||||||
|
|
||||||
|
QueryInput queryInput = new QueryInput();
|
||||||
|
queryInput.setTableName("variant");
|
||||||
|
QueryOutput output = new QueryAction().execute(queryInput);
|
||||||
|
List<Serializable> ids = output.getRecords().stream().map(r -> r.getValue("id")).toList();
|
||||||
|
|
||||||
|
DeleteInput deleteInput = new DeleteInput();
|
||||||
|
deleteInput.setTableName("variant");
|
||||||
|
deleteInput.setPrimaryKeys(ids);
|
||||||
|
new DeleteAction().execute(deleteInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -603,6 +617,72 @@ class BaseAPIActionUtilTest extends BaseTest
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void testBackendWithVariantsApiKey() throws QException
|
||||||
|
{
|
||||||
|
APIBackendMetaData backend = (APIBackendMetaData) QContext.getQInstance().getBackend(TestUtils.MOCK_BACKEND_NAME);
|
||||||
|
backend.setAuthorizationType(AuthorizationType.API_KEY_HEADER);
|
||||||
|
backend.setUsesVariants(true);
|
||||||
|
backend.setVariantOptionsTableName("variant");
|
||||||
|
backend.setVariantOptionsTableIdField("id");
|
||||||
|
backend.setVariantOptionsTableApiKeyField("apiKey");
|
||||||
|
backend.setVariantOptionsTableTypeValue("API_KEY_TYPE");
|
||||||
|
|
||||||
|
InsertInput insertInput = new InsertInput();
|
||||||
|
insertInput.setTableName("variant");
|
||||||
|
insertInput.setRecords(List.of(new QRecord()
|
||||||
|
.withValue("type", "API_KEY_TYPE")
|
||||||
|
.withValue("apiKey", "abcdefg1234567")));
|
||||||
|
InsertOutput insertOutput = new InsertAction().execute(insertInput);
|
||||||
|
|
||||||
|
QContext.getQSession().setBackendVariants(Map.of("API_KEY_TYPE", insertOutput.getRecords().get(0).getValue("id")));
|
||||||
|
HttpGet httpGet = new HttpGet();
|
||||||
|
BaseAPIActionUtil util = new BaseAPIActionUtil();
|
||||||
|
util.setBackendMetaData(backend);
|
||||||
|
util.setupAuthorizationInRequest(httpGet);
|
||||||
|
Header authHeader = httpGet.getFirstHeader("API-Key");
|
||||||
|
assertTrue(authHeader.getValue().startsWith("abcde"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void testBackendWithVariantsUsernamePassword() throws QException
|
||||||
|
{
|
||||||
|
APIBackendMetaData backend = (APIBackendMetaData) QContext.getQInstance().getBackend(TestUtils.MOCK_BACKEND_NAME);
|
||||||
|
backend.setAuthorizationType(AuthorizationType.BASIC_AUTH_USERNAME_PASSWORD);
|
||||||
|
backend.setUsesVariants(true);
|
||||||
|
backend.setVariantOptionsTableName("variant");
|
||||||
|
backend.setVariantOptionsTableIdField("id");
|
||||||
|
backend.setVariantOptionsTableUsernameField("username");
|
||||||
|
backend.setVariantOptionsTablePasswordField("password");
|
||||||
|
backend.setVariantOptionsTableTypeValue("USER_PASS");
|
||||||
|
|
||||||
|
InsertInput insertInput = new InsertInput();
|
||||||
|
insertInput.setTableName("variant");
|
||||||
|
insertInput.setRecords(List.of(new QRecord()
|
||||||
|
.withValue("type", "USER_PASS")
|
||||||
|
.withValue("username", "user")
|
||||||
|
.withValue("password", "pass")));
|
||||||
|
InsertOutput insertOutput = new InsertAction().execute(insertInput);
|
||||||
|
|
||||||
|
QContext.getQSession().setBackendVariants(Map.of("USER_PASS", insertOutput.getRecords().get(0).getValue("id")));
|
||||||
|
HttpGet httpGet = new HttpGet();
|
||||||
|
BaseAPIActionUtil util = new BaseAPIActionUtil();
|
||||||
|
util.setBackendMetaData(backend);
|
||||||
|
util.setupAuthorizationInRequest(httpGet);
|
||||||
|
Header authHeader = httpGet.getFirstHeader("Authorization");
|
||||||
|
assertTrue(authHeader.getValue().equals(util.getBasicAuthenticationHeader("user", "pass")));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
@ -87,6 +87,8 @@ import com.kingsrook.qqq.backend.core.model.actions.tables.get.GetInput;
|
|||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.get.GetOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.get.GetOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertInput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertOutput;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter;
|
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.QueryInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryJoin;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryJoin;
|
||||||
@ -98,11 +100,13 @@ import com.kingsrook.qqq.backend.core.model.actions.values.SearchPossibleValueSo
|
|||||||
import com.kingsrook.qqq.backend.core.model.actions.widgets.RenderWidgetInput;
|
import com.kingsrook.qqq.backend.core.model.actions.widgets.RenderWidgetInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.widgets.RenderWidgetOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.widgets.RenderWidgetOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.AdornmentType;
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.AdornmentType;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.FieldAdornment;
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.FieldAdornment;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
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.fields.QFieldType;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.frontend.QFrontendVariant;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData;
|
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.metadata.tables.QTableMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.session.QSession;
|
import com.kingsrook.qqq.backend.core.model.session.QSession;
|
||||||
@ -114,6 +118,7 @@ import com.kingsrook.qqq.backend.core.utils.ExceptionUtils;
|
|||||||
import com.kingsrook.qqq.backend.core.utils.JsonUtils;
|
import com.kingsrook.qqq.backend.core.utils.JsonUtils;
|
||||||
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
||||||
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
|
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
|
||||||
|
import com.kingsrook.qqq.backend.core.utils.collections.MapBuilder;
|
||||||
import com.kingsrook.qqq.backend.core.utils.lambdas.UnsafeConsumer;
|
import com.kingsrook.qqq.backend.core.utils.lambdas.UnsafeConsumer;
|
||||||
import com.kingsrook.qqq.backend.core.utils.lambdas.UnsafeFunction;
|
import com.kingsrook.qqq.backend.core.utils.lambdas.UnsafeFunction;
|
||||||
import io.javalin.Javalin;
|
import io.javalin.Javalin;
|
||||||
@ -348,6 +353,7 @@ public class QJavalinImplementation
|
|||||||
post("/", QJavalinImplementation::dataInsert);
|
post("/", QJavalinImplementation::dataInsert);
|
||||||
get("/count", QJavalinImplementation::dataCount);
|
get("/count", QJavalinImplementation::dataCount);
|
||||||
post("/count", QJavalinImplementation::dataCount);
|
post("/count", QJavalinImplementation::dataCount);
|
||||||
|
get("/variants", QJavalinImplementation::variants);
|
||||||
get("/export", QJavalinImplementation::dataExportWithoutFilename);
|
get("/export", QJavalinImplementation::dataExportWithoutFilename);
|
||||||
post("/export", QJavalinImplementation::dataExportWithoutFilename);
|
post("/export", QJavalinImplementation::dataExportWithoutFilename);
|
||||||
get("/export/{filename}", QJavalinImplementation::dataExportWithFilename);
|
get("/export/{filename}", QJavalinImplementation::dataExportWithFilename);
|
||||||
@ -478,6 +484,13 @@ public class QJavalinImplementation
|
|||||||
QSession session = authenticationModule.createSession(qInstance, authenticationContext);
|
QSession session = authenticationModule.createSession(qInstance, authenticationContext);
|
||||||
QContext.init(qInstance, session, null, input);
|
QContext.init(qInstance, session, null, input);
|
||||||
|
|
||||||
|
String tableVariant = StringUtils.hasContent(context.formParam("tableVariant")) ? context.formParam("tableVariant") : context.queryParam("tableVariant");
|
||||||
|
if(StringUtils.hasContent(tableVariant))
|
||||||
|
{
|
||||||
|
JSONObject variant = new JSONObject(tableVariant);
|
||||||
|
QContext.getQSession().setBackendVariants(MapBuilder.of(variant.getString("type"), variant.getInt("id")));
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
// if we got a session id cookie in, then send it back with updated cookie age //
|
// if we got a session id cookie in, then send it back with updated cookie age //
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -975,6 +988,57 @@ public class QJavalinImplementation
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
*******************************************************************************/
|
||||||
|
static void variants(Context context)
|
||||||
|
{
|
||||||
|
String table = context.pathParam("table");
|
||||||
|
List<QFrontendVariant> variants = new ArrayList<>();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
QueryInput queryInput = new QueryInput();
|
||||||
|
setupSession(context, queryInput);
|
||||||
|
|
||||||
|
////////////////////////////////////
|
||||||
|
// get the backend for this table //
|
||||||
|
////////////////////////////////////
|
||||||
|
QTableMetaData tableMetaData = QContext.getQInstance().getTable(table);
|
||||||
|
QBackendMetaData backend = QContext.getQInstance().getBackend(tableMetaData.getBackendName());
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// if the backend uses variants, query for all possible variants of the given type //
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
if(backend != null && backend.getUsesVariants())
|
||||||
|
{
|
||||||
|
queryInput.setTableName(backend.getVariantOptionsTableName());
|
||||||
|
queryInput.setFilter(new QQueryFilter(new QFilterCriteria(backend.getVariantOptionsTableTypeField(), QCriteriaOperator.EQUALS, backend.getVariantOptionsTableTypeValue())));
|
||||||
|
QueryOutput output = new QueryAction().execute(queryInput);
|
||||||
|
for(QRecord qRecord : output.getRecords())
|
||||||
|
{
|
||||||
|
variants.add(new QFrontendVariant()
|
||||||
|
.withId(qRecord.getValue(backend.getVariantOptionsTableIdField()))
|
||||||
|
.withType(backend.getVariantOptionsTableTypeValue())
|
||||||
|
.withName(qRecord.getValueString(backend.getVariantOptionsTableNameField())));
|
||||||
|
}
|
||||||
|
|
||||||
|
QJavalinAccessLogger.logStartSilent("variants");
|
||||||
|
PermissionsHelper.checkTablePermissionThrowing(queryInput, TablePermissionSubType.READ);
|
||||||
|
}
|
||||||
|
|
||||||
|
QJavalinAccessLogger.logEndSuccessIfSlow(SLOW_LOG_THRESHOLD_MS, logPair("table", table), logPair("input", queryInput));
|
||||||
|
context.result(JsonUtils.toJson(variants));
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
QJavalinAccessLogger.logEndFail(e, logPair("table", table));
|
||||||
|
handleException(context, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* Filter parameter is a serialized QQueryFilter object, that is to say:
|
* Filter parameter is a serialized QQueryFilter object, that is to say:
|
||||||
|
Reference in New Issue
Block a user