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