
001package ca.uhn.fhir.jpa.api.config; 002 003import ca.uhn.fhir.jpa.api.model.WarmCacheEntry; 004import ca.uhn.fhir.jpa.model.entity.ModelConfig; 005import ca.uhn.fhir.jpa.model.entity.ResourceEncodingEnum; 006import ca.uhn.fhir.rest.api.SearchTotalModeEnum; 007import ca.uhn.fhir.util.HapiExtensions; 008import com.google.common.annotations.VisibleForTesting; 009import com.google.common.collect.Sets; 010import org.apache.commons.lang3.Validate; 011import org.apache.commons.lang3.time.DateUtils; 012import org.hl7.fhir.dstu2.model.Subscription; 013import org.hl7.fhir.r4.model.Bundle; 014import org.slf4j.Logger; 015import org.slf4j.LoggerFactory; 016 017import java.util.ArrayList; 018import java.util.Arrays; 019import java.util.Collections; 020import java.util.List; 021import java.util.Set; 022import java.util.TreeSet; 023 024/* 025 * #%L 026 * HAPI FHIR JPA API 027 * %% 028 * Copyright (C) 2014 - 2021 Smile CDR, Inc. 029 * %% 030 * Licensed under the Apache License, Version 2.0 (the "License"); 031 * you may not use this file except in compliance with the License. 032 * You may obtain a copy of the License at 033 * 034 * http://www.apache.org/licenses/LICENSE-2.0 035 * 036 * Unless required by applicable law or agreed to in writing, software 037 * distributed under the License is distributed on an "AS IS" BASIS, 038 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 039 * See the License for the specific language governing permissions and 040 * limitations under the License. 041 * #L% 042 */ 043 044public class DaoConfig { 045 046 /** 047 * Default value for {@link #setReuseCachedSearchResultsForMillis(Long)}: 60000ms (one minute) 048 */ 049 public static final Long DEFAULT_REUSE_CACHED_SEARCH_RESULTS_FOR_MILLIS = DateUtils.MILLIS_PER_MINUTE; 050 /** 051 * Default value for {@link #setTranslationCachesExpireAfterWriteInMinutes(Long)}: 60 minutes 052 * 053 * @see #setTranslationCachesExpireAfterWriteInMinutes(Long) 054 */ 055 public static final Long DEFAULT_TRANSLATION_CACHES_EXPIRE_AFTER_WRITE_IN_MINUTES = 60L; 056 /** 057 * See {@link #setStatusBasedReindexingDisabled(boolean)} 058 */ 059 public static final String DISABLE_STATUS_BASED_REINDEX = "disable_status_based_reindex"; 060 /** 061 * Default {@link #setBundleTypesAllowedForStorage(Set)} value: 062 * <ul> 063 * <li>collection</li> 064 * <li>document</li> 065 * <li>message</li> 066 * </ul> 067 */ 068 @SuppressWarnings("WeakerAccess") 069 public static final Set<String> DEFAULT_BUNDLE_TYPES_ALLOWED_FOR_STORAGE = Collections.unmodifiableSet(new TreeSet<>(Sets.newHashSet( 070 Bundle.BundleType.COLLECTION.toCode(), 071 Bundle.BundleType.DOCUMENT.toCode(), 072 Bundle.BundleType.MESSAGE.toCode() 073 ))); 074 // update setter javadoc if default changes 075 public static final int DEFAULT_MAX_EXPANSION_SIZE = 1000; 076 /** 077 * Default value for {@link #setMaximumSearchResultCountInTransaction(Integer)} 078 * 079 * @see #setMaximumSearchResultCountInTransaction(Integer) 080 */ 081 private static final Integer DEFAULT_MAXIMUM_SEARCH_RESULT_COUNT_IN_TRANSACTION = null; 082 private static final Integer DEFAULT_MAXIMUM_TRANSACTION_BUNDLE_SIZE = null; 083 private static final Logger ourLog = LoggerFactory.getLogger(DaoConfig.class); 084 private static final int DEFAULT_EXPUNGE_BATCH_SIZE = 800; 085 private static final int DEFAULT_MAXIMUM_DELETE_CONFLICT_COUNT = 60; 086 private IndexEnabledEnum myIndexMissingFieldsEnabled = IndexEnabledEnum.DISABLED; 087 /** 088 * Child Configurations 089 */ 090 091 private ModelConfig myModelConfig = new ModelConfig(); 092 093 /** 094 * update setter javadoc if default changes 095 */ 096 private Long myTranslationCachesExpireAfterWriteInMinutes = DEFAULT_TRANSLATION_CACHES_EXPIRE_AFTER_WRITE_IN_MINUTES; 097 /** 098 * update setter javadoc if default changes 099 */ 100 private boolean myAllowInlineMatchUrlReferences = true; 101 private boolean myAllowMultipleDelete; 102 /** 103 * update setter javadoc if default changes 104 */ 105 private int myDeferIndexingForCodesystemsOfSize = 100; 106 private boolean myDeleteStaleSearches = true; 107 private boolean myEnforceReferentialIntegrityOnDelete = true; 108 private boolean myUniqueIndexesEnabled = true; 109 private boolean myUniqueIndexesCheckedBeforeSave = true; 110 private boolean myEnforceReferentialIntegrityOnWrite = true; 111 private SearchTotalModeEnum myDefaultTotalMode = null; 112 private int myEverythingIncludesFetchPageSize = 50; 113 /** 114 * update setter javadoc if default changes 115 */ 116 private long myExpireSearchResultsAfterMillis = DateUtils.MILLIS_PER_HOUR; 117 /** 118 * update setter javadoc if default changes 119 */ 120 private Integer myFetchSizeDefaultMaximum = null; 121 private int myHardTagListLimit = 1000; 122 /** 123 * update setter javadoc if default changes 124 */ 125 private boolean myIndexContainedResources = true; 126 private int myMaximumExpansionSize = DEFAULT_MAX_EXPANSION_SIZE; 127 private Integer myMaximumSearchResultCountInTransaction = DEFAULT_MAXIMUM_SEARCH_RESULT_COUNT_IN_TRANSACTION; 128 129 private Integer myMaximumTransactionBundleSize = DEFAULT_MAXIMUM_TRANSACTION_BUNDLE_SIZE; 130 private ResourceEncodingEnum myResourceEncoding = ResourceEncodingEnum.JSONC; 131 /** 132 * update setter javadoc if default changes 133 */ 134 private Integer myResourceMetaCountHardLimit = 1000; 135 private Long myReuseCachedSearchResultsForMillis = DEFAULT_REUSE_CACHED_SEARCH_RESULTS_FOR_MILLIS; 136 private boolean mySchedulingDisabled; 137 private boolean mySuppressUpdatesWithNoChange = true; 138 private boolean myAutoCreatePlaceholderReferenceTargets; 139 private Integer myCacheControlNoStoreMaxResultsUpperLimit = 1000; 140 private Integer myCountSearchResultsUpTo = null; 141 private boolean myStatusBasedReindexingDisabled; 142 private IdStrategyEnum myResourceServerIdStrategy = IdStrategyEnum.SEQUENTIAL_NUMERIC; 143 private boolean myMarkResourcesForReindexingUponSearchParameterChange; 144 private boolean myExpungeEnabled; 145 private boolean myDeleteExpungeEnabled; 146 private int myExpungeBatchSize = DEFAULT_EXPUNGE_BATCH_SIZE; 147 private int myReindexThreadCount; 148 private int myExpungeThreadCount; 149 private Set<String> myBundleTypesAllowedForStorage; 150 private boolean myValidateSearchParameterExpressionsOnSave = true; 151 private List<Integer> mySearchPreFetchThresholds = Arrays.asList(500, 2000, -1); 152 private List<WarmCacheEntry> myWarmCacheEntries = new ArrayList<>(); 153 private boolean myDisableHashBasedSearches; 154 private boolean myEnableInMemorySubscriptionMatching = true; 155 private boolean myEnforceReferenceTargetTypes = true; 156 private ClientIdStrategyEnum myResourceClientIdStrategy = ClientIdStrategyEnum.ALPHANUMERIC; 157 private boolean myFilterParameterEnabled = false; 158 private StoreMetaSourceInformationEnum myStoreMetaSourceInformation = StoreMetaSourceInformationEnum.SOURCE_URI_AND_REQUEST_ID; 159 /** 160 * update setter javadoc if default changes 161 */ 162 private Integer myMaximumDeleteConflictQueryCount = DEFAULT_MAXIMUM_DELETE_CONFLICT_COUNT; 163 /** 164 * Do not change default of {@code true}! 165 * 166 * @since 4.1.0 167 */ 168 private boolean myPreExpandValueSets = true; 169 /** 170 * Do not change default of {@code 0}! 171 * 172 * @since 4.1.0 173 */ 174 private int myPreExpandValueSetsDefaultOffset = 0; 175 /** 176 * Do not change default of {@code 1000}! 177 * 178 * @since 4.1.0 179 */ 180 private int myPreExpandValueSetsDefaultCount = 1000; 181 /** 182 * Do not change default of {@code 1000}! 183 * 184 * @since 4.1.0 185 */ 186 private int myPreExpandValueSetsMaxCount = 1000; 187 188 /** 189 * @since 4.2.0 190 */ 191 private boolean myPopulateIdentifierInAutoCreatedPlaceholderReferenceTargets; 192 193 /** 194 * @since 5.0.0 195 */ 196 private boolean myDeleteEnabled = true; 197 /** 198 * @since 5.1.0 199 */ 200 private boolean myLastNEnabled = false; 201 /** 202 * @since 5.2.0 203 */ 204 private boolean myUseLegacySearchBuilder = false; 205 206 /** 207 * Constructor 208 */ 209 public DaoConfig() { 210 setSubscriptionEnabled(true); 211 setSubscriptionPollDelay(0); 212 setSubscriptionPurgeInactiveAfterMillis(Long.MAX_VALUE); 213 setMarkResourcesForReindexingUponSearchParameterChange(true); 214 setReindexThreadCount(Runtime.getRuntime().availableProcessors()); 215 setExpungeThreadCount(Runtime.getRuntime().availableProcessors()); 216 setBundleTypesAllowedForStorage(DEFAULT_BUNDLE_TYPES_ALLOWED_FOR_STORAGE); 217 218 if ("true".equalsIgnoreCase(System.getProperty(DISABLE_STATUS_BASED_REINDEX))) { 219 ourLog.info("Status based reindexing is DISABLED"); 220 setStatusBasedReindexingDisabled(true); 221 } 222 } 223 224 /** 225 * If set to <code>true</code> (default is <code>false</code>) the <code>$lastn</code> operation will be enabled for 226 * indexing Observation resources. This operation involves creating a special set of tables in ElasticSearch for 227 * discovering Observation resources. Enabling this setting increases the amount of storage space required, and can 228 * slow write operations, but can be very useful for searching for collections of Observations for some applications. 229 * 230 * @since 5.1.0 231 */ 232 public boolean isLastNEnabled() { 233 return myLastNEnabled; 234 } 235 236 /** 237 * If set to <code>true</code> (default is <code>false</code>) the <code>$lastn</code> operation will be enabled for 238 * indexing Observation resources. This operation involves creating a special set of tables in ElasticSearch for 239 * discovering Observation resources. Enabling this setting increases the amount of storage space required, and can 240 * slow write operations, but can be very useful for searching for collections of Observations for some applications. 241 * 242 * @since 5.1.0 243 */ 244 public void setLastNEnabled(boolean theLastNEnabled) { 245 myLastNEnabled = theLastNEnabled; 246 } 247 248 /** 249 * This method controls whether to use the new non-hibernate search SQL builder that was introduced in HAPI FHIR 5.2.0. 250 * By default this will be <code>false</code> meaning that the new SQL builder is used. Set to <code>true</code> to use the 251 * legacy SQL builder based on Hibernate. 252 * <p>Note that this method will be removed in HAPI FHIR 5.4.0</p> 253 * 254 * @since 5.3.0 255 */ 256 public boolean isUseLegacySearchBuilder() { 257 return myUseLegacySearchBuilder; 258 } 259 260 /** 261 * This method controls whether to use the new non-hibernate search SQL builder that was introduced in HAPI FHIR 5.2.0. 262 * By default this will be <code>false</code> meaning that the new SQL builder is used. Set to <code>true</code> to use the 263 * legacy SQL builder based on Hibernate. 264 * <p>Note that this method will be removed in HAPI FHIR 5.4.0</p> 265 * 266 * @since 5.3.0 267 */ 268 public void setUseLegacySearchBuilder(boolean theUseLegacySearchBuilder) { 269 myUseLegacySearchBuilder = theUseLegacySearchBuilder; 270 } 271 272 /** 273 * If set to <code>true</code> (default is true) when a resource is being persisted, 274 * the target resource types of references will be validated to ensure that they 275 * are appropriate for the field containing the reference. This is generally a good idea 276 * because invalid reference target types may not be searchable. 277 */ 278 public boolean isEnforceReferenceTargetTypes() { 279 return myEnforceReferenceTargetTypes; 280 } 281 282 /** 283 * If set to <code>true</code> (default is true) when a resource is being persisted, 284 * the target resource types of references will be validated to ensure that they 285 * are appropriate for the field containing the reference. This is generally a good idea 286 * because invalid reference target types may not be searchable. 287 */ 288 public void setEnforceReferenceTargetTypes(boolean theEnforceReferenceTargetTypes) { 289 myEnforceReferenceTargetTypes = theEnforceReferenceTargetTypes; 290 } 291 292 /** 293 * If a non-null value is supplied (default is <code>null</code>), a default 294 * for the <code>_total</code> parameter may be specified here. For example, 295 * setting this value to {@link SearchTotalModeEnum#ACCURATE} will force a 296 * count to always be calculated for all searches. This can have a performance impact 297 * since it means that a count query will always be performed, but this is desirable 298 * for some solutions. 299 */ 300 public SearchTotalModeEnum getDefaultTotalMode() { 301 return myDefaultTotalMode; 302 } 303 304 /** 305 * If a non-null value is supplied (default is <code>null</code>), a default 306 * for the <code>_total</code> parameter may be specified here. For example, 307 * setting this value to {@link SearchTotalModeEnum#ACCURATE} will force a 308 * count to always be calculated for all searches. This can have a performance impact 309 * since it means that a count query will always be performed, but this is desirable 310 * for some solutions. 311 */ 312 public void setDefaultTotalMode(SearchTotalModeEnum theDefaultTotalMode) { 313 myDefaultTotalMode = theDefaultTotalMode; 314 } 315 316 /** 317 * Returns a set of searches that should be kept "warm", meaning that 318 * searches will periodically be performed in the background to 319 * keep results ready for this search 320 */ 321 public List<WarmCacheEntry> getWarmCacheEntries() { 322 if (myWarmCacheEntries == null) { 323 myWarmCacheEntries = new ArrayList<>(); 324 } 325 return myWarmCacheEntries; 326 } 327 328 public void setWarmCacheEntries(List<WarmCacheEntry> theWarmCacheEntries) { 329 myWarmCacheEntries = theWarmCacheEntries; 330 } 331 332 /** 333 * If set to <code>true</code> (default is false), the reindexing of search parameters 334 * using a query on the HFJ_RESOURCE.SP_INDEX_STATUS column will be disabled completely. 335 * This query is just not efficient on Oracle and bogs the system down when there are 336 * a lot of resources. A more efficient way of doing this will be introduced 337 * in the next release of HAPI FHIR. 338 * 339 * @since 3.5.0 340 */ 341 public boolean isStatusBasedReindexingDisabled() { 342 return myStatusBasedReindexingDisabled; 343 } 344 345 /** 346 * If set to <code>true</code> (default is false), the reindexing of search parameters 347 * using a query on the HFJ_RESOURCE.SP_INDEX_STATUS column will be disabled completely. 348 * This query is just not efficient on Oracle and bogs the system down when there are 349 * a lot of resources. A more efficient way of doing this will be introduced 350 * in the next release of HAPI FHIR. 351 * 352 * @since 3.5.0 353 */ 354 public void setStatusBasedReindexingDisabled(boolean theStatusBasedReindexingDisabled) { 355 myStatusBasedReindexingDisabled = theStatusBasedReindexingDisabled; 356 } 357 358 /** 359 * Add a value to the {@link #setTreatReferencesAsLogical(Set) logical references list}. 360 * 361 * @see #setTreatReferencesAsLogical(Set) 362 */ 363 public void addTreatReferencesAsLogical(String theTreatReferencesAsLogical) { 364 myModelConfig.addTreatReferencesAsLogical(theTreatReferencesAsLogical); 365 } 366 367 /** 368 * This setting specifies the bundle types (<code>Bundle.type</code>) that 369 * are allowed to be stored as-is on the /Bundle endpoint. 370 * 371 * @see #DEFAULT_BUNDLE_TYPES_ALLOWED_FOR_STORAGE 372 */ 373 public Set<String> getBundleTypesAllowedForStorage() { 374 return myBundleTypesAllowedForStorage; 375 } 376 377 /** 378 * This setting specifies the bundle types (<code>Bundle.type</code>) that 379 * are allowed to be stored as-is on the /Bundle endpoint. 380 * 381 * @see #DEFAULT_BUNDLE_TYPES_ALLOWED_FOR_STORAGE 382 */ 383 public void setBundleTypesAllowedForStorage(Set<String> theBundleTypesAllowedForStorage) { 384 Validate.notNull(theBundleTypesAllowedForStorage, "theBundleTypesAllowedForStorage must not be null"); 385 myBundleTypesAllowedForStorage = theBundleTypesAllowedForStorage; 386 } 387 388 /** 389 * Specifies the highest number that a client is permitted to use in a 390 * <code>Cache-Control: nostore, max-results=NNN</code> 391 * directive. If the client tries to exceed this limit, the 392 * request will be denied. Defaults to 1000. 393 */ 394 public Integer getCacheControlNoStoreMaxResultsUpperLimit() { 395 return myCacheControlNoStoreMaxResultsUpperLimit; 396 } 397 398 /** 399 * Specifies the highest number that a client is permitted to use in a 400 * <code>Cache-Control: nostore, max-results=NNN</code> 401 * directive. If the client tries to exceed this limit, the 402 * request will be denied. Defaults to 1000. 403 */ 404 public void setCacheControlNoStoreMaxResultsUpperLimit(Integer theCacheControlNoStoreMaxResults) { 405 myCacheControlNoStoreMaxResultsUpperLimit = theCacheControlNoStoreMaxResults; 406 } 407 408 /** 409 * When searching, if set to a non-null value (default is <code>null</code>) the 410 * search coordinator will attempt to find at least this many results 411 * before returning a response to the client. This parameter mainly affects 412 * whether a "total count" is included in the response bundle for searches that 413 * return large amounts of data. 414 * <p> 415 * For a search that returns 10000 results, if this value is set to 416 * 10000 the search coordinator will find all 10000 results 417 * prior to returning, so the initial response bundle will have the 418 * total set to 10000. If this value is null (or less than 10000) 419 * the response bundle will likely return slightly faster, but will 420 * not include the total. Subsequent page requests will likely 421 * include the total however, if they are performed after the 422 * search coordinator has found all results. 423 * </p> 424 * <p> 425 * Set this value to <code>0</code> to always load all 426 * results before returning. 427 * </p> 428 */ 429 public Integer getCountSearchResultsUpTo() { 430 return myCountSearchResultsUpTo; 431 } 432 433 /** 434 * When searching, if set to a non-null value (default is <code>null</code>) the 435 * search coordinator will attempt to find at least this many results 436 * before returning a response to the client. This parameter mainly affects 437 * whether a "total count" is included in the response bundle for searches that 438 * return large amounts of data. 439 * <p> 440 * For a search that returns 10000 results, if this value is set to 441 * 10000 the search coordinator will find all 10000 results 442 * prior to returning, so the initial response bundle will have the 443 * total set to 10000. If this value is null (or less than 10000) 444 * the response bundle will likely return slightly faster, but will 445 * not include the total. Subsequent page requests will likely 446 * include the total however, if they are performed after the 447 * search coordinator has found all results. 448 * </p> 449 * <p> 450 * Set this value to <code>0</code> to always load all 451 * results before returning. 452 * </p> 453 */ 454 public void setCountSearchResultsUpTo(Integer theCountSearchResultsUpTo) { 455 myCountSearchResultsUpTo = theCountSearchResultsUpTo; 456 } 457 458 /** 459 * When a code system is added that contains more than this number of codes, 460 * the code system will be indexed later in an incremental process in order to 461 * avoid overwhelming Lucene with a huge number of codes in a single operation. 462 * <p> 463 * Defaults to 100 464 * </p> 465 */ 466 public int getDeferIndexingForCodesystemsOfSize() { 467 return myDeferIndexingForCodesystemsOfSize; 468 } 469 470 /** 471 * When a code system is added that contains more than this number of codes, 472 * the code system will be indexed later in an incremental process in order to 473 * avoid overwhelming Lucene with a huge number of codes in a single operation. 474 * <p> 475 * Defaults to 100 476 * </p> 477 */ 478 public void setDeferIndexingForCodesystemsOfSize(int theDeferIndexingForCodesystemsOfSize) { 479 myDeferIndexingForCodesystemsOfSize = theDeferIndexingForCodesystemsOfSize; 480 } 481 482 /** 483 * Unlike with normal search queries, $everything queries have their _includes loaded by the main search thread and these included results 484 * 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 485 * as the search results are paged over. 486 * <p> 487 * In order to recursively load _includes, we process the original results in batches of this size. Adjust with caution, increasing this 488 * value may improve performance but may also cause memory issues. 489 * </p> 490 * <p> 491 * The default value is 50 492 * </p> 493 */ 494 public int getEverythingIncludesFetchPageSize() { 495 return myEverythingIncludesFetchPageSize; 496 } 497 498 /** 499 * Unlike with normal search queries, $everything queries have their _includes loaded by the main search thread and these included results 500 * 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 501 * as the search results are paged over. 502 * <p> 503 * In order to recursively load _includes, we process the original results in batches of this size. Adjust with caution, increasing this 504 * value may improve performance but may also cause memory issues. 505 * </p> 506 * <p> 507 * The default value is 50 508 * </p> 509 */ 510 public void setEverythingIncludesFetchPageSize(int theEverythingIncludesFetchPageSize) { 511 Validate.inclusiveBetween(1, Integer.MAX_VALUE, theEverythingIncludesFetchPageSize); 512 myEverythingIncludesFetchPageSize = theEverythingIncludesFetchPageSize; 513 } 514 515 /** 516 * Sets the number of milliseconds that search results for a given client search 517 * should be preserved before being purged from the database. 518 * <p> 519 * Search results are stored in the database so that they can be paged over multiple 520 * requests. After this 521 * number of milliseconds, they will be deleted from the database, and any paging links 522 * (next/prev links in search response bundles) will become invalid. Defaults to 1 hour. 523 * </p> 524 * <p> 525 * To disable this feature entirely, see {@link #setExpireSearchResults(boolean)} 526 * </p> 527 * 528 * @since 1.5 529 */ 530 public long getExpireSearchResultsAfterMillis() { 531 return myExpireSearchResultsAfterMillis; 532 } 533 534 /** 535 * Sets the number of milliseconds that search results for a given client search 536 * should be preserved before being purged from the database. 537 * <p> 538 * Search results are stored in the database so that they can be paged over multiple 539 * requests. After this 540 * number of milliseconds, they will be deleted from the database, and any paging links 541 * (next/prev links in search response bundles) will become invalid. Defaults to 1 hour. 542 * </p> 543 * <p> 544 * To disable this feature entirely, see {@link #setExpireSearchResults(boolean)} 545 * </p> 546 * 547 * @since 1.5 548 */ 549 public void setExpireSearchResultsAfterMillis(long theExpireSearchResultsAfterMillis) { 550 myExpireSearchResultsAfterMillis = theExpireSearchResultsAfterMillis; 551 } 552 553 /** 554 * Gets the default maximum number of results to load in a query. 555 * <p> 556 * For example, if the database has a million Patient resources in it, and 557 * the client requests <code>GET /Patient</code>, if this value is set 558 * to a non-null value (default is <code>null</code>) only this number 559 * of results will be fetched. Setting this value appropriately 560 * can be useful to improve performance in some situations. 561 * </p> 562 */ 563 public Integer getFetchSizeDefaultMaximum() { 564 return myFetchSizeDefaultMaximum; 565 } 566 567 /** 568 * Gets the default maximum number of results to load in a query. 569 * <p> 570 * For example, if the database has a million Patient resources in it, and 571 * the client requests <code>GET /Patient</code>, if this value is set 572 * to a non-null value (default is <code>null</code>) only this number 573 * of results will be fetched. Setting this value appropriately 574 * can be useful to improve performance in some situations. 575 * </p> 576 */ 577 public void setFetchSizeDefaultMaximum(Integer theFetchSizeDefaultMaximum) { 578 myFetchSizeDefaultMaximum = theFetchSizeDefaultMaximum; 579 } 580 581 /** 582 * Gets the maximum number of results to return in a GetTags query (DSTU1 only) 583 */ 584 public int getHardTagListLimit() { 585 return myHardTagListLimit; 586 } 587 588 /** 589 * Gets the maximum number of results to return in a GetTags query (DSTU1 only) 590 */ 591 public void setHardTagListLimit(int theHardTagListLimit) { 592 myHardTagListLimit = theHardTagListLimit; 593 } 594 595 /** 596 * If set to {@link IndexEnabledEnum#DISABLED} (default is {@link IndexEnabledEnum#DISABLED}) 597 * the server will not create search indexes for search parameters with no values in resources. 598 * <p> 599 * Disabling this feature means that the <code>:missing</code> search modifier will not be 600 * supported on the server, but also means that storage and indexing (i.e. writes to the 601 * database) may be much faster on servers which have lots of search parameters and need 602 * to write quickly. 603 * </p> 604 * <p> 605 * This feature may be enabled on servers where supporting the use of the :missing parameter is 606 * of higher importance than raw write performance 607 * </p> 608 */ 609 public IndexEnabledEnum getIndexMissingFields() { 610 return myIndexMissingFieldsEnabled; 611 } 612 613 /** 614 * If set to {@link IndexEnabledEnum#DISABLED} (default is {@link IndexEnabledEnum#DISABLED}) 615 * the server will not create search indexes for search parameters with no values in resources. 616 * <p> 617 * Disabling this feature means that the <code>:missing</code> search modifier will not be 618 * supported on the server, but also means that storage and indexing (i.e. writes to the 619 * database) may be much faster on servers which have lots of search parameters and need 620 * to write quickly. 621 * </p> 622 * <p> 623 * This feature may be enabled on servers where supporting the use of the :missing parameter is 624 * of higher importance than raw write performance 625 * </p> 626 * <p> 627 * Note that this setting also has an impact on sorting (i.e. using the 628 * <code>_sort</code> parameter on searches): If the server is configured 629 * to not index missing field. 630 * </p> 631 */ 632 public void setIndexMissingFields(IndexEnabledEnum theIndexMissingFields) { 633 Validate.notNull(theIndexMissingFields, "theIndexMissingFields must not be null"); 634 myIndexMissingFieldsEnabled = theIndexMissingFields; 635 } 636 637 /** 638 * See {@link #setMaximumExpansionSize(int)} 639 */ 640 public int getMaximumExpansionSize() { 641 return myMaximumExpansionSize; 642 } 643 644 /** 645 * Sets the maximum number of codes that will be added to an in-memory valueset expansion before 646 * the operation will be failed as too costly. Note that this setting applies only to 647 * in-memory expansions and does not apply to expansions that are being pre-calculated. 648 * <p> 649 * The default value for this setting is 1000. 650 * </p> 651 */ 652 public void setMaximumExpansionSize(int theMaximumExpansionSize) { 653 Validate.isTrue(theMaximumExpansionSize > 0, "theMaximumExpansionSize must be > 0"); 654 myMaximumExpansionSize = theMaximumExpansionSize; 655 } 656 657 /** 658 * Provides the maximum number of results which may be returned by a search (HTTP GET) which 659 * is executed as a sub-operation within within a FHIR <code>transaction</code> or 660 * <code>batch</code> operation. For example, if this value is set to <code>100</code> and 661 * a FHIR transaction is processed with a sub-request for <code>Patient?gender=male</code>, 662 * the server will throw an error (and the transaction will fail) if there are more than 663 * 100 resources on the server which match this query. 664 * <p> 665 * The default value is <code>null</code>, which means that there is no limit. 666 * </p> 667 */ 668 public Integer getMaximumSearchResultCountInTransaction() { 669 return myMaximumSearchResultCountInTransaction; 670 } 671 672 /** 673 * Provides the maximum number of results which may be returned by a search (HTTP GET) which 674 * is executed as a sub-operation within within a FHIR <code>transaction</code> or 675 * <code>batch</code> operation. For example, if this value is set to <code>100</code> and 676 * a FHIR transaction is processed with a sub-request for <code>Patient?gender=male</code>, 677 * the server will throw an error (and the transaction will fail) if there are more than 678 * 100 resources on the server which match this query. 679 * <p> 680 * The default value is <code>null</code>, which means that there is no limit. 681 * </p> 682 */ 683 public void setMaximumSearchResultCountInTransaction(Integer theMaximumSearchResultCountInTransaction) { 684 myMaximumSearchResultCountInTransaction = theMaximumSearchResultCountInTransaction; 685 } 686 687 /** 688 * Specifies the maximum number of resources permitted within a single transaction bundle. 689 * If a transaction bundle is submitted with more than this number of resources, it will be 690 * rejected with a PayloadTooLarge exception. 691 * <p> 692 * The default value is <code>null</code>, which means that there is no limit. 693 * </p> 694 */ 695 public Integer getMaximumTransactionBundleSize() { 696 return myMaximumTransactionBundleSize; 697 } 698 699 /** 700 * Specifies the maximum number of resources permitted within a single transaction bundle. 701 * If a transaction bundle is submitted with more than this number of resources, it will be 702 * rejected with a PayloadTooLarge exception. 703 * <p> 704 * The default value is <code>null</code>, which means that there is no limit. 705 * </p> 706 */ 707 public DaoConfig setMaximumTransactionBundleSize(Integer theMaximumTransactionBundleSize) { 708 myMaximumTransactionBundleSize = theMaximumTransactionBundleSize; 709 return this; 710 } 711 712 /** 713 * This setting controls the number of threads allocated to resource reindexing 714 * (which is only ever used if SearchParameters change, or a manual reindex is 715 * triggered due to a HAPI FHIR upgrade or some other reason). 716 * <p> 717 * The default value is set to the number of available processors 718 * (via <code>Runtime.getRuntime().availableProcessors()</code>). Value 719 * for this setting must be a positive integer. 720 * </p> 721 */ 722 public int getReindexThreadCount() { 723 return myReindexThreadCount; 724 } 725 726 /** 727 * This setting controls the number of threads allocated to resource reindexing 728 * (which is only ever used if SearchParameters change, or a manual reindex is 729 * triggered due to a HAPI FHIR upgrade or some other reason). 730 * <p> 731 * The default value is set to the number of available processors 732 * (via <code>Runtime.getRuntime().availableProcessors()</code>). Value 733 * for this setting must be a positive integer. 734 * </p> 735 */ 736 public void setReindexThreadCount(int theReindexThreadCount) { 737 myReindexThreadCount = theReindexThreadCount; 738 myReindexThreadCount = Math.max(myReindexThreadCount, 1); // Minimum of 1 739 } 740 741 /** 742 * This setting controls the number of threads allocated to the expunge operation 743 * <p> 744 * The default value is set to the number of available processors 745 * (via <code>Runtime.getRuntime().availableProcessors()</code>). Value 746 * for this setting must be a positive integer. 747 * </p> 748 */ 749 public int getExpungeThreadCount() { 750 return myExpungeThreadCount; 751 } 752 753 /** 754 * This setting controls the number of threads allocated to the expunge operation 755 * <p> 756 * The default value is set to the number of available processors 757 * (via <code>Runtime.getRuntime().availableProcessors()</code>). Value 758 * for this setting must be a positive integer. 759 * </p> 760 */ 761 public void setExpungeThreadCount(int theExpungeThreadCount) { 762 myExpungeThreadCount = theExpungeThreadCount; 763 myExpungeThreadCount = Math.max(myExpungeThreadCount, 1); // Minimum of 1 764 } 765 766 public ResourceEncodingEnum getResourceEncoding() { 767 return myResourceEncoding; 768 } 769 770 public void setResourceEncoding(ResourceEncodingEnum theResourceEncoding) { 771 myResourceEncoding = theResourceEncoding; 772 } 773 774 /** 775 * If set, an individual resource will not be allowed to have more than the 776 * given number of tags, profiles, and security labels (the limit is for the combined 777 * total for all of these things on an individual resource). 778 * <p> 779 * If set to <code>null</code>, no limit will be applied. 780 * </p> 781 * <p> 782 * The default value for this setting is 1000. 783 * </p> 784 */ 785 public Integer getResourceMetaCountHardLimit() { 786 return myResourceMetaCountHardLimit; 787 } 788 789 /** 790 * If set, an individual resource will not be allowed to have more than the 791 * given number of tags, profiles, and security labels (the limit is for the combined 792 * total for all of these things on an individual resource). 793 * <p> 794 * If set to <code>null</code>, no limit will be applied. 795 * </p> 796 * <p> 797 * The default value for this setting is 1000. 798 * </p> 799 */ 800 public void setResourceMetaCountHardLimit(Integer theResourceMetaCountHardLimit) { 801 myResourceMetaCountHardLimit = theResourceMetaCountHardLimit; 802 } 803 804 /** 805 * Controls the behaviour when a client-assigned ID is encountered, i.e. an HTTP PUT 806 * on a resource ID that does not already exist in the database. 807 * <p> 808 * Default is {@link ClientIdStrategyEnum#ALPHANUMERIC} 809 * </p> 810 */ 811 public ClientIdStrategyEnum getResourceClientIdStrategy() { 812 return myResourceClientIdStrategy; 813 } 814 815 /** 816 * Controls the behaviour when a client-assigned ID is encountered, i.e. an HTTP PUT 817 * on a resource ID that does not already exist in the database. 818 * <p> 819 * Default is {@link ClientIdStrategyEnum#ALPHANUMERIC} 820 * </p> 821 * 822 * @param theResourceClientIdStrategy Must not be <code>null</code> 823 */ 824 public void setResourceClientIdStrategy(ClientIdStrategyEnum theResourceClientIdStrategy) { 825 Validate.notNull(theResourceClientIdStrategy, "theClientIdStrategy must not be null"); 826 myResourceClientIdStrategy = theResourceClientIdStrategy; 827 } 828 829 /** 830 * This setting configures the strategy to use in generating IDs for newly 831 * created resources on the server. The default is {@link IdStrategyEnum#SEQUENTIAL_NUMERIC}. 832 * <p> 833 * This strategy is only used for server-assigned IDs, i.e. for HTTP POST 834 * where the client is requesing that the server store a new resource and give 835 * it an ID. 836 * </p> 837 */ 838 public IdStrategyEnum getResourceServerIdStrategy() { 839 return myResourceServerIdStrategy; 840 } 841 842 /** 843 * This setting configures the strategy to use in generating IDs for newly 844 * created resources on the server. The default is {@link IdStrategyEnum#SEQUENTIAL_NUMERIC}. 845 * <p> 846 * This strategy is only used for server-assigned IDs, i.e. for HTTP POST 847 * where the client is requesing that the server store a new resource and give 848 * it an ID. 849 * </p> 850 * 851 * @param theResourceIdStrategy The strategy. Must not be <code>null</code>. 852 */ 853 public void setResourceServerIdStrategy(IdStrategyEnum theResourceIdStrategy) { 854 Validate.notNull(theResourceIdStrategy, "theResourceIdStrategy must not be null"); 855 myResourceServerIdStrategy = theResourceIdStrategy; 856 } 857 858 /** 859 * If set to a non {@literal null} value (default is {@link #DEFAULT_REUSE_CACHED_SEARCH_RESULTS_FOR_MILLIS non null}) 860 * if an identical search is requested multiple times within this window, the same results will be returned 861 * to multiple queries. For example, if this value is set to 1 minute and a client searches for all 862 * patients named "smith", and then a second client also performs the same search within 1 minute, 863 * the same cached results will be returned. 864 * <p> 865 * This approach can improve performance, especially under heavy load, but can also mean that 866 * searches may potentially return slightly out-of-date results. 867 * </p> 868 * <p> 869 * Note that if this is set to a non-null value, clients may override this setting by using 870 * the <code>Cache-Control</code> header. If this is set to <code>null</code>, the Cache-Control 871 * header will be ignored. 872 * </p> 873 */ 874 public Long getReuseCachedSearchResultsForMillis() { 875 return myReuseCachedSearchResultsForMillis; 876 } 877 878 /** 879 * If set to a non {@literal null} value (default is {@link #DEFAULT_REUSE_CACHED_SEARCH_RESULTS_FOR_MILLIS non null}) 880 * if an identical search is requested multiple times within this window, the same results will be returned 881 * to multiple queries. For example, if this value is set to 1 minute and a client searches for all 882 * patients named "smith", and then a second client also performs the same search within 1 minute, 883 * the same cached results will be returned. 884 * <p> 885 * This approach can improve performance, especially under heavy load, but can also mean that 886 * searches may potentially return slightly out-of-date results. 887 * </p> 888 * <p> 889 * Note that if this is set to a non-null value, clients may override this setting by using 890 * the <code>Cache-Control</code> header. If this is set to <code>null</code>, the Cache-Control 891 * header will be ignored. 892 * </p> 893 */ 894 public void setReuseCachedSearchResultsForMillis(Long theReuseCachedSearchResultsForMillis) { 895 myReuseCachedSearchResultsForMillis = theReuseCachedSearchResultsForMillis; 896 } 897 898 /** 899 * Specifies the duration in minutes for which values will be retained after being 900 * written to the terminology translation cache. Defaults to 60. 901 */ 902 public Long getTranslationCachesExpireAfterWriteInMinutes() { 903 return myTranslationCachesExpireAfterWriteInMinutes; 904 } 905 906 /** 907 * Specifies the duration in minutes for which values will be retained after being 908 * written to the terminology translation cache. Defaults to 60. 909 */ 910 public void setTranslationCachesExpireAfterWriteInMinutes(Long translationCachesExpireAfterWriteInMinutes) { 911 myTranslationCachesExpireAfterWriteInMinutes = translationCachesExpireAfterWriteInMinutes; 912 } 913 914 /** 915 * This setting may be used to advise the server that any references found in 916 * resources that have any of the base URLs given here will be treated as logical 917 * references instead of being treated as real references. 918 * <p> 919 * A logical reference is a reference which is treated as an identifier, and 920 * does not neccesarily resolve. See <a href="http://hl7.org/fhir/references.html">references</a> for 921 * a description of logical references. For example, the valueset 922 * <a href="http://hl7.org/fhir/valueset-quantity-comparator.html">valueset-quantity-comparator</a> is a logical 923 * reference. 924 * </p> 925 * <p> 926 * Values for this field may take either of the following forms: 927 * </p> 928 * <ul> 929 * <li><code>http://example.com/some-url</code> <b>(will be matched exactly)</b></li> 930 * <li><code>http://example.com/some-base*</code> <b>(will match anything beginning with the part before the *)</b></li> 931 * </ul> 932 * 933 * @see ModelConfig#DEFAULT_LOGICAL_BASE_URLS Default values for this property 934 */ 935 public Set<String> getTreatReferencesAsLogical() { 936 return myModelConfig.getTreatReferencesAsLogical(); 937 } 938 939 /** 940 * This setting may be used to advise the server that any references found in 941 * resources that have any of the base URLs given here will be treated as logical 942 * references instead of being treated as real references. 943 * <p> 944 * A logical reference is a reference which is treated as an identifier, and 945 * does not neccesarily resolve. See <a href="http://hl7.org/fhir/references.html">references</a> for 946 * a description of logical references. For example, the valueset 947 * <a href="http://hl7.org/fhir/valueset-quantity-comparator.html">valueset-quantity-comparator</a> is a logical 948 * reference. 949 * </p> 950 * <p> 951 * Values for this field may take either of the following forms: 952 * </p> 953 * <ul> 954 * <li><code>http://example.com/some-url</code> <b>(will be matched exactly)</b></li> 955 * <li><code>http://example.com/some-base*</code> <b>(will match anything beginning with the part before the *)</b></li> 956 * </ul> 957 * 958 * @see ModelConfig#DEFAULT_LOGICAL_BASE_URLS Default values for this property 959 */ 960 public DaoConfig setTreatReferencesAsLogical(Set<String> theTreatReferencesAsLogical) { 961 myModelConfig.setTreatReferencesAsLogical(theTreatReferencesAsLogical); 962 return this; 963 } 964 965 /** 966 * If set to <code>true</code> (default is <code>false</code>) the server will allow 967 * resources to have references to external servers. For example if this server is 968 * running at <code>http://example.com/fhir</code> and this setting is set to 969 * <code>true</code> the server will allow a Patient resource to be saved with a 970 * Patient.organization value of <code>http://foo.com/Organization/1</code>. 971 * <p> 972 * Under the default behaviour if this value has not been changed, the above 973 * resource would be rejected by the server because it requires all references 974 * to be resolvable on the local server. 975 * </p> 976 * <p> 977 * Note that external references will be indexed by the server and may be searched 978 * (e.g. <code>Patient:organization</code>), but 979 * chained searches (e.g. <code>Patient:organization.name</code>) will not work across 980 * these references. 981 * </p> 982 * <p> 983 * It is recommended to also set {@link #setTreatBaseUrlsAsLocal(Set)} if this value 984 * is set to <code>true</code> 985 * </p> 986 * 987 * @see #setTreatBaseUrlsAsLocal(Set) 988 * @see #setAllowExternalReferences(boolean) 989 */ 990 public boolean isAllowExternalReferences() { 991 return myModelConfig.isAllowExternalReferences(); 992 } 993 994 /** 995 * If set to <code>true</code> (default is <code>false</code>) the server will allow 996 * resources to have references to external servers. For example if this server is 997 * running at <code>http://example.com/fhir</code> and this setting is set to 998 * <code>true</code> the server will allow a Patient resource to be saved with a 999 * Patient.organization value of <code>http://foo.com/Organization/1</code>. 1000 * <p> 1001 * Under the default behaviour if this value has not been changed, the above 1002 * resource would be rejected by the server because it requires all references 1003 * to be resolvable on the local server. 1004 * </p> 1005 * <p> 1006 * Note that external references will be indexed by the server and may be searched 1007 * (e.g. <code>Patient:organization</code>), but 1008 * chained searches (e.g. <code>Patient:organization.name</code>) will not work across 1009 * these references. 1010 * </p> 1011 * <p> 1012 * It is recommended to also set {@link #setTreatBaseUrlsAsLocal(Set)} if this value 1013 * is set to <code>true</code> 1014 * </p> 1015 * 1016 * @see #setTreatBaseUrlsAsLocal(Set) 1017 * @see #setAllowExternalReferences(boolean) 1018 */ 1019 public void setAllowExternalReferences(boolean theAllowExternalReferences) { 1020 myModelConfig.setAllowExternalReferences(theAllowExternalReferences); 1021 } 1022 1023 /** 1024 * @see #setAllowInlineMatchUrlReferences(boolean) 1025 */ 1026 public boolean isAllowInlineMatchUrlReferences() { 1027 return myAllowInlineMatchUrlReferences; 1028 } 1029 1030 /** 1031 * Should references containing match URLs be resolved and replaced in create and update operations. For 1032 * example, if this property is set to true and a resource is created containing a reference 1033 * to "Patient?identifier=12345", this is reference match URL will be resolved and replaced according 1034 * to the usual match URL rules. 1035 * <p> 1036 * Default is {@literal true} beginning in HAPI FHIR 2.4, since this 1037 * feature is now specified in the FHIR specification. (Previously it 1038 * was an experimental/proposed feature) 1039 * </p> 1040 * 1041 * @since 1.5 1042 */ 1043 public void setAllowInlineMatchUrlReferences(boolean theAllowInlineMatchUrlReferences) { 1044 myAllowInlineMatchUrlReferences = theAllowInlineMatchUrlReferences; 1045 } 1046 1047 public boolean isAllowMultipleDelete() { 1048 return myAllowMultipleDelete; 1049 } 1050 1051 public void setAllowMultipleDelete(boolean theAllowMultipleDelete) { 1052 myAllowMultipleDelete = theAllowMultipleDelete; 1053 } 1054 1055 /** 1056 * When creating or updating a resource: If this property is set to <code>true</code> 1057 * (default is <code>false</code>), if the resource has a reference to another resource 1058 * on the local server but that reference does not exist, a placeholder resource will be 1059 * created. 1060 * <p> 1061 * In other words, if an observation with subject <code>Patient/FOO</code> is created, but 1062 * there is no resource called <code>Patient/FOO</code> on the server, this property causes 1063 * an empty patient with ID "FOO" to be created in order to prevent this operation 1064 * from failing. 1065 * </p> 1066 * <p> 1067 * This property can be useful in cases where replication between two servers is wanted. 1068 * Note however that references containing purely numeric IDs will not be auto-created 1069 * as they are never allowed to be client supplied in HAPI FHIR JPA. 1070 * </p> 1071 */ 1072 public boolean isAutoCreatePlaceholderReferenceTargets() { 1073 return myAutoCreatePlaceholderReferenceTargets; 1074 } 1075 1076 /** 1077 * When creating or updating a resource: If this property is set to <code>true</code> 1078 * (default is <code>false</code>), if the resource has a reference to another resource 1079 * on the local server but that reference does not exist, a placeholder resource will be 1080 * created. 1081 * <p> 1082 * In other words, if an observation with subject <code>Patient/FOO</code> is created, but 1083 * there is no resource called <code>Patient/FOO</code> on the server, this property causes 1084 * an empty patient with ID "FOO" to be created in order to prevent this operation 1085 * from failing. 1086 * </p> 1087 * <p> 1088 * This property can be useful in cases where replication between two servers is wanted. 1089 * Note however that references containing purely numeric IDs will not be auto-created 1090 * as they are never allowed to be client supplied in HAPI FHIR JPA. 1091 * </p> 1092 */ 1093 public void setAutoCreatePlaceholderReferenceTargets(boolean theAutoCreatePlaceholderReferenceTargets) { 1094 myAutoCreatePlaceholderReferenceTargets = theAutoCreatePlaceholderReferenceTargets; 1095 } 1096 1097 /** 1098 * When {@link #setAutoCreatePlaceholderReferenceTargets(boolean)} is enabled, if this 1099 * setting is set to <code>true</code> (default is <code>false</code>) and the source 1100 * reference has an identifier populated, the identifier will be copied to the target 1101 * resource. 1102 * <p> 1103 * When enabled, if an Observation contains a reference like the one below, 1104 * and no existing resource was found that matches the given ID, a new 1105 * one will be created and its <code>Patient.identifier</code> value will be 1106 * populated using the value from <code>Observation.subject.identifier</code>. 1107 * </p> 1108 * <pre> 1109 * { 1110 * "resourceType": "Observation", 1111 * "subject": { 1112 * "reference": "Patient/ABC", 1113 * "identifier": { 1114 * "system": "http://foo", 1115 * "value": "123" 1116 * } 1117 * } 1118 * } 1119 * </pre> 1120 * <p> 1121 * This method is often combined with {@link #setAllowInlineMatchUrlReferences(boolean)}. 1122 * </p> 1123 * <p> 1124 * In other words if an Observation contains a reference like the one below, 1125 * and no existing resource was found that matches the given match URL, a new 1126 * one will be created and its <code>Patient.identifier</code> value will be 1127 * populated using the value from <code>Observation.subject.identifier</code>. 1128 * </p> 1129 * <pre> 1130 * { 1131 * "resourceType": "Observation", 1132 * "subject": { 1133 * "reference": "Patient?identifier=http://foo|123", 1134 * "identifier": { 1135 * "system": "http://foo", 1136 * "value": "123" 1137 * } 1138 * } 1139 * } 1140 * </pre> 1141 * 1142 * @since 4.2.0 1143 */ 1144 public boolean isPopulateIdentifierInAutoCreatedPlaceholderReferenceTargets() { 1145 return myPopulateIdentifierInAutoCreatedPlaceholderReferenceTargets; 1146 } 1147 1148 /** 1149 * When {@link #setAutoCreatePlaceholderReferenceTargets(boolean)} is enabled, if this 1150 * setting is set to <code>true</code> (default is <code>false</code>) and the source 1151 * reference has an identifier populated, the identifier will be copied to the target 1152 * resource. 1153 * <p> 1154 * When enabled, if an Observation contains a reference like the one below, 1155 * and no existing resource was found that matches the given ID, a new 1156 * one will be created and its <code>Patient.identifier</code> value will be 1157 * populated using the value from <code>Observation.subject.identifier</code>. 1158 * </p> 1159 * <pre> 1160 * { 1161 * "resourceType": "Observation", 1162 * "subject": { 1163 * "reference": "Patient/ABC", 1164 * "identifier": { 1165 * "system": "http://foo", 1166 * "value": "123" 1167 * } 1168 * } 1169 * } 1170 * </pre> 1171 * <p> 1172 * This method is often combined with {@link #setAllowInlineMatchUrlReferences(boolean)}. 1173 * </p> 1174 * <p> 1175 * In other words if an Observation contains a reference like the one below, 1176 * and no existing resource was found that matches the given match URL, a new 1177 * one will be created and its <code>Patient.identifier</code> value will be 1178 * populated using the value from <code>Observation.subject.identifier</code>. 1179 * </p> 1180 * <pre> 1181 * { 1182 * "resourceType": "Observation", 1183 * "subject": { 1184 * "reference": "Patient?identifier=http://foo|123", 1185 * "identifier": { 1186 * "system": "http://foo", 1187 * "value": "123" 1188 * } 1189 * } 1190 * } 1191 * </pre> 1192 * 1193 * @since 4.2.0 1194 */ 1195 public void setPopulateIdentifierInAutoCreatedPlaceholderReferenceTargets(boolean thePopulateIdentifierInAutoCreatedPlaceholderReferenceTargets) { 1196 myPopulateIdentifierInAutoCreatedPlaceholderReferenceTargets = thePopulateIdentifierInAutoCreatedPlaceholderReferenceTargets; 1197 } 1198 1199 /** 1200 * If set to <code>false</code> (default is <code>true</code>) resources will be permitted to be 1201 * deleted even if other resources currently contain references to them. 1202 * <p> 1203 * This property can cause confusing results for clients of the server since searches, includes, 1204 * and other FHIR features may not behave as expected when referential integrity is not 1205 * preserved. Use this feature with caution. 1206 * </p> 1207 */ 1208 public boolean isEnforceReferentialIntegrityOnDelete() { 1209 return myEnforceReferentialIntegrityOnDelete; 1210 } 1211 1212 /** 1213 * If set to <code>false</code> (default is <code>true</code>) resources will be permitted to be 1214 * deleted even if other resources currently contain references to them. 1215 * <p> 1216 * This property can cause confusing results for clients of the server since searches, includes, 1217 * and other FHIR features may not behave as expected when referential integrity is not 1218 * preserved. Use this feature with caution. 1219 * </p> 1220 */ 1221 public void setEnforceReferentialIntegrityOnDelete(boolean theEnforceReferentialIntegrityOnDelete) { 1222 myEnforceReferentialIntegrityOnDelete = theEnforceReferentialIntegrityOnDelete; 1223 } 1224 1225 /** 1226 * If set to <code>false</code> (default is <code>true</code>) resources will be permitted to be 1227 * created or updated even if they contain references to local resources that do not exist. 1228 * <p> 1229 * For example, if a patient contains a reference to managing organization <code>Organization/FOO</code> 1230 * but FOO is not a valid ID for an organization on the server, the operation will be blocked unless 1231 * this propery has been set to <code>false</code> 1232 * </p> 1233 * <p> 1234 * This property can cause confusing results for clients of the server since searches, includes, 1235 * and other FHIR features may not behave as expected when referential integrity is not 1236 * preserved. Use this feature with caution. 1237 * </p> 1238 */ 1239 public boolean isEnforceReferentialIntegrityOnWrite() { 1240 return myEnforceReferentialIntegrityOnWrite; 1241 } 1242 1243 /** 1244 * If set to <code>false</code> (default is <code>true</code>) resources will be permitted to be 1245 * created or updated even if they contain references to local resources that do not exist. 1246 * <p> 1247 * For example, if a patient contains a reference to managing organization <code>Organization/FOO</code> 1248 * but FOO is not a valid ID for an organization on the server, the operation will be blocked unless 1249 * this propery has been set to <code>false</code> 1250 * </p> 1251 * <p> 1252 * This property can cause confusing results for clients of the server since searches, includes, 1253 * and other FHIR features may not behave as expected when referential integrity is not 1254 * preserved. Use this feature with caution. 1255 * </p> 1256 */ 1257 public void setEnforceReferentialIntegrityOnWrite(boolean theEnforceReferentialIntegrityOnWrite) { 1258 myEnforceReferentialIntegrityOnWrite = theEnforceReferentialIntegrityOnWrite; 1259 } 1260 1261 /** 1262 * If this is set to <code>false</code> (default is <code>true</code>) the stale search deletion 1263 * task will be disabled (meaning that search results will be retained in the database indefinitely). USE WITH CAUTION. 1264 * <p> 1265 * This feature is useful if you want to define your own process for deleting these (e.g. because 1266 * you are running in a cluster) 1267 * </p> 1268 */ 1269 public boolean isExpireSearchResults() { 1270 return myDeleteStaleSearches; 1271 } 1272 1273 /** 1274 * If this is set to <code>false</code> (default is <code>true</code>) the stale search deletion 1275 * task will be disabled (meaning that search results will be retained in the database indefinitely). USE WITH CAUTION. 1276 * <p> 1277 * This feature is useful if you want to define your own process for deleting these (e.g. because 1278 * you are running in a cluster) 1279 * </p> 1280 */ 1281 public void setExpireSearchResults(boolean theDeleteStaleSearches) { 1282 myDeleteStaleSearches = theDeleteStaleSearches; 1283 } 1284 1285 /** 1286 * If set to <code>true</code> (default is <code>false</code>), the $expunge operation 1287 * will be enabled on this server. This operation is potentially dangerous since it allows 1288 * a client to physically delete data in a way that can not be recovered (without resorting 1289 * to backups). 1290 * <p> 1291 * It is recommended to not enable this setting without appropriate security 1292 * in place on your server to prevent non-administrators from using this 1293 * operation. 1294 * </p> 1295 */ 1296 public boolean isExpungeEnabled() { 1297 return myExpungeEnabled; 1298 } 1299 1300 /** 1301 * If set to <code>true</code> (default is <code>false</code>), the _expunge parameter on the DELETE 1302 * operation will be enabled on this server. DELETE _expunge removes all data associated with a resource in a highly performant 1303 * way, skipping most of the the checks that are enforced with usual DELETE operations. The only check 1304 * that is performed before deleting the resources and their indexes is that no other resources reference the resources about to 1305 * be deleted. This operation is potentially dangerous since it allows 1306 * a client to physically delete data in a way that can not be recovered (without resorting 1307 * to backups). 1308 * <p> 1309 * It is recommended to not enable this setting without appropriate security 1310 * in place on your server to prevent non-administrators from using this 1311 * operation. 1312 * </p> 1313 */ 1314 public void setDeleteExpungeEnabled(boolean theDeleteExpungeEnabled) { 1315 myDeleteExpungeEnabled = theDeleteExpungeEnabled; 1316 } 1317 1318 /** 1319 * If set to <code>true</code> (default is <code>false</code>), the _expunge parameter on the DELETE 1320 * operation will be enabled on this server. DELETE _expunge removes all data associated with a resource in a highly performant 1321 * way, skipping most of the the checks that are enforced with usual DELETE operations. The only check 1322 * that is performed before deleting the data is that no other resources reference the resources about to 1323 * be deleted. This operation is potentially dangerous since it allows 1324 * a client to physically delete data in a way that can not be recovered (without resorting 1325 * to backups). 1326 * <p> 1327 * It is recommended to not enable this setting without appropriate security 1328 * in place on your server to prevent non-administrators from using this 1329 * operation. 1330 * </p> 1331 */ 1332 public boolean isDeleteExpungeEnabled() { 1333 return myDeleteExpungeEnabled; 1334 } 1335 1336 /** 1337 * If set to <code>true</code> (default is <code>false</code>), the $expunge operation 1338 * will be enabled on this server. This operation is potentially dangerous since it allows 1339 * a client to physically delete data in a way that can not be recovered (without resorting 1340 * to backups). 1341 * <p> 1342 * It is recommended to not enable this setting without appropriate security 1343 * in place on your server to prevent non-administrators from using this 1344 * operation. 1345 * </p> 1346 */ 1347 public void setExpungeEnabled(boolean theExpungeEnabled) { 1348 myExpungeEnabled = theExpungeEnabled; 1349 } 1350 1351 /** 1352 * The expunge batch size (default 800) determines the number of records deleted within a single transaction by the 1353 * expunge operation. 1354 */ 1355 public int getExpungeBatchSize() { 1356 return myExpungeBatchSize; 1357 } 1358 1359 /** 1360 * The expunge batch size (default 800) determines the number of records deleted within a single transaction by the 1361 * expunge operation. 1362 */ 1363 public void setExpungeBatchSize(int theExpungeBatchSize) { 1364 myExpungeBatchSize = theExpungeBatchSize; 1365 } 1366 1367 /** 1368 * Should contained IDs be indexed the same way that non-contained IDs are (default is 1369 * <code>true</code>) 1370 */ 1371 public boolean isIndexContainedResources() { 1372 return myIndexContainedResources; 1373 } 1374 1375 /** 1376 * Should contained IDs be indexed the same way that non-contained IDs are (default is 1377 * <code>true</code>) 1378 */ 1379 public void setIndexContainedResources(boolean theIndexContainedResources) { 1380 myIndexContainedResources = theIndexContainedResources; 1381 } 1382 1383 /** 1384 * Should resources be marked as needing reindexing when a 1385 * SearchParameter resource is added or changed. This should generally 1386 * be true (which is the default) 1387 */ 1388 public boolean isMarkResourcesForReindexingUponSearchParameterChange() { 1389 return myMarkResourcesForReindexingUponSearchParameterChange; 1390 } 1391 1392 /** 1393 * Should resources be marked as needing reindexing when a 1394 * SearchParameter resource is added or changed. This should generally 1395 * be true (which is the default) 1396 */ 1397 public void setMarkResourcesForReindexingUponSearchParameterChange(boolean theMarkResourcesForReindexingUponSearchParameterChange) { 1398 myMarkResourcesForReindexingUponSearchParameterChange = theMarkResourcesForReindexingUponSearchParameterChange; 1399 } 1400 1401 public boolean isSchedulingDisabled() { 1402 return mySchedulingDisabled; 1403 } 1404 1405 public void setSchedulingDisabled(boolean theSchedulingDisabled) { 1406 mySchedulingDisabled = theSchedulingDisabled; 1407 } 1408 1409 /** 1410 * If set to {@literal true} (default is true), if a client performs an update which does not actually 1411 * result in any chance to a given resource (e.g. an update where the resource body matches the 1412 * existing resource body in the database) the operation will succeed but a new version (and corresponding history 1413 * entry) will not actually be created. The existing resource version will be returned to the client. 1414 * <p> 1415 * If set to {@literal false}, all updates will result in the creation of a new version 1416 * </p> 1417 */ 1418 public boolean isSuppressUpdatesWithNoChange() { 1419 return mySuppressUpdatesWithNoChange; 1420 } 1421 1422 /** 1423 * If set to {@literal true} (default is true), if a client performs an update which does not actually 1424 * result in any chance to a given resource (e.g. an update where the resource body matches the 1425 * existing resource body in the database) the operation will succeed but a new version (and corresponding history 1426 * entry) will not actually be created. The existing resource version will be returned to the client. 1427 * <p> 1428 * If set to {@literal false}, all updates will result in the creation of a new version 1429 * </p> 1430 */ 1431 public void setSuppressUpdatesWithNoChange(boolean theSuppressUpdatesWithNoChange) { 1432 mySuppressUpdatesWithNoChange = theSuppressUpdatesWithNoChange; 1433 1434 } 1435 1436 /** 1437 * When using {@link #setUniqueIndexesEnabled(boolean) unique indexes}, if this 1438 * setting is set to <code>true</code> (default is <code>true</code>) the system 1439 * will test for the existence of a particular unique index value prior to saving 1440 * a new one. 1441 * <p> 1442 * This causes friendlier error messages to be generated, but adds an 1443 * extra round-trip to the database for eavh save so it can cause 1444 * a small performance hit. 1445 * </p> 1446 */ 1447 public boolean isUniqueIndexesCheckedBeforeSave() { 1448 return myUniqueIndexesCheckedBeforeSave; 1449 } 1450 1451 /** 1452 * When using {@link #setUniqueIndexesEnabled(boolean) unique indexes}, if this 1453 * setting is set to <code>true</code> (default is <code>true</code>) the system 1454 * will test for the existence of a particular unique index value prior to saving 1455 * a new one. 1456 * <p> 1457 * This causes friendlier error messages to be generated, but adds an 1458 * extra round-trip to the database for each save so it can cause 1459 * a small performance hit. 1460 * </p> 1461 */ 1462 public void setUniqueIndexesCheckedBeforeSave(boolean theUniqueIndexesCheckedBeforeSave) { 1463 myUniqueIndexesCheckedBeforeSave = theUniqueIndexesCheckedBeforeSave; 1464 } 1465 1466 /** 1467 * If set to <code>true</code> (default is <code>true</code>), indexes will be 1468 * created for search parameters marked as {@link HapiExtensions#EXT_SP_UNIQUE}. 1469 * This is a HAPI FHIR specific extension which can be used to specify that no more than one 1470 * resource can exist which matches a given criteria, using a database constraint to 1471 * enforce this. 1472 */ 1473 public boolean isUniqueIndexesEnabled() { 1474 return myUniqueIndexesEnabled; 1475 } 1476 1477 /** 1478 * If set to <code>true</code> (default is <code>true</code>), indexes will be 1479 * created for search parameters marked as {@link HapiExtensions#EXT_SP_UNIQUE}. 1480 * This is a HAPI FHIR specific extension which can be used to specify that no more than one 1481 * resource can exist which matches a given criteria, using a database constraint to 1482 * enforce this. 1483 */ 1484 public void setUniqueIndexesEnabled(boolean theUniqueIndexesEnabled) { 1485 myUniqueIndexesEnabled = theUniqueIndexesEnabled; 1486 } 1487 1488 /** 1489 * If <code>true</code> (default is <code>true</code>), before allowing a 1490 * SearchParameter resource to be stored (create, update, etc.) the 1491 * expression will be performed against an empty resource to ensure that 1492 * the FHIRPath executor is able to process it. 1493 * <p> 1494 * This should proabably always be set to true, but is configurable 1495 * in order to support some unit tests. 1496 * </p> 1497 */ 1498 public boolean isValidateSearchParameterExpressionsOnSave() { 1499 return myValidateSearchParameterExpressionsOnSave; 1500 } 1501 1502 /** 1503 * If <code>true</code> (default is <code>true</code>), before allowing a 1504 * SearchParameter resource to be stored (create, update, etc.) the 1505 * expression will be performed against an empty resource to ensure that 1506 * the FHIRPath executor is able to process it. 1507 * <p> 1508 * This should proabably always be set to true, but is configurable 1509 * in order to support some unit tests. 1510 * </p> 1511 */ 1512 public void setValidateSearchParameterExpressionsOnSave(boolean theValidateSearchParameterExpressionsOnSave) { 1513 myValidateSearchParameterExpressionsOnSave = theValidateSearchParameterExpressionsOnSave; 1514 } 1515 1516 /** 1517 * Do not call this method, it exists only for legacy reasons. It 1518 * will be removed in a future version. Configure the page size on your 1519 * paging provider instead. 1520 * 1521 * @deprecated This method does not do anything. Configure the page size on your 1522 * paging provider instead. Deprecated in HAPI FHIR 2.3 (Jan 2017) 1523 */ 1524 @Deprecated 1525 public void setHardSearchLimit(int theHardSearchLimit) { 1526 // this method does nothing 1527 } 1528 1529 /** 1530 * This is the maximum number of resources that will be added to a single page of returned resources. Because of 1531 * includes with wildcards and other possibilities it is possible for a client to make requests that include very 1532 * large amounts of data, so this hard limit can be imposed to prevent runaway requests. 1533 * 1534 * @deprecated Deprecated in HAPI FHIR 3.2.0 as this method doesn't actually do anything 1535 */ 1536 @Deprecated 1537 public void setIncludeLimit(@SuppressWarnings("unused") int theIncludeLimit) { 1538 // nothing 1539 } 1540 1541 /** 1542 * @deprecated As of HAPI FHIR 3.0.0, subscriptions no longer use polling for 1543 * detecting changes, so this setting has no effect 1544 */ 1545 @Deprecated 1546 public void setSubscriptionEnabled(boolean theSubscriptionEnabled) { 1547 // nothing 1548 } 1549 1550 /** 1551 * @deprecated As of HAPI FHIR 3.0.0, subscriptions no longer use polling for 1552 * detecting changes, so this setting has no effect 1553 */ 1554 @Deprecated 1555 public void setSubscriptionPollDelay(long theSubscriptionPollDelay) { 1556 // ignore 1557 } 1558 1559 /** 1560 * @deprecated As of HAPI FHIR 3.0.0, subscriptions no longer use polling for 1561 * detecting changes, so this setting has no effect 1562 */ 1563 @Deprecated 1564 public void setSubscriptionPurgeInactiveAfterMillis(Long theMillis) { 1565 // ignore 1566 } 1567 1568 public void setSubscriptionPurgeInactiveAfterSeconds(int theSeconds) { 1569 setSubscriptionPurgeInactiveAfterMillis(theSeconds * DateUtils.MILLIS_PER_SECOND); 1570 } 1571 1572 /** 1573 * This setting sets the number of search results to prefetch. For example, if this list 1574 * is set to [100, 1000, -1] then the server will initially load 100 results and not 1575 * attempt to load more. If the user requests subsequent page(s) of results and goes 1576 * past 100 results, the system will load the next 900 (up to the following threshold of 1000). 1577 * The system will progressively work through these thresholds. 1578 * 1579 * <p> 1580 * A threshold of -1 means to load all results. Note that if the final threshold is a 1581 * number other than <code>-1</code>, the system will never prefetch more than the 1582 * given number. 1583 * </p> 1584 */ 1585 public List<Integer> getSearchPreFetchThresholds() { 1586 return mySearchPreFetchThresholds; 1587 } 1588 1589 /** 1590 * This setting sets the number of search results to prefetch. For example, if this list 1591 * is set to [100, 1000, -1] then the server will initially load 100 results and not 1592 * attempt to load more. If the user requests subsequent page(s) of results and goes 1593 * past 100 results, the system will load the next 900 (up to the following threshold of 1000). 1594 * The system will progressively work through these thresholds. 1595 * 1596 * <p> 1597 * A threshold of -1 means to load all results. Note that if the final threshold is a 1598 * number other than <code>-1</code>, the system will never prefetch more than the 1599 * given number. 1600 * </p> 1601 */ 1602 public void setSearchPreFetchThresholds(List<Integer> thePreFetchThresholds) { 1603 Validate.isTrue(thePreFetchThresholds.size() > 0, "thePreFetchThresholds must not be empty"); 1604 int last = 0; 1605 for (Integer nextInt : thePreFetchThresholds) { 1606 Validate.isTrue(nextInt > 0 || nextInt == -1, nextInt + " is not a valid prefetch threshold"); 1607 Validate.isTrue(nextInt != last, "Prefetch thresholds must be sequential"); 1608 Validate.isTrue(nextInt > last || nextInt == -1, "Prefetch thresholds must be sequential"); 1609 Validate.isTrue(last != -1, "Prefetch thresholds must be sequential"); 1610 last = nextInt; 1611 } 1612 mySearchPreFetchThresholds = thePreFetchThresholds; 1613 } 1614 1615 /** 1616 * If set to <code>true</code> (default is false) the server will not use 1617 * hash based searches. These searches were introduced in HAPI FHIR 3.5.0 1618 * and are the new default way of searching. However they require a very 1619 * large data migration if an existing system has a large amount of data 1620 * so this setting can be used to use the old search mechanism while data 1621 * is migrated. 1622 * 1623 * @since 3.6.0 1624 */ 1625 public boolean getDisableHashBasedSearches() { 1626 return myDisableHashBasedSearches; 1627 } 1628 1629 /** 1630 * If set to <code>true</code> (default is false) the server will not use 1631 * hash based searches. These searches were introduced in HAPI FHIR 3.5.0 1632 * and are the new default way of searching. However they require a very 1633 * large data migration if an existing system has a large amount of data 1634 * so this setting can be used to use the old search mechanism while data 1635 * is migrated. 1636 * 1637 * @since 3.6.0 1638 */ 1639 public void setDisableHashBasedSearches(boolean theDisableHashBasedSearches) { 1640 myDisableHashBasedSearches = theDisableHashBasedSearches; 1641 } 1642 1643 /** 1644 * If set to <code>false</code> (default is true) the server will not use 1645 * in-memory subscription searching and instead use the database matcher for all subscription 1646 * criteria matching. 1647 * <p> 1648 * When there are subscriptions registered 1649 * on the server, the default behaviour is to compare the changed resource to the 1650 * subscription criteria directly in-memory without going out to the database. 1651 * Certain types of subscription criteria, e.g. chained references of queries with 1652 * qualifiers or prefixes, are not supported by the in-memory matcher and will fall back 1653 * to a database matcher. 1654 * <p> 1655 * The database matcher performs a query against the 1656 * database by prepending ?id=XYZ to the subscription criteria where XYZ is the id of the changed entity 1657 * 1658 * @since 3.6.1 1659 */ 1660 1661 public boolean isEnableInMemorySubscriptionMatching() { 1662 return myEnableInMemorySubscriptionMatching; 1663 } 1664 1665 /** 1666 * If set to <code>false</code> (default is true) the server will not use 1667 * in-memory subscription searching and instead use the database matcher for all subscription 1668 * criteria matching. 1669 * <p> 1670 * When there are subscriptions registered 1671 * on the server, the default behaviour is to compare the changed resource to the 1672 * subscription criteria directly in-memory without going out to the database. 1673 * Certain types of subscription criteria, e.g. chained references of queries with 1674 * qualifiers or prefixes, are not supported by the in-memory matcher and will fall back 1675 * to a database matcher. 1676 * <p> 1677 * The database matcher performs a query against the 1678 * database by prepending ?id=XYZ to the subscription criteria where XYZ is the id of the changed entity 1679 * 1680 * @since 3.6.1 1681 */ 1682 1683 public void setEnableInMemorySubscriptionMatching(boolean theEnableInMemorySubscriptionMatching) { 1684 myEnableInMemorySubscriptionMatching = theEnableInMemorySubscriptionMatching; 1685 } 1686 1687 public ModelConfig getModelConfig() { 1688 return myModelConfig; 1689 } 1690 1691 /** 1692 * If enabled, the server will support the use of :contains searches, 1693 * which are helpful but can have adverse effects on performance. 1694 * <p> 1695 * Default is <code>false</code> (Note that prior to HAPI FHIR 1696 * 3.5.0 the default was <code>true</code>) 1697 * </p> 1698 * <p> 1699 * Note: If you change this value after data already has 1700 * already been stored in the database, you must for a reindexing 1701 * of all data in the database or resources may not be 1702 * searchable. 1703 * </p> 1704 */ 1705 public boolean isAllowContainsSearches() { 1706 return this.myModelConfig.isAllowContainsSearches(); 1707 } 1708 1709 /** 1710 * If enabled, the server will support the use of :contains searches, 1711 * which are helpful but can have adverse effects on performance. 1712 * <p> 1713 * Default is <code>false</code> (Note that prior to HAPI FHIR 1714 * 3.5.0 the default was <code>true</code>) 1715 * </p> 1716 * <p> 1717 * Note: If you change this value after data already has 1718 * already been stored in the database, you must for a reindexing 1719 * of all data in the database or resources may not be 1720 * searchable. 1721 * </p> 1722 */ 1723 public void setAllowContainsSearches(boolean theAllowContainsSearches) { 1724 this.myModelConfig.setAllowContainsSearches(theAllowContainsSearches); 1725 } 1726 1727 /** 1728 * This setting may be used to advise the server that any references found in 1729 * resources that have any of the base URLs given here will be replaced with 1730 * simple local references. 1731 * <p> 1732 * For example, if the set contains the value <code>http://example.com/base/</code> 1733 * and a resource is submitted to the server that contains a reference to 1734 * <code>http://example.com/base/Patient/1</code>, the server will automatically 1735 * convert this reference to <code>Patient/1</code> 1736 * </p> 1737 * <p> 1738 * Note that this property has different behaviour from {@link DaoConfig#getTreatReferencesAsLogical()} 1739 * </p> 1740 * 1741 * @see #getTreatReferencesAsLogical() 1742 */ 1743 public Set<String> getTreatBaseUrlsAsLocal() { 1744 return myModelConfig.getTreatBaseUrlsAsLocal(); 1745 } 1746 1747 /** 1748 * This setting may be used to advise the server that any references found in 1749 * resources that have any of the base URLs given here will be replaced with 1750 * simple local references. 1751 * <p> 1752 * For example, if the set contains the value <code>http://example.com/base/</code> 1753 * and a resource is submitted to the server that contains a reference to 1754 * <code>http://example.com/base/Patient/1</code>, the server will automatically 1755 * convert this reference to <code>Patient/1</code> 1756 * </p> 1757 * 1758 * @param theTreatBaseUrlsAsLocal The set of base URLs. May be <code>null</code>, which 1759 * means no references will be treated as external 1760 */ 1761 public void setTreatBaseUrlsAsLocal(Set<String> theTreatBaseUrlsAsLocal) { 1762 myModelConfig.setTreatBaseUrlsAsLocal(theTreatBaseUrlsAsLocal); 1763 } 1764 1765 /** 1766 * If set to {@code true} the default search params (i.e. the search parameters that are 1767 * defined by the FHIR specification itself) may be overridden by uploading search 1768 * parameters to the server with the same code as the built-in search parameter. 1769 * <p> 1770 * This can be useful if you want to be able to disable or alter 1771 * the behaviour of the default search parameters. 1772 * </p> 1773 * <p> 1774 * The default value for this setting is {@code false} 1775 * </p> 1776 */ 1777 public boolean isDefaultSearchParamsCanBeOverridden() { 1778 return myModelConfig.isDefaultSearchParamsCanBeOverridden(); 1779 } 1780 1781 /** 1782 * If set to {@code true} the default search params (i.e. the search parameters that are 1783 * defined by the FHIR specification itself) may be overridden by uploading search 1784 * parameters to the server with the same code as the built-in search parameter. 1785 * <p> 1786 * This can be useful if you want to be able to disable or alter 1787 * the behaviour of the default search parameters. 1788 * </p> 1789 * <p> 1790 * The default value for this setting is {@code false} 1791 * </p> 1792 */ 1793 public void setDefaultSearchParamsCanBeOverridden(boolean theDefaultSearchParamsCanBeOverridden) { 1794 myModelConfig.setDefaultSearchParamsCanBeOverridden(theDefaultSearchParamsCanBeOverridden); 1795 } 1796 1797 /** 1798 * This setting indicates which subscription channel types are supported by the server. Any subscriptions submitted 1799 * to the server matching these types will be activated. 1800 */ 1801 public DaoConfig addSupportedSubscriptionType(Subscription.SubscriptionChannelType theSubscriptionChannelType) { 1802 myModelConfig.addSupportedSubscriptionType(theSubscriptionChannelType); 1803 return this; 1804 } 1805 1806 /** 1807 * This setting indicates which subscription channel types are supported by the server. Any subscriptions submitted 1808 * to the server matching these types will be activated. 1809 * 1810 * @see #addSupportedSubscriptionType(Subscription.SubscriptionChannelType) 1811 */ 1812 public Set<Subscription.SubscriptionChannelType> getSupportedSubscriptionTypes() { 1813 return myModelConfig.getSupportedSubscriptionTypes(); 1814 } 1815 1816 @VisibleForTesting 1817 public void clearSupportedSubscriptionTypesForUnitTest() { 1818 myModelConfig.clearSupportedSubscriptionTypesForUnitTest(); 1819 } 1820 1821 /** 1822 * If e-mail subscriptions are supported, the From address used when sending e-mails 1823 */ 1824 1825 public String getEmailFromAddress() { 1826 return myModelConfig.getEmailFromAddress(); 1827 } 1828 1829 /** 1830 * If e-mail subscriptions are supported, the From address used when sending e-mails 1831 */ 1832 1833 public void setEmailFromAddress(String theEmailFromAddress) { 1834 myModelConfig.setEmailFromAddress(theEmailFromAddress); 1835 } 1836 1837 /** 1838 * If websocket subscriptions are enabled, this defines the context path that listens to them. Default value "/websocket". 1839 */ 1840 1841 public String getWebsocketContextPath() { 1842 return myModelConfig.getWebsocketContextPath(); 1843 } 1844 1845 /** 1846 * If websocket subscriptions are enabled, this defines the context path that listens to them. Default value "/websocket". 1847 */ 1848 1849 public void setWebsocketContextPath(String theWebsocketContextPath) { 1850 myModelConfig.setWebsocketContextPath(theWebsocketContextPath); 1851 } 1852 1853 /** 1854 * If set to <code>true</code> the _filter search parameter will be enabled on this server. Note that _filter 1855 * is very powerful, but also potentially dangerous as it can allow a user to create a query for which there 1856 * are no indexes or efficient query plans for the database to leverage while performing the query. 1857 * As a result, this feature is recommended only for servers where the querying applications are known in advance 1858 * and a database administrator can properly tune the database for the resulting queries. 1859 */ 1860 public boolean isFilterParameterEnabled() { 1861 return myFilterParameterEnabled; 1862 } 1863 1864 /** 1865 * If set to <code>true</code> the _filter search parameter will be enabled on this server. Note that _filter 1866 * is very powerful, but also potentially dangerous as it can allow a user to create a query for which there 1867 * are no indexes or efficient query plans for the database to leverage while performing the query. 1868 * As a result, this feature is recommended only for servers where the querying applications are known in advance 1869 * and a database administrator can properly tune the database for the resulting queries. 1870 */ 1871 public void setFilterParameterEnabled(boolean theFilterParameterEnabled) { 1872 myFilterParameterEnabled = theFilterParameterEnabled; 1873 } 1874 1875 /** 1876 * If enabled, resource source information (<code>Resource.meta.source</code>) will be persisted along with 1877 * each resource. This adds extra table and index space so it should be disabled if it is not being 1878 * used. 1879 * <p> 1880 * Default is {@link StoreMetaSourceInformationEnum#SOURCE_URI_AND_REQUEST_ID} 1881 * </p> 1882 */ 1883 public StoreMetaSourceInformationEnum getStoreMetaSourceInformation() { 1884 return myStoreMetaSourceInformation; 1885 } 1886 1887 /** 1888 * If enabled, resource source information (<code>Resource.meta.source</code>) will be persisted along with 1889 * each resource. This adds extra table and index space so it should be disabled if it is not being 1890 * used. 1891 * <p> 1892 * Default is {@link StoreMetaSourceInformationEnum#SOURCE_URI_AND_REQUEST_ID} 1893 * </p> 1894 */ 1895 public void setStoreMetaSourceInformation(StoreMetaSourceInformationEnum theStoreMetaSourceInformation) { 1896 Validate.notNull(theStoreMetaSourceInformation, "theStoreMetaSourceInformation must not be null"); 1897 myStoreMetaSourceInformation = theStoreMetaSourceInformation; 1898 } 1899 1900 /** 1901 * <p> 1902 * If set to {@code true}, ValueSets and expansions are stored in terminology tables. This is to facilitate 1903 * optimization of the $expand operation on large ValueSets. 1904 * </p> 1905 * <p> 1906 * The default value for this setting is {@code true}. 1907 * </p> 1908 * 1909 * @since 4.1.0 1910 */ 1911 public boolean isPreExpandValueSets() { 1912 return myPreExpandValueSets; 1913 } 1914 1915 /** 1916 * <p> 1917 * If set to {@code true}, ValueSets and expansions are stored in terminology tables. This is to facilitate 1918 * optimization of the $expand operation on large ValueSets. 1919 * </p> 1920 * <p> 1921 * The default value for this setting is {@code true}. 1922 * </p> 1923 * 1924 * @since 4.1.0 1925 */ 1926 public void setPreExpandValueSets(boolean thePreExpandValueSets) { 1927 myPreExpandValueSets = thePreExpandValueSets; 1928 } 1929 1930 /** 1931 * <p> 1932 * This is the default value of {@code offset} parameter for the ValueSet {@code $expand} operation when 1933 * {@link DaoConfig#isPreExpandValueSets()} returns {@code true}. 1934 * </p> 1935 * <p> 1936 * The default value for this setting is {@code 0}. 1937 * </p> 1938 * 1939 * @since 4.1.0 1940 */ 1941 public int getPreExpandValueSetsDefaultOffset() { 1942 return myPreExpandValueSetsDefaultOffset; 1943 } 1944 1945 /** 1946 * <p> 1947 * This is the default value of {@code count} parameter for the ValueSet {@code $expand} operation when 1948 * {@link DaoConfig#isPreExpandValueSets()} returns {@code true}. 1949 * </p> 1950 * <p> 1951 * The default value for this setting is {@code 1000}. 1952 * </p> 1953 * 1954 * @since 4.1.0 1955 */ 1956 public int getPreExpandValueSetsDefaultCount() { 1957 return myPreExpandValueSetsDefaultCount; 1958 } 1959 1960 /** 1961 * <p> 1962 * This is the default value of {@code count} parameter for the ValueSet {@code $expand} operation when 1963 * {@link DaoConfig#isPreExpandValueSets()} returns {@code true}. 1964 * </p> 1965 * <p> 1966 * If {@code thePreExpandValueSetsDefaultCount} is greater than 1967 * {@link DaoConfig#getPreExpandValueSetsMaxCount()}, the lesser value is used. 1968 * </p> 1969 * <p> 1970 * The default value for this setting is {@code 1000}. 1971 * </p> 1972 * 1973 * @since 4.1.0 1974 */ 1975 public void setPreExpandValueSetsDefaultCount(int thePreExpandValueSetsDefaultCount) { 1976 myPreExpandValueSetsDefaultCount = Math.min(thePreExpandValueSetsDefaultCount, getPreExpandValueSetsMaxCount()); 1977 } 1978 1979 /** 1980 * <p> 1981 * This is the max value of {@code count} parameter for the ValueSet {@code $expand} operation when 1982 * {@link DaoConfig#isPreExpandValueSets()} returns {@code true}. 1983 * </p> 1984 * <p> 1985 * The default value for this setting is {@code 1000}. 1986 * </p> 1987 * 1988 * @since 4.1.0 1989 */ 1990 public int getPreExpandValueSetsMaxCount() { 1991 return myPreExpandValueSetsMaxCount; 1992 } 1993 1994 /** 1995 * <p> 1996 * This is the max value of {@code count} parameter for the ValueSet {@code $expand} operation when 1997 * {@link DaoConfig#isPreExpandValueSets()} returns {@code true}. 1998 * </p> 1999 * <p> 2000 * If {@code thePreExpandValueSetsMaxCount} is lesser than 2001 * {@link DaoConfig#getPreExpandValueSetsDefaultCount()}, the default {@code count} is lowered to the 2002 * new max {@code count}. 2003 * </p> 2004 * <p> 2005 * The default value for this setting is {@code 1000}. 2006 * </p> 2007 * 2008 * @since 4.1.0 2009 */ 2010 public void setPreExpandValueSetsMaxCount(int thePreExpandValueSetsMaxCount) { 2011 myPreExpandValueSetsMaxCount = thePreExpandValueSetsMaxCount; 2012 setPreExpandValueSetsDefaultCount(Math.min(getPreExpandValueSetsDefaultCount(), getPreExpandValueSetsMaxCount())); 2013 } 2014 2015 /** 2016 * This setting should be disabled (set to <code>false</code>) on servers that are not allowing 2017 * deletes. Default is <code>true</code>. If deletes are disabled, some checks for resource 2018 * deletion can be skipped, which improves performance. This is particularly helpful when large 2019 * amounts of data containing client-assigned IDs are being loaded, but it can also improve 2020 * search performance. 2021 * 2022 * @since 5.0.0 2023 */ 2024 public boolean isDeleteEnabled() { 2025 return myDeleteEnabled; 2026 } 2027 2028 /** 2029 * This setting should be disabled (set to <code>false</code>) on servers that are not allowing 2030 * deletes. Default is <code>true</code>. If deletes are disabled, some checks for resource 2031 * deletion can be skipped, which improves performance. This is particularly helpful when large 2032 * amounts of data containing client-assigned IDs are being loaded, but it can also improve 2033 * search performance. 2034 * 2035 * @since 5.0.0 2036 */ 2037 public void setDeleteEnabled(boolean theDeleteEnabled) { 2038 myDeleteEnabled = theDeleteEnabled; 2039 } 2040 2041 /** 2042 * <p> 2043 * This determines the maximum number of conflicts that should be fetched and handled while retrying a delete of a resource. 2044 * </p> 2045 * <p> 2046 * The default value for this setting is {@code 60}. 2047 * </p> 2048 * 2049 * @since 5.1.0 2050 */ 2051 public Integer getMaximumDeleteConflictQueryCount() { 2052 return myMaximumDeleteConflictQueryCount; 2053 } 2054 2055 /** 2056 * <p> 2057 * This determines the maximum number of conflicts that should be fetched and handled while retrying a delete of a resource. 2058 * </p> 2059 * <p> 2060 * The default value for this setting is {@code 60}. 2061 * </p> 2062 * 2063 * @since 5.1.0 2064 */ 2065 public void setMaximumDeleteConflictQueryCount(Integer theMaximumDeleteConflictQueryCount) { 2066 myMaximumDeleteConflictQueryCount = theMaximumDeleteConflictQueryCount; 2067 } 2068 2069 /** 2070 * <p> 2071 * This determines whether $binary-access-write operations should first load the InputStream into memory before persisting the 2072 * contents to the database. This needs to be enabled for MS SQL Server as this DB requires that the blob size be known 2073 * in advance. 2074 * </p> 2075 * <p> 2076 * Note that this setting should be enabled with caution as it can lead to significant demands on memory. 2077 * </p> 2078 * <p> 2079 * The default value for this setting is {@code false}. 2080 * </p> 2081 * 2082 * @since 5.1.0 2083 * @deprecated In 5.2.0 this setting no longer does anything 2084 */ 2085 @Deprecated 2086 public void setPreloadBlobFromInputStream(Boolean thePreloadBlobFromInputStream) { 2087 // ignore 2088 } 2089 2090 public enum StoreMetaSourceInformationEnum { 2091 NONE(false, false), 2092 SOURCE_URI(true, false), 2093 REQUEST_ID(false, true), 2094 SOURCE_URI_AND_REQUEST_ID(true, true); 2095 2096 private final boolean myStoreSourceUri; 2097 private final boolean myStoreRequestId; 2098 2099 StoreMetaSourceInformationEnum(boolean theStoreSourceUri, boolean theStoreRequestId) { 2100 myStoreSourceUri = theStoreSourceUri; 2101 myStoreRequestId = theStoreRequestId; 2102 } 2103 2104 public boolean isStoreSourceUri() { 2105 return myStoreSourceUri; 2106 } 2107 2108 public boolean isStoreRequestId() { 2109 return myStoreRequestId; 2110 } 2111 } 2112 2113 public enum IndexEnabledEnum { 2114 ENABLED, 2115 DISABLED 2116 } 2117 2118 /** 2119 * This enum provides allowable options for {@link #setResourceServerIdStrategy(IdStrategyEnum)} 2120 */ 2121 public enum IdStrategyEnum { 2122 /** 2123 * This strategy is the default strategy, and it simply uses a sequential 2124 * numeric ID for each newly created resource. 2125 */ 2126 SEQUENTIAL_NUMERIC, 2127 /** 2128 * Each resource will receive a randomly generated UUID 2129 */ 2130 UUID 2131 } 2132 2133 /** 2134 * This enum provides allowable options for {@link #setResourceClientIdStrategy(ClientIdStrategyEnum)} 2135 */ 2136 public enum ClientIdStrategyEnum { 2137 /** 2138 * Clients are not allowed to supply IDs for resources that do not 2139 * already exist 2140 */ 2141 NOT_ALLOWED, 2142 2143 /** 2144 * Clients may supply IDs but these IDs are not permitted to be purely 2145 * numeric. In other words, values such as "A", "A1" and "000A" would be considered 2146 * valid but "123" would not. 2147 * <p><b>This is the default setting.</b></p> 2148 */ 2149 ALPHANUMERIC, 2150 2151 /** 2152 * Clients may supply any ID including purely numeric IDs. Note that this setting should 2153 * only be set on an empty database, or on a database that has always had this setting 2154 * set as it causes a "forced ID" to be used for all resources. 2155 * <p> 2156 * Note that if you use this setting, it is highly recommended that you also 2157 * set the {@link #setResourceServerIdStrategy(IdStrategyEnum) ResourceServerIdStrategy} 2158 * to {@link IdStrategyEnum#UUID} in order to avoid any potential for conflicts. Otherwise 2159 * a database sequence will be used to generate IDs and these IDs can conflict with 2160 * client-assigned numeric IDs. 2161 * </p> 2162 */ 2163 ANY 2164 } 2165 2166}