edu.byu.hbll.box.SourceConfig Maven / Gradle / Ivy
package edu.byu.hbll.box;
import edu.byu.hbll.box.impl.MemoryDatabase;
import edu.byu.hbll.scheduler.CronSchedule;
import edu.byu.hbll.scheduler.PeriodicSchedule;
import edu.byu.hbll.scheduler.Schedule;
import java.time.Duration;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import lombok.Getter;
import lombok.Singular;
/** The configuration of a source in Box. */
@lombok.Builder
@Getter
public class SourceConfig {
/** Always points to the principal source. */
public static final String PRINCIPAL_SOURCE_ALIAS = "box";
/** For participating operations, this refers to all sources. */
public static final String ALL_SOURCES_ALIAS = "all";
/** Reserved source names. */
public static final Set RESERVED_SOURCE_NAMES =
Set.of(PRINCIPAL_SOURCE_ALIAS, ALL_SOURCES_ALIAS);
/** The name of the source. */
private final String name;
/**
* Whether to enable or disable this source. A disabled source behaves like it doesn't even exist.
* Default true.
*/
@lombok.Builder.Default private final boolean enabled = true;
/**
* Whether to mark this source as the principal source or in other words the main source of the
* box. Also some apis are simplified for the principal source because no source name has to be
* specified. If no source is explicitly marked as principal, the first one added to the
* configuration will be considered as principal. Default false.
*/
private final boolean principal;
/** The processor to use for this source. Setting this enables direct processing of documents. */
private final Processor processor;
/**
* How long to wait before running a batch at less than capacity. Only valid for the processor.
* Default Duration.ZERO.
*/
@lombok.Builder.Default private final Duration batchDelay = Duration.ZERO;
/** The maximum size a batch can grow before processing occurs. Default 1. */
@lombok.Builder.Default private final int batchCapacity = 1;
/** How many threads should be processing batches. Default 1. */
@lombok.Builder.Default private final int threadCount = 1;
/** How long to suspend processing threads after each batch. Default Duration.ZERO. */
@lombok.Builder.Default private final Duration suspend = Duration.ZERO;
/** Stop processing when quota is reached. Default 0 (no quota). */
private final int quota;
/**
* When to reset the processed count to zero to allow more processing to occur until the quota is
* reached again. Default midnight each day.
*/
@lombok.Builder.Default private final Schedule quotaReset = CronSchedule.of("0 0 0 * * * *");
/** When to turn on processing for a window of time. Default null (always on). */
private final Schedule on;
/** When to turn of processing for a window of time. Default null (always on). */
private final Schedule off;
/**
* Whether or not to enable or disable this processor. If disabled, this source behaves as if it
* doesn't have a processor. Default true.
*/
@lombok.Builder.Default private final boolean processEnabled = true;
/**
* The harvester to use for this source. Setting this enables harvesting of documents. Default
* null.
*/
private final Harvester harvester;
/**
* Whether or not to enable or disable this harvester. If disabled, this source behaves as if it
* doesn't have a harvester. Default true.
*/
@lombok.Builder.Default private final boolean harvestEnabled = true;
/** A cron-like schedule of when to run the harvester. Default every minute. */
@lombok.Builder.Default private final Schedule harvestSchedule = PeriodicSchedule.ofMinutes(1);
/**
* A cron-like schedule of when to reset the harvester and cause it to start from the very
* beginning. Default null (never).
*
* @deprecated use {@link #reharvestSchedule} instead
*/
@Deprecated private final Schedule harvestResetSchedule;
/**
* Reharvest according to this cron-like schedule. This tells Box to start a new secondary harvest
* from the beginning. Default null (never).
*/
private final Schedule reharvestSchedule;
/** Whether or not to save new deleted documents during harvests. Default false. */
private final boolean saveDeleted;
@lombok.Builder.Default private final Duration retryDelay = Duration.ofMinutes(1);
@lombok.Builder.Default private final double retryJitter = 0.5;
/** Reprocess old documents that haven't been processed for this long. Default null (never). */
private final Duration reprocessAge;
/** When to go looking for old documents to reprocess. Default every minute. */
@lombok.Builder.Default private final Schedule reprocessSchedule = PeriodicSchedule.ofMinutes(1);
/** Remove deleted documents that have been deleted for this long. Default null (never). */
private final Duration removeAge;
/** When to run the remove process. Default every minute. */
@lombok.Builder.Default private final Schedule removeSchedule = PeriodicSchedule.ofMinutes(1);
/**
* Each time a document is saved, fields that match the dot-notated paths will be added as facets
* with the given name.
*/
private final Map> facetFields;
/**
* Whether or not to save documents to the database. This is important for sources that need to
* always process in real-time. Default true.
*/
@lombok.Builder.Default private final boolean save = true;
/** Whether or not to always process documents synchronously in real-time. Default false. */
private final boolean process;
/** Whether to wait for requested documents to be processed if not already. Default false. */
private final boolean wait;
/**
* Whether or not this source is only a dependency for other sources. When set to true, documents
* from this source are only saved if they are dependencies for other sources. Default false.
*/
private final boolean dependencyOnly;
/** The default limit of documents to return for harvest type queries. Default 10. */
@lombok.Builder.Default private final int defaultLimit = 10;
/**
* Use this database for storing documents and other info for Box. Databases are source specific
* so do not use the same one for multiple sources. Default MemoryDatabase.
*/
@lombok.Builder.Default private final BoxDatabase db = new MemoryDatabase();
/**
* In the case that the database is read-only database, it's still important to know where a
* harvest left off. This will override the regular db if set. Default null.
*/
private final BoxDatabase cursorDb;
/** If there is any other extension class that you want Box to manage. */
@Singular private final List others;
/** Whether or not to enable posting of documents to web endpoints. */
private final boolean postEnabled;
/**
* Returns cursorDb if not null, otherwise db.
*
* @return cursorDb if not null, otherwise db
*/
public BoxDatabase getPreferredCursorDb() {
return cursorDb != null ? cursorDb : db;
}
public static SourceConfigBuilder builder() {
return new SourceConfigBuilder().new InnerSourceConfigBuilder();
}
public static class SourceConfigBuilder {
private Map> facetFields = new LinkedHashMap<>();
/**
* Each time a document is saved, fields that match the dot-notated paths will be added as
* facets with the given name.
*
* @param name name of the facet
* @param path path to the field in the document
* @return this
*/
public SourceConfigBuilder facetFields(String name, String... path) {
return facetFields(name, Arrays.asList(path));
}
/**
* Each time a document is saved, fields that match the dot-notated paths will be added as
* facets with the given name.
*
* @param name name of facet
* @param path path to the field in the document
* @return this
*/
public SourceConfigBuilder facetFields(String name, Collection path) {
facetFields.computeIfAbsent(name, k -> new LinkedHashSet<>()).addAll(path);
return this;
}
protected String getName() {
return name;
}
private class InnerSourceConfigBuilder extends SourceConfigBuilder {
@Override
public SourceConfig build() {
if (RESERVED_SOURCE_NAMES.contains(super.name)) {
throw new IllegalArgumentException(super.name + " is a reserved source name");
}
Map> newFacetFields = new LinkedHashMap<>();
super.facetFields
.entrySet()
.forEach(
e ->
newFacetFields.put(
e.getKey(),
Collections.unmodifiableSet(new LinkedHashSet<>(e.getValue()))));
super.facetFields = Collections.unmodifiableMap(newFacetFields);
return super.build();
}
}
}
/**
* Creates a new builder for SourceConfig.
*
* @deprecated Use {@link SourceConfig#builder()} instead.
* @author Charles Draper
*/
@Deprecated
public static class Builder extends SourceConfigBuilder {
/**
* Creates a new {@link Builder}.
*
* @param name the name of the source
*/
public Builder(String name) {
if (RESERVED_SOURCE_NAMES.contains(name)) {
throw new IllegalArgumentException(name + " is a reserved source name");
}
name(name);
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy