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