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