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