001package ca.uhn.fhir.jpa.api.config;
002
003import ca.uhn.fhir.jpa.api.model.HistoryCountModeEnum;
004import ca.uhn.fhir.jpa.api.model.WarmCacheEntry;
005import ca.uhn.fhir.jpa.model.entity.ModelConfig;
006import ca.uhn.fhir.jpa.model.entity.ResourceEncodingEnum;
007import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
008import ca.uhn.fhir.rest.api.SearchTotalModeEnum;
009import ca.uhn.fhir.system.HapiSystemProperties;
010import ca.uhn.fhir.util.HapiExtensions;
011import ca.uhn.fhir.validation.FhirValidator;
012import com.google.common.annotations.VisibleForTesting;
013import com.google.common.collect.Sets;
014import org.apache.commons.io.FileUtils;
015import org.apache.commons.lang3.StringUtils;
016import org.apache.commons.lang3.Validate;
017import org.apache.commons.lang3.time.DateUtils;
018import org.hl7.fhir.dstu2.model.Subscription;
019import org.hl7.fhir.r4.model.Bundle;
020import org.slf4j.Logger;
021import org.slf4j.LoggerFactory;
022
023import javax.annotation.Nonnull;
024import javax.annotation.Nullable;
025import java.util.ArrayList;
026import java.util.Arrays;
027import java.util.Collections;
028import java.util.List;
029import java.util.Set;
030import java.util.TreeSet;
031
032/*
033 * #%L
034 * HAPI FHIR Storage api
035 * %%
036 * Copyright (C) 2014 - 2023 Smile CDR, Inc.
037 * %%
038 * Licensed under the Apache License, Version 2.0 (the "License");
039 * you may not use this file except in compliance with the License.
040 * You may obtain a copy of the License at
041 *
042 * http://www.apache.org/licenses/LICENSE-2.0
043 *
044 * Unless required by applicable law or agreed to in writing, software
045 * distributed under the License is distributed on an "AS IS" BASIS,
046 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
047 * See the License for the specific language governing permissions and
048 * limitations under the License.
049 * #L%
050 */
051
052public class DaoConfig {
053
054        /**
055         * Default value for {@link #setReuseCachedSearchResultsForMillis(Long)}: 60000ms (one minute)
056         */
057        public static final Long DEFAULT_REUSE_CACHED_SEARCH_RESULTS_FOR_MILLIS = DateUtils.MILLIS_PER_MINUTE;
058        /**
059         * Default value for {@link #myTranslationCachesExpireAfterWriteInMinutes}: 60 minutes
060         *
061         * @see #myTranslationCachesExpireAfterWriteInMinutes
062         */
063        public static final Long DEFAULT_TRANSLATION_CACHES_EXPIRE_AFTER_WRITE_IN_MINUTES = 60L;
064        /**
065         * Default {@link #setBundleTypesAllowedForStorage(Set)} value:
066         * <ul>
067         * <li>collection</li>
068         * <li>document</li>
069         * <li>message</li>
070         * </ul>
071         */
072        @SuppressWarnings("WeakerAccess")
073        public static final Set<String> DEFAULT_BUNDLE_TYPES_ALLOWED_FOR_STORAGE = Collections.unmodifiableSet(new TreeSet<>(Sets.newHashSet(
074                Bundle.BundleType.COLLECTION.toCode(),
075                Bundle.BundleType.DOCUMENT.toCode(),
076                Bundle.BundleType.MESSAGE.toCode()
077        )));
078        // update setter javadoc if default changes
079        public static final int DEFAULT_MAX_EXPANSION_SIZE = 1000;
080        public static final HistoryCountModeEnum DEFAULT_HISTORY_COUNT_MODE = HistoryCountModeEnum.CACHED_ONLY_WITHOUT_OFFSET;
081        /**
082         * This constant applies to task enablement, e.g. {@link #setEnableTaskStaleSearchCleanup(boolean)}.
083         * <p>
084         * By default, all are enabled.
085         */
086        public static final boolean DEFAULT_ENABLE_TASKS = true;
087        public static final int DEFAULT_MAXIMUM_INCLUDES_TO_LOAD_PER_PAGE = 1000;
088        /**
089         * @since 5.5.0
090         */
091        public static final TagStorageModeEnum DEFAULT_TAG_STORAGE_MODE = TagStorageModeEnum.VERSIONED;
092        public static final int DEFAULT_EXPUNGE_BATCH_SIZE = 800;
093        /**
094         * @since 5.6.0
095         */
096        // Thread Pool size used by batch in bundle
097        public static final int DEFAULT_BUNDLE_BATCH_POOL_SIZE = 20; // 1 for single thread
098        public static final int DEFAULT_BUNDLE_BATCH_MAX_POOL_SIZE = 100; // 1 for single thread
099        public static final int DEFAULT_BUNDLE_BATCH_QUEUE_CAPACITY = 200;
100        /**
101         * Default value for {@link #setMaximumSearchResultCountInTransaction(Integer)}
102         *
103         * @see #setMaximumSearchResultCountInTransaction(Integer)
104         */
105        private static final Integer DEFAULT_MAXIMUM_SEARCH_RESULT_COUNT_IN_TRANSACTION = null;
106        private static final Integer DEFAULT_MAXIMUM_TRANSACTION_BUNDLE_SIZE = null;
107        private static final Logger ourLog = LoggerFactory.getLogger(DaoConfig.class);
108        private static final int DEFAULT_REINDEX_BATCH_SIZE = 800;
109        private static final int DEFAULT_MAXIMUM_DELETE_CONFLICT_COUNT = 60;
110        /**
111         * Child Configurations
112         */
113        private static final Integer DEFAULT_INTERNAL_SYNCHRONOUS_SEARCH_SIZE = 10000;
114        private final ModelConfig myModelConfig = new ModelConfig();
115        /**
116         * Do not change default of {@code 0}!
117         *
118         * @since 4.1.0
119         */
120        private final int myPreExpandValueSetsDefaultOffset = 0;
121        /**
122         * update setter javadoc if default changes
123         */
124        @Nonnull
125        private final Long myTranslationCachesExpireAfterWriteInMinutes = DEFAULT_TRANSLATION_CACHES_EXPIRE_AFTER_WRITE_IN_MINUTES;
126        /**
127         * @since 5.5.0
128         */
129        @Nullable
130        private Integer myMaximumIncludesToLoadPerPage = DEFAULT_MAXIMUM_INCLUDES_TO_LOAD_PER_PAGE;
131        private IndexEnabledEnum myIndexMissingFieldsEnabled = IndexEnabledEnum.DISABLED;
132        /**
133         * update setter javadoc if default changes
134         */
135        private boolean myAllowInlineMatchUrlReferences = true;
136        private boolean myAllowMultipleDelete;
137        /**
138         * update setter javadoc if default changes
139         */
140        private int myDeferIndexingForCodesystemsOfSize = 100;
141        private boolean myDeleteStaleSearches = true;
142        private boolean myEnforceReferentialIntegrityOnDelete = true;
143        private boolean myUniqueIndexesEnabled = true;
144        private boolean myUniqueIndexesCheckedBeforeSave = true;
145        private boolean myEnforceReferentialIntegrityOnWrite = true;
146        private SearchTotalModeEnum myDefaultTotalMode = null;
147        private int myEverythingIncludesFetchPageSize = 50;
148        private int myBulkImportMaxRetryCount = 10;
149        private TagStorageModeEnum myTagStorageMode = DEFAULT_TAG_STORAGE_MODE;
150        /**
151         * update setter javadoc if default changes
152         */
153        private long myExpireSearchResultsAfterMillis = DateUtils.MILLIS_PER_HOUR;
154        /**
155         * update setter javadoc if default changes
156         */
157        private Integer myFetchSizeDefaultMaximum = null;
158        private int myMaximumExpansionSize = DEFAULT_MAX_EXPANSION_SIZE;
159        private Integer myMaximumSearchResultCountInTransaction = DEFAULT_MAXIMUM_SEARCH_RESULT_COUNT_IN_TRANSACTION;
160        private Integer myMaximumTransactionBundleSize = DEFAULT_MAXIMUM_TRANSACTION_BUNDLE_SIZE;
161        private ResourceEncodingEnum myResourceEncoding = ResourceEncodingEnum.JSONC;
162        /**
163         * update setter javadoc if default changes
164         */
165        private Integer myResourceMetaCountHardLimit = 1000;
166        private Long myReuseCachedSearchResultsForMillis = DEFAULT_REUSE_CACHED_SEARCH_RESULTS_FOR_MILLIS;
167        private boolean mySchedulingDisabled;
168        private boolean mySuppressUpdatesWithNoChange = true;
169        private boolean myAutoCreatePlaceholderReferenceTargets;
170        private Integer myCacheControlNoStoreMaxResultsUpperLimit = 1000;
171        private Integer myCountSearchResultsUpTo = null;
172        private boolean myStatusBasedReindexingDisabled;
173        private IdStrategyEnum myResourceServerIdStrategy = IdStrategyEnum.SEQUENTIAL_NUMERIC;
174        private boolean myMarkResourcesForReindexingUponSearchParameterChange;
175        private boolean myExpungeEnabled;
176        private boolean myDeleteExpungeEnabled;
177        private int myExpungeBatchSize = DEFAULT_EXPUNGE_BATCH_SIZE;
178        private int myReindexBatchSize = DEFAULT_REINDEX_BATCH_SIZE;
179        private int myReindexThreadCount;
180        private int myExpungeThreadCount;
181        private Set<String> myBundleTypesAllowedForStorage;
182        private boolean myValidateSearchParameterExpressionsOnSave = true;
183
184        // start with a tiny number so our first page always loads quickly.
185        // If they fetch the second page, fetch more.
186        // Use prime sizes to avoid empty next links.
187        private List<Integer> mySearchPreFetchThresholds = Arrays.asList(13, 503, 2003, -1);
188        private List<WarmCacheEntry> myWarmCacheEntries = new ArrayList<>();
189        private boolean myDisableHashBasedSearches;
190        private boolean myEnableInMemorySubscriptionMatching = true;
191        private boolean myEnforceReferenceTargetTypes = true;
192        private ClientIdStrategyEnum myResourceClientIdStrategy = ClientIdStrategyEnum.ALPHANUMERIC;
193        private boolean myFilterParameterEnabled = false;
194        private StoreMetaSourceInformationEnum myStoreMetaSourceInformation = StoreMetaSourceInformationEnum.SOURCE_URI_AND_REQUEST_ID;
195        private HistoryCountModeEnum myHistoryCountMode = DEFAULT_HISTORY_COUNT_MODE;
196        private int myInternalSynchronousSearchSize = DEFAULT_INTERNAL_SYNCHRONOUS_SEARCH_SIZE;
197        /**
198         * update setter javadoc if default changes
199         */
200        private Integer myMaximumDeleteConflictQueryCount = DEFAULT_MAXIMUM_DELETE_CONFLICT_COUNT;
201        /**
202         * Do not change default of {@code true}!
203         *
204         * @since 4.1.0
205         */
206        private boolean myPreExpandValueSets = true;
207        /**
208         * Do not change default of {@code 1000}!
209         *
210         * @since 4.1.0
211         */
212        private int myPreExpandValueSetsDefaultCount = 1000;
213        /**
214         * Do not change default of {@code 1000}!
215         *
216         * @since 4.1.0
217         */
218        private int myPreExpandValueSetsMaxCount = 1000;
219        /**
220         * Do not change default of {@code true}!
221         *
222         * @since 4.2.0
223         */
224        private boolean myPopulateIdentifierInAutoCreatedPlaceholderReferenceTargets = true;
225        /**
226         * @since 5.0.0
227         */
228        private boolean myDeleteEnabled = true;
229        /**
230         * @since 5.1.0
231         */
232        private boolean myLastNEnabled = false;
233        /**
234         * @since 5.2.0
235         */
236        private boolean myUseLegacySearchBuilder = false;
237        /**
238         * @since 5.5.0
239         */
240        private boolean myReindexEnabled = true;
241        /**
242         * @since 5.4.0
243         */
244        private boolean myMatchUrlCacheEnabled;
245        /**
246         * @since 5.5.0
247         */
248        private boolean myEnableTaskBulkImportJobExecution;
249        /**
250         * @since 5.5.0
251         */
252        private boolean myEnableTaskStaleSearchCleanup;
253        /**
254         * @since 5.5.0
255         */
256        private boolean myEnableTaskPreExpandValueSets;
257        /**
258         * @since 5.5.0
259         */
260        private boolean myEnableTaskResourceReindexing;
261        /**
262         * @since 5.5.0
263         */
264        private boolean myEnableTaskBulkExportJobExecution;
265        private boolean myMassIngestionMode;
266        private boolean myAccountForDateIndexNulls;
267        private boolean myTriggerSubscriptionsForNonVersioningChanges;
268        /**
269         * @since 5.6.0
270         */
271        private String myHSearchIndexPrefix;
272        private Integer myBundleBatchPoolSize = DEFAULT_BUNDLE_BATCH_POOL_SIZE;
273        private Integer myBundleBatchMaxPoolSize = DEFAULT_BUNDLE_BATCH_MAX_POOL_SIZE;
274
275        /**
276         * Activates the new HSearch indexing of search parameters.
277         * When active, string, token, and reference parameters will be indexed and
278         * queried within Hibernate Search.
279         *
280         * @since 5.6.0
281         */
282        private boolean myAdvancedHSearchIndexing = false;
283        /**
284         * If set to a positive number, any resources with a character length at or below the given number
285         * of characters will be stored inline in the <code>HFJ_RES_VER</code> table instead of using a
286         * separate LOB column.
287         *
288         * @since 5.7.0
289         */
290        private int myInlineResourceTextBelowSize = 0;
291
292        /**
293         * @since 5.7.0
294         */
295        private boolean myStoreResourceInHSearchIndex;
296
297        /**
298         * @see FhirValidator#isConcurrentBundleValidation()
299         * @since 5.7.0
300         */
301        private boolean myConcurrentBundleValidation;
302
303        /**
304         * Since 6.0.0
305         */
306        private boolean myAllowAutoInflateBinaries = true;
307        /**
308         * Since 6.0.0
309         */
310        private long myAutoInflateBinariesMaximumBytes = 10 * FileUtils.ONE_MB;
311
312        /**
313         * Since 6.0.0
314         */
315        private int myBulkExportFileRetentionPeriodHours = 2;
316
317        /**
318         * Since 6.2.0
319         */
320        private boolean myEnableBulkExportJobReuse = true;
321
322        /**
323         * Since 6.1.0
324         */
325        private boolean myUpdateWithHistoryRewriteEnabled = false;
326
327        /**
328         * Since 6.2.0
329         */
330        private boolean myPreserveRequestIdInResourceBody = false;
331
332        /**
333         * Since 6.2.0
334         */
335        private int myBulkExportFileMaximumCapacity = 1_000;
336        /**
337         * Since 6.4.0
338         */
339        private boolean myJobFastTrackingEnabled = false;
340
341        /**
342         * Constructor
343         */
344        public DaoConfig() {
345                setMarkResourcesForReindexingUponSearchParameterChange(true);
346                setReindexThreadCount(Runtime.getRuntime().availableProcessors());
347                setExpungeThreadCount(Runtime.getRuntime().availableProcessors());
348                setBundleTypesAllowedForStorage(DEFAULT_BUNDLE_TYPES_ALLOWED_FOR_STORAGE);
349
350                // Scheduled tasks are all enabled by default
351                setEnableTaskBulkImportJobExecution(DEFAULT_ENABLE_TASKS);
352                setEnableTaskBulkExportJobExecution(DEFAULT_ENABLE_TASKS);
353                setEnableTaskStaleSearchCleanup(DEFAULT_ENABLE_TASKS);
354                setEnableTaskPreExpandValueSets(DEFAULT_ENABLE_TASKS);
355                setEnableTaskResourceReindexing(DEFAULT_ENABLE_TASKS);
356
357                if (HapiSystemProperties.isDisableStatusBasedReindex()) {
358                        ourLog.info("Status based reindexing is DISABLED");
359                        setStatusBasedReindexingDisabled(true);
360                }
361                if (HapiSystemProperties.isUnitTestModeEnabled()) {
362                        setJobFastTrackingEnabled(true);
363                }
364
365        }
366
367        /**
368         * If set to a positive number, any resources with a character length at or below the given number
369         * of characters will be stored inline in the <code>HFJ_RES_VER</code> table instead of using a
370         * separate LOB column.
371         *
372         * @since 5.7.0
373         */
374        public int getInlineResourceTextBelowSize() {
375                return myInlineResourceTextBelowSize;
376        }
377
378        /**
379         * If set to a positive number, any resources with a character length at or below the given number
380         * of characters will be stored inline in the <code>HFJ_RES_VER</code> table instead of using a
381         * separate LOB column.
382         *
383         * @since 5.7.0
384         */
385        public void setInlineResourceTextBelowSize(int theInlineResourceTextBelowSize) {
386                myInlineResourceTextBelowSize = theInlineResourceTextBelowSize;
387        }
388
389        /**
390         * Sets the tag storage mode for the server. Default is {@link TagStorageModeEnum#VERSIONED}.
391         *
392         * @since 5.5.0
393         */
394        @Nonnull
395        public TagStorageModeEnum getTagStorageMode() {
396                return myTagStorageMode;
397        }
398
399        /**
400         * Sets the tag storage mode for the server. Default is {@link TagStorageModeEnum#VERSIONED}.
401         *
402         * @since 5.5.0
403         */
404        public void setTagStorageMode(@Nonnull TagStorageModeEnum theTagStorageMode) {
405                Validate.notNull(theTagStorageMode, "theTagStorageMode must not be null");
406                myTagStorageMode = theTagStorageMode;
407        }
408
409        /**
410         * Specifies the maximum number of times that a chunk will be retried during bulk import
411         * processes before giving up.
412         *
413         * @since 5.5.0
414         */
415        public int getBulkImportMaxRetryCount() {
416                return myBulkImportMaxRetryCount;
417        }
418
419        /**
420         * Specifies the maximum number of times that a chunk will be retried during bulk import
421         * processes before giving up.
422         *
423         * @since 5.5.0
424         */
425        public void setBulkImportMaxRetryCount(int theBulkImportMaxRetryCount) {
426                myBulkImportMaxRetryCount = theBulkImportMaxRetryCount;
427        }
428
429        /**
430         * Specifies the maximum number of <code>_include</code> and <code>_revinclude</code> results to return in a
431         * single page of results. The default is <code>1000</code>, and <code>null</code> may be used
432         * to indicate that there is no limit.
433         *
434         * @since 5.5.0
435         */
436        @Nullable
437        public Integer getMaximumIncludesToLoadPerPage() {
438                return myMaximumIncludesToLoadPerPage;
439        }
440
441        /**
442         * Specifies the maximum number of <code>_include</code> and <code>_revinclude</code> results to return in a
443         * single page of results. The default is <code>1000</code>, and <code>null</code> may be used
444         * to indicate that there is no limit.
445         *
446         * @since 5.5.0
447         */
448        public void setMaximumIncludesToLoadPerPage(@Nullable Integer theMaximumIncludesToLoadPerPage) {
449                myMaximumIncludesToLoadPerPage = theMaximumIncludesToLoadPerPage;
450        }
451
452        /**
453         * When performing a FHIR history operation, a <code>Bundle.total</code> value is included in the
454         * response, indicating the total number of history entries. This response is calculated using a
455         * SQL COUNT query statement which can be expensive. This setting allows the results of the count
456         * query to be cached, resulting in a much lighter load on the server, at the expense of
457         * returning total values that may be slightly out of date. Total counts can also be disabled,
458         * or forced to always be accurate.
459         * <p>
460         * In {@link HistoryCountModeEnum#CACHED_ONLY_WITHOUT_OFFSET} mode, a loading cache is used to fetch the value,
461         * meaning that only one thread per JVM will fetch the count, and others will block while waiting
462         * for the cache to load, avoiding excessive load on the database.
463         * </p>
464         * <p>
465         * Default is {@link HistoryCountModeEnum#CACHED_ONLY_WITHOUT_OFFSET}
466         * </p>
467         *
468         * @since 5.4.0
469         */
470        public HistoryCountModeEnum getHistoryCountMode() {
471                return myHistoryCountMode;
472        }
473
474        /**
475         * When performing a FHIR history operation, a <code>Bundle.total</code> value is included in the
476         * response, indicating the total number of history entries. This response is calculated using a
477         * SQL COUNT query statement which can be expensive. This setting allows the results of the count
478         * query to be cached, resulting in a much lighter load on the server, at the expense of
479         * returning total values that may be slightly out of date. Total counts can also be disabled,
480         * or forced to always be accurate.
481         * <p>
482         * In {@link HistoryCountModeEnum#CACHED_ONLY_WITHOUT_OFFSET} mode, a loading cache is used to fetch the value,
483         * meaning that only one thread per JVM will fetch the count, and others will block while waiting
484         * for the cache to load, avoiding excessive load on the database.
485         * </p>
486         * <p>
487         * Default is {@link HistoryCountModeEnum#CACHED_ONLY_WITHOUT_OFFSET}
488         * </p>
489         *
490         * @since 5.4.0
491         */
492        public void setHistoryCountMode(@Nonnull HistoryCountModeEnum theHistoryCountMode) {
493
494                Validate.notNull(theHistoryCountMode, "theHistoryCountMode must not be null");
495                myHistoryCountMode = theHistoryCountMode;
496        }
497
498        /**
499         * If set to <code>true</code> (default is <code>false</code>) the <code>$lastn</code> operation will be enabled for
500         * indexing Observation resources. This operation involves creating a special set of tables in hsearch for
501         * discovering Observation resources. Enabling this setting increases the amount of storage space required, and can
502         * slow write operations, but can be very useful for searching for collections of Observations for some applications.
503         *
504         * @since 5.1.0
505         */
506        public boolean isLastNEnabled() {
507                return myLastNEnabled;
508        }
509
510        /**
511         * If set to <code>true</code> (default is <code>false</code>) the <code>$lastn</code> operation will be enabled for
512         * indexing Observation resources. This operation involves creating a special set of tables in hsearch for
513         * discovering Observation resources. Enabling this setting increases the amount of storage space required, and can
514         * slow write operations, but can be very useful for searching for collections of Observations for some applications.
515         *
516         * @since 5.1.0
517         */
518        public void setLastNEnabled(boolean theLastNEnabled) {
519                myLastNEnabled = theLastNEnabled;
520        }
521
522        /**
523         * This method controls whether to use the new non-hibernate search SQL builder that was introduced in HAPI FHIR 5.2.0.
524         * By default this will be <code>false</code> meaning that the new SQL builder is used. Set to <code>true</code> to use the
525         * legacy SQL builder based on Hibernate.
526         * <p>Note that this method will be removed in HAPI FHIR 5.4.0</p>
527         *
528         * @since 5.3.0
529         */
530        public boolean isUseLegacySearchBuilder() {
531                return false;
532        }
533
534        /**
535         * This method controls whether to use the new non-hibernate search SQL builder that was introduced in HAPI FHIR 5.2.0.
536         * By default this will be <code>false</code> meaning that the new SQL builder is used. Set to <code>true</code> to use the
537         * legacy SQL builder based on Hibernate.
538         * <p>Note that this method will be removed in HAPI FHIR 5.4.0</p>
539         *
540         * @since 5.3.0
541         * @deprecated in 6.1.0, this toggle will be removed in 6.2.0 as the Legacy Search Builder has been removed.
542         */
543        @Deprecated
544        public void setUseLegacySearchBuilder(boolean theUseLegacySearchBuilder) {
545                //Nop
546        }
547
548        /**
549         * Specifies the duration in minutes for which values will be retained after being
550         * written to the terminology translation cache. Defaults to 60.
551         */
552        @Nonnull
553        public Long getTranslationCachesExpireAfterWriteInMinutes() {
554                return myTranslationCachesExpireAfterWriteInMinutes;
555        }
556
557        /**
558         * If enabled, resolutions for match URLs (e.g. conditional create URLs, conditional update URLs, etc) will be
559         * cached in an in-memory cache. This cache can have a noticeable improvement on write performance on servers
560         * where conditional operations are frequently performed, but note that this cache will not be
561         * invalidated based on updates to resources so this may have detrimental effects.
562         * <p>
563         * Default is <code>false</code>
564         *
565         * @since 5.4.0
566         * @deprecated Deprecated in 5.5.0. Use {@link #isMatchUrlCacheEnabled()} instead (the name of this method is misleading)
567         */
568        @Deprecated
569        public boolean getMatchUrlCache() {
570                return myMatchUrlCacheEnabled;
571        }
572
573        /**
574         * If enabled, resolutions for match URLs (e.g. conditional create URLs, conditional update URLs, etc) will be
575         * cached in an in-memory cache. This cache can have a noticeable improvement on write performance on servers
576         * where conditional operations are frequently performed, but note that this cache will not be
577         * invalidated based on updates to resources so this may have detrimental effects.
578         * <p>
579         * Default is <code>false</code>
580         *
581         * @since 5.4.0
582         * @deprecated Deprecated in 5.5.0. Use {@link #setMatchUrlCacheEnabled(boolean)} instead (the name of this method is misleading)
583         */
584        @Deprecated
585        public void setMatchUrlCache(boolean theMatchUrlCache) {
586                myMatchUrlCacheEnabled = theMatchUrlCache;
587        }
588
589        /**
590         * If enabled, resolutions for match URLs (e.g. conditional create URLs, conditional update URLs, etc) will be
591         * cached in an in-memory cache. This cache can have a noticeable improvement on write performance on servers
592         * where conditional operations are frequently performed, but note that this cache will not be
593         * invalidated based on updates to resources so this may have detrimental effects.
594         * <p>
595         * Default is <code>false</code>
596         *
597         * @since 5.5.0
598         */
599        public boolean isMatchUrlCacheEnabled() {
600                return getMatchUrlCache();
601        }
602
603        /**
604         * If enabled, resolutions for match URLs (e.g. conditional create URLs, conditional update URLs, etc) will be
605         * cached in an in-memory cache. This cache can have a noticeable improvement on write performance on servers
606         * where conditional operations are frequently performed, but note that this cache will not be
607         * invalidated based on updates to resources so this may have detrimental effects.
608         * <p>
609         * Default is <code>false</code>
610         *
611         * @since 5.5.0
612         */
613        public void setMatchUrlCacheEnabled(boolean theMatchUrlCache) {
614                setMatchUrlCache(theMatchUrlCache);
615        }
616
617        /**
618         * If set to <code>true</code> (default is true) when a resource is being persisted,
619         * the target resource types of references will be validated to ensure that they
620         * are appropriate for the field containing the reference. This is generally a good idea
621         * because invalid reference target types may not be searchable.
622         */
623        public boolean isEnforceReferenceTargetTypes() {
624                return myEnforceReferenceTargetTypes;
625        }
626
627        /**
628         * If set to <code>true</code> (default is true) when a resource is being persisted,
629         * the target resource types of references will be validated to ensure that they
630         * are appropriate for the field containing the reference. This is generally a good idea
631         * because invalid reference target types may not be searchable.
632         */
633        public void setEnforceReferenceTargetTypes(boolean theEnforceReferenceTargetTypes) {
634                myEnforceReferenceTargetTypes = theEnforceReferenceTargetTypes;
635        }
636
637        /**
638         * If a non-null value is supplied (default is <code>null</code>), a default
639         * for the <code>_total</code> parameter may be specified here. For example,
640         * setting this value to {@link SearchTotalModeEnum#ACCURATE} will force a
641         * count to always be calculated for all searches. This can have a performance impact
642         * since it means that a count query will always be performed, but this is desirable
643         * for some solutions.
644         */
645        public SearchTotalModeEnum getDefaultTotalMode() {
646                return myDefaultTotalMode;
647        }
648
649        /**
650         * If a non-null value is supplied (default is <code>null</code>), a default
651         * for the <code>_total</code> parameter may be specified here. For example,
652         * setting this value to {@link SearchTotalModeEnum#ACCURATE} will force a
653         * count to always be calculated for all searches. This can have a performance impact
654         * since it means that a count query will always be performed, but this is desirable
655         * for some solutions.
656         */
657        public void setDefaultTotalMode(SearchTotalModeEnum theDefaultTotalMode) {
658                myDefaultTotalMode = theDefaultTotalMode;
659        }
660
661        /**
662         * Returns a set of searches that should be kept "warm", meaning that
663         * searches will periodically be performed in the background to
664         * keep results ready for this search
665         */
666        public List<WarmCacheEntry> getWarmCacheEntries() {
667                if (myWarmCacheEntries == null) {
668                        myWarmCacheEntries = new ArrayList<>();
669                }
670                return myWarmCacheEntries;
671        }
672
673        public void setWarmCacheEntries(List<WarmCacheEntry> theWarmCacheEntries) {
674                myWarmCacheEntries = theWarmCacheEntries;
675        }
676
677        /**
678         * If set to <code>true</code> (default is false), the reindexing of search parameters
679         * using a query on the HFJ_RESOURCE.SP_INDEX_STATUS column will be disabled completely.
680         * This query is just not efficient on Oracle and bogs the system down when there are
681         * a lot of resources. A more efficient way of doing this will be introduced
682         * in the next release of HAPI FHIR.
683         *
684         * @since 3.5.0
685         */
686        public boolean isStatusBasedReindexingDisabled() {
687                return myStatusBasedReindexingDisabled;
688        }
689
690        /**
691         * If set to <code>true</code> (default is false), the reindexing of search parameters
692         * using a query on the HFJ_RESOURCE.SP_INDEX_STATUS column will be disabled completely.
693         * This query is just not efficient on Oracle and bogs the system down when there are
694         * a lot of resources. A more efficient way of doing this will be introduced
695         * in the next release of HAPI FHIR.
696         *
697         * @since 3.5.0
698         */
699        public void setStatusBasedReindexingDisabled(boolean theStatusBasedReindexingDisabled) {
700                myStatusBasedReindexingDisabled = theStatusBasedReindexingDisabled;
701        }
702
703        /**
704         * Add a value to the {@link #setTreatReferencesAsLogical(Set) logical references list}.
705         *
706         * @see #setTreatReferencesAsLogical(Set)
707         */
708        public void addTreatReferencesAsLogical(String theTreatReferencesAsLogical) {
709                myModelConfig.addTreatReferencesAsLogical(theTreatReferencesAsLogical);
710        }
711
712        /**
713         * This setting specifies the bundle types (<code>Bundle.type</code>) that
714         * are allowed to be stored as-is on the /Bundle endpoint.
715         *
716         * @see #DEFAULT_BUNDLE_TYPES_ALLOWED_FOR_STORAGE
717         */
718        public Set<String> getBundleTypesAllowedForStorage() {
719                return myBundleTypesAllowedForStorage;
720        }
721
722        /**
723         * This setting specifies the bundle types (<code>Bundle.type</code>) that
724         * are allowed to be stored as-is on the /Bundle endpoint.
725         *
726         * @see #DEFAULT_BUNDLE_TYPES_ALLOWED_FOR_STORAGE
727         */
728        public void setBundleTypesAllowedForStorage(Set<String> theBundleTypesAllowedForStorage) {
729                Validate.notNull(theBundleTypesAllowedForStorage, "theBundleTypesAllowedForStorage must not be null");
730                myBundleTypesAllowedForStorage = theBundleTypesAllowedForStorage;
731        }
732
733        /**
734         * Specifies the highest number that a client is permitted to use in a
735         * <code>Cache-Control: nostore, max-results=NNN</code>
736         * directive. If the client tries to exceed this limit, the
737         * request will be denied. Defaults to 1000.
738         */
739        public Integer getCacheControlNoStoreMaxResultsUpperLimit() {
740                return myCacheControlNoStoreMaxResultsUpperLimit;
741        }
742
743        /**
744         * Specifies the highest number that a client is permitted to use in a
745         * <code>Cache-Control: nostore, max-results=NNN</code>
746         * directive. If the client tries to exceed this limit, the
747         * request will be denied. Defaults to 1000.
748         */
749        public void setCacheControlNoStoreMaxResultsUpperLimit(Integer theCacheControlNoStoreMaxResults) {
750                myCacheControlNoStoreMaxResultsUpperLimit = theCacheControlNoStoreMaxResults;
751        }
752
753        /**
754         * When searching, if set to a non-null value (default is <code>null</code>) the
755         * search coordinator will attempt to find at least this many results
756         * before returning a response to the client. This parameter mainly affects
757         * whether a "total count" is included in the response bundle for searches that
758         * return large amounts of data.
759         * <p>
760         * For a search that returns 10000 results, if this value is set to
761         * 10000 the search coordinator will find all 10000 results
762         * prior to returning, so the initial response bundle will have the
763         * total set to 10000. If this value is null (or less than 10000)
764         * the response bundle will likely return slightly faster, but will
765         * not include the total. Subsequent page requests will likely
766         * include the total however, if they are performed after the
767         * search coordinator has found all results.
768         * </p>
769         * <p>
770         * Set this value to <code>0</code> to always load all
771         * results before returning.
772         * </p>
773         */
774        public Integer getCountSearchResultsUpTo() {
775                return myCountSearchResultsUpTo;
776        }
777
778        /**
779         * When searching, if set to a non-null value (default is <code>null</code>) the
780         * search coordinator will attempt to find at least this many results
781         * before returning a response to the client. This parameter mainly affects
782         * whether a "total count" is included in the response bundle for searches that
783         * return large amounts of data.
784         * <p>
785         * For a search that returns 10000 results, if this value is set to
786         * 10000 the search coordinator will find all 10000 results
787         * prior to returning, so the initial response bundle will have the
788         * total set to 10000. If this value is null (or less than 10000)
789         * the response bundle will likely return slightly faster, but will
790         * not include the total. Subsequent page requests will likely
791         * include the total however, if they are performed after the
792         * search coordinator has found all results.
793         * </p>
794         * <p>
795         * Set this value to <code>0</code> to always load all
796         * results before returning.
797         * </p>
798         */
799        public void setCountSearchResultsUpTo(Integer theCountSearchResultsUpTo) {
800                myCountSearchResultsUpTo = theCountSearchResultsUpTo;
801        }
802
803        /**
804         * When a code system is added that contains more than this number of codes,
805         * the code system will be indexed later in an incremental process in order to
806         * avoid overwhelming Lucene with a huge number of codes in a single operation.
807         * <p>
808         * Defaults to 100
809         * </p>
810         */
811        public int getDeferIndexingForCodesystemsOfSize() {
812                return myDeferIndexingForCodesystemsOfSize;
813        }
814
815        /**
816         * When a code system is added that contains more than this number of codes,
817         * the code system will be indexed later in an incremental process in order to
818         * avoid overwhelming Lucene with a huge number of codes in a single operation.
819         * <p>
820         * Defaults to 100
821         * </p>
822         */
823        public void setDeferIndexingForCodesystemsOfSize(int theDeferIndexingForCodesystemsOfSize) {
824                myDeferIndexingForCodesystemsOfSize = theDeferIndexingForCodesystemsOfSize;
825        }
826
827        /**
828         * Unlike with normal search queries, $everything queries have their _includes loaded by the main search thread and these included results
829         * are added to the normal search results instead of being added on as extras in a page. This means that they will not appear multiple times
830         * as the search results are paged over.
831         * <p>
832         * In order to recursively load _includes, we process the original results in batches of this size. Adjust with caution, increasing this
833         * value may improve performance but may also cause memory issues.
834         * </p>
835         * <p>
836         * The default value is 50
837         * </p>
838         */
839        public int getEverythingIncludesFetchPageSize() {
840                return myEverythingIncludesFetchPageSize;
841        }
842
843        /**
844         * Unlike with normal search queries, $everything queries have their _includes loaded by the main search thread and these included results
845         * are added to the normal search results instead of being added on as extras in a page. This means that they will not appear multiple times
846         * as the search results are paged over.
847         * <p>
848         * In order to recursively load _includes, we process the original results in batches of this size. Adjust with caution, increasing this
849         * value may improve performance but may also cause memory issues.
850         * </p>
851         * <p>
852         * The default value is 50
853         * </p>
854         */
855        public void setEverythingIncludesFetchPageSize(int theEverythingIncludesFetchPageSize) {
856                Validate.inclusiveBetween(1, Integer.MAX_VALUE, theEverythingIncludesFetchPageSize);
857                myEverythingIncludesFetchPageSize = theEverythingIncludesFetchPageSize;
858        }
859
860        /**
861         * Sets the number of milliseconds that search results for a given client search
862         * should be preserved before being purged from the database.
863         * <p>
864         * Search results are stored in the database so that they can be paged over multiple
865         * requests. After this
866         * number of milliseconds, they will be deleted from the database, and any paging links
867         * (next/prev links in search response bundles) will become invalid. Defaults to 1 hour.
868         * </p>
869         * <p>
870         * To disable this feature entirely, see {@link #setExpireSearchResults(boolean)}
871         * </p>
872         *
873         * @since 1.5
874         */
875        public long getExpireSearchResultsAfterMillis() {
876                return myExpireSearchResultsAfterMillis;
877        }
878
879        /**
880         * Sets the number of milliseconds that search results for a given client search
881         * should be preserved before being purged from the database.
882         * <p>
883         * Search results are stored in the database so that they can be paged over multiple
884         * requests. After this
885         * number of milliseconds, they will be deleted from the database, and any paging links
886         * (next/prev links in search response bundles) will become invalid. Defaults to 1 hour.
887         * </p>
888         * <p>
889         * To disable this feature entirely, see {@link #setExpireSearchResults(boolean)}
890         * </p>
891         *
892         * @since 1.5
893         */
894        public void setExpireSearchResultsAfterMillis(long theExpireSearchResultsAfterMillis) {
895                myExpireSearchResultsAfterMillis = theExpireSearchResultsAfterMillis;
896        }
897
898        /**
899         * Gets the default maximum number of results to load in a query.
900         * <p>
901         * For example, if the database has a million Patient resources in it, and
902         * the client requests <code>GET /Patient</code>, if this value is set
903         * to a non-null value (default is <code>null</code>) only this number
904         * of results will be fetched. Setting this value appropriately
905         * can be useful to improve performance in some situations.
906         * </p>
907         */
908        public Integer getFetchSizeDefaultMaximum() {
909                return myFetchSizeDefaultMaximum;
910        }
911
912        /**
913         * Gets the default maximum number of results to load in a query.
914         * <p>
915         * For example, if the database has a million Patient resources in it, and
916         * the client requests <code>GET /Patient</code>, if this value is set
917         * to a non-null value (default is <code>null</code>) only this number
918         * of results will be fetched. Setting this value appropriately
919         * can be useful to improve performance in some situations.
920         * </p>
921         */
922        public void setFetchSizeDefaultMaximum(Integer theFetchSizeDefaultMaximum) {
923                myFetchSizeDefaultMaximum = theFetchSizeDefaultMaximum;
924        }
925
926        /**
927         * If set to {@link IndexEnabledEnum#DISABLED} (default is {@link IndexEnabledEnum#DISABLED})
928         * the server will not create search indexes for search parameters with no values in resources.
929         * <p>
930         * Disabling this feature means that the <code>:missing</code> search modifier will not be
931         * supported on the server, but also means that storage and indexing (i.e. writes to the
932         * database) may be much faster on servers which have lots of search parameters and need
933         * to write quickly.
934         * </p>
935         * <p>
936         * This feature may be enabled on servers where supporting the use of the :missing parameter is
937         * of higher importance than raw write performance
938         * </p>
939         */
940        public IndexEnabledEnum getIndexMissingFields() {
941                return myIndexMissingFieldsEnabled;
942        }
943
944        /**
945         * If set to {@link IndexEnabledEnum#DISABLED} (default is {@link IndexEnabledEnum#DISABLED})
946         * the server will not create search indexes for search parameters with no values in resources.
947         * <p>
948         * Disabling this feature means that the <code>:missing</code> search modifier will not be
949         * supported on the server, but also means that storage and indexing (i.e. writes to the
950         * database) may be much faster on servers which have lots of search parameters and need
951         * to write quickly.
952         * </p>
953         * <p>
954         * This feature may be enabled on servers where supporting the use of the :missing parameter is
955         * of higher importance than raw write performance
956         * </p>
957         * <p>
958         * Note that this setting also has an impact on sorting (i.e. using the
959         * <code>_sort</code> parameter on searches): If the server is configured
960         * to not index missing field.
961         * </p>
962         * <p>
963         * The following index may need to be added into the indexed tables such as <code>HFJ_SPIDX_TOKEN</code>
964         * to improve the search performance while <code>:missing</code> is enabled.
965         * <code>RES_TYPE, SP_NAME, SP_MISSING</code>
966         * </p>
967         */
968        public void setIndexMissingFields(IndexEnabledEnum theIndexMissingFields) {
969                Validate.notNull(theIndexMissingFields, "theIndexMissingFields must not be null");
970                myIndexMissingFieldsEnabled = theIndexMissingFields;
971        }
972
973        /**
974         * See {@link #setMaximumExpansionSize(int)}
975         */
976        public int getMaximumExpansionSize() {
977                return myMaximumExpansionSize;
978        }
979
980        /**
981         * Sets the maximum number of codes that will be added to an in-memory valueset expansion before
982         * the operation will be failed as too costly. Note that this setting applies only to
983         * in-memory expansions and does not apply to expansions that are being pre-calculated.
984         * <p>
985         * The default value for this setting is 1000.
986         * </p>
987         */
988        public void setMaximumExpansionSize(int theMaximumExpansionSize) {
989                Validate.isTrue(theMaximumExpansionSize > 0, "theMaximumExpansionSize must be > 0");
990                myMaximumExpansionSize = theMaximumExpansionSize;
991        }
992
993        /**
994         * Provides the maximum number of results which may be returned by a search (HTTP GET) which
995         * is executed as a sub-operation within within a FHIR <code>transaction</code> or
996         * <code>batch</code> operation. For example, if this value is set to <code>100</code> and
997         * a FHIR transaction is processed with a sub-request for <code>Patient?gender=male</code>,
998         * the server will throw an error (and the transaction will fail) if there are more than
999         * 100 resources on the server which match this query.
1000         * <p>
1001         * The default value is <code>null</code>, which means that there is no limit.
1002         * </p>
1003         */
1004        public Integer getMaximumSearchResultCountInTransaction() {
1005                return myMaximumSearchResultCountInTransaction;
1006        }
1007
1008        /**
1009         * Provides the maximum number of results which may be returned by a search (HTTP GET) which
1010         * is executed as a sub-operation within within a FHIR <code>transaction</code> or
1011         * <code>batch</code> operation. For example, if this value is set to <code>100</code> and
1012         * a FHIR transaction is processed with a sub-request for <code>Patient?gender=male</code>,
1013         * the server will throw an error (and the transaction will fail) if there are more than
1014         * 100 resources on the server which match this query.
1015         * <p>
1016         * The default value is <code>null</code>, which means that there is no limit.
1017         * </p>
1018         */
1019        public void setMaximumSearchResultCountInTransaction(Integer theMaximumSearchResultCountInTransaction) {
1020                myMaximumSearchResultCountInTransaction = theMaximumSearchResultCountInTransaction;
1021        }
1022
1023        /**
1024         * Specifies the maximum number of resources permitted within a single transaction bundle.
1025         * If a transaction bundle is submitted with more than this number of resources, it will be
1026         * rejected with a PayloadTooLarge exception.
1027         * <p>
1028         * The default value is <code>null</code>, which means that there is no limit.
1029         * </p>
1030         */
1031        public Integer getMaximumTransactionBundleSize() {
1032                return myMaximumTransactionBundleSize;
1033        }
1034
1035        /**
1036         * Specifies the maximum number of resources permitted within a single transaction bundle.
1037         * If a transaction bundle is submitted with more than this number of resources, it will be
1038         * rejected with a PayloadTooLarge exception.
1039         * <p>
1040         * The default value is <code>null</code>, which means that there is no limit.
1041         * </p>
1042         */
1043        public DaoConfig setMaximumTransactionBundleSize(Integer theMaximumTransactionBundleSize) {
1044                myMaximumTransactionBundleSize = theMaximumTransactionBundleSize;
1045                return this;
1046        }
1047
1048        /**
1049         * This setting controls the number of threads allocated to resource reindexing
1050         * (which is only ever used if SearchParameters change, or a manual reindex is
1051         * triggered due to a HAPI FHIR upgrade or some other reason).
1052         * <p>
1053         * The default value is set to the number of available processors
1054         * (via <code>Runtime.getRuntime().availableProcessors()</code>). Value
1055         * for this setting must be a positive integer.
1056         * </p>
1057         */
1058        public int getReindexThreadCount() {
1059                return myReindexThreadCount;
1060        }
1061
1062        /**
1063         * This setting controls the number of threads allocated to resource reindexing
1064         * (which is only ever used if SearchParameters change, or a manual reindex is
1065         * triggered due to a HAPI FHIR upgrade or some other reason).
1066         * <p>
1067         * The default value is set to the number of available processors
1068         * (via <code>Runtime.getRuntime().availableProcessors()</code>). Value
1069         * for this setting must be a positive integer.
1070         * </p>
1071         */
1072        public void setReindexThreadCount(int theReindexThreadCount) {
1073                myReindexThreadCount = theReindexThreadCount;
1074                myReindexThreadCount = Math.max(myReindexThreadCount, 1); // Minimum of 1
1075        }
1076
1077        /**
1078         * This setting controls the number of threads allocated to the expunge operation
1079         * <p>
1080         * The default value is set to the number of available processors
1081         * (via <code>Runtime.getRuntime().availableProcessors()</code>). Value
1082         * for this setting must be a positive integer.
1083         * </p>
1084         */
1085        public int getExpungeThreadCount() {
1086                return myExpungeThreadCount;
1087        }
1088
1089        /**
1090         * This setting controls the number of threads allocated to the expunge operation
1091         * <p>
1092         * The default value is set to the number of available processors
1093         * (via <code>Runtime.getRuntime().availableProcessors()</code>). Value
1094         * for this setting must be a positive integer.
1095         * </p>
1096         */
1097        public void setExpungeThreadCount(int theExpungeThreadCount) {
1098                myExpungeThreadCount = theExpungeThreadCount;
1099                myExpungeThreadCount = Math.max(myExpungeThreadCount, 1); // Minimum of 1
1100        }
1101
1102        public ResourceEncodingEnum getResourceEncoding() {
1103                return myResourceEncoding;
1104        }
1105
1106        public void setResourceEncoding(ResourceEncodingEnum theResourceEncoding) {
1107                myResourceEncoding = theResourceEncoding;
1108        }
1109
1110        /**
1111         * If set, an individual resource will not be allowed to have more than the
1112         * given number of tags, profiles, and security labels (the limit is for the combined
1113         * total for all of these things on an individual resource).
1114         * <p>
1115         * If set to <code>null</code>, no limit will be applied.
1116         * </p>
1117         * <p>
1118         * The default value for this setting is 1000.
1119         * </p>
1120         */
1121        public Integer getResourceMetaCountHardLimit() {
1122                return myResourceMetaCountHardLimit;
1123        }
1124
1125        /**
1126         * If set, an individual resource will not be allowed to have more than the
1127         * given number of tags, profiles, and security labels (the limit is for the combined
1128         * total for all of these things on an individual resource).
1129         * <p>
1130         * If set to <code>null</code>, no limit will be applied.
1131         * </p>
1132         * <p>
1133         * The default value for this setting is 1000.
1134         * </p>
1135         */
1136        public void setResourceMetaCountHardLimit(Integer theResourceMetaCountHardLimit) {
1137                myResourceMetaCountHardLimit = theResourceMetaCountHardLimit;
1138        }
1139
1140        /**
1141         * Controls the behaviour when a client-assigned ID is encountered, i.e. an HTTP PUT
1142         * on a resource ID that does not already exist in the database.
1143         * <p>
1144         * Default is {@link ClientIdStrategyEnum#ALPHANUMERIC}
1145         * </p>
1146         */
1147        public ClientIdStrategyEnum getResourceClientIdStrategy() {
1148                return myResourceClientIdStrategy;
1149        }
1150
1151        /**
1152         * Controls the behaviour when a client-assigned ID is encountered, i.e. an HTTP PUT
1153         * on a resource ID that does not already exist in the database.
1154         * <p>
1155         * Default is {@link ClientIdStrategyEnum#ALPHANUMERIC}
1156         * </p>
1157         *
1158         * @param theResourceClientIdStrategy Must not be <code>null</code>
1159         */
1160        public void setResourceClientIdStrategy(ClientIdStrategyEnum theResourceClientIdStrategy) {
1161                Validate.notNull(theResourceClientIdStrategy, "theClientIdStrategy must not be null");
1162                myResourceClientIdStrategy = theResourceClientIdStrategy;
1163        }
1164
1165        /**
1166         * This setting configures the strategy to use in generating IDs for newly
1167         * created resources on the server. The default is {@link IdStrategyEnum#SEQUENTIAL_NUMERIC}.
1168         * <p>
1169         * This strategy is only used for server-assigned IDs, i.e. for HTTP POST
1170         * where the client is requesing that the server store a new resource and give
1171         * it an ID.
1172         * </p>
1173         */
1174        public IdStrategyEnum getResourceServerIdStrategy() {
1175                return myResourceServerIdStrategy;
1176        }
1177
1178        /**
1179         * This setting configures the strategy to use in generating IDs for newly
1180         * created resources on the server. The default is {@link IdStrategyEnum#SEQUENTIAL_NUMERIC}.
1181         * <p>
1182         * This strategy is only used for server-assigned IDs, i.e. for HTTP POST
1183         * where the client is requesing that the server store a new resource and give
1184         * it an ID.
1185         * </p>
1186         *
1187         * @param theResourceIdStrategy The strategy. Must not be <code>null</code>.
1188         */
1189        public void setResourceServerIdStrategy(IdStrategyEnum theResourceIdStrategy) {
1190                Validate.notNull(theResourceIdStrategy, "theResourceIdStrategy must not be null");
1191                myResourceServerIdStrategy = theResourceIdStrategy;
1192        }
1193
1194        /**
1195         * If set to a non {@literal null} value (default is {@link #DEFAULT_REUSE_CACHED_SEARCH_RESULTS_FOR_MILLIS non null})
1196         * if an identical search is requested multiple times within this window, the same results will be returned
1197         * to multiple queries. For example, if this value is set to 1 minute and a client searches for all
1198         * patients named "smith", and then a second client also performs the same search within 1 minute,
1199         * the same cached results will be returned.
1200         * <p>
1201         * This approach can improve performance, especially under heavy load, but can also mean that
1202         * searches may potentially return slightly out-of-date results.
1203         * </p>
1204         * <p>
1205         * Note that if this is set to a non-null value, clients may override this setting by using
1206         * the <code>Cache-Control</code> header. If this is set to <code>null</code>, the Cache-Control
1207         * header will be ignored.
1208         * </p>
1209         */
1210        public Long getReuseCachedSearchResultsForMillis() {
1211                return myReuseCachedSearchResultsForMillis;
1212        }
1213
1214        /**
1215         * If set to a non {@literal null} value (default is {@link #DEFAULT_REUSE_CACHED_SEARCH_RESULTS_FOR_MILLIS non null})
1216         * if an identical search is requested multiple times within this window, the same results will be returned
1217         * to multiple queries. For example, if this value is set to 1 minute and a client searches for all
1218         * patients named "smith", and then a second client also performs the same search within 1 minute,
1219         * the same cached results will be returned.
1220         * <p>
1221         * This approach can improve performance, especially under heavy load, but can also mean that
1222         * searches may potentially return slightly out-of-date results.
1223         * </p>
1224         * <p>
1225         * Note that if this is set to a non-null value, clients may override this setting by using
1226         * the <code>Cache-Control</code> header. If this is set to <code>null</code>, the Cache-Control
1227         * header will be ignored.
1228         * </p>
1229         */
1230        public void setReuseCachedSearchResultsForMillis(Long theReuseCachedSearchResultsForMillis) {
1231                myReuseCachedSearchResultsForMillis = theReuseCachedSearchResultsForMillis;
1232        }
1233
1234        /**
1235         * This setting may be used to advise the server that any references found in
1236         * resources that have any of the base URLs given here will be treated as logical
1237         * references instead of being treated as real references.
1238         * <p>
1239         * A logical reference is a reference which is treated as an identifier, and
1240         * does not neccesarily resolve. See <a href="http://hl7.org/fhir/references.html">references</a> for
1241         * a description of logical references. For example, the valueset
1242         * <a href="http://hl7.org/fhir/valueset-quantity-comparator.html">valueset-quantity-comparator</a> is a logical
1243         * reference.
1244         * </p>
1245         * <p>
1246         * Values for this field may take either of the following forms:
1247         * </p>
1248         * <ul>
1249         * <li><code>http://example.com/some-url</code> <b>(will be matched exactly)</b></li>
1250         * <li><code>http://example.com/some-base*</code> <b>(will match anything beginning with the part before the *)</b></li>
1251         * </ul>
1252         *
1253         * @see ModelConfig#DEFAULT_LOGICAL_BASE_URLS Default values for this property
1254         */
1255        public Set<String> getTreatReferencesAsLogical() {
1256                return myModelConfig.getTreatReferencesAsLogical();
1257        }
1258
1259        /**
1260         * This setting may be used to advise the server that any references found in
1261         * resources that have any of the base URLs given here will be treated as logical
1262         * references instead of being treated as real references.
1263         * <p>
1264         * A logical reference is a reference which is treated as an identifier, and
1265         * does not neccesarily resolve. See <a href="http://hl7.org/fhir/references.html">references</a> for
1266         * a description of logical references. For example, the valueset
1267         * <a href="http://hl7.org/fhir/valueset-quantity-comparator.html">valueset-quantity-comparator</a> is a logical
1268         * reference.
1269         * </p>
1270         * <p>
1271         * Values for this field may take either of the following forms:
1272         * </p>
1273         * <ul>
1274         * <li><code>http://example.com/some-url</code> <b>(will be matched exactly)</b></li>
1275         * <li><code>http://example.com/some-base*</code> <b>(will match anything beginning with the part before the *)</b></li>
1276         * </ul>
1277         *
1278         * @see ModelConfig#DEFAULT_LOGICAL_BASE_URLS Default values for this property
1279         */
1280        public DaoConfig setTreatReferencesAsLogical(Set<String> theTreatReferencesAsLogical) {
1281                myModelConfig.setTreatReferencesAsLogical(theTreatReferencesAsLogical);
1282                return this;
1283        }
1284
1285        /**
1286         * If set to <code>true</code> (default is <code>false</code>) the server will allow
1287         * resources to have references to external servers. For example if this server is
1288         * running at <code>http://example.com/fhir</code> and this setting is set to
1289         * <code>true</code> the server will allow a Patient resource to be saved with a
1290         * Patient.organization value of <code>http://foo.com/Organization/1</code>.
1291         * <p>
1292         * Under the default behaviour if this value has not been changed, the above
1293         * resource would be rejected by the server because it requires all references
1294         * to be resolvable on the local server.
1295         * </p>
1296         * <p>
1297         * Note that external references will be indexed by the server and may be searched
1298         * (e.g. <code>Patient:organization</code>), but
1299         * chained searches (e.g. <code>Patient:organization.name</code>) will not work across
1300         * these references.
1301         * </p>
1302         * <p>
1303         * It is recommended to also set {@link #setTreatBaseUrlsAsLocal(Set)} if this value
1304         * is set to <code>true</code>
1305         * </p>
1306         *
1307         * @see #setTreatBaseUrlsAsLocal(Set)
1308         * @see #setAllowExternalReferences(boolean)
1309         */
1310        public boolean isAllowExternalReferences() {
1311                return myModelConfig.isAllowExternalReferences();
1312        }
1313
1314        /**
1315         * If set to <code>true</code> (default is <code>false</code>) the server will allow
1316         * resources to have references to external servers. For example if this server is
1317         * running at <code>http://example.com/fhir</code> and this setting is set to
1318         * <code>true</code> the server will allow a Patient resource to be saved with a
1319         * Patient.organization value of <code>http://foo.com/Organization/1</code>.
1320         * <p>
1321         * Under the default behaviour if this value has not been changed, the above
1322         * resource would be rejected by the server because it requires all references
1323         * to be resolvable on the local server.
1324         * </p>
1325         * <p>
1326         * Note that external references will be indexed by the server and may be searched
1327         * (e.g. <code>Patient:organization</code>), but
1328         * chained searches (e.g. <code>Patient:organization.name</code>) will not work across
1329         * these references.
1330         * </p>
1331         * <p>
1332         * It is recommended to also set {@link #setTreatBaseUrlsAsLocal(Set)} if this value
1333         * is set to <code>true</code>
1334         * </p>
1335         *
1336         * @see #setTreatBaseUrlsAsLocal(Set)
1337         * @see #setAllowExternalReferences(boolean)
1338         */
1339        public void setAllowExternalReferences(boolean theAllowExternalReferences) {
1340                myModelConfig.setAllowExternalReferences(theAllowExternalReferences);
1341        }
1342
1343        /**
1344         * @see #setAllowInlineMatchUrlReferences(boolean)
1345         */
1346        public boolean isAllowInlineMatchUrlReferences() {
1347                return myAllowInlineMatchUrlReferences;
1348        }
1349
1350        /**
1351         * Should references containing match URLs be resolved and replaced in create and update operations. For
1352         * example, if this property is set to true and a resource is created containing a reference
1353         * to "Patient?identifier=12345", this is reference match URL will be resolved and replaced according
1354         * to the usual match URL rules.
1355         * <p>
1356         * Default is {@literal true} beginning in HAPI FHIR 2.4, since this
1357         * feature is now specified in the FHIR specification. (Previously it
1358         * was an experimental/proposed feature)
1359         * </p>
1360         *
1361         * @since 1.5
1362         */
1363        public void setAllowInlineMatchUrlReferences(boolean theAllowInlineMatchUrlReferences) {
1364                myAllowInlineMatchUrlReferences = theAllowInlineMatchUrlReferences;
1365        }
1366
1367        public boolean isAllowMultipleDelete() {
1368                return myAllowMultipleDelete;
1369        }
1370
1371        public void setAllowMultipleDelete(boolean theAllowMultipleDelete) {
1372                myAllowMultipleDelete = theAllowMultipleDelete;
1373        }
1374
1375        /**
1376         * When creating or updating a resource: If this property is set to <code>true</code>
1377         * (default is <code>false</code>), if the resource has a reference to another resource
1378         * on the local server but that reference does not exist, a placeholder resource will be
1379         * created.
1380         * <p>
1381         * In other words, if an observation with subject <code>Patient/FOO</code> is created, but
1382         * there is no resource called <code>Patient/FOO</code> on the server, this property causes
1383         * an empty patient with ID "FOO" to be created in order to prevent this operation
1384         * from failing.
1385         * </p>
1386         * <p>
1387         * This property can be useful in cases where replication between two servers is wanted.
1388         * Note however that references containing purely numeric IDs will not be auto-created
1389         * as they are never allowed to be client supplied in HAPI FHIR JPA.
1390         * <p>
1391         * All placeholder resources created in this way have an extension
1392         * with the URL {@link HapiExtensions#EXT_RESOURCE_PLACEHOLDER} and the value "true".
1393         * </p>
1394         */
1395        public boolean isAutoCreatePlaceholderReferenceTargets() {
1396                return myAutoCreatePlaceholderReferenceTargets;
1397        }
1398
1399        /**
1400         * When creating or updating a resource: If this property is set to <code>true</code>
1401         * (default is <code>false</code>), if the resource has a reference to another resource
1402         * on the local server but that reference does not exist, a placeholder resource will be
1403         * created.
1404         * <p>
1405         * In other words, if an observation with subject <code>Patient/FOO</code> is created, but
1406         * there is no resource called <code>Patient/FOO</code> on the server, this property causes
1407         * an empty patient with ID "FOO" to be created in order to prevent this operation
1408         * from failing.
1409         * </p>
1410         * <p>
1411         * This property can be useful in cases where replication between two servers is wanted.
1412         * Note however that references containing purely numeric IDs will not be auto-created
1413         * as they are never allowed to be client supplied in HAPI FHIR JPA.
1414         * <p>
1415         * All placeholder resources created in this way have an extension
1416         * with the URL {@link HapiExtensions#EXT_RESOURCE_PLACEHOLDER} and the value "true".
1417         * </p>
1418         */
1419        public void setAutoCreatePlaceholderReferenceTargets(boolean theAutoCreatePlaceholderReferenceTargets) {
1420                myAutoCreatePlaceholderReferenceTargets = theAutoCreatePlaceholderReferenceTargets;
1421        }
1422
1423        /**
1424         * When {@link #setAutoCreatePlaceholderReferenceTargets(boolean)} is enabled, if this
1425         * setting is set to <code>true</code> (default is <code>true</code>) and the source
1426         * reference has an identifier populated, the identifier will be copied to the target
1427         * resource.
1428         * <p>
1429         * When enabled, if an Observation contains a reference like the one below,
1430         * and no existing resource was found that matches the given ID, a new
1431         * one will be created and its <code>Patient.identifier</code> value will be
1432         * populated using the value from <code>Observation.subject.identifier</code>.
1433         * </p>
1434         * <pre>
1435         * {
1436         *   "resourceType": "Observation",
1437         *   "subject": {
1438         *     "reference": "Patient/ABC",
1439         *     "identifier": {
1440         *       "system": "http://foo",
1441         *       "value": "123"
1442         *     }
1443         *   }
1444         * }
1445         * </pre>
1446         * <p>
1447         * This method is often combined with {@link #setAllowInlineMatchUrlReferences(boolean)}.
1448         * </p>
1449         * <p>
1450         * In other words if an Observation contains a reference like the one below,
1451         * and no existing resource was found that matches the given match URL, a new
1452         * one will be created and its <code>Patient.identifier</code> value will be
1453         * populated using the value from <code>Observation.subject.identifier</code>.
1454         * </p>
1455         * <pre>
1456         * {
1457         *   "resourceType": "Observation",
1458         *   "subject": {
1459         *     "reference": "Patient?identifier=http://foo|123",
1460         *     "identifier": {
1461         *       "system": "http://foo",
1462         *       "value": "123"
1463         *     }
1464         *   }
1465         * }
1466         * </pre>
1467         * <p>
1468         * Note that the default for this setting was previously <code>false</code>, and was changed to <code>true</code>
1469         * in 5.4.0 with consideration to the following:
1470         * </p>
1471         * <pre>
1472         * CP = Auto-Create Placeholder Reference Targets
1473         * PI = Populate Identifier in Auto-Created Placeholder Reference Targets
1474         *
1475         * CP | PI
1476         * -------
1477         *  F | F  <- PI=F is ignored
1478         *  F | T  <- PI=T is ignored
1479         *  T | F  <- resources may reference placeholder reference targets that are never updated : (
1480         *  T | T  <- placeholder reference targets can be updated : )
1481         * </pre>
1482         * <p>
1483         * Where CP=T and PI=F, the following could happen:
1484         * </p>
1485         * <ol>
1486         *    <li>
1487         *       Resource instance A is created with a reference to resource instance B. B is a placeholder reference target
1488         *       without an identifier.
1489         *    </li>
1490         *    <li>
1491         *         Resource instance C is conditionally created using a match URL. It is not matched to B although these
1492         *         resources represent the same entity.
1493         *    </li>
1494         *    <li>
1495         *       A continues to reference placeholder B, and does not reference populated C.
1496         *    </li>
1497         * </ol>
1498         * <p>
1499         * There may be cases where configuring this setting to <code>false</code> would be appropriate; however, these are
1500         * exceptional cases that should be opt-in.
1501         * </p>
1502         *
1503         * @since 4.2.0
1504         */
1505        public boolean isPopulateIdentifierInAutoCreatedPlaceholderReferenceTargets() {
1506                return myPopulateIdentifierInAutoCreatedPlaceholderReferenceTargets;
1507        }
1508
1509        /**
1510         * When {@link #setAutoCreatePlaceholderReferenceTargets(boolean)} is enabled, if this
1511         * setting is set to <code>true</code> (default is <code>true</code>) and the source
1512         * reference has an identifier populated, the identifier will be copied to the target
1513         * resource.
1514         * <p>
1515         * When enabled, if an Observation contains a reference like the one below,
1516         * and no existing resource was found that matches the given ID, a new
1517         * one will be created and its <code>Patient.identifier</code> value will be
1518         * populated using the value from <code>Observation.subject.identifier</code>.
1519         * </p>
1520         * <pre>
1521         * {
1522         *   "resourceType": "Observation",
1523         *   "subject": {
1524         *     "reference": "Patient/ABC",
1525         *     "identifier": {
1526         *       "system": "http://foo",
1527         *       "value": "123"
1528         *     }
1529         *   }
1530         * }
1531         * </pre>
1532         * <p>
1533         * This method is often combined with {@link #setAllowInlineMatchUrlReferences(boolean)}.
1534         * </p>
1535         * <p>
1536         * In other words if an Observation contains a reference like the one below,
1537         * and no existing resource was found that matches the given match URL, a new
1538         * one will be created and its <code>Patient.identifier</code> value will be
1539         * populated using the value from <code>Observation.subject.identifier</code>.
1540         * </p>
1541         * <pre>
1542         * {
1543         *   "resourceType": "Observation",
1544         *   "subject": {
1545         *     "reference": "Patient?identifier=http://foo|123",
1546         *     "identifier": {
1547         *       "system": "http://foo",
1548         *       "value": "123"
1549         *     }
1550         *   }
1551         * }
1552         * </pre>
1553         * <p>
1554         * Note that the default for this setting was previously <code>false</code>, and was changed to <code>true</code>
1555         * in 5.4.0 with consideration to the following:
1556         * </p>
1557         * <pre>
1558         * CP = Auto-Create Placeholder Reference Targets
1559         * PI = Populate Identifier in Auto-Created Placeholder Reference Targets
1560         *
1561         * CP | PI
1562         * -------
1563         *  F | F  <- PI=F is ignored
1564         *  F | T  <- PI=T is ignored
1565         *  T | F  <- resources may reference placeholder reference targets that are never updated : (
1566         *  T | T  <- placeholder reference targets can be updated : )
1567         * </pre>
1568         * <p>
1569         * Where CP=T and PI=F, the following could happen:
1570         * </p>
1571         * <ol>
1572         *    <li>
1573         *       Resource instance A is created with a reference to resource instance B. B is a placeholder reference target
1574         *       without an identifier.
1575         *    </li>
1576         *    <li>
1577         *         Resource instance C is conditionally created using a match URL. It is not matched to B although these
1578         *         resources represent the same entity.
1579         *    </li>
1580         *    <li>
1581         *       A continues to reference placeholder B, and does not reference populated C.
1582         *    </li>
1583         * </ol>
1584         * <p>
1585         * There may be cases where configuring this setting to <code>false</code> would be appropriate; however, these are
1586         * exceptional cases that should be opt-in.
1587         * </p>
1588         *
1589         * @since 4.2.0
1590         */
1591        public void setPopulateIdentifierInAutoCreatedPlaceholderReferenceTargets(boolean thePopulateIdentifierInAutoCreatedPlaceholderReferenceTargets) {
1592                myPopulateIdentifierInAutoCreatedPlaceholderReferenceTargets = thePopulateIdentifierInAutoCreatedPlaceholderReferenceTargets;
1593        }
1594
1595        /**
1596         * If set to <code>false</code> (default is <code>true</code>) resources will be permitted to be
1597         * deleted even if other resources currently contain references to them.
1598         * <p>
1599         * This property can cause confusing results for clients of the server since searches, includes,
1600         * and other FHIR features may not behave as expected when referential integrity is not
1601         * preserved. Use this feature with caution.
1602         * </p>
1603         */
1604        public boolean isEnforceReferentialIntegrityOnDelete() {
1605                return myEnforceReferentialIntegrityOnDelete;
1606        }
1607
1608        /**
1609         * If set to <code>false</code> (default is <code>true</code>) resources will be permitted to be
1610         * deleted even if other resources currently contain references to them.
1611         * <p>
1612         * This property can cause confusing results for clients of the server since searches, includes,
1613         * and other FHIR features may not behave as expected when referential integrity is not
1614         * preserved. Use this feature with caution.
1615         * </p>
1616         */
1617        public void setEnforceReferentialIntegrityOnDelete(boolean theEnforceReferentialIntegrityOnDelete) {
1618                myEnforceReferentialIntegrityOnDelete = theEnforceReferentialIntegrityOnDelete;
1619        }
1620
1621        /**
1622         * If set to <code>false</code> (default is <code>true</code>) resources will be permitted to be
1623         * created or updated even if they contain references to local resources that do not exist.
1624         * <p>
1625         * For example, if a patient contains a reference to managing organization <code>Organization/FOO</code>
1626         * but FOO is not a valid ID for an organization on the server, the operation will be blocked unless
1627         * this propery has been set to <code>false</code>
1628         * </p>
1629         * <p>
1630         * This property can cause confusing results for clients of the server since searches, includes,
1631         * and other FHIR features may not behave as expected when referential integrity is not
1632         * preserved. Use this feature with caution.
1633         * </p>
1634         */
1635        public boolean isEnforceReferentialIntegrityOnWrite() {
1636                return myEnforceReferentialIntegrityOnWrite;
1637        }
1638
1639        /**
1640         * If set to <code>false</code> (default is <code>true</code>) resources will be permitted to be
1641         * created or updated even if they contain references to local resources that do not exist.
1642         * <p>
1643         * For example, if a patient contains a reference to managing organization <code>Organization/FOO</code>
1644         * but FOO is not a valid ID for an organization on the server, the operation will be blocked unless
1645         * this propery has been set to <code>false</code>
1646         * </p>
1647         * <p>
1648         * This property can cause confusing results for clients of the server since searches, includes,
1649         * and other FHIR features may not behave as expected when referential integrity is not
1650         * preserved. Use this feature with caution.
1651         * </p>
1652         */
1653        public void setEnforceReferentialIntegrityOnWrite(boolean theEnforceReferentialIntegrityOnWrite) {
1654                myEnforceReferentialIntegrityOnWrite = theEnforceReferentialIntegrityOnWrite;
1655        }
1656
1657        /**
1658         * If this is set to <code>false</code> (default is <code>true</code>) the stale search deletion
1659         * task will be disabled (meaning that search results will be retained in the database indefinitely). USE WITH CAUTION.
1660         * <p>
1661         * This feature is useful if you want to define your own process for deleting these (e.g. because
1662         * you are running in a cluster)
1663         * </p>
1664         */
1665        public boolean isExpireSearchResults() {
1666                return myDeleteStaleSearches;
1667        }
1668
1669        /**
1670         * If this is set to <code>false</code> (default is <code>true</code>) the stale search deletion
1671         * task will be disabled (meaning that search results will be retained in the database indefinitely). USE WITH CAUTION.
1672         * <p>
1673         * This feature is useful if you want to define your own process for deleting these (e.g. because
1674         * you are running in a cluster)
1675         * </p>
1676         */
1677        public void setExpireSearchResults(boolean theDeleteStaleSearches) {
1678                myDeleteStaleSearches = theDeleteStaleSearches;
1679        }
1680
1681        /**
1682         * If set to <code>true</code> (default is <code>false</code>), the $expunge operation
1683         * will be enabled on this server. This operation is potentially dangerous since it allows
1684         * a client to physically delete data in a way that can not be recovered (without resorting
1685         * to backups).
1686         * <p>
1687         * It is recommended to not enable this setting without appropriate security
1688         * in place on your server to prevent non-administrators from using this
1689         * operation.
1690         * </p>
1691         */
1692        public boolean isExpungeEnabled() {
1693                return myExpungeEnabled;
1694        }
1695
1696        /**
1697         * If set to <code>true</code> (default is <code>false</code>), the $expunge operation
1698         * will be enabled on this server. This operation is potentially dangerous since it allows
1699         * a client to physically delete data in a way that can not be recovered (without resorting
1700         * to backups).
1701         * <p>
1702         * It is recommended to not enable this setting without appropriate security
1703         * in place on your server to prevent non-administrators from using this
1704         * operation.
1705         * </p>
1706         */
1707        public void setExpungeEnabled(boolean theExpungeEnabled) {
1708                myExpungeEnabled = theExpungeEnabled;
1709        }
1710
1711        /**
1712         * If set to <code>true</code> (default is <code>false</code>), the _expunge parameter on the DELETE
1713         * operation will be enabled on this server. DELETE _expunge removes all data associated with a resource in a highly performant
1714         * way, skipping most of the the checks that are enforced with usual DELETE operations.  The only check
1715         * that is performed before deleting the data is that no other resources reference the resources about to
1716         * be deleted.  This operation is potentially dangerous since it allows
1717         * a client to physically delete data in a way that can not be recovered (without resorting
1718         * to backups).
1719         * <p>
1720         * It is recommended to not enable this setting without appropriate security
1721         * in place on your server to prevent non-administrators from using this
1722         * operation.
1723         * </p>
1724         */
1725        public boolean isDeleteExpungeEnabled() {
1726                return myDeleteExpungeEnabled;
1727        }
1728
1729        /**
1730         * If set to <code>true</code> (default is <code>false</code>), the _expunge parameter on the DELETE
1731         * operation will be enabled on this server. DELETE _expunge removes all data associated with a resource in a highly performant
1732         * way, skipping most of the the checks that are enforced with usual DELETE operations.  The only check
1733         * that is performed before deleting the resources and their indexes is that no other resources reference the resources about to
1734         * be deleted.  This operation is potentially dangerous since it allows
1735         * a client to physically delete data in a way that can not be recovered (without resorting
1736         * to backups).
1737         * <p>
1738         * It is recommended to not enable this setting without appropriate security
1739         * in place on your server to prevent non-administrators from using this
1740         * operation.
1741         * </p>
1742         */
1743        public void setDeleteExpungeEnabled(boolean theDeleteExpungeEnabled) {
1744                myDeleteExpungeEnabled = theDeleteExpungeEnabled;
1745        }
1746
1747        /**
1748         * The expunge batch size (default 800) determines the number of records deleted within a single transaction by the
1749         * expunge operation.  When expunging via DELETE ?_expunge=true, then this value determines the batch size for
1750         * the number of resources deleted and expunged at a time.
1751         */
1752        public int getExpungeBatchSize() {
1753                return myExpungeBatchSize;
1754        }
1755
1756        /**
1757         * The expunge batch size (default 800) determines the number of records deleted within a single transaction by the
1758         * expunge operation.  When expunging via DELETE ?_expunge=true, then this value determines the batch size for
1759         * the number of resources deleted and expunged at a time.
1760         */
1761        public void setExpungeBatchSize(int theExpungeBatchSize) {
1762                myExpungeBatchSize = theExpungeBatchSize;
1763        }
1764
1765        /**
1766         * The reindex batch size (default 800) determines the number of records reindexed in a single transaction.
1767         */
1768        public int getReindexBatchSize() {
1769                return myReindexBatchSize;
1770        }
1771
1772        /**
1773         * The reindex batch size (default 800) determines the number of records reindexed in a single transaction.
1774         */
1775        public void setReindexBatchSize(int theReindexBatchSize) {
1776                myReindexBatchSize = theReindexBatchSize;
1777        }
1778
1779
1780        /**
1781         * If set to <code>false</code> (default is <code>true</code>), reindexing of resources will be disabled on this
1782         * server.
1783         */
1784        public boolean isReindexEnabled() {
1785                return myReindexEnabled;
1786        }
1787
1788        /**
1789         * If set to <code>false</code> (default is <code>true</code>), reindexing of resources will be disabled on this
1790         * server.
1791         */
1792
1793        public void setReindexEnabled(boolean theReindexEnabled) {
1794                myReindexEnabled = theReindexEnabled;
1795        }
1796
1797        /**
1798         * Should resources be marked as needing reindexing when a
1799         * SearchParameter resource is added or changed. This should generally
1800         * be true (which is the default)
1801         */
1802        public boolean isMarkResourcesForReindexingUponSearchParameterChange() {
1803                return myMarkResourcesForReindexingUponSearchParameterChange;
1804        }
1805
1806        /**
1807         * Should resources be marked as needing reindexing when a
1808         * SearchParameter resource is added or changed. This should generally
1809         * be true (which is the default)
1810         */
1811        public void setMarkResourcesForReindexingUponSearchParameterChange(boolean theMarkResourcesForReindexingUponSearchParameterChange) {
1812                myMarkResourcesForReindexingUponSearchParameterChange = theMarkResourcesForReindexingUponSearchParameterChange;
1813        }
1814
1815        public boolean isSchedulingDisabled() {
1816                return mySchedulingDisabled;
1817        }
1818
1819        public void setSchedulingDisabled(boolean theSchedulingDisabled) {
1820                mySchedulingDisabled = theSchedulingDisabled;
1821        }
1822
1823        /**
1824         * If set to {@literal true} (default is true), if a client performs an update which does not actually
1825         * result in any chance to a given resource (e.g. an update where the resource body matches the
1826         * existing resource body in the database) the operation will succeed but a new version (and corresponding history
1827         * entry) will not actually be created. The existing resource version will be returned to the client.
1828         * <p>
1829         * If set to {@literal false}, all updates will result in the creation of a new version
1830         * </p>
1831         */
1832        public boolean isSuppressUpdatesWithNoChange() {
1833                return mySuppressUpdatesWithNoChange;
1834        }
1835
1836        /**
1837         * If set to {@literal true} (default is true), if a client performs an update which does not actually
1838         * result in any chance to a given resource (e.g. an update where the resource body matches the
1839         * existing resource body in the database) the operation will succeed but a new version (and corresponding history
1840         * entry) will not actually be created. The existing resource version will be returned to the client.
1841         * <p>
1842         * If set to {@literal false}, all updates will result in the creation of a new version
1843         * </p>
1844         */
1845        public void setSuppressUpdatesWithNoChange(boolean theSuppressUpdatesWithNoChange) {
1846                mySuppressUpdatesWithNoChange = theSuppressUpdatesWithNoChange;
1847
1848        }
1849
1850        /**
1851         * When using {@link #setUniqueIndexesEnabled(boolean) unique indexes}, if this
1852         * setting is set to <code>true</code> (default is <code>true</code>) the system
1853         * will test for the existence of a particular unique index value prior to saving
1854         * a new one.
1855         * <p>
1856         * This causes friendlier error messages to be generated, but adds an
1857         * extra round-trip to the database for eavh save so it can cause
1858         * a small performance hit.
1859         * </p>
1860         */
1861        public boolean isUniqueIndexesCheckedBeforeSave() {
1862                return myUniqueIndexesCheckedBeforeSave;
1863        }
1864
1865        /**
1866         * When using {@link #setUniqueIndexesEnabled(boolean) unique indexes}, if this
1867         * setting is set to <code>true</code> (default is <code>true</code>) the system
1868         * will test for the existence of a particular unique index value prior to saving
1869         * a new one.
1870         * <p>
1871         * This causes friendlier error messages to be generated, but adds an
1872         * extra round-trip to the database for each save so it can cause
1873         * a small performance hit.
1874         * </p>
1875         */
1876        public void setUniqueIndexesCheckedBeforeSave(boolean theUniqueIndexesCheckedBeforeSave) {
1877                myUniqueIndexesCheckedBeforeSave = theUniqueIndexesCheckedBeforeSave;
1878        }
1879
1880        /**
1881         * If set to <code>true</code> (default is <code>true</code>), indexes will be
1882         * created for search parameters marked as {@link HapiExtensions#EXT_SP_UNIQUE}.
1883         * This is a HAPI FHIR specific extension which can be used to specify that no more than one
1884         * resource can exist which matches a given criteria, using a database constraint to
1885         * enforce this.
1886         */
1887        public boolean isUniqueIndexesEnabled() {
1888                return myUniqueIndexesEnabled;
1889        }
1890
1891        /**
1892         * If set to <code>true</code> (default is <code>true</code>), indexes will be
1893         * created for search parameters marked as {@link HapiExtensions#EXT_SP_UNIQUE}.
1894         * This is a HAPI FHIR specific extension which can be used to specify that no more than one
1895         * resource can exist which matches a given criteria, using a database constraint to
1896         * enforce this.
1897         */
1898        public void setUniqueIndexesEnabled(boolean theUniqueIndexesEnabled) {
1899                myUniqueIndexesEnabled = theUniqueIndexesEnabled;
1900        }
1901
1902        /**
1903         * If <code>true</code> (default is <code>true</code>), before allowing a
1904         * SearchParameter resource to be stored (create, update, etc.) the
1905         * expression will be performed against an empty resource to ensure that
1906         * the FHIRPath executor is able to process it.
1907         * <p>
1908         * This should proabably always be set to true, but is configurable
1909         * in order to support some unit tests.
1910         * </p>
1911         */
1912        public boolean isValidateSearchParameterExpressionsOnSave() {
1913                return myValidateSearchParameterExpressionsOnSave;
1914        }
1915
1916        /**
1917         * If <code>true</code> (default is <code>true</code>), before allowing a
1918         * SearchParameter resource to be stored (create, update, etc.) the
1919         * expression will be performed against an empty resource to ensure that
1920         * the FHIRPath executor is able to process it.
1921         * <p>
1922         * This should proabably always be set to true, but is configurable
1923         * in order to support some unit tests.
1924         * </p>
1925         */
1926        public void setValidateSearchParameterExpressionsOnSave(boolean theValidateSearchParameterExpressionsOnSave) {
1927                myValidateSearchParameterExpressionsOnSave = theValidateSearchParameterExpressionsOnSave;
1928        }
1929
1930        /**
1931         * This setting sets the number of search results to prefetch. For example, if this list
1932         * is set to [100, 1000, -1] then the server will initially load 100 results and not
1933         * attempt to load more. If the user requests subsequent page(s) of results and goes
1934         * past 100 results, the system will load the next 900 (up to the following threshold of 1000).
1935         * The system will progressively work through these thresholds.
1936         *
1937         * <p>
1938         * A threshold of -1 means to load all results. Note that if the final threshold is a
1939         * number other than <code>-1</code>, the system will never prefetch more than the
1940         * given number.
1941         * </p>
1942         */
1943        public List<Integer> getSearchPreFetchThresholds() {
1944                return mySearchPreFetchThresholds;
1945        }
1946
1947        /**
1948         * This setting sets the number of search results to prefetch. For example, if this list
1949         * is set to [100, 1000, -1] then the server will initially load 100 results and not
1950         * attempt to load more. If the user requests subsequent page(s) of results and goes
1951         * past 100 results, the system will load the next 900 (up to the following threshold of 1000).
1952         * The system will progressively work through these thresholds.
1953         *
1954         * <p>
1955         * A threshold of -1 means to load all results. Note that if the final threshold is a
1956         * number other than <code>-1</code>, the system will never prefetch more than the
1957         * given number.
1958         * </p>
1959         */
1960        public void setSearchPreFetchThresholds(List<Integer> thePreFetchThresholds) {
1961                Validate.isTrue(thePreFetchThresholds.size() > 0, "thePreFetchThresholds must not be empty");
1962                int last = 0;
1963                for (Integer nextInt : thePreFetchThresholds) {
1964                        Validate.isTrue(nextInt > 0 || nextInt == -1, nextInt + " is not a valid prefetch threshold");
1965                        Validate.isTrue(nextInt != last, "Prefetch thresholds must be sequential");
1966                        Validate.isTrue(nextInt > last || nextInt == -1, "Prefetch thresholds must be sequential");
1967                        Validate.isTrue(last != -1, "Prefetch thresholds must be sequential");
1968                        last = nextInt;
1969                }
1970                mySearchPreFetchThresholds = thePreFetchThresholds;
1971        }
1972
1973        /**
1974         * If set to <code>true</code> (default is false) the server will not use
1975         * hash based searches. These searches were introduced in HAPI FHIR 3.5.0
1976         * and are the new default way of searching. However they require a very
1977         * large data migration if an existing system has a large amount of data
1978         * so this setting can be used to use the old search mechanism while data
1979         * is migrated.
1980         *
1981         * @since 3.6.0
1982         */
1983        public boolean getDisableHashBasedSearches() {
1984                return myDisableHashBasedSearches;
1985        }
1986
1987        /**
1988         * If set to <code>true</code> (default is false) the server will not use
1989         * hash based searches. These searches were introduced in HAPI FHIR 3.5.0
1990         * and are the new default way of searching. However they require a very
1991         * large data migration if an existing system has a large amount of data
1992         * so this setting can be used to use the old search mechanism while data
1993         * is migrated.
1994         *
1995         * @since 3.6.0
1996         */
1997        public void setDisableHashBasedSearches(boolean theDisableHashBasedSearches) {
1998                myDisableHashBasedSearches = theDisableHashBasedSearches;
1999        }
2000
2001        /**
2002         * If set to <code>false</code> (default is true) the server will not use
2003         * in-memory subscription searching and instead use the database matcher for all subscription
2004         * criteria matching.
2005         * <p>
2006         * When there are subscriptions registered
2007         * on the server, the default behaviour is to compare the changed resource to the
2008         * subscription criteria directly in-memory without going out to the database.
2009         * Certain types of subscription criteria, e.g. chained references of queries with
2010         * qualifiers or prefixes, are not supported by the in-memory matcher and will fall back
2011         * to a database matcher.
2012         * <p>
2013         * The database matcher performs a query against the
2014         * database by prepending ?id=XYZ to the subscription criteria where XYZ is the id of the changed entity
2015         *
2016         * @since 3.6.1
2017         */
2018
2019        public boolean isEnableInMemorySubscriptionMatching() {
2020                return myEnableInMemorySubscriptionMatching;
2021        }
2022
2023        /**
2024         * If set to <code>false</code> (default is true) the server will not use
2025         * in-memory subscription searching and instead use the database matcher for all subscription
2026         * criteria matching.
2027         * <p>
2028         * When there are subscriptions registered
2029         * on the server, the default behaviour is to compare the changed resource to the
2030         * subscription criteria directly in-memory without going out to the database.
2031         * Certain types of subscription criteria, e.g. chained references of queries with
2032         * qualifiers or prefixes, are not supported by the in-memory matcher and will fall back
2033         * to a database matcher.
2034         * <p>
2035         * The database matcher performs a query against the
2036         * database by prepending ?id=XYZ to the subscription criteria where XYZ is the id of the changed entity
2037         *
2038         * @since 3.6.1
2039         */
2040
2041        public void setEnableInMemorySubscriptionMatching(boolean theEnableInMemorySubscriptionMatching) {
2042                myEnableInMemorySubscriptionMatching = theEnableInMemorySubscriptionMatching;
2043        }
2044
2045        public ModelConfig getModelConfig() {
2046                return myModelConfig;
2047        }
2048
2049        /**
2050         * If enabled, the server will support the use of :contains searches,
2051         * which are helpful but can have adverse effects on performance.
2052         * <p>
2053         * Default is <code>false</code> (Note that prior to HAPI FHIR
2054         * 3.5.0 the default was <code>true</code>)
2055         * </p>
2056         * <p>
2057         * Note: If you change this value after data already has
2058         * already been stored in the database, you must for a reindexing
2059         * of all data in the database or resources may not be
2060         * searchable.
2061         * </p>
2062         */
2063        public boolean isAllowContainsSearches() {
2064                return this.myModelConfig.isAllowContainsSearches();
2065        }
2066
2067        /**
2068         * If enabled, the server will support the use of :contains searches,
2069         * which are helpful but can have adverse effects on performance.
2070         * <p>
2071         * Default is <code>false</code> (Note that prior to HAPI FHIR
2072         * 3.5.0 the default was <code>true</code>)
2073         * </p>
2074         * <p>
2075         * Note: If you change this value after data already has
2076         * already been stored in the database, you must for a reindexing
2077         * of all data in the database or resources may not be
2078         * searchable.
2079         * </p>
2080         */
2081        public void setAllowContainsSearches(boolean theAllowContainsSearches) {
2082                this.myModelConfig.setAllowContainsSearches(theAllowContainsSearches);
2083        }
2084
2085        /**
2086         * If enabled, the server will support the use of :mdm search parameter qualifier on Reference Search Parameters.
2087         * This Parameter Qualifier is HAPI-specific, and not defined anywhere in the FHIR specification. Using this qualifier
2088         * will result in an MDM expansion being done on the reference, which will expand the search scope. For example, if Patient/1
2089         * is MDM-matched to Patient/2 and you execute the search:
2090         * Observation?subject:mdm=Patient/1 , you will receive observations for both Patient/1 and Patient/2.
2091         * <p>
2092         * Default is <code>false</code>
2093         * </p>
2094         *
2095         * @since 5.4.0
2096         */
2097        public boolean isAllowMdmExpansion() {
2098                return myModelConfig.isAllowMdmExpansion();
2099        }
2100
2101        /**
2102         * If enabled, the server will support the use of :mdm search parameter qualifier on Reference Search Parameters.
2103         * This Parameter Qualifier is HAPI-specific, and not defined anywhere in the FHIR specification. Using this qualifier
2104         * will result in an MDM expansion being done on the reference, which will expand the search scope. For example, if Patient/1
2105         * is MDM-matched to Patient/2 and you execute the search:
2106         * Observation?subject:mdm=Patient/1 , you will receive observations for both Patient/1 and Patient/2.
2107         * <p>
2108         * Default is <code>false</code>
2109         * </p>
2110         *
2111         * @since 5.4.0
2112         */
2113        public void setAllowMdmExpansion(boolean theAllowMdmExpansion) {
2114                myModelConfig.setAllowMdmExpansion(theAllowMdmExpansion);
2115        }
2116
2117        /**
2118         * This setting may be used to advise the server that any references found in
2119         * resources that have any of the base URLs given here will be replaced with
2120         * simple local references.
2121         * <p>
2122         * For example, if the set contains the value <code>http://example.com/base/</code>
2123         * and a resource is submitted to the server that contains a reference to
2124         * <code>http://example.com/base/Patient/1</code>, the server will automatically
2125         * convert this reference to <code>Patient/1</code>
2126         * </p>
2127         * <p>
2128         * Note that this property has different behaviour from {@link DaoConfig#getTreatReferencesAsLogical()}
2129         * </p>
2130         *
2131         * @see #getTreatReferencesAsLogical()
2132         */
2133        public Set<String> getTreatBaseUrlsAsLocal() {
2134                return myModelConfig.getTreatBaseUrlsAsLocal();
2135        }
2136
2137        /**
2138         * This setting may be used to advise the server that any references found in
2139         * resources that have any of the base URLs given here will be replaced with
2140         * simple local references.
2141         * <p>
2142         * For example, if the set contains the value <code>http://example.com/base/</code>
2143         * and a resource is submitted to the server that contains a reference to
2144         * <code>http://example.com/base/Patient/1</code>, the server will automatically
2145         * convert this reference to <code>Patient/1</code>
2146         * </p>
2147         *
2148         * @param theTreatBaseUrlsAsLocal The set of base URLs. May be <code>null</code>, which
2149         *                                means no references will be treated as external
2150         */
2151        public void setTreatBaseUrlsAsLocal(Set<String> theTreatBaseUrlsAsLocal) {
2152                myModelConfig.setTreatBaseUrlsAsLocal(theTreatBaseUrlsAsLocal);
2153        }
2154
2155        /**
2156         * If set to {@code true} the default search params (i.e. the search parameters that are
2157         * defined by the FHIR specification itself) may be overridden by uploading search
2158         * parameters to the server with the same code as the built-in search parameter.
2159         * <p>
2160         * This can be useful if you want to be able to disable or alter
2161         * the behaviour of the default search parameters.
2162         * </p>
2163         * <p>
2164         * The default value for this setting is {@code false}
2165         * </p>
2166         */
2167        public boolean isDefaultSearchParamsCanBeOverridden() {
2168                return myModelConfig.isDefaultSearchParamsCanBeOverridden();
2169        }
2170
2171        /**
2172         * If set to {@code true} the default search params (i.e. the search parameters that are
2173         * defined by the FHIR specification itself) may be overridden by uploading search
2174         * parameters to the server with the same code as the built-in search parameter.
2175         * <p>
2176         * This can be useful if you want to be able to disable or alter
2177         * the behaviour of the default search parameters.
2178         * </p>
2179         * <p>
2180         * The default value for this setting is {@code false}
2181         * </p>
2182         */
2183        public void setDefaultSearchParamsCanBeOverridden(boolean theDefaultSearchParamsCanBeOverridden) {
2184                myModelConfig.setDefaultSearchParamsCanBeOverridden(theDefaultSearchParamsCanBeOverridden);
2185        }
2186
2187        /**
2188         * This setting indicates which subscription channel types are supported by the server.  Any subscriptions submitted
2189         * to the server matching these types will be activated.
2190         */
2191        public DaoConfig addSupportedSubscriptionType(Subscription.SubscriptionChannelType theSubscriptionChannelType) {
2192                myModelConfig.addSupportedSubscriptionType(theSubscriptionChannelType);
2193                return this;
2194        }
2195
2196        /**
2197         * This setting indicates which subscription channel types are supported by the server.  Any subscriptions submitted
2198         * to the server matching these types will be activated.
2199         *
2200         * @see #addSupportedSubscriptionType(Subscription.SubscriptionChannelType)
2201         */
2202        public Set<Subscription.SubscriptionChannelType> getSupportedSubscriptionTypes() {
2203                return myModelConfig.getSupportedSubscriptionTypes();
2204        }
2205
2206        @VisibleForTesting
2207        public void clearSupportedSubscriptionTypesForUnitTest() {
2208                myModelConfig.clearSupportedSubscriptionTypesForUnitTest();
2209        }
2210
2211        /**
2212         * If e-mail subscriptions are supported, the From address used when sending e-mails
2213         */
2214
2215        public String getEmailFromAddress() {
2216                return myModelConfig.getEmailFromAddress();
2217        }
2218
2219        /**
2220         * If e-mail subscriptions are supported, the From address used when sending e-mails
2221         */
2222
2223        public void setEmailFromAddress(String theEmailFromAddress) {
2224                myModelConfig.setEmailFromAddress(theEmailFromAddress);
2225        }
2226
2227        /**
2228         * If websocket subscriptions are enabled, this defines the context path that listens to them.  Default value "/websocket".
2229         */
2230
2231        public String getWebsocketContextPath() {
2232                return myModelConfig.getWebsocketContextPath();
2233        }
2234
2235        /**
2236         * If websocket subscriptions are enabled, this defines the context path that listens to them.  Default value "/websocket".
2237         */
2238
2239        public void setWebsocketContextPath(String theWebsocketContextPath) {
2240                myModelConfig.setWebsocketContextPath(theWebsocketContextPath);
2241        }
2242
2243        /**
2244         * If set to <code>true</code> the _filter search parameter will be enabled on this server. Note that _filter
2245         * is very powerful, but also potentially dangerous as it can allow a user to create a query for which there
2246         * are no indexes or efficient query plans for the database to leverage while performing the query.
2247         * As a result, this feature is recommended only for servers where the querying applications are known in advance
2248         * and a database administrator can properly tune the database for the resulting queries.
2249         */
2250        public boolean isFilterParameterEnabled() {
2251                return myFilterParameterEnabled;
2252        }
2253
2254        /**
2255         * If set to <code>true</code> the _filter search parameter will be enabled on this server. Note that _filter
2256         * is very powerful, but also potentially dangerous as it can allow a user to create a query for which there
2257         * are no indexes or efficient query plans for the database to leverage while performing the query.
2258         * As a result, this feature is recommended only for servers where the querying applications are known in advance
2259         * and a database administrator can properly tune the database for the resulting queries.
2260         */
2261        public void setFilterParameterEnabled(boolean theFilterParameterEnabled) {
2262                myFilterParameterEnabled = theFilterParameterEnabled;
2263        }
2264
2265        /**
2266         * If enabled, resource source information (<code>Resource.meta.source</code>) will be persisted along with
2267         * each resource. This adds extra table and index space so it should be disabled if it is not being
2268         * used.
2269         * <p>
2270         * Default is {@link StoreMetaSourceInformationEnum#SOURCE_URI_AND_REQUEST_ID}
2271         * </p>
2272         */
2273        public StoreMetaSourceInformationEnum getStoreMetaSourceInformation() {
2274                return myStoreMetaSourceInformation;
2275        }
2276
2277        /**
2278         * If enabled, resource source information (<code>Resource.meta.source</code>) will be persisted along with
2279         * each resource. This adds extra table and index space so it should be disabled if it is not being
2280         * used.
2281         * <p>
2282         * Default is {@link StoreMetaSourceInformationEnum#SOURCE_URI_AND_REQUEST_ID}
2283         * </p>
2284         */
2285        public void setStoreMetaSourceInformation(StoreMetaSourceInformationEnum theStoreMetaSourceInformation) {
2286                Validate.notNull(theStoreMetaSourceInformation, "theStoreMetaSourceInformation must not be null");
2287                myStoreMetaSourceInformation = theStoreMetaSourceInformation;
2288        }
2289
2290        /**
2291         * <p>
2292         * If set to {@code true}, ValueSets and expansions are stored in terminology tables. This is to facilitate
2293         * optimization of the $expand operation on large ValueSets.
2294         * </p>
2295         * <p>
2296         * The default value for this setting is {@code true}.
2297         * </p>
2298         *
2299         * @since 4.1.0
2300         */
2301        public boolean isPreExpandValueSets() {
2302                return myPreExpandValueSets;
2303        }
2304
2305        /**
2306         * <p>
2307         * If set to {@code true}, ValueSets and expansions are stored in terminology tables. This is to facilitate
2308         * optimization of the $expand operation on large ValueSets.
2309         * </p>
2310         * <p>
2311         * The default value for this setting is {@code true}.
2312         * </p>
2313         *
2314         * @since 4.1.0
2315         */
2316        public void setPreExpandValueSets(boolean thePreExpandValueSets) {
2317                myPreExpandValueSets = thePreExpandValueSets;
2318        }
2319
2320        /**
2321         * <p>
2322         * This is the default value of {@code offset} parameter for the ValueSet {@code $expand} operation when
2323         * {@link DaoConfig#isPreExpandValueSets()} returns {@code true}.
2324         * </p>
2325         * <p>
2326         * The default value for this setting is {@code 0}.
2327         * </p>
2328         *
2329         * @since 4.1.0
2330         */
2331        public int getPreExpandValueSetsDefaultOffset() {
2332                return myPreExpandValueSetsDefaultOffset;
2333        }
2334
2335        /**
2336         * <p>
2337         * This is the default value of {@code count} parameter for the ValueSet {@code $expand} operation when
2338         * {@link DaoConfig#isPreExpandValueSets()} returns {@code true}.
2339         * </p>
2340         * <p>
2341         * The default value for this setting is {@code 1000}.
2342         * </p>
2343         *
2344         * @since 4.1.0
2345         */
2346        public int getPreExpandValueSetsDefaultCount() {
2347                return myPreExpandValueSetsDefaultCount;
2348        }
2349
2350        /**
2351         * <p>
2352         * This is the default value of {@code count} parameter for the ValueSet {@code $expand} operation when
2353         * {@link DaoConfig#isPreExpandValueSets()} returns {@code true}.
2354         * </p>
2355         * <p>
2356         * If {@code thePreExpandValueSetsDefaultCount} is greater than
2357         * {@link DaoConfig#getPreExpandValueSetsMaxCount()}, the lesser value is used.
2358         * </p>
2359         * <p>
2360         * The default value for this setting is {@code 1000}.
2361         * </p>
2362         *
2363         * @since 4.1.0
2364         */
2365        public void setPreExpandValueSetsDefaultCount(int thePreExpandValueSetsDefaultCount) {
2366                myPreExpandValueSetsDefaultCount = Math.min(thePreExpandValueSetsDefaultCount, getPreExpandValueSetsMaxCount());
2367        }
2368
2369        /**
2370         * <p>
2371         * This is the max value of {@code count} parameter for the ValueSet {@code $expand} operation when
2372         * {@link DaoConfig#isPreExpandValueSets()} returns {@code true}.
2373         * </p>
2374         * <p>
2375         * The default value for this setting is {@code 1000}.
2376         * </p>
2377         *
2378         * @since 4.1.0
2379         */
2380        public int getPreExpandValueSetsMaxCount() {
2381                return myPreExpandValueSetsMaxCount;
2382        }
2383
2384        /**
2385         * <p>
2386         * This is the max value of {@code count} parameter for the ValueSet {@code $expand} operation when
2387         * {@link DaoConfig#isPreExpandValueSets()} returns {@code true}.
2388         * </p>
2389         * <p>
2390         * If {@code thePreExpandValueSetsMaxCount} is lesser than
2391         * {@link DaoConfig#getPreExpandValueSetsDefaultCount()}, the default {@code count} is lowered to the
2392         * new max {@code count}.
2393         * </p>
2394         * <p>
2395         * The default value for this setting is {@code 1000}.
2396         * </p>
2397         *
2398         * @since 4.1.0
2399         */
2400        public void setPreExpandValueSetsMaxCount(int thePreExpandValueSetsMaxCount) {
2401                myPreExpandValueSetsMaxCount = thePreExpandValueSetsMaxCount;
2402                setPreExpandValueSetsDefaultCount(Math.min(getPreExpandValueSetsDefaultCount(), getPreExpandValueSetsMaxCount()));
2403        }
2404
2405        /**
2406         * This setting should be disabled (set to <code>false</code>) on servers that are not allowing
2407         * deletes. Default is <code>true</code>. If deletes are disabled, some checks for resource
2408         * deletion can be skipped, which improves performance. This is particularly helpful when large
2409         * amounts of data containing client-assigned IDs are being loaded, but it can also improve
2410         * search performance.
2411         *
2412         * @since 5.0.0
2413         */
2414        public boolean isDeleteEnabled() {
2415                return myDeleteEnabled;
2416        }
2417
2418        /**
2419         * This setting should be disabled (set to <code>false</code>) on servers that are not allowing
2420         * deletes. Default is <code>true</code>. If deletes are disabled, some checks for resource
2421         * deletion can be skipped, which improves performance. This is particularly helpful when large
2422         * amounts of data containing client-assigned IDs are being loaded, but it can also improve
2423         * search performance.
2424         *
2425         * @since 5.0.0
2426         */
2427        public void setDeleteEnabled(boolean theDeleteEnabled) {
2428                myDeleteEnabled = theDeleteEnabled;
2429        }
2430
2431        /**
2432         * <p>
2433         * This determines the maximum number of conflicts that should be fetched and handled while retrying a delete of a resource.
2434         * </p>
2435         * <p>
2436         * The default value for this setting is {@code 60}.
2437         * </p>
2438         *
2439         * @since 5.1.0
2440         */
2441        public Integer getMaximumDeleteConflictQueryCount() {
2442                return myMaximumDeleteConflictQueryCount;
2443        }
2444
2445        /**
2446         * <p>
2447         * This determines the maximum number of conflicts that should be fetched and handled while retrying a delete of a resource.
2448         * </p>
2449         * <p>
2450         * The default value for this setting is {@code 60}.
2451         * </p>
2452         *
2453         * @since 5.1.0
2454         */
2455        public void setMaximumDeleteConflictQueryCount(Integer theMaximumDeleteConflictQueryCount) {
2456                myMaximumDeleteConflictQueryCount = theMaximumDeleteConflictQueryCount;
2457        }
2458
2459        /**
2460         * <p>
2461         * This determines whether $binary-access-write operations should first load the InputStream into memory before persisting the
2462         * contents to the database. This needs to be enabled for MS SQL Server as this DB requires that the blob size be known
2463         * in advance.
2464         * </p>
2465         * <p>
2466         * Note that this setting should be enabled with caution as it can lead to significant demands on memory.
2467         * </p>
2468         * <p>
2469         * The default value for this setting is {@code false}.
2470         * </p>
2471         *
2472         * @since 5.1.0
2473         * @deprecated In 5.2.0 this setting no longer does anything
2474         */
2475        @Deprecated
2476        public void setPreloadBlobFromInputStream(Boolean thePreloadBlobFromInputStream) {
2477                // ignore
2478        }
2479
2480        /**
2481         * <p>
2482         * This determines the internal search size that is run synchronously during operations such as searching for
2483         * Code System IDs by System and Code
2484         * </p>
2485         *
2486         * @since 5.4.0
2487         */
2488        public Integer getInternalSynchronousSearchSize() {
2489                return myInternalSynchronousSearchSize;
2490        }
2491
2492        /**
2493         * <p>
2494         * This determines the internal search size that is run synchronously during operations such as searching for
2495         * Code System IDs by System and Code
2496         * </p>
2497         *
2498         * @since 5.4.0
2499         */
2500        public void setInternalSynchronousSearchSize(Integer theInternalSynchronousSearchSize) {
2501                myInternalSynchronousSearchSize = theInternalSynchronousSearchSize;
2502        }
2503
2504
2505        /**
2506         * If this is enabled (this is the default), this server will attempt to activate and run <b>Bulk Import</b>
2507         * batch jobs. Otherwise, this server will not.
2508         *
2509         * @since 5.5.0
2510         */
2511        public boolean isEnableTaskBulkImportJobExecution() {
2512                return myEnableTaskBulkImportJobExecution;
2513        }
2514
2515        /**
2516         * If this is enabled (this is the default), this server will attempt to activate and run <b>Bulk Import</b>
2517         * batch jobs. Otherwise, this server will not.
2518         *
2519         * @since 5.5.0
2520         */
2521        public void setEnableTaskBulkImportJobExecution(boolean theEnableTaskBulkImportJobExecution) {
2522                myEnableTaskBulkImportJobExecution = theEnableTaskBulkImportJobExecution;
2523        }
2524
2525        /**
2526         * If this is enabled (this is the default), this server will attempt to activate and run <b>Bulk Export</b>
2527         * batch jobs. Otherwise, this server will not.
2528         *
2529         * @since 5.5.0
2530         */
2531        public boolean isEnableTaskBulkExportJobExecution() {
2532                return myEnableTaskBulkExportJobExecution;
2533        }
2534
2535        /**
2536         * If this is enabled (this is the default), this server will attempt to activate and run <b>Bulk Export</b>
2537         * batch jobs. Otherwise, this server will not.
2538         *
2539         * @since 5.5.0
2540         */
2541        public void setEnableTaskBulkExportJobExecution(boolean theEnableTaskBulkExportJobExecution) {
2542                myEnableTaskBulkExportJobExecution = theEnableTaskBulkExportJobExecution;
2543        }
2544
2545        /**
2546         * If this is enabled (this is the default), this server will attempt to pre-expand any ValueSets that
2547         * have been uploaded and are not yet pre-expanded. Otherwise, this server will not.
2548         *
2549         * @since 5.5.0
2550         */
2551        public boolean isEnableTaskPreExpandValueSets() {
2552                return myEnableTaskPreExpandValueSets;
2553        }
2554
2555        /**
2556         * If this is enabled (this is the default), this server will attempt to pre-expand any ValueSets that
2557         * have been uploaded and are not yet pre-expanded. Otherwise, this server will not.
2558         *
2559         * @since 5.5.0
2560         */
2561        public void setEnableTaskPreExpandValueSets(boolean theEnableTaskPreExpandValueSets) {
2562                myEnableTaskPreExpandValueSets = theEnableTaskPreExpandValueSets;
2563        }
2564
2565        /**
2566         * If this is enabled (this is the default), this server will periodically scan for and try to delete
2567         * stale searches in the database. Otherwise, this server will not.
2568         *
2569         * @since 5.5.0
2570         */
2571        public boolean isEnableTaskStaleSearchCleanup() {
2572                return myEnableTaskStaleSearchCleanup;
2573        }
2574
2575        /**
2576         * If this is enabled (this is the default), this server will periodically scan for and try to delete
2577         * stale searches in the database. Otherwise, this server will not.
2578         *
2579         * @since 5.5.0
2580         */
2581        public void setEnableTaskStaleSearchCleanup(boolean theEnableTaskStaleSearchCleanup) {
2582                myEnableTaskStaleSearchCleanup = theEnableTaskStaleSearchCleanup;
2583        }
2584
2585        /**
2586         * If this is enabled (this is the default), this server will attempt to run resource reindexing jobs.
2587         * Otherwise, this server will not.
2588         *
2589         * @since 5.5.0
2590         */
2591        public boolean isEnableTaskResourceReindexing() {
2592                return myEnableTaskResourceReindexing;
2593        }
2594
2595        /**
2596         * If this is enabled (this is the default), this server will attempt to run resource reindexing jobs.
2597         * Otherwise, this server will not.
2598         *
2599         * @since 5.5.0
2600         */
2601        public void setEnableTaskResourceReindexing(boolean theEnableTaskResourceReindexing) {
2602                myEnableTaskResourceReindexing = theEnableTaskResourceReindexing;
2603        }
2604
2605        /**
2606         * If this is enabled (disabled by default), Mass Ingestion Mode is enabled. In this mode, a number of
2607         * runtime checks are disabled. This mode is designed for rapid backloading of data while the system is not
2608         * being otherwise used.
2609         * <p>
2610         * In this mode:
2611         * <p>
2612         * - Tags/Profiles/Security Labels will not be updated on existing resources that already have them
2613         * - Resources modification checks will be skipped in favour of a simple hash check
2614         * - Extra resource ID caching is enabled
2615         *
2616         * @since 5.5.0
2617         */
2618        public boolean isMassIngestionMode() {
2619                return myMassIngestionMode;
2620        }
2621
2622        /**
2623         * If this is enabled (disabled by default), Mass Ingestion Mode is enabled. In this mode, a number of
2624         * runtime checks are disabled. This mode is designed for rapid backloading of data while the system is not
2625         * being otherwise used.
2626         * <p>
2627         * In this mode:
2628         * <p>
2629         * - Tags/Profiles/Security Labels will not be updated on existing resources that already have them
2630         * - Resources modification checks will be skipped in favour of a simple hash check
2631         * - Extra resource ID caching is enabled
2632         *
2633         * @since 5.5.0
2634         */
2635        public void setMassIngestionMode(boolean theMassIngestionMode) {
2636                myMassIngestionMode = theMassIngestionMode;
2637        }
2638
2639        /**
2640         * If set to true (default is false), date indexes will account for null values in the range columns. As of 5.3.0
2641         * we no longer place null values in these columns, but legacy data may exist that still has these values. Note that
2642         * enabling this results in more complexity in the search SQL.
2643         *
2644         * @since 5.5.0
2645         */
2646        public boolean isAccountForDateIndexNulls() {
2647                return myAccountForDateIndexNulls;
2648        }
2649
2650        /**
2651         * If set to true (default is false), date indexes will account for null values in the range columns. As of 5.3.0
2652         * we no longer place null values in these columns, but legacy data may exist that still has these values. Note that
2653         * enabling this results in more complexity in the search SQL.
2654         *
2655         * @since 5.5.0
2656         */
2657        public void setAccountForDateIndexNulls(boolean theAccountForDateIndexNulls) {
2658                myAccountForDateIndexNulls = theAccountForDateIndexNulls;
2659        }
2660
2661        /**
2662         * If set to true (default is false) then subscriptions will be triggered for resource updates even if they
2663         * do not trigger a new version (e.g. $meta-add and $meta-delete).
2664         *
2665         * @since 5.5.0
2666         */
2667        public boolean isTriggerSubscriptionsForNonVersioningChanges() {
2668                return myTriggerSubscriptionsForNonVersioningChanges;
2669        }
2670
2671        /**
2672         * If set to true (default is false) then subscriptions will be triggered for resource updates even if they
2673         * do not trigger a new version (e.g. $meta-add and $meta-delete).
2674         *
2675         * @since 5.5.0
2676         */
2677        public void setTriggerSubscriptionsForNonVersioningChanges(boolean theTriggerSubscriptionsForNonVersioningChanges) {
2678                myTriggerSubscriptionsForNonVersioningChanges = theTriggerSubscriptionsForNonVersioningChanges;
2679        }
2680
2681        /**
2682         * Get the batch transaction thread pool size.
2683         *
2684         * @since 5.6.0
2685         */
2686        public Integer getBundleBatchPoolSize() {
2687                return myBundleBatchPoolSize;
2688        }
2689
2690        /**
2691         * Set the batch transaction thread pool size. The default is @see {@link #DEFAULT_BUNDLE_BATCH_POOL_SIZE}
2692         * set pool size to 1 for single thread
2693         *
2694         * @since 5.6.0
2695         */
2696        public void setBundleBatchPoolSize(Integer theBundleBatchPoolSize) {
2697                this.myBundleBatchPoolSize = theBundleBatchPoolSize;
2698        }
2699
2700        /**
2701         * Get the batch transaction thread max pool size.
2702         * set max pool size to 1 for single thread
2703         *
2704         * @since 5.6.0
2705         */
2706        public Integer getBundleBatchMaxPoolSize() {
2707                return myBundleBatchMaxPoolSize;
2708        }
2709
2710        /**
2711         * Set the batch transaction thread pool size. The default is @see {@link #DEFAULT_BUNDLE_BATCH_MAX_POOL_SIZE}
2712         *
2713         * @since 5.6.0
2714         */
2715        public void setBundleBatchMaxPoolSize(Integer theBundleBatchMaxPoolSize) {
2716                this.myBundleBatchMaxPoolSize = theBundleBatchMaxPoolSize;
2717        }
2718
2719        public boolean canDeleteExpunge() {
2720                return isAllowMultipleDelete() && isExpungeEnabled() && isDeleteExpungeEnabled();
2721        }
2722
2723        public String cannotDeleteExpungeReason() {
2724                List<String> reasons = new ArrayList<>();
2725                if (!isAllowMultipleDelete()) {
2726                        reasons.add("Multiple Delete");
2727                }
2728                if (!isExpungeEnabled()) {
2729                        reasons.add("Expunge");
2730                }
2731                if (!isDeleteExpungeEnabled()) {
2732                        reasons.add("Delete Expunge");
2733                }
2734                String retval = "Delete Expunge is not supported on this server.  ";
2735                if (reasons.size() == 1) {
2736                        retval += reasons.get(0) + " is disabled.";
2737                } else {
2738                        retval += "The following configurations are disabled: " + StringUtils.join(reasons, ", ");
2739                }
2740                return retval;
2741        }
2742
2743        /**
2744         * Sets a prefix for any indexes created when interacting with hsearch. This will apply to fulltext search indexes
2745         * and terminology expansion indexes.
2746         *
2747         * @since 5.6.0
2748         */
2749        public String getHSearchIndexPrefix() {
2750                return myHSearchIndexPrefix;
2751        }
2752
2753        /**
2754         * Sets a prefix for any indexes created when interacting with hsearch. This will apply to fulltext search indexes
2755         * and terminology expansion indexes.
2756         *
2757         * @since 5.6.0
2758         */
2759        public void setHSearchIndexPrefix(String thePrefix) {
2760                myHSearchIndexPrefix = thePrefix;
2761        }
2762
2763        /**
2764         * Is HSearch indexing enabled beyond _contains or _text?
2765         *
2766         * @since 5.6.0
2767         */
2768        public boolean isAdvancedHSearchIndexing() {
2769                return myAdvancedHSearchIndexing;
2770        }
2771
2772        /**
2773         * Enable/disable HSearch indexing enabled beyond _contains or _text.
2774         * <p>
2775         * String, token, and reference parameters can be indexed in HSearch.
2776         * This extends token search to support :text searches, as well as supporting
2777         * :contains and :text on string parameters.
2778         *
2779         * @since 5.6.0
2780         */
2781        public void setAdvancedHSearchIndexing(boolean theAdvancedHSearchIndexing) {
2782                this.myAdvancedHSearchIndexing = theAdvancedHSearchIndexing;
2783        }
2784
2785        /**
2786         * Is storing of Resource in HSearch index enabled?
2787         *
2788         * @since 5.7.0
2789         */
2790        public boolean isStoreResourceInHSearchIndex() {
2791                return myStoreResourceInHSearchIndex;
2792        }
2793
2794        /**
2795         * <p>
2796         * Enable Resource to be stored inline with HSearch index mappings.
2797         * This is useful in cases where after performing a search operation the resulting resource identifiers don't have to be
2798         * looked up in the persistent storage, but rather the inline stored resource can be used instead.
2799         * </p>
2800         * <p>
2801         * For e.g - Storing Observation resource in HSearch index would be useful when performing
2802         * <a href="https://www.hl7.org/fhir/observation-operation-lastn.html">$lastn</a> operation.
2803         * </p>
2804         *
2805         * @since 5.7.0
2806         */
2807        public void setStoreResourceInHSearchIndex(boolean theStoreResourceInHSearchIndex) {
2808                myStoreResourceInHSearchIndex = theStoreResourceInHSearchIndex;
2809        }
2810
2811        /**
2812         * @see FhirValidator#isConcurrentBundleValidation()
2813         * @since 5.7.0
2814         */
2815        public boolean isConcurrentBundleValidation() {
2816                return myConcurrentBundleValidation;
2817        }
2818
2819        /**
2820         * @see FhirValidator#isConcurrentBundleValidation()
2821         * @since 5.7.0
2822         */
2823        public DaoConfig setConcurrentBundleValidation(boolean theConcurrentBundleValidation) {
2824                myConcurrentBundleValidation = theConcurrentBundleValidation;
2825                return this;
2826        }
2827
2828        /**
2829         * This setting indicates if a cross-partition subscription can be made.
2830         *
2831         * @see ModelConfig#setCrossPartitionSubscription(boolean)
2832         * @since 7.5.0
2833         */
2834        public boolean isCrossPartitionSubscriptionEnabled() {
2835                return this.myModelConfig.isCrossPartitionSubscription();
2836        }
2837
2838        /**
2839         * This setting indicates if a cross-partition subscription can be made.
2840         *
2841         * @see ModelConfig#setCrossPartitionSubscription(boolean)
2842         * @since 5.7.0
2843         */
2844        public void setCrossPartitionSubscription(boolean theAllowCrossPartitionSubscription) {
2845                this.myModelConfig.setCrossPartitionSubscription(theAllowCrossPartitionSubscription);
2846        }
2847
2848
2849        /**
2850         *
2851         * This setting indicates whether binaries are allowed to be automatically inflated from external storage during requests.
2852         * Default is true.
2853         *
2854         * @since 6.0.0
2855         * @return whether binaries are allowed to be automatically inflated from external storage during requests.
2856         */
2857        public boolean isAllowAutoInflateBinaries() {
2858                return myAllowAutoInflateBinaries;
2859        }
2860
2861
2862        /**
2863         * This setting indicates whether binaries are allowed to be automatically inflated from external storage during requests.
2864         * Default is true.
2865         *
2866         * @since 6.0.0
2867         * @param theAllowAutoDeExternalizingBinaries the value to set.
2868         */
2869        public void setAllowAutoInflateBinaries(boolean theAllowAutoDeExternalizingBinaries) {
2870                myAllowAutoInflateBinaries = theAllowAutoDeExternalizingBinaries;
2871        }
2872
2873        /**
2874         * This setting controls how many bytes of binaries will be automatically inflated from external storage during requests.
2875         * which contain binary data.
2876         * Default is 10MB
2877         *
2878         * @since 6.0.0
2879         * @param theAutoInflateBinariesMaximumBytes the maximum number of bytes to de-externalize.
2880         */
2881        public void setAutoInflateBinariesMaximumBytes(long theAutoInflateBinariesMaximumBytes) {
2882                myAutoInflateBinariesMaximumBytes = theAutoInflateBinariesMaximumBytes;
2883        }
2884
2885        /**
2886         * This setting controls how many bytes of binaries will be automatically inflated from external storage during requests.
2887         * which contain binary data.
2888         * Default is 10MB
2889         *
2890         * @since 6.0.0
2891         * @return the number of bytes to de-externalize during requests.
2892         */
2893        public long getAutoInflateBinariesMaximumBytes() {
2894                return myAutoInflateBinariesMaximumBytes;
2895        }
2896
2897
2898        /**
2899         * This setting controls how long Bulk Export collection entities will be retained after job start.
2900         * Default is 2 hours. Setting this value to 0 or less will cause Bulk Export collection entities to never be expired.
2901         *
2902         * @since 6.0.0
2903         */
2904    public int getBulkExportFileRetentionPeriodHours() {
2905        return myBulkExportFileRetentionPeriodHours;
2906         }
2907
2908        /**
2909         * This setting controls how long Bulk Export collection entities will be retained after job start.
2910         * Default is 2 hours. Setting this value to 0 or less will cause Bulk Export collection entities to never be expired.
2911         *
2912         * @since 6.0.0
2913         */
2914        public void setBulkExportFileRetentionPeriodHours(int theBulkExportFileRetentionPeriodHours) {
2915                myBulkExportFileRetentionPeriodHours = theBulkExportFileRetentionPeriodHours;
2916        }
2917
2918        /**
2919         * This setting controls whether, upon receiving a request for an $export operation, if a batch job already exists
2920         * that exactly matches the new request, the system should attempt to reuse the batch job. Default is true.
2921         */
2922        public boolean getEnableBulkExportJobReuse() {
2923                return myEnableBulkExportJobReuse;
2924        }
2925
2926        /**
2927         * This setting controls whether, upon receiving a request for an $export operation, if a batch job already exists
2928         * that exactly matches the new request, the system should attempt to reuse the batch job. Default is true.
2929         */
2930        public void setEnableBulkExportJobReuse(boolean theEnableBulkExportJobReuse) {
2931                myEnableBulkExportJobReuse = theEnableBulkExportJobReuse;
2932        }
2933
2934        /**
2935         * This setting indicates whether updating the history of a resource is allowed.
2936         * Default is false.
2937         *
2938         * @since 6.1.0
2939         */
2940        public boolean isUpdateWithHistoryRewriteEnabled() {
2941                return myUpdateWithHistoryRewriteEnabled;
2942        }
2943
2944        /**
2945         * This setting indicates whether updating the history of a resource is allowed.
2946         * Default is false.
2947         *
2948         * @since 6.1.0
2949         */
2950        public void setUpdateWithHistoryRewriteEnabled(boolean theUpdateWithHistoryRewriteEnabled) {
2951                myUpdateWithHistoryRewriteEnabled = theUpdateWithHistoryRewriteEnabled;
2952        }
2953
2954        /**
2955         * This setting indicate whether a providedResource.meta.source requestID (source#requestID)
2956         * should be preserved or overwritten.
2957         *
2958         * @since 6.2.0
2959         */
2960        public boolean isPreserveRequestIdInResourceBody() {
2961                return myPreserveRequestIdInResourceBody;
2962        }
2963
2964        /**
2965         * This setting indicate whether a providedResource.meta.source requestID (source#requestID)
2966         * should be preserved or overwritten.
2967         * Default is false. This means that a client provided requestId will be overwritten.
2968         *
2969         * @since 6.2.0
2970         */
2971        public void setPreserveRequestIdInResourceBody(boolean thePreserveRequestIdInResourceBody) {
2972                myPreserveRequestIdInResourceBody = thePreserveRequestIdInResourceBody;
2973        }
2974
2975        /**
2976         * This setting controls how many resources will be stored in each binary file created by a bulk export.
2977         * Default is 1000 resources per file.
2978         *
2979         * @since 6.2.0
2980         */
2981        public int getBulkExportFileMaximumCapacity() {
2982                return myBulkExportFileMaximumCapacity;
2983        }
2984
2985        /**
2986         * This setting controls how many resources will be stored in each binary file created by a bulk export.
2987         * Default is 1000 resources per file.
2988         *
2989         * @since 6.2.0
2990         */
2991        public void setBulkExportFileMaximumCapacity(int theBulkExportFileMaximumCapacity) {
2992                myBulkExportFileMaximumCapacity = theBulkExportFileMaximumCapacity;
2993        }
2994
2995        /**
2996         * If this setting is enabled, then gated batch jobs that produce only one chunk will immediately trigger a batch
2997         * maintenance job.  This may be useful for testing, but is not recommended for production use.
2998         *
2999         * @since 6.4.0
3000         */
3001        public boolean isJobFastTrackingEnabled() {
3002                return myJobFastTrackingEnabled;
3003        }
3004
3005        /**
3006         * If this setting is enabled, then gated batch jobs that produce only one chunk will immediately trigger a batch
3007         * maintenance job.  This may be useful for testing, but is not recommended for production use.
3008         *
3009         * @since 6.4.0
3010         */
3011        public void setJobFastTrackingEnabled(boolean theJobFastTrackingEnabled) {
3012                myJobFastTrackingEnabled = theJobFastTrackingEnabled;
3013        }
3014
3015        public enum StoreMetaSourceInformationEnum {
3016                NONE(false, false),
3017                SOURCE_URI(true, false),
3018                REQUEST_ID(false, true),
3019                SOURCE_URI_AND_REQUEST_ID(true, true);
3020
3021                private final boolean myStoreSourceUri;
3022                private final boolean myStoreRequestId;
3023
3024                StoreMetaSourceInformationEnum(boolean theStoreSourceUri, boolean theStoreRequestId) {
3025                        myStoreSourceUri = theStoreSourceUri;
3026                        myStoreRequestId = theStoreRequestId;
3027                }
3028
3029                public boolean isStoreSourceUri() {
3030                        return myStoreSourceUri;
3031                }
3032
3033                public boolean isStoreRequestId() {
3034                        return myStoreRequestId;
3035                }
3036        }
3037
3038
3039        public enum IndexEnabledEnum {
3040                ENABLED,
3041                DISABLED
3042        }
3043
3044        /**
3045         * This enum provides allowable options for {@link #setResourceServerIdStrategy(IdStrategyEnum)}
3046         */
3047        public enum IdStrategyEnum {
3048                /**
3049                 * This strategy is the default strategy, and it simply uses a sequential
3050                 * numeric ID for each newly created resource.
3051                 */
3052                SEQUENTIAL_NUMERIC,
3053                /**
3054                 * Each resource will receive a randomly generated UUID
3055                 */
3056                UUID
3057        }
3058
3059        /**
3060         * This enum provides allowable options for {@link #setResourceClientIdStrategy(ClientIdStrategyEnum)}
3061         */
3062        public enum ClientIdStrategyEnum {
3063                /**
3064                 * Clients are not allowed to supply IDs for resources that do not
3065                 * already exist
3066                 */
3067                NOT_ALLOWED,
3068
3069                /**
3070                 * Clients may supply IDs but these IDs are not permitted to be purely
3071                 * numeric. In other words, values such as "A", "A1" and "000A" would be considered
3072                 * valid but "123" would not.
3073                 * <p><b>This is the default setting.</b></p>
3074                 */
3075                ALPHANUMERIC,
3076
3077                /**
3078                 * Clients may supply any ID including purely numeric IDs. Note that this setting should
3079                 * only be set on an empty database, or on a database that has always had this setting
3080                 * set as it causes a "forced ID" to be used for all resources.
3081                 * <p>
3082                 * Note that if you use this setting, it is highly recommended that you also
3083                 * set the {@link #setResourceServerIdStrategy(IdStrategyEnum) ResourceServerIdStrategy}
3084                 * to {@link IdStrategyEnum#UUID} in order to avoid any potential for conflicts. Otherwise
3085                 * a database sequence will be used to generate IDs and these IDs can conflict with
3086                 * client-assigned numeric IDs.
3087                 * </p>
3088                 */
3089                ANY
3090        }
3091
3092        public enum TagStorageModeEnum {
3093
3094                /**
3095                 * A separate set of tags is stored for each resource version
3096                 */
3097                VERSIONED,
3098
3099                /**
3100                 * A single set of tags is shared by all resource versions
3101                 */
3102                NON_VERSIONED,
3103
3104                /**
3105                 * Tags are stored directly in the resource body (in the {@link ResourceHistoryTable}
3106                 * entry for the resource, meaning that they are not indexed separately, and are versioned with the rest
3107                 * of the resource.
3108                 */
3109                INLINE
3110
3111        }
3112}