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