Owner rule (2026-10-12): "table names should always be lowercase and use _, and qbits should always be prefixed with their name". For 1.1.0-RC.3, metadata only (the QBit ships no DDL): - tables: quick_search_index, quick_search_index_run, quick_search_failed_event, quick_search_diagnostic_event, quick_search_validation_run (were camelCase) - possible-value sources: quick_search_index, quick_search_searchable_table - permission bases: quick_search_admin, quick_search_debug; table permissions follow the table names - applyTablePrefix: a host prefix is snake_cased and joined with "_" (myApp -> my_app_quick_search_index); processes, widgets and apps keep applyPrefix - @Deprecated LEGACY_* constants keep the old names for upgrade scripts - docs/MIGRATION-1.1.md: upgrade steps, ALTER TABLE for camelCase databases, UPDATEs for audit_table, saved views and reports, permission grants; no reindex needed - QuickSearchTableNamesTest covers new names, legacy constants and prefixing Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2556 lines
91 KiB
Java
2556 lines
91 KiB
Java
/*
|
|
* Copyright 2024 Kingsrook, LLC
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package com.kingsrook.qbits.quicksearch;
|
|
|
|
|
|
import java.net.URI;
|
|
import java.text.ParseException;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.HashSet;
|
|
import java.util.List;
|
|
import java.util.Set;
|
|
import java.util.TimeZone;
|
|
import java.util.regex.Pattern;
|
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
|
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
|
import com.kingsrook.qqq.backend.core.model.metadata.permissions.PermissionLevel;
|
|
import com.kingsrook.qqq.backend.core.model.metadata.permissions.QPermissionRules;
|
|
import com.kingsrook.qqq.backend.core.model.metadata.producers.MetaDataCustomizerInterface;
|
|
import com.kingsrook.qqq.backend.core.model.metadata.qbits.QBitConfig;
|
|
import com.kingsrook.qqq.backend.core.model.metadata.scheduleing.QSchedulerMetaData;
|
|
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
|
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
|
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
|
import com.kingsrook.qbits.quicksearch.model.QuickSearchIndex;
|
|
import com.kingsrook.qbits.quicksearch.model.QuickSearchIndexRun;
|
|
import com.kingsrook.qbits.quicksearch.publisher.IndexEventPublisher;
|
|
import org.quartz.CronExpression;
|
|
|
|
|
|
/*******************************************************************************
|
|
** Host-facing configuration for the Quick Search QBit.
|
|
**
|
|
** Connection: opensearchUrl (preferred) or opensearchHost/opensearchPort/useSsl.
|
|
** Authentication: authMode NONE, BASIC (opensearchUsername/opensearchPassword)
|
|
** or AWS_SIGV4 (awsRegion, awsServiceName, awsAssumeRoleArn). Secret-bearing
|
|
** values may be ${env.X} / ${prop.X} references, resolved only when the
|
|
** transport is built. TLS trust lives in tls. Timeouts, pool size and a
|
|
** transportCustomizer complete the transport settings.
|
|
**
|
|
** Behaviour: startupMode, enableRealTimeIndexing, enableBasepullProcess,
|
|
** enableMaintenanceProcesses, schedulerName plus basepull/reconcile schedules,
|
|
** permission rules for the admin surface, search bounds, and indexing limits.
|
|
**
|
|
** Core search: serveCoreRecordSearch (default true) registers
|
|
** QuickSearchRecordSearchProvider, so QQQ's POST /qqq/v1/search (the Next UI
|
|
** global search) is served from OpenSearch for indexed tables, bounded by
|
|
** recordSearchTimeoutMillis.
|
|
**
|
|
** Tables: searchableEntityClasses (annotated entities) and/or searchableTables
|
|
** (config-driven). validate() is list-based and never throws; the producer
|
|
** fails production when it reports errors.
|
|
*******************************************************************************/
|
|
public class QuickSearchQBitConfig implements QBitConfig
|
|
{
|
|
public static final String DEFAULT_ADMIN_PERMISSION_BASE_NAME = "quick_search_admin";
|
|
public static final String DEFAULT_BASEPULL_TIMESTAMP_FIELD = "modifyDate";
|
|
public static final int DEFAULT_RECORD_SEARCH_TIMEOUT_MILLIS = 2500;
|
|
public static final String DEFAULT_DEBUG_PERMISSION_BASE_NAME = "quick_search_debug";
|
|
/** Admin permission base name before 1.1.0-RC.3 (camelCase). */
|
|
@Deprecated(since = "1.1.0-RC.3")
|
|
public static final String LEGACY_ADMIN_PERMISSION_BASE_NAME = "quickSearchAdmin";
|
|
/** Debug permission base name before 1.1.0-RC.3 (camelCase). */
|
|
@Deprecated(since = "1.1.0-RC.3")
|
|
public static final String LEGACY_DEBUG_PERMISSION_BASE_NAME = "quickSearchDebug";
|
|
public static final int DEFAULT_VALIDATION_SAMPLE_SIZE = 50;
|
|
public static final int MAX_VALIDATION_SAMPLE_SIZE = 1000;
|
|
public static final int DEFAULT_DIAGNOSTIC_RUNS_PER_MINUTE = 30;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// a live full reindex refreshes its run record after every page; a page is //
|
|
// one source query plus sourceBatchSize / bulkBatchSize bulk requests, each //
|
|
// bounded by the transport timeouts (a few minutes at most by default), //
|
|
// so 30 minutes leaves a wide margin before a slow run is judged dead, and //
|
|
// basepull (every 5 minutes by default) recovers a dead one soon after //
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
public static final Integer DEFAULT_FULL_REINDEX_STALE_MINUTES = 30;
|
|
|
|
private static final Pattern INDEX_NAME_PATTERN = Pattern.compile("^[a-z0-9][a-z0-9_+.-]*$");
|
|
private static final Set<String> AWS_SERVICE_NAMES = Set.of("es", "aoss");
|
|
|
|
private String backendName;
|
|
private String tableNamePrefix;
|
|
private String opensearchUrl;
|
|
private String opensearchHost;
|
|
private Integer opensearchPort;
|
|
private Boolean useSsl = false;
|
|
private String opensearchIndexName;
|
|
private QuickSearchAuthMode authMode;
|
|
private String opensearchUsername;
|
|
private String opensearchPassword;
|
|
private String awsRegion;
|
|
private String awsServiceName = "es";
|
|
private String awsAssumeRoleArn;
|
|
private Boolean allowPlaintextCredentials = false;
|
|
private QuickSearchTlsConfig tls;
|
|
private Integer connectTimeoutMillis = 5000;
|
|
private Integer responseTimeoutMillis = 60000;
|
|
private Integer maxConnections = 30;
|
|
private Integer maxBulkRequestBytes = 5 * 1024 * 1024;
|
|
private QCodeReference transportCustomizer;
|
|
private QuickSearchStartupMode startupMode = QuickSearchStartupMode.FAIL_FAST;
|
|
private Boolean enableRealTimeIndexing = true;
|
|
private Boolean enableBasepullProcess = true;
|
|
private Boolean enableMaintenanceProcesses = true;
|
|
private String schedulerName;
|
|
private Integer basepullRepeatSeconds = 300;
|
|
private String reconcileCronExpression;
|
|
private String reconcileCronTimeZoneId;
|
|
private Integer basepullOverlapSeconds = 300;
|
|
private Integer defaultBasepullIntervalMinutes = 5;
|
|
private Integer runHistoryRetentionDays = 30;
|
|
private Integer fullReindexStaleMinutes = DEFAULT_FULL_REINDEX_STALE_MINUTES;
|
|
private Integer bulkBatchSize = 500;
|
|
private Integer sourceBatchSize = 1000;
|
|
private Integer maxFieldLength = 10000;
|
|
private Integer maxSearchLimit = 100;
|
|
private Boolean applyRecordSecurityLocks = true;
|
|
private Boolean serveCoreRecordSearch = true;
|
|
private Integer recordSearchTimeoutMillis = DEFAULT_RECORD_SEARCH_TIMEOUT_MILLIS;
|
|
private Boolean enableDiagnosticTools = true;
|
|
private Boolean enableRecordDiagnosticActions = true;
|
|
private String validationCronExpression;
|
|
private String validationCronTimeZoneId;
|
|
private Integer validationSampleSize = DEFAULT_VALIDATION_SAMPLE_SIZE;
|
|
private Integer diagnosticRunsPerMinute = DEFAULT_DIAGNOSTIC_RUNS_PER_MINUTE;
|
|
private List<Class<?>> searchableEntityClasses;
|
|
private List<SearchableTableConfig> searchableTables;
|
|
|
|
private transient IndexEventPublisher indexEventPublisher;
|
|
private transient QPermissionRules adminPermissionRules = new QPermissionRules().withLevel(PermissionLevel.HAS_ACCESS_PERMISSION).withPermissionBaseName(DEFAULT_ADMIN_PERMISSION_BASE_NAME);
|
|
private transient QPermissionRules tablePermissionRules = new QPermissionRules().withLevel(PermissionLevel.READ_WRITE_PERMISSIONS);
|
|
private transient QPermissionRules debugPermissionRules = new QPermissionRules().withLevel(PermissionLevel.HAS_ACCESS_PERMISSION).withPermissionBaseName(DEFAULT_DEBUG_PERMISSION_BASE_NAME);
|
|
private transient MetaDataCustomizerInterface<QTableMetaData> tableMetaDataCustomizer;
|
|
private transient QuickSearchRuntime runtime;
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Collect configuration errors. Never throws; null-safe for a partially
|
|
** built QInstance.
|
|
*******************************************************************************/
|
|
@Override
|
|
public void validate(QInstance qInstance, List<String> errors)
|
|
{
|
|
validateBackend(qInstance, errors);
|
|
validateConnection(errors);
|
|
validateAuth(errors);
|
|
validateTls(errors);
|
|
validateIndexName(errors);
|
|
validateTables(qInstance, errors);
|
|
validateNumbers(errors);
|
|
validateScheduling(qInstance, errors);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
**
|
|
*******************************************************************************/
|
|
private void validateBackend(QInstance qInstance, List<String> errors)
|
|
{
|
|
if(!StringUtils.hasContent(backendName))
|
|
{
|
|
errors.add("backendName is required for QuickSearchQBit");
|
|
}
|
|
else if(qInstance != null && qInstance.getBackends() != null && qInstance.getBackend(backendName) == null)
|
|
{
|
|
errors.add("Backend not found: " + backendName);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
**
|
|
*******************************************************************************/
|
|
private void validateConnection(List<String> errors)
|
|
{
|
|
if(StringUtils.hasContent(opensearchUrl))
|
|
{
|
|
try
|
|
{
|
|
URI uri = new URI(opensearchUrl.trim());
|
|
if(uri.getScheme() == null || !(uri.getScheme().equalsIgnoreCase("http") || uri.getScheme().equalsIgnoreCase("https")))
|
|
{
|
|
errors.add("opensearchUrl must start with http:// or https://");
|
|
}
|
|
if(!StringUtils.hasContent(uri.getHost()))
|
|
{
|
|
errors.add("opensearchUrl must include a host");
|
|
}
|
|
if(uri.getRawUserInfo() != null)
|
|
{
|
|
errors.add("opensearchUrl must not contain credentials; use opensearchUsername and opensearchPassword");
|
|
}
|
|
}
|
|
catch(Exception e)
|
|
{
|
|
errors.add("opensearchUrl is not a valid URL; expected http(s)://host[:port]");
|
|
}
|
|
return;
|
|
}
|
|
|
|
if(!StringUtils.hasContent(opensearchHost))
|
|
{
|
|
errors.add("opensearchHost is required for QuickSearchQBit");
|
|
}
|
|
|
|
if(opensearchPort == null)
|
|
{
|
|
errors.add("opensearchPort is required for QuickSearchQBit");
|
|
}
|
|
else if(opensearchPort <= 0)
|
|
{
|
|
errors.add("opensearchPort must be positive for QuickSearchQBit");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
**
|
|
*******************************************************************************/
|
|
private void validateAuth(List<String> errors)
|
|
{
|
|
boolean hasUsername = StringUtils.hasContent(opensearchUsername);
|
|
boolean hasPassword = StringUtils.hasContent(opensearchPassword);
|
|
|
|
QuickSearchAuthMode effectiveAuthMode = getEffectiveAuthMode();
|
|
switch(effectiveAuthMode)
|
|
{
|
|
case BASIC ->
|
|
{
|
|
if(hasUsername && !hasPassword)
|
|
{
|
|
errors.add("opensearchPassword is required when opensearchUsername is set");
|
|
}
|
|
else if(!hasUsername && hasPassword)
|
|
{
|
|
errors.add("opensearchUsername is required when opensearchPassword is set");
|
|
}
|
|
else if(!hasUsername)
|
|
{
|
|
errors.add("opensearchUsername and opensearchPassword are required for authMode BASIC");
|
|
}
|
|
|
|
if("http".equals(getEffectiveScheme()) && !Boolean.TRUE.equals(allowPlaintextCredentials))
|
|
{
|
|
errors.add("BASIC credentials over plain http are refused; use https or set allowPlaintextCredentials=true for development");
|
|
}
|
|
}
|
|
case AWS_SIGV4 ->
|
|
{
|
|
if(hasUsername || hasPassword)
|
|
{
|
|
errors.add("opensearchUsername and opensearchPassword are not used with authMode AWS_SIGV4");
|
|
}
|
|
if(!StringUtils.hasContent(getEffectiveAwsRegion()))
|
|
{
|
|
errors.add("awsRegion is required for authMode AWS_SIGV4 (or set AWS_REGION in the environment)");
|
|
}
|
|
if(!AWS_SERVICE_NAMES.contains(getEffectiveAwsServiceName()))
|
|
{
|
|
errors.add("awsServiceName must be es or aoss for authMode AWS_SIGV4");
|
|
}
|
|
if(!"https".equals(getEffectiveScheme()))
|
|
{
|
|
errors.add("authMode AWS_SIGV4 requires an https connection");
|
|
}
|
|
}
|
|
case NONE ->
|
|
{
|
|
if(hasUsername || hasPassword)
|
|
{
|
|
errors.add("opensearchUsername and opensearchPassword are set but authMode is NONE");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
**
|
|
*******************************************************************************/
|
|
private void validateTls(List<String> errors)
|
|
{
|
|
if(tls == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if(Boolean.TRUE.equals(tls.getInsecureSkipVerify()) && !isLoopbackHost(getEffectiveHost()) && !Boolean.TRUE.equals(tls.getAllowInsecureInProduction()))
|
|
{
|
|
errors.add("tls.insecureSkipVerify is only allowed for loopback hosts unless tls.allowInsecureInProduction=true");
|
|
}
|
|
|
|
if(StringUtils.hasContent(tls.getCaCertificatePath()) && StringUtils.hasContent(tls.getTrustStorePath()))
|
|
{
|
|
errors.add("Set either tls.caCertificatePath or tls.trustStorePath, not both");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
**
|
|
*******************************************************************************/
|
|
private void validateIndexName(List<String> errors)
|
|
{
|
|
if(!StringUtils.hasContent(opensearchIndexName))
|
|
{
|
|
errors.add("opensearchIndexName is required for QuickSearchQBit");
|
|
}
|
|
else if(!isValidIndexName(opensearchIndexName))
|
|
{
|
|
errors.add("opensearchIndexName must be lowercase, up to 255 characters, contain only letters, digits, _ - + ., and not start with _ - or +");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
**
|
|
*******************************************************************************/
|
|
private void validateTables(QInstance qInstance, List<String> errors)
|
|
{
|
|
boolean hasEntityClasses = !CollectionUtils.nullSafeIsEmpty(searchableEntityClasses);
|
|
boolean hasSearchableTables = !CollectionUtils.nullSafeIsEmpty(searchableTables);
|
|
|
|
if(!hasEntityClasses && !hasSearchableTables)
|
|
{
|
|
errors.add("At least one of searchableEntityClasses or searchableTables is required for QuickSearchQBit");
|
|
}
|
|
|
|
if(!hasSearchableTables)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Set<String> seenTableNames = new HashSet<>();
|
|
for(SearchableTableConfig tableConfig : searchableTables)
|
|
{
|
|
String tableName = tableConfig.getTableName();
|
|
if(!StringUtils.hasContent(tableName))
|
|
{
|
|
errors.add("tableName is required on each SearchableTableConfig for QuickSearchQBit");
|
|
}
|
|
else if(!seenTableNames.add(tableName))
|
|
{
|
|
errors.add("Duplicate tableName in searchableTables: " + tableName);
|
|
}
|
|
else if(tableName.contains(":"))
|
|
{
|
|
errors.add("tableName must not contain ':' (it is part of the document id): " + tableName);
|
|
}
|
|
|
|
if(CollectionUtils.nullSafeIsEmpty(tableConfig.getFields()))
|
|
{
|
|
errors.add("fields is required and must be non-empty on SearchableTableConfig"
|
|
+ (StringUtils.hasContent(tableName) ? " [" + tableName + "]" : "")
|
|
+ " for QuickSearchQBit");
|
|
}
|
|
|
|
QTableMetaData table = (qInstance == null || tableName == null) ? null : qInstance.getTable(tableName);
|
|
if(table != null)
|
|
{
|
|
validateFieldsExist(table, tableConfig, errors);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Check that configured fields exist on a table that is already in the
|
|
** instance. Tables added after this QBit is produced are checked by the
|
|
** validator plugin.
|
|
*******************************************************************************/
|
|
public static void validateFieldsExist(QTableMetaData table, SearchableTableConfig tableConfig, List<String> errors)
|
|
{
|
|
for(SearchableFieldConfig field : CollectionUtils.nonNullList(tableConfig.getFields()))
|
|
{
|
|
if(field.getFieldName() != null && !table.getFields().containsKey(field.getFieldName()))
|
|
{
|
|
errors.add("Searchable field [" + field.getFieldName() + "] does not exist on table [" + table.getName() + "]");
|
|
}
|
|
}
|
|
|
|
String timestampField = tableConfig.getBasepullTimestampField();
|
|
if(timestampField != null && !DEFAULT_BASEPULL_TIMESTAMP_FIELD.equals(timestampField) && !table.getFields().containsKey(timestampField))
|
|
{
|
|
errors.add("basepullTimestampField [" + timestampField + "] does not exist on table [" + table.getName() + "]; set it to null to disable incremental basepull for that table");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
**
|
|
*******************************************************************************/
|
|
private void validateNumbers(List<String> errors)
|
|
{
|
|
requirePositive(bulkBatchSize, "bulkBatchSize", errors);
|
|
requirePositive(sourceBatchSize, "sourceBatchSize", errors);
|
|
requirePositive(defaultBasepullIntervalMinutes, "defaultBasepullIntervalMinutes", errors);
|
|
requirePositive(connectTimeoutMillis, "connectTimeoutMillis", errors);
|
|
requirePositive(responseTimeoutMillis, "responseTimeoutMillis", errors);
|
|
requirePositive(maxConnections, "maxConnections", errors);
|
|
requirePositive(maxBulkRequestBytes, "maxBulkRequestBytes", errors);
|
|
requirePositive(basepullRepeatSeconds, "basepullRepeatSeconds", errors);
|
|
requirePositive(maxSearchLimit, "maxSearchLimit", errors);
|
|
requirePositive(recordSearchTimeoutMillis, "recordSearchTimeoutMillis", errors);
|
|
requirePositive(maxFieldLength, "maxFieldLength", errors);
|
|
requirePositive(runHistoryRetentionDays, "runHistoryRetentionDays", errors);
|
|
requirePositive(fullReindexStaleMinutes, "fullReindexStaleMinutes", errors);
|
|
requirePositive(validationSampleSize, "validationSampleSize", errors);
|
|
requirePositive(diagnosticRunsPerMinute, "diagnosticRunsPerMinute", errors);
|
|
|
|
if(validationSampleSize != null && validationSampleSize > MAX_VALIDATION_SAMPLE_SIZE)
|
|
{
|
|
errors.add("validationSampleSize must be at most " + MAX_VALIDATION_SAMPLE_SIZE + " for QuickSearchQBit");
|
|
}
|
|
|
|
if(basepullOverlapSeconds != null && basepullOverlapSeconds < 0)
|
|
{
|
|
errors.add("basepullOverlapSeconds must not be negative for QuickSearchQBit");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
**
|
|
*******************************************************************************/
|
|
private static void requirePositive(Integer value, String name, List<String> errors)
|
|
{
|
|
if(value != null && value <= 0)
|
|
{
|
|
errors.add(name + " must be positive for QuickSearchQBit");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** The scheduler must exist when the instance already has schedulers. A
|
|
** reconcile cron gets the checks QQQ's instance validator applies to every
|
|
** cron schedule (Quartz syntax, a required and known time zone, which QQQ
|
|
** never defaults), plus a scheduler that supports cron, so a bad schedule
|
|
** fails produce() naming these fields instead of failing at startup.
|
|
*******************************************************************************/
|
|
private void validateScheduling(QInstance qInstance, List<String> errors)
|
|
{
|
|
QSchedulerMetaData scheduler = null;
|
|
if(StringUtils.hasContent(schedulerName) && qInstance != null && !CollectionUtils.nullSafeIsEmpty(qInstance.getSchedulers()))
|
|
{
|
|
scheduler = qInstance.getScheduler(schedulerName);
|
|
if(scheduler == null)
|
|
{
|
|
errors.add("Scheduler not found: " + schedulerName);
|
|
}
|
|
}
|
|
|
|
validateCron("reconcile", reconcileCronExpression, reconcileCronTimeZoneId, scheduler, errors);
|
|
validateCron("validation", validationCronExpression, validationCronTimeZoneId, scheduler, errors);
|
|
|
|
if(StringUtils.hasContent(validationCronExpression) && !Boolean.TRUE.equals(enableDiagnosticTools))
|
|
{
|
|
errors.add("validationCronExpression requires enableDiagnosticTools");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** A cron schedule (prefix "reconcile" or "validation"): needs schedulerName
|
|
** on a scheduler that supports cron, a valid Quartz expression and a
|
|
** recognized time zone ID.
|
|
*******************************************************************************/
|
|
private void validateCron(String prefix, String cronExpression, String cronTimeZoneId, QSchedulerMetaData scheduler, List<String> errors)
|
|
{
|
|
if(StringUtils.hasContent(cronExpression))
|
|
{
|
|
if(!StringUtils.hasContent(schedulerName))
|
|
{
|
|
errors.add(prefix + "CronExpression requires schedulerName");
|
|
}
|
|
else if(scheduler != null && !scheduler.supportsCronSchedules())
|
|
{
|
|
errors.add(prefix + "CronExpression requires a scheduler that supports cron schedules, such as a QuartzSchedulerMetaData; scheduler [" + schedulerName + "] is of type " + scheduler.getType());
|
|
}
|
|
|
|
try
|
|
{
|
|
CronExpression.validateExpression(cronExpression);
|
|
}
|
|
catch(ParseException e)
|
|
{
|
|
errors.add(prefix + "CronExpression [" + cronExpression + "] is not a valid Quartz cron expression: " + e.getMessage());
|
|
}
|
|
|
|
if(!StringUtils.hasContent(cronTimeZoneId))
|
|
{
|
|
errors.add(prefix + "CronExpression requires " + prefix + "CronTimeZoneId (a time zone ID such as UTC or America/Chicago)");
|
|
}
|
|
}
|
|
|
|
if(StringUtils.hasContent(cronTimeZoneId) && !Arrays.asList(TimeZone.getAvailableIDs()).contains(cronTimeZoneId))
|
|
{
|
|
errors.add(prefix + "CronTimeZoneId [" + cronTimeZoneId + "] is not a recognized time zone ID");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** OpenSearch index and alias naming rules.
|
|
*******************************************************************************/
|
|
public static boolean isValidIndexName(String name)
|
|
{
|
|
if(name == null || name.isEmpty() || name.length() > 255 || name.equals(".") || name.equals(".."))
|
|
{
|
|
return (false);
|
|
}
|
|
return (INDEX_NAME_PATTERN.matcher(name).matches());
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
**
|
|
*******************************************************************************/
|
|
private static boolean isLoopbackHost(String host)
|
|
{
|
|
if(host == null)
|
|
{
|
|
return (false);
|
|
}
|
|
String lower = host.toLowerCase();
|
|
return (lower.equals("localhost") || lower.equals("127.0.0.1") || lower.equals("::1") || lower.equals("[::1]") || lower.startsWith("127."));
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** The auth mode in effect: the configured one, else BASIC when credentials
|
|
** are present, else NONE.
|
|
*******************************************************************************/
|
|
@JsonIgnore
|
|
public QuickSearchAuthMode getEffectiveAuthMode()
|
|
{
|
|
if(authMode != null)
|
|
{
|
|
return (authMode);
|
|
}
|
|
return (StringUtils.hasContent(opensearchUsername) || StringUtils.hasContent(opensearchPassword) ? QuickSearchAuthMode.BASIC : QuickSearchAuthMode.NONE);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** http or https, from opensearchUrl or useSsl.
|
|
*******************************************************************************/
|
|
@JsonIgnore
|
|
public String getEffectiveScheme()
|
|
{
|
|
URI uri = parseUrlQuietly();
|
|
if(uri != null && uri.getScheme() != null)
|
|
{
|
|
return (uri.getScheme().toLowerCase());
|
|
}
|
|
return (Boolean.TRUE.equals(useSsl) ? "https" : "http");
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Host from opensearchUrl or opensearchHost.
|
|
*******************************************************************************/
|
|
@JsonIgnore
|
|
public String getEffectiveHost()
|
|
{
|
|
URI uri = parseUrlQuietly();
|
|
if(uri != null && StringUtils.hasContent(uri.getHost()))
|
|
{
|
|
return (uri.getHost());
|
|
}
|
|
return (opensearchHost);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Port from opensearchUrl (443 for https, 9200 for http when absent) or
|
|
** opensearchPort.
|
|
*******************************************************************************/
|
|
@JsonIgnore
|
|
public Integer getEffectivePort()
|
|
{
|
|
URI uri = parseUrlQuietly();
|
|
if(uri != null && StringUtils.hasContent(uri.getHost()))
|
|
{
|
|
if(uri.getPort() > 0)
|
|
{
|
|
return (uri.getPort());
|
|
}
|
|
return ("https".equalsIgnoreCase(uri.getScheme()) ? 443 : 9200);
|
|
}
|
|
return (opensearchPort);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** awsRegion, else AWS_REGION, else AWS_DEFAULT_REGION from the environment.
|
|
*******************************************************************************/
|
|
@JsonIgnore
|
|
public String getEffectiveAwsRegion()
|
|
{
|
|
if(StringUtils.hasContent(awsRegion))
|
|
{
|
|
return (awsRegion);
|
|
}
|
|
String fromEnv = System.getenv("AWS_REGION");
|
|
if(!StringUtils.hasContent(fromEnv))
|
|
{
|
|
fromEnv = System.getenv("AWS_DEFAULT_REGION");
|
|
}
|
|
return (fromEnv);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** awsServiceName, defaulting to es.
|
|
*******************************************************************************/
|
|
@JsonIgnore
|
|
public String getEffectiveAwsServiceName()
|
|
{
|
|
return (StringUtils.hasContent(awsServiceName) ? awsServiceName.toLowerCase() : "es");
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** fullReindexStaleMinutes, defaulting to DEFAULT_FULL_REINDEX_STALE_MINUTES.
|
|
*******************************************************************************/
|
|
@JsonIgnore
|
|
public Integer getEffectiveFullReindexStaleMinutes()
|
|
{
|
|
return (fullReindexStaleMinutes == null ? DEFAULT_FULL_REINDEX_STALE_MINUTES : fullReindexStaleMinutes);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
**
|
|
*******************************************************************************/
|
|
private URI parseUrlQuietly()
|
|
{
|
|
if(!StringUtils.hasContent(opensearchUrl))
|
|
{
|
|
return (null);
|
|
}
|
|
try
|
|
{
|
|
return (new URI(opensearchUrl.trim()));
|
|
}
|
|
catch(Exception e)
|
|
{
|
|
return (null);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Apply the table-name prefix to a table or possible-value source name.
|
|
** Table names are lowercase snake_case (owner naming rule, 2026-10-12), so a
|
|
** prefix is converted to snake_case and joined with "_": prefix "acme" and
|
|
** quick_search_index give acme_quick_search_index.
|
|
*******************************************************************************/
|
|
public String applyTablePrefix(String name)
|
|
{
|
|
if(StringUtils.hasContent(tableNamePrefix))
|
|
{
|
|
String prefix = toSnakeCase(tableNamePrefix);
|
|
return (prefix.endsWith("_") ? prefix : prefix + "_") + name;
|
|
}
|
|
return name;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Convert a camelCase name to lowercase snake_case.
|
|
*******************************************************************************/
|
|
static String toSnakeCase(String name)
|
|
{
|
|
return name.replaceAll("([a-z0-9])([A-Z])", "$1_$2").replace('-', '_').toLowerCase();
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Apply the name prefix, if any, to a process, widget or app name.
|
|
*******************************************************************************/
|
|
public String applyPrefix(String name)
|
|
{
|
|
if(StringUtils.hasContent(tableNamePrefix))
|
|
{
|
|
return tableNamePrefix + name;
|
|
}
|
|
return name;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Name of the produced quick_search_index table.
|
|
*******************************************************************************/
|
|
public String getQuickSearchIndexTableName()
|
|
{
|
|
return applyTablePrefix(QuickSearchIndex.TABLE_NAME);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Name of the produced quick_search_index_run table.
|
|
*******************************************************************************/
|
|
public String getQuickSearchIndexRunTableName()
|
|
{
|
|
return applyTablePrefix(QuickSearchIndexRun.TABLE_NAME);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** QBitConfig hook: tables this QBit produces default to backendName.
|
|
*******************************************************************************/
|
|
@Override
|
|
public String getDefaultBackendNameForTables()
|
|
{
|
|
return (backendName);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** QBitConfig hook: host-supplied customizer for produced tables.
|
|
*******************************************************************************/
|
|
@Override
|
|
public MetaDataCustomizerInterface<QTableMetaData> getTableMetaDataCustomizer()
|
|
{
|
|
return (tableMetaDataCustomizer);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for tableMetaDataCustomizer
|
|
*******************************************************************************/
|
|
public void setTableMetaDataCustomizer(MetaDataCustomizerInterface<QTableMetaData> tableMetaDataCustomizer)
|
|
{
|
|
this.tableMetaDataCustomizer = tableMetaDataCustomizer;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for tableMetaDataCustomizer
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withTableMetaDataCustomizer(MetaDataCustomizerInterface<QTableMetaData> tableMetaDataCustomizer)
|
|
{
|
|
this.tableMetaDataCustomizer = tableMetaDataCustomizer;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Deprecated alias: true when both enableBasepullProcess and
|
|
** enableMaintenanceProcesses are true.
|
|
**
|
|
** @deprecated use enableBasepullProcess and enableMaintenanceProcesses
|
|
*******************************************************************************/
|
|
@Deprecated
|
|
public Boolean getEnableScheduledProcesses()
|
|
{
|
|
return (Boolean.TRUE.equals(enableBasepullProcess) && Boolean.TRUE.equals(enableMaintenanceProcesses));
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Deprecated alias: sets both enableBasepullProcess and
|
|
** enableMaintenanceProcesses.
|
|
**
|
|
** @deprecated use enableBasepullProcess and enableMaintenanceProcesses
|
|
*******************************************************************************/
|
|
@Deprecated
|
|
public void setEnableScheduledProcesses(Boolean enableScheduledProcesses)
|
|
{
|
|
this.enableBasepullProcess = enableScheduledProcesses;
|
|
this.enableMaintenanceProcesses = enableScheduledProcesses;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Deprecated alias: sets both enableBasepullProcess and
|
|
** enableMaintenanceProcesses.
|
|
**
|
|
** @deprecated use enableBasepullProcess and enableMaintenanceProcesses
|
|
*******************************************************************************/
|
|
@Deprecated
|
|
public QuickSearchQBitConfig withEnableScheduledProcesses(Boolean enableScheduledProcesses)
|
|
{
|
|
setEnableScheduledProcesses(enableScheduledProcesses);
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Add one config-driven searchable table.
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withSearchableTable(SearchableTableConfig tableConfig)
|
|
{
|
|
if(this.searchableTables == null)
|
|
{
|
|
this.searchableTables = new ArrayList<>();
|
|
}
|
|
this.searchableTables.add(tableConfig);
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Add one config-driven searchable table from its name and fields.
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withSearchableTable(String tableName, List<SearchableFieldConfig> fields)
|
|
{
|
|
return withSearchableTable(new SearchableTableConfig(tableName, fields));
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Summary without secrets.
|
|
*******************************************************************************/
|
|
@Override
|
|
public String toString()
|
|
{
|
|
return ("QuickSearchQBitConfig{backendName=" + backendName
|
|
+ ", url=" + getEffectiveScheme() + "://" + getEffectiveHost() + ":" + getEffectivePort()
|
|
+ ", indexName=" + opensearchIndexName
|
|
+ ", authMode=" + getEffectiveAuthMode()
|
|
+ ", username=" + (StringUtils.hasContent(opensearchUsername) ? "[set]" : "[none]")
|
|
+ ", password=" + (StringUtils.hasContent(opensearchPassword) ? "[redacted]" : "[none]")
|
|
+ ", startupMode=" + startupMode
|
|
+ ", schedulerName=" + schedulerName
|
|
+ ", entityClasses=" + (searchableEntityClasses == null ? 0 : searchableEntityClasses.size())
|
|
+ ", searchableTables=" + (searchableTables == null ? 0 : searchableTables.size())
|
|
+ "}");
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for backendName: QQQ backend that holds the operational tables (required)
|
|
*******************************************************************************/
|
|
public String getBackendName()
|
|
{
|
|
return (this.backendName);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for backendName
|
|
*******************************************************************************/
|
|
public void setBackendName(String backendName)
|
|
{
|
|
this.backendName = backendName;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for backendName
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withBackendName(String backendName)
|
|
{
|
|
this.backendName = backendName;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for tableNamePrefix: optional prefix for produced table, process and app names
|
|
*******************************************************************************/
|
|
public String getTableNamePrefix()
|
|
{
|
|
return (this.tableNamePrefix);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for tableNamePrefix
|
|
*******************************************************************************/
|
|
public void setTableNamePrefix(String tableNamePrefix)
|
|
{
|
|
this.tableNamePrefix = tableNamePrefix;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for tableNamePrefix
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withTableNamePrefix(String tableNamePrefix)
|
|
{
|
|
this.tableNamePrefix = tableNamePrefix;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for opensearchUrl: full OpenSearch URL, e.g. https://search.example.com:443 (preferred over host/port/useSsl)
|
|
*******************************************************************************/
|
|
public String getOpensearchUrl()
|
|
{
|
|
return (this.opensearchUrl);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for opensearchUrl
|
|
*******************************************************************************/
|
|
public void setOpensearchUrl(String opensearchUrl)
|
|
{
|
|
this.opensearchUrl = opensearchUrl;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for opensearchUrl
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withOpensearchUrl(String opensearchUrl)
|
|
{
|
|
this.opensearchUrl = opensearchUrl;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for opensearchHost: OpenSearch host (when opensearchUrl is not set)
|
|
*******************************************************************************/
|
|
public String getOpensearchHost()
|
|
{
|
|
return (this.opensearchHost);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for opensearchHost
|
|
*******************************************************************************/
|
|
public void setOpensearchHost(String opensearchHost)
|
|
{
|
|
this.opensearchHost = opensearchHost;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for opensearchHost
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withOpensearchHost(String opensearchHost)
|
|
{
|
|
this.opensearchHost = opensearchHost;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for opensearchPort: OpenSearch port (when opensearchUrl is not set)
|
|
*******************************************************************************/
|
|
public Integer getOpensearchPort()
|
|
{
|
|
return (this.opensearchPort);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for opensearchPort
|
|
*******************************************************************************/
|
|
public void setOpensearchPort(Integer opensearchPort)
|
|
{
|
|
this.opensearchPort = opensearchPort;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for opensearchPort
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withOpensearchPort(Integer opensearchPort)
|
|
{
|
|
this.opensearchPort = opensearchPort;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for useSsl: use https (when opensearchUrl is not set)
|
|
*******************************************************************************/
|
|
public Boolean getUseSsl()
|
|
{
|
|
return (this.useSsl);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for useSsl
|
|
*******************************************************************************/
|
|
public void setUseSsl(Boolean useSsl)
|
|
{
|
|
this.useSsl = useSsl;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for useSsl
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withUseSsl(Boolean useSsl)
|
|
{
|
|
this.useSsl = useSsl;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for opensearchIndexName: name of the OpenSearch index (alias) this QBit owns (required)
|
|
*******************************************************************************/
|
|
public String getOpensearchIndexName()
|
|
{
|
|
return (this.opensearchIndexName);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for opensearchIndexName
|
|
*******************************************************************************/
|
|
public void setOpensearchIndexName(String opensearchIndexName)
|
|
{
|
|
this.opensearchIndexName = opensearchIndexName;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for opensearchIndexName
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withOpensearchIndexName(String opensearchIndexName)
|
|
{
|
|
this.opensearchIndexName = opensearchIndexName;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for authMode: authentication mode; inferred as BASIC when credentials are set, else NONE
|
|
*******************************************************************************/
|
|
public QuickSearchAuthMode getAuthMode()
|
|
{
|
|
return (this.authMode);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for authMode
|
|
*******************************************************************************/
|
|
public void setAuthMode(QuickSearchAuthMode authMode)
|
|
{
|
|
this.authMode = authMode;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for authMode
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withAuthMode(QuickSearchAuthMode authMode)
|
|
{
|
|
this.authMode = authMode;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for opensearchUsername: BASIC auth username; may be a ${env.X} reference
|
|
*******************************************************************************/
|
|
public String getOpensearchUsername()
|
|
{
|
|
return (this.opensearchUsername);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for opensearchUsername
|
|
*******************************************************************************/
|
|
public void setOpensearchUsername(String opensearchUsername)
|
|
{
|
|
this.opensearchUsername = opensearchUsername;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for opensearchUsername
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withOpensearchUsername(String opensearchUsername)
|
|
{
|
|
this.opensearchUsername = opensearchUsername;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for opensearchPassword: BASIC auth password; may be a ${env.X} reference. Never serialized to JSON
|
|
*******************************************************************************/
|
|
@JsonIgnore
|
|
public String getOpensearchPassword()
|
|
{
|
|
return (this.opensearchPassword);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for opensearchPassword
|
|
*******************************************************************************/
|
|
public void setOpensearchPassword(String opensearchPassword)
|
|
{
|
|
this.opensearchPassword = opensearchPassword;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for opensearchPassword
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withOpensearchPassword(String opensearchPassword)
|
|
{
|
|
this.opensearchPassword = opensearchPassword;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for awsRegion: AWS_SIGV4 region; defaults to AWS_REGION / AWS_DEFAULT_REGION from the environment
|
|
*******************************************************************************/
|
|
public String getAwsRegion()
|
|
{
|
|
return (this.awsRegion);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for awsRegion
|
|
*******************************************************************************/
|
|
public void setAwsRegion(String awsRegion)
|
|
{
|
|
this.awsRegion = awsRegion;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for awsRegion
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withAwsRegion(String awsRegion)
|
|
{
|
|
this.awsRegion = awsRegion;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for awsServiceName: AWS_SIGV4 signing service: es (managed domains) or aoss (Serverless)
|
|
*******************************************************************************/
|
|
public String getAwsServiceName()
|
|
{
|
|
return (this.awsServiceName);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for awsServiceName
|
|
*******************************************************************************/
|
|
public void setAwsServiceName(String awsServiceName)
|
|
{
|
|
this.awsServiceName = awsServiceName;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for awsServiceName
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withAwsServiceName(String awsServiceName)
|
|
{
|
|
this.awsServiceName = awsServiceName;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for awsAssumeRoleArn: AWS_SIGV4 optional role to assume via STS
|
|
*******************************************************************************/
|
|
public String getAwsAssumeRoleArn()
|
|
{
|
|
return (this.awsAssumeRoleArn);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for awsAssumeRoleArn
|
|
*******************************************************************************/
|
|
public void setAwsAssumeRoleArn(String awsAssumeRoleArn)
|
|
{
|
|
this.awsAssumeRoleArn = awsAssumeRoleArn;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for awsAssumeRoleArn
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withAwsAssumeRoleArn(String awsAssumeRoleArn)
|
|
{
|
|
this.awsAssumeRoleArn = awsAssumeRoleArn;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for allowPlaintextCredentials: permit BASIC credentials over plain http (development only)
|
|
*******************************************************************************/
|
|
public Boolean getAllowPlaintextCredentials()
|
|
{
|
|
return (this.allowPlaintextCredentials);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for allowPlaintextCredentials
|
|
*******************************************************************************/
|
|
public void setAllowPlaintextCredentials(Boolean allowPlaintextCredentials)
|
|
{
|
|
this.allowPlaintextCredentials = allowPlaintextCredentials;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for allowPlaintextCredentials
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withAllowPlaintextCredentials(Boolean allowPlaintextCredentials)
|
|
{
|
|
this.allowPlaintextCredentials = allowPlaintextCredentials;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for tls: TLS trust and client certificate settings
|
|
*******************************************************************************/
|
|
public QuickSearchTlsConfig getTls()
|
|
{
|
|
return (this.tls);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for tls
|
|
*******************************************************************************/
|
|
public void setTls(QuickSearchTlsConfig tls)
|
|
{
|
|
this.tls = tls;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for tls
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withTls(QuickSearchTlsConfig tls)
|
|
{
|
|
this.tls = tls;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for connectTimeoutMillis: transport connect timeout
|
|
*******************************************************************************/
|
|
public Integer getConnectTimeoutMillis()
|
|
{
|
|
return (this.connectTimeoutMillis);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for connectTimeoutMillis
|
|
*******************************************************************************/
|
|
public void setConnectTimeoutMillis(Integer connectTimeoutMillis)
|
|
{
|
|
this.connectTimeoutMillis = connectTimeoutMillis;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for connectTimeoutMillis
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withConnectTimeoutMillis(Integer connectTimeoutMillis)
|
|
{
|
|
this.connectTimeoutMillis = connectTimeoutMillis;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for responseTimeoutMillis: transport response timeout
|
|
*******************************************************************************/
|
|
public Integer getResponseTimeoutMillis()
|
|
{
|
|
return (this.responseTimeoutMillis);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for responseTimeoutMillis
|
|
*******************************************************************************/
|
|
public void setResponseTimeoutMillis(Integer responseTimeoutMillis)
|
|
{
|
|
this.responseTimeoutMillis = responseTimeoutMillis;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for responseTimeoutMillis
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withResponseTimeoutMillis(Integer responseTimeoutMillis)
|
|
{
|
|
this.responseTimeoutMillis = responseTimeoutMillis;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for maxConnections: transport connection pool size
|
|
*******************************************************************************/
|
|
public Integer getMaxConnections()
|
|
{
|
|
return (this.maxConnections);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for maxConnections
|
|
*******************************************************************************/
|
|
public void setMaxConnections(Integer maxConnections)
|
|
{
|
|
this.maxConnections = maxConnections;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for maxConnections
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withMaxConnections(Integer maxConnections)
|
|
{
|
|
this.maxConnections = maxConnections;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for maxBulkRequestBytes: flush a bulk request when its serialized size reaches this many bytes
|
|
*******************************************************************************/
|
|
public Integer getMaxBulkRequestBytes()
|
|
{
|
|
return (this.maxBulkRequestBytes);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for maxBulkRequestBytes
|
|
*******************************************************************************/
|
|
public void setMaxBulkRequestBytes(Integer maxBulkRequestBytes)
|
|
{
|
|
this.maxBulkRequestBytes = maxBulkRequestBytes;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for maxBulkRequestBytes
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withMaxBulkRequestBytes(Integer maxBulkRequestBytes)
|
|
{
|
|
this.maxBulkRequestBytes = maxBulkRequestBytes;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for transportCustomizer: QCodeReference to an OpenSearchTransportCustomizer
|
|
*******************************************************************************/
|
|
public QCodeReference getTransportCustomizer()
|
|
{
|
|
return (this.transportCustomizer);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for transportCustomizer
|
|
*******************************************************************************/
|
|
public void setTransportCustomizer(QCodeReference transportCustomizer)
|
|
{
|
|
this.transportCustomizer = transportCustomizer;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for transportCustomizer
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withTransportCustomizer(QCodeReference transportCustomizer)
|
|
{
|
|
this.transportCustomizer = transportCustomizer;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for startupMode: FAIL_FAST or DEGRADED startup when OpenSearch is unreachable
|
|
*******************************************************************************/
|
|
public QuickSearchStartupMode getStartupMode()
|
|
{
|
|
return (this.startupMode);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for startupMode
|
|
*******************************************************************************/
|
|
public void setStartupMode(QuickSearchStartupMode startupMode)
|
|
{
|
|
this.startupMode = startupMode;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for startupMode
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withStartupMode(QuickSearchStartupMode startupMode)
|
|
{
|
|
this.startupMode = startupMode;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for enableRealTimeIndexing: register the record-change listener that indexes writes as they happen
|
|
*******************************************************************************/
|
|
public Boolean getEnableRealTimeIndexing()
|
|
{
|
|
return (this.enableRealTimeIndexing);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for enableRealTimeIndexing
|
|
*******************************************************************************/
|
|
public void setEnableRealTimeIndexing(Boolean enableRealTimeIndexing)
|
|
{
|
|
this.enableRealTimeIndexing = enableRealTimeIndexing;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for enableRealTimeIndexing
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withEnableRealTimeIndexing(Boolean enableRealTimeIndexing)
|
|
{
|
|
this.enableRealTimeIndexing = enableRealTimeIndexing;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for enableBasepullProcess: register the basepull catch-up process
|
|
*******************************************************************************/
|
|
public Boolean getEnableBasepullProcess()
|
|
{
|
|
return (this.enableBasepullProcess);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for enableBasepullProcess
|
|
*******************************************************************************/
|
|
public void setEnableBasepullProcess(Boolean enableBasepullProcess)
|
|
{
|
|
this.enableBasepullProcess = enableBasepullProcess;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for enableBasepullProcess
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withEnableBasepullProcess(Boolean enableBasepullProcess)
|
|
{
|
|
this.enableBasepullProcess = enableBasepullProcess;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for enableMaintenanceProcesses: register the full reindex and reconcile processes
|
|
*******************************************************************************/
|
|
public Boolean getEnableMaintenanceProcesses()
|
|
{
|
|
return (this.enableMaintenanceProcesses);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for enableMaintenanceProcesses
|
|
*******************************************************************************/
|
|
public void setEnableMaintenanceProcesses(Boolean enableMaintenanceProcesses)
|
|
{
|
|
this.enableMaintenanceProcesses = enableMaintenanceProcesses;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for enableMaintenanceProcesses
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withEnableMaintenanceProcesses(Boolean enableMaintenanceProcesses)
|
|
{
|
|
this.enableMaintenanceProcesses = enableMaintenanceProcesses;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for schedulerName: QQQ scheduler to run basepull and reconcile on; null leaves them unscheduled
|
|
*******************************************************************************/
|
|
public String getSchedulerName()
|
|
{
|
|
return (this.schedulerName);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for schedulerName
|
|
*******************************************************************************/
|
|
public void setSchedulerName(String schedulerName)
|
|
{
|
|
this.schedulerName = schedulerName;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for schedulerName
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withSchedulerName(String schedulerName)
|
|
{
|
|
this.schedulerName = schedulerName;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for basepullRepeatSeconds: basepull schedule interval when schedulerName is set
|
|
*******************************************************************************/
|
|
public Integer getBasepullRepeatSeconds()
|
|
{
|
|
return (this.basepullRepeatSeconds);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for basepullRepeatSeconds
|
|
*******************************************************************************/
|
|
public void setBasepullRepeatSeconds(Integer basepullRepeatSeconds)
|
|
{
|
|
this.basepullRepeatSeconds = basepullRepeatSeconds;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for basepullRepeatSeconds
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withBasepullRepeatSeconds(Integer basepullRepeatSeconds)
|
|
{
|
|
this.basepullRepeatSeconds = basepullRepeatSeconds;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for reconcileCronExpression: optional Quartz cron schedule for
|
|
** reconcile; needs reconcileCronTimeZoneId and a scheduler that supports
|
|
** cron (Quartz)
|
|
*******************************************************************************/
|
|
public String getReconcileCronExpression()
|
|
{
|
|
return (this.reconcileCronExpression);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for reconcileCronExpression
|
|
*******************************************************************************/
|
|
public void setReconcileCronExpression(String reconcileCronExpression)
|
|
{
|
|
this.reconcileCronExpression = reconcileCronExpression;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for reconcileCronExpression
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withReconcileCronExpression(String reconcileCronExpression)
|
|
{
|
|
this.reconcileCronExpression = reconcileCronExpression;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for reconcileCronTimeZoneId: time zone ID for
|
|
** reconcileCronExpression (UTC, America/Chicago); required with it, since
|
|
** QQQ has no default zone for cron schedules
|
|
*******************************************************************************/
|
|
public String getReconcileCronTimeZoneId()
|
|
{
|
|
return (this.reconcileCronTimeZoneId);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for reconcileCronTimeZoneId
|
|
*******************************************************************************/
|
|
public void setReconcileCronTimeZoneId(String reconcileCronTimeZoneId)
|
|
{
|
|
this.reconcileCronTimeZoneId = reconcileCronTimeZoneId;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for reconcileCronTimeZoneId
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withReconcileCronTimeZoneId(String reconcileCronTimeZoneId)
|
|
{
|
|
this.reconcileCronTimeZoneId = reconcileCronTimeZoneId;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for basepullOverlapSeconds: how far before the previous run start basepull re-reads, to absorb clock skew and long transactions
|
|
*******************************************************************************/
|
|
public Integer getBasepullOverlapSeconds()
|
|
{
|
|
return (this.basepullOverlapSeconds);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for basepullOverlapSeconds
|
|
*******************************************************************************/
|
|
public void setBasepullOverlapSeconds(Integer basepullOverlapSeconds)
|
|
{
|
|
this.basepullOverlapSeconds = basepullOverlapSeconds;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for basepullOverlapSeconds
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withBasepullOverlapSeconds(Integer basepullOverlapSeconds)
|
|
{
|
|
this.basepullOverlapSeconds = basepullOverlapSeconds;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for defaultBasepullIntervalMinutes: default per-table basepull interval for config-driven tables
|
|
*******************************************************************************/
|
|
public Integer getDefaultBasepullIntervalMinutes()
|
|
{
|
|
return (this.defaultBasepullIntervalMinutes);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for defaultBasepullIntervalMinutes
|
|
*******************************************************************************/
|
|
public void setDefaultBasepullIntervalMinutes(Integer defaultBasepullIntervalMinutes)
|
|
{
|
|
this.defaultBasepullIntervalMinutes = defaultBasepullIntervalMinutes;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for defaultBasepullIntervalMinutes
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withDefaultBasepullIntervalMinutes(Integer defaultBasepullIntervalMinutes)
|
|
{
|
|
this.defaultBasepullIntervalMinutes = defaultBasepullIntervalMinutes;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for runHistoryRetentionDays: delete quick_search_index_run rows older than this many days; null keeps them forever
|
|
*******************************************************************************/
|
|
public Integer getRunHistoryRetentionDays()
|
|
{
|
|
return (this.runHistoryRetentionDays);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for runHistoryRetentionDays
|
|
*******************************************************************************/
|
|
public void setRunHistoryRetentionDays(Integer runHistoryRetentionDays)
|
|
{
|
|
this.runHistoryRetentionDays = runHistoryRetentionDays;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for runHistoryRetentionDays
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withRunHistoryRetentionDays(Integer runHistoryRetentionDays)
|
|
{
|
|
this.runHistoryRetentionDays = runHistoryRetentionDays;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for fullReindexStaleMinutes: a RUNNING full reindex whose run record shows no sign of life (start or heartbeat) for this many minutes is treated as stopped; null means the default
|
|
*******************************************************************************/
|
|
public Integer getFullReindexStaleMinutes()
|
|
{
|
|
return (this.fullReindexStaleMinutes);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for fullReindexStaleMinutes
|
|
*******************************************************************************/
|
|
public void setFullReindexStaleMinutes(Integer fullReindexStaleMinutes)
|
|
{
|
|
this.fullReindexStaleMinutes = fullReindexStaleMinutes;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for fullReindexStaleMinutes
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withFullReindexStaleMinutes(Integer fullReindexStaleMinutes)
|
|
{
|
|
this.fullReindexStaleMinutes = fullReindexStaleMinutes;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for bulkBatchSize: documents per OpenSearch bulk request
|
|
*******************************************************************************/
|
|
public Integer getBulkBatchSize()
|
|
{
|
|
return (this.bulkBatchSize);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for bulkBatchSize
|
|
*******************************************************************************/
|
|
public void setBulkBatchSize(Integer bulkBatchSize)
|
|
{
|
|
this.bulkBatchSize = bulkBatchSize;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for bulkBatchSize
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withBulkBatchSize(Integer bulkBatchSize)
|
|
{
|
|
this.bulkBatchSize = bulkBatchSize;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for sourceBatchSize: records per source table query page
|
|
*******************************************************************************/
|
|
public Integer getSourceBatchSize()
|
|
{
|
|
return (this.sourceBatchSize);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for sourceBatchSize
|
|
*******************************************************************************/
|
|
public void setSourceBatchSize(Integer sourceBatchSize)
|
|
{
|
|
this.sourceBatchSize = sourceBatchSize;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for sourceBatchSize
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withSourceBatchSize(Integer sourceBatchSize)
|
|
{
|
|
this.sourceBatchSize = sourceBatchSize;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for maxFieldLength: truncate each indexed field value to this many characters; null for no limit
|
|
*******************************************************************************/
|
|
public Integer getMaxFieldLength()
|
|
{
|
|
return (this.maxFieldLength);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for maxFieldLength
|
|
*******************************************************************************/
|
|
public void setMaxFieldLength(Integer maxFieldLength)
|
|
{
|
|
this.maxFieldLength = maxFieldLength;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for maxFieldLength
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withMaxFieldLength(Integer maxFieldLength)
|
|
{
|
|
this.maxFieldLength = maxFieldLength;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for maxSearchLimit: largest page size QuickSearchAction will honour
|
|
*******************************************************************************/
|
|
public Integer getMaxSearchLimit()
|
|
{
|
|
return (this.maxSearchLimit);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for maxSearchLimit
|
|
*******************************************************************************/
|
|
public void setMaxSearchLimit(Integer maxSearchLimit)
|
|
{
|
|
this.maxSearchLimit = maxSearchLimit;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for maxSearchLimit
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withMaxSearchLimit(Integer maxSearchLimit)
|
|
{
|
|
this.maxSearchLimit = maxSearchLimit;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for applyRecordSecurityLocks: re-read search hits through QueryAction so record security locks apply
|
|
*******************************************************************************/
|
|
public Boolean getApplyRecordSecurityLocks()
|
|
{
|
|
return (this.applyRecordSecurityLocks);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for applyRecordSecurityLocks
|
|
*******************************************************************************/
|
|
public void setApplyRecordSecurityLocks(Boolean applyRecordSecurityLocks)
|
|
{
|
|
this.applyRecordSecurityLocks = applyRecordSecurityLocks;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for applyRecordSecurityLocks
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withApplyRecordSecurityLocks(Boolean applyRecordSecurityLocks)
|
|
{
|
|
this.applyRecordSecurityLocks = applyRecordSecurityLocks;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for serveCoreRecordSearch: register QuickSearchRecordSearchProvider
|
|
** so core RecordSearchAction (POST /qqq/v1/search) searches indexed tables in
|
|
** OpenSearch, and give indexed tables core searchFields when they have none
|
|
*******************************************************************************/
|
|
public Boolean getServeCoreRecordSearch()
|
|
{
|
|
return (this.serveCoreRecordSearch);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for serveCoreRecordSearch
|
|
*******************************************************************************/
|
|
public void setServeCoreRecordSearch(Boolean serveCoreRecordSearch)
|
|
{
|
|
this.serveCoreRecordSearch = serveCoreRecordSearch;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for serveCoreRecordSearch
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withServeCoreRecordSearch(Boolean serveCoreRecordSearch)
|
|
{
|
|
this.serveCoreRecordSearch = serveCoreRecordSearch;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for recordSearchTimeoutMillis: wall-clock limit on the OpenSearch
|
|
** request behind a core record search; past it the provider fails and core
|
|
** falls back to its own search (default 2500)
|
|
*******************************************************************************/
|
|
public Integer getRecordSearchTimeoutMillis()
|
|
{
|
|
return (this.recordSearchTimeoutMillis);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for recordSearchTimeoutMillis
|
|
*******************************************************************************/
|
|
public void setRecordSearchTimeoutMillis(Integer recordSearchTimeoutMillis)
|
|
{
|
|
this.recordSearchTimeoutMillis = recordSearchTimeoutMillis;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for recordSearchTimeoutMillis
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withRecordSearchTimeoutMillis(Integer recordSearchTimeoutMillis)
|
|
{
|
|
this.recordSearchTimeoutMillis = recordSearchTimeoutMillis;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for searchableEntityClasses: entity classes annotated with @QuickSearchable
|
|
*******************************************************************************/
|
|
public List<Class<?>> getSearchableEntityClasses()
|
|
{
|
|
return (this.searchableEntityClasses);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for searchableEntityClasses
|
|
*******************************************************************************/
|
|
public void setSearchableEntityClasses(List<Class<?>> searchableEntityClasses)
|
|
{
|
|
this.searchableEntityClasses = searchableEntityClasses;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for searchableEntityClasses
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withSearchableEntityClasses(List<Class<?>> searchableEntityClasses)
|
|
{
|
|
this.searchableEntityClasses = searchableEntityClasses;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for searchableTables: config-driven searchable tables
|
|
*******************************************************************************/
|
|
public List<SearchableTableConfig> getSearchableTables()
|
|
{
|
|
return (this.searchableTables);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for searchableTables
|
|
*******************************************************************************/
|
|
public void setSearchableTables(List<SearchableTableConfig> searchableTables)
|
|
{
|
|
this.searchableTables = searchableTables;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for searchableTables
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withSearchableTables(List<SearchableTableConfig> searchableTables)
|
|
{
|
|
this.searchableTables = searchableTables;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for indexEventPublisher: host-supplied publisher (defaults to SynchronousIndexEventPublisher)
|
|
*******************************************************************************/
|
|
public IndexEventPublisher getIndexEventPublisher()
|
|
{
|
|
return (this.indexEventPublisher);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for indexEventPublisher
|
|
*******************************************************************************/
|
|
public void setIndexEventPublisher(IndexEventPublisher indexEventPublisher)
|
|
{
|
|
this.indexEventPublisher = indexEventPublisher;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for indexEventPublisher
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withIndexEventPublisher(IndexEventPublisher indexEventPublisher)
|
|
{
|
|
this.indexEventPublisher = indexEventPublisher;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for adminPermissionRules: permission rules for the admin app and the three processes
|
|
*******************************************************************************/
|
|
public QPermissionRules getAdminPermissionRules()
|
|
{
|
|
return (this.adminPermissionRules);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for adminPermissionRules
|
|
*******************************************************************************/
|
|
public void setAdminPermissionRules(QPermissionRules adminPermissionRules)
|
|
{
|
|
this.adminPermissionRules = adminPermissionRules;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for adminPermissionRules
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withAdminPermissionRules(QPermissionRules adminPermissionRules)
|
|
{
|
|
this.adminPermissionRules = adminPermissionRules;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for tablePermissionRules: permission rules for the operational tables
|
|
*******************************************************************************/
|
|
public QPermissionRules getTablePermissionRules()
|
|
{
|
|
return (this.tablePermissionRules);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for tablePermissionRules
|
|
*******************************************************************************/
|
|
public void setTablePermissionRules(QPermissionRules tablePermissionRules)
|
|
{
|
|
this.tablePermissionRules = tablePermissionRules;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for tablePermissionRules
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withTablePermissionRules(QPermissionRules tablePermissionRules)
|
|
{
|
|
this.tablePermissionRules = tablePermissionRules;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for enableDiagnosticTools: add the admin diagnostic tools (search playground, index validation, analyzer tester, diagnostic event and validation run tables, diagnostics widget); default true
|
|
*******************************************************************************/
|
|
public Boolean getEnableDiagnosticTools()
|
|
{
|
|
return (this.enableDiagnosticTools);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for enableDiagnosticTools
|
|
*******************************************************************************/
|
|
public void setEnableDiagnosticTools(Boolean enableDiagnosticTools)
|
|
{
|
|
this.enableDiagnosticTools = enableDiagnosticTools;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for enableDiagnosticTools
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withEnableDiagnosticTools(Boolean enableDiagnosticTools)
|
|
{
|
|
this.enableDiagnosticTools = enableDiagnosticTools;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for enableRecordDiagnosticActions: with enableDiagnosticTools, also add the per-table record actions (inspect search document, reindex records) to every indexed table; default true
|
|
*******************************************************************************/
|
|
public Boolean getEnableRecordDiagnosticActions()
|
|
{
|
|
return (this.enableRecordDiagnosticActions);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for enableRecordDiagnosticActions
|
|
*******************************************************************************/
|
|
public void setEnableRecordDiagnosticActions(Boolean enableRecordDiagnosticActions)
|
|
{
|
|
this.enableRecordDiagnosticActions = enableRecordDiagnosticActions;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for enableRecordDiagnosticActions
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withEnableRecordDiagnosticActions(Boolean enableRecordDiagnosticActions)
|
|
{
|
|
this.enableRecordDiagnosticActions = enableRecordDiagnosticActions;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for validationCronExpression: cron schedule for the index validation process (needs schedulerName); none by default
|
|
*******************************************************************************/
|
|
public String getValidationCronExpression()
|
|
{
|
|
return (this.validationCronExpression);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for validationCronExpression
|
|
*******************************************************************************/
|
|
public void setValidationCronExpression(String validationCronExpression)
|
|
{
|
|
this.validationCronExpression = validationCronExpression;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for validationCronExpression
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withValidationCronExpression(String validationCronExpression)
|
|
{
|
|
this.validationCronExpression = validationCronExpression;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for validationCronTimeZoneId: time zone for validationCronExpression
|
|
*******************************************************************************/
|
|
public String getValidationCronTimeZoneId()
|
|
{
|
|
return (this.validationCronTimeZoneId);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for validationCronTimeZoneId
|
|
*******************************************************************************/
|
|
public void setValidationCronTimeZoneId(String validationCronTimeZoneId)
|
|
{
|
|
this.validationCronTimeZoneId = validationCronTimeZoneId;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for validationCronTimeZoneId
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withValidationCronTimeZoneId(String validationCronTimeZoneId)
|
|
{
|
|
this.validationCronTimeZoneId = validationCronTimeZoneId;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for validationSampleSize: records sampled per table by index validation (default 50, at most 1000)
|
|
*******************************************************************************/
|
|
public Integer getValidationSampleSize()
|
|
{
|
|
return (this.validationSampleSize);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for validationSampleSize
|
|
*******************************************************************************/
|
|
public void setValidationSampleSize(Integer validationSampleSize)
|
|
{
|
|
this.validationSampleSize = validationSampleSize;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for validationSampleSize
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withValidationSampleSize(Integer validationSampleSize)
|
|
{
|
|
this.validationSampleSize = validationSampleSize;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for diagnosticRunsPerMinute: per-user limit on diagnostic tool runs per minute (default 30)
|
|
*******************************************************************************/
|
|
public Integer getDiagnosticRunsPerMinute()
|
|
{
|
|
return (this.diagnosticRunsPerMinute);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for diagnosticRunsPerMinute
|
|
*******************************************************************************/
|
|
public void setDiagnosticRunsPerMinute(Integer diagnosticRunsPerMinute)
|
|
{
|
|
this.diagnosticRunsPerMinute = diagnosticRunsPerMinute;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for diagnosticRunsPerMinute
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withDiagnosticRunsPerMinute(Integer diagnosticRunsPerMinute)
|
|
{
|
|
this.diagnosticRunsPerMinute = diagnosticRunsPerMinute;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for debugPermissionRules: permission rules for the read-only diagnostic tools and the diagnostics widget (default: quick_search_debug.hasAccess)
|
|
*******************************************************************************/
|
|
public QPermissionRules getDebugPermissionRules()
|
|
{
|
|
return (this.debugPermissionRules);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for debugPermissionRules
|
|
*******************************************************************************/
|
|
public void setDebugPermissionRules(QPermissionRules debugPermissionRules)
|
|
{
|
|
this.debugPermissionRules = debugPermissionRules;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for debugPermissionRules
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withDebugPermissionRules(QPermissionRules debugPermissionRules)
|
|
{
|
|
this.debugPermissionRules = debugPermissionRules;
|
|
return (this);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Getter for runtime: live state once produced (client, publisher, discovered tables)
|
|
*******************************************************************************/
|
|
@JsonIgnore
|
|
public QuickSearchRuntime getRuntime()
|
|
{
|
|
return (this.runtime);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Setter for runtime
|
|
*******************************************************************************/
|
|
public void setRuntime(QuickSearchRuntime runtime)
|
|
{
|
|
this.runtime = runtime;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
** Fluent setter for runtime
|
|
*******************************************************************************/
|
|
public QuickSearchQBitConfig withRuntime(QuickSearchRuntime runtime)
|
|
{
|
|
this.runtime = runtime;
|
|
return (this);
|
|
}
|
|
|
|
}
|