From a2bc9a7212fe022d922053e3e4d212afeb13ea9e Mon Sep 17 00:00:00 2001 From: James Agnew Date: Sun, 2 Apr 2023 11:50:20 -0400 Subject: [PATCH] Partition aware search cleanup (#4706) * Partition aware search cleanup * Compile fixes * Build fixes * HAPI FHIR version bump * License * License header * Tests --- hapi-deployable-pom/pom.xml | 3 +- hapi-fhir-android/pom.xml | 3 +- hapi-fhir-base/pom.xml | 3 +- hapi-fhir-bom/pom.xml | 6 +- hapi-fhir-checkstyle/pom.xml | 3 +- hapi-fhir-cli/hapi-fhir-cli-api/pom.xml | 3 +- hapi-fhir-cli/hapi-fhir-cli-app/pom.xml | 3 +- hapi-fhir-cli/hapi-fhir-cli-jpaserver/pom.xml | 3 +- hapi-fhir-cli/pom.xml | 3 +- hapi-fhir-client-okhttp/pom.xml | 3 +- hapi-fhir-client/pom.xml | 3 +- hapi-fhir-converter/pom.xml | 3 +- hapi-fhir-dist/pom.xml | 3 +- hapi-fhir-docs/pom.xml | 3 +- hapi-fhir-jacoco/pom.xml | 3 +- hapi-fhir-jaxrsserver-base/pom.xml | 3 +- hapi-fhir-jpa/pom.xml | 3 +- hapi-fhir-jpaserver-base/pom.xml | 3 +- .../ca/uhn/fhir/jpa/config/SearchConfig.java | 3 +- .../search/PersistedJpaBundleProvider.java | 4 +- .../jpa/search/SearchCoordinatorSvcImpl.java | 14 +-- .../search/StaleSearchDeletingSvcImpl.java | 3 +- .../jpa/search/builder/tasks/SearchTask.java | 2 +- .../cache/DatabaseSearchCacheSvcImpl.java | 107 ++++++++++-------- .../jpa/search/cache/ISearchCacheSvc.java | 8 +- .../pom.xml | 2 +- hapi-fhir-jpaserver-ips/pom.xml | 3 +- hapi-fhir-jpaserver-mdm/pom.xml | 3 +- hapi-fhir-jpaserver-model/pom.xml | 3 +- hapi-fhir-jpaserver-searchparam/pom.xml | 3 +- hapi-fhir-jpaserver-subscription/pom.xml | 2 +- hapi-fhir-jpaserver-test-dstu2/pom.xml | 3 +- .../search/SearchCoordinatorSvcImplTest.java | 25 ++-- hapi-fhir-jpaserver-test-dstu3/pom.xml | 3 +- hapi-fhir-jpaserver-test-r4/pom.xml | 3 +- .../jpa/dao/r4/FhirResourceDaoR4Test.java | 2 +- .../dao/r4/SearchCoordinatorSvcImplTest.java | 7 +- hapi-fhir-jpaserver-test-r4b/pom.xml | 3 +- hapi-fhir-jpaserver-test-r5/pom.xml | 3 +- hapi-fhir-jpaserver-test-utilities/pom.xml | 3 +- .../jpa/test/Dstu3ValidationTestUtil.java | 19 ++++ .../fhir/jpa/test/R4ValidationTestUtil.java | 19 ++++ .../cache/DatabaseSearchCacheSvcImplTest.java | 14 +-- hapi-fhir-jpaserver-uhnfhirtest/pom.xml | 3 +- hapi-fhir-server-mdm/pom.xml | 3 +- hapi-fhir-server-openapi/pom.xml | 3 +- hapi-fhir-server/pom.xml | 7 +- .../ResponseHighlighterInterceptor.java | 24 +--- .../fhir/rest/server/util/NarrativeUtil.java | 91 +++++++++++++++ .../rest/server/util/NarrativeUtilTest.java | 39 +++++++ .../hapi-fhir-caching-api/pom.xml | 3 +- .../hapi-fhir-caching-caffeine/pom.xml | 6 +- .../hapi-fhir-caching-guava/pom.xml | 3 +- .../hapi-fhir-caching-testing/pom.xml | 3 +- hapi-fhir-serviceloaders/pom.xml | 2 +- .../pom.xml | 3 +- .../pom.xml | 2 +- .../pom.xml | 3 +- .../pom.xml | 3 +- .../hapi-fhir-spring-boot-samples/pom.xml | 3 +- .../hapi-fhir-spring-boot-starter/pom.xml | 3 +- hapi-fhir-spring-boot/pom.xml | 3 +- hapi-fhir-sql-migrate/pom.xml | 3 +- hapi-fhir-storage-batch2-jobs/pom.xml | 3 +- .../pom.xml | 3 +- hapi-fhir-storage-batch2/pom.xml | 3 +- hapi-fhir-storage-cr/pom.xml | 3 +- hapi-fhir-storage-mdm/pom.xml | 3 +- hapi-fhir-storage-test-utilities/pom.xml | 3 +- hapi-fhir-storage/pom.xml | 3 +- .../jpa/api/svc/ISearchCoordinatorSvc.java | 2 +- .../jpa/dao/tx/IHapiTransactionService.java | 16 +++ hapi-fhir-structures-dstu2.1/pom.xml | 3 +- hapi-fhir-structures-dstu2/pom.xml | 3 +- hapi-fhir-structures-dstu3/pom.xml | 3 +- hapi-fhir-structures-hl7org-dstu2/pom.xml | 3 +- hapi-fhir-structures-r4/pom.xml | 3 +- .../ResponseHighlightingInterceptorTest.java | 3 +- hapi-fhir-structures-r4b/pom.xml | 3 +- hapi-fhir-structures-r5/pom.xml | 3 +- hapi-fhir-test-utilities/pom.xml | 3 +- hapi-fhir-testpage-overlay/pom.xml | 3 +- .../java/ca/uhn/fhir/to/BaseController.java | 3 +- .../pom.xml | 3 +- hapi-fhir-validation-resources-dstu2/pom.xml | 3 +- hapi-fhir-validation-resources-dstu3/pom.xml | 3 +- hapi-fhir-validation-resources-r4/pom.xml | 3 +- hapi-fhir-validation-resources-r4b/pom.xml | 3 +- hapi-fhir-validation-resources-r5/pom.xml | 3 +- hapi-fhir-validation/pom.xml | 3 +- hapi-tinder-plugin/pom.xml | 3 +- hapi-tinder-test/pom.xml | 3 +- pom.xml | 8 +- .../pom.xml | 3 +- .../pom.xml | 3 +- .../pom.xml | 3 +- 96 files changed, 454 insertions(+), 190 deletions(-) create mode 100644 hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/util/NarrativeUtil.java create mode 100644 hapi-fhir-server/src/test/java/ca/uhn/fhir/rest/server/util/NarrativeUtilTest.java diff --git a/hapi-deployable-pom/pom.xml b/hapi-deployable-pom/pom.xml index d1d00a4500f..e5463754381 100644 --- a/hapi-deployable-pom/pom.xml +++ b/hapi-deployable-pom/pom.xml @@ -5,7 +5,8 @@ ca.uhn.hapi.fhir hapi-fhir - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT + ../pom.xml diff --git a/hapi-fhir-android/pom.xml b/hapi-fhir-android/pom.xml index e06ff02f534..665f6a02661 100644 --- a/hapi-fhir-android/pom.xml +++ b/hapi-fhir-android/pom.xml @@ -5,7 +5,8 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT + ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-base/pom.xml b/hapi-fhir-base/pom.xml index 761d70e5e55..2ceb0fd2d00 100644 --- a/hapi-fhir-base/pom.xml +++ b/hapi-fhir-base/pom.xml @@ -5,7 +5,8 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT + ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-bom/pom.xml b/hapi-fhir-bom/pom.xml index 2d8663a278e..125aba306fa 100644 --- a/hapi-fhir-bom/pom.xml +++ b/hapi-fhir-bom/pom.xml @@ -4,14 +4,16 @@ 4.0.0 ca.uhn.hapi.fhir hapi-fhir-bom - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT + pom HAPI FHIR BOM ca.uhn.hapi.fhir hapi-deployable-pom - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT + ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-checkstyle/pom.xml b/hapi-fhir-checkstyle/pom.xml index 8495ff5cda1..03667f2a69d 100644 --- a/hapi-fhir-checkstyle/pom.xml +++ b/hapi-fhir-checkstyle/pom.xml @@ -5,7 +5,8 @@ ca.uhn.hapi.fhir hapi-fhir - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT + ../pom.xml diff --git a/hapi-fhir-cli/hapi-fhir-cli-api/pom.xml b/hapi-fhir-cli/hapi-fhir-cli-api/pom.xml index 19e6204f078..3e0f78b837a 100644 --- a/hapi-fhir-cli/hapi-fhir-cli-api/pom.xml +++ b/hapi-fhir-cli/hapi-fhir-cli-api/pom.xml @@ -4,7 +4,8 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT + ../../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-cli/hapi-fhir-cli-app/pom.xml b/hapi-fhir-cli/hapi-fhir-cli-app/pom.xml index 071914a1900..b38bbff564c 100644 --- a/hapi-fhir-cli/hapi-fhir-cli-app/pom.xml +++ b/hapi-fhir-cli/hapi-fhir-cli-app/pom.xml @@ -6,7 +6,8 @@ ca.uhn.hapi.fhir hapi-fhir-cli - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT + ../pom.xml diff --git a/hapi-fhir-cli/hapi-fhir-cli-jpaserver/pom.xml b/hapi-fhir-cli/hapi-fhir-cli-jpaserver/pom.xml index 0e59c1de1f6..3dc23dd132d 100644 --- a/hapi-fhir-cli/hapi-fhir-cli-jpaserver/pom.xml +++ b/hapi-fhir-cli/hapi-fhir-cli-jpaserver/pom.xml @@ -6,7 +6,8 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT + ../../hapi-deployable-pom diff --git a/hapi-fhir-cli/pom.xml b/hapi-fhir-cli/pom.xml index f6fc6aa49d9..dda93b942ed 100644 --- a/hapi-fhir-cli/pom.xml +++ b/hapi-fhir-cli/pom.xml @@ -5,7 +5,8 @@ ca.uhn.hapi.fhir hapi-fhir - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT + ../pom.xml diff --git a/hapi-fhir-client-okhttp/pom.xml b/hapi-fhir-client-okhttp/pom.xml index 937ace806e2..194a35b3187 100644 --- a/hapi-fhir-client-okhttp/pom.xml +++ b/hapi-fhir-client-okhttp/pom.xml @@ -4,7 +4,8 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT + ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-client/pom.xml b/hapi-fhir-client/pom.xml index b2967811ce7..55a35016dda 100644 --- a/hapi-fhir-client/pom.xml +++ b/hapi-fhir-client/pom.xml @@ -4,7 +4,8 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT + ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-converter/pom.xml b/hapi-fhir-converter/pom.xml index 773473901e6..8704b295417 100644 --- a/hapi-fhir-converter/pom.xml +++ b/hapi-fhir-converter/pom.xml @@ -5,7 +5,8 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT + ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-dist/pom.xml b/hapi-fhir-dist/pom.xml index 1cbf54aaa90..cdf22a9fb5c 100644 --- a/hapi-fhir-dist/pom.xml +++ b/hapi-fhir-dist/pom.xml @@ -5,7 +5,8 @@ ca.uhn.hapi.fhir hapi-fhir - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT + ../pom.xml diff --git a/hapi-fhir-docs/pom.xml b/hapi-fhir-docs/pom.xml index 0400d094840..1ea2df3e7d1 100644 --- a/hapi-fhir-docs/pom.xml +++ b/hapi-fhir-docs/pom.xml @@ -5,7 +5,8 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT + ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jacoco/pom.xml b/hapi-fhir-jacoco/pom.xml index d096e22d4ae..a2ba9fd6ca3 100644 --- a/hapi-fhir-jacoco/pom.xml +++ b/hapi-fhir-jacoco/pom.xml @@ -11,7 +11,8 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT + ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jaxrsserver-base/pom.xml b/hapi-fhir-jaxrsserver-base/pom.xml index 101eb749be4..d39e5b47a0b 100644 --- a/hapi-fhir-jaxrsserver-base/pom.xml +++ b/hapi-fhir-jaxrsserver-base/pom.xml @@ -4,7 +4,8 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT + ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpa/pom.xml b/hapi-fhir-jpa/pom.xml index e63d5004337..e8dfba3ed7f 100644 --- a/hapi-fhir-jpa/pom.xml +++ b/hapi-fhir-jpa/pom.xml @@ -5,7 +5,8 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT + ../hapi-deployable-pom/pom.xml 4.0.0 diff --git a/hapi-fhir-jpaserver-base/pom.xml b/hapi-fhir-jpaserver-base/pom.xml index 6b41787078e..3729f9c7ee7 100644 --- a/hapi-fhir-jpaserver-base/pom.xml +++ b/hapi-fhir-jpaserver-base/pom.xml @@ -5,7 +5,8 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT + ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/SearchConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/SearchConfig.java index 0cbc723dca7..a4f7d96c37b 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/SearchConfig.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/SearchConfig.java @@ -120,8 +120,7 @@ public class SearchConfig { mySearchBuilderFactory, mySynchronousSearchSvc, myPersistedJpaBundleProviderFactory, - myRequestPartitionHelperService, - mySearchParamRegistry, + mySearchParamRegistry, mySearchStrategyFactory, exceptionService(), myBeanFactory diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/PersistedJpaBundleProvider.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/PersistedJpaBundleProvider.java index 85df3e6a91a..e4047a857c0 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/PersistedJpaBundleProvider.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/PersistedJpaBundleProvider.java @@ -249,7 +249,7 @@ public class PersistedJpaBundleProvider implements IBundleProvider { Optional searchOpt = myTxService .withRequest(myRequest) .withRequestPartitionId(myRequestPartitionId) - .execute(() -> mySearchCacheSvc.fetchByUuid(myUuid)); + .execute(() -> mySearchCacheSvc.fetchByUuid(myUuid, myRequestPartitionId)); if (!searchOpt.isPresent()) { return false; } @@ -404,7 +404,7 @@ public class PersistedJpaBundleProvider implements IBundleProvider { if (mySearchEntity.getSearchType() == SearchTypeEnum.HISTORY) { return null; } else { - return mySearchCoordinatorSvc.getSearchTotal(myUuid, myRequest).orElse(null); + return mySearchCoordinatorSvc.getSearchTotal(myUuid, myRequest, myRequestPartitionId).orElse(null); } } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java index c42637fdd8c..b4211055369 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java @@ -39,7 +39,6 @@ import ca.uhn.fhir.jpa.dao.tx.HapiTransactionService; import ca.uhn.fhir.jpa.entity.Search; import ca.uhn.fhir.jpa.model.dao.JpaPid; import ca.uhn.fhir.jpa.model.search.SearchStatusEnum; -import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc; import ca.uhn.fhir.jpa.search.builder.StorageInterceptorHooksFacade; import ca.uhn.fhir.jpa.search.builder.tasks.SearchContinuationTask; import ca.uhn.fhir.jpa.search.builder.tasks.SearchTask; @@ -113,7 +112,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc { private final BeanFactory myBeanFactory; private final ConcurrentHashMap myIdToSearchTask = new ConcurrentHashMap<>(); - private final Consumer myOnRemoveSearchTask = (theId) -> myIdToSearchTask.remove(theId); + private final Consumer myOnRemoveSearchTask = myIdToSearchTask::remove; private final StorageInterceptorHooksFacade myStorageInterceptorHooks; private Integer myLoadingThrottleForUnitTests = null; @@ -135,7 +134,6 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc { SearchBuilderFactory theSearchBuilderFactory, ISynchronousSearchSvc theSynchronousSearchSvc, PersistedJpaBundleProviderFactory thePersistedJpaBundleProviderFactory, - IRequestPartitionHelperSvc theRequestPartitionHelperService, ISearchParamRegistry theSearchParamRegistry, SearchStrategyFactory theSearchStrategyFactory, ExceptionService theExceptionSvc, @@ -245,7 +243,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc { } Callable searchCallback = () -> mySearchCacheSvc - .fetchByUuid(theUuid) + .fetchByUuid(theUuid, theRequestPartitionId) .orElseThrow(() -> myExceptionSvc.newUnknownSearchException(theUuid)); search = myTxService .withRequest(theRequestDetails) @@ -271,7 +269,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc { // start a new pass if (search.getStatus() == SearchStatusEnum.PASSCMPLET) { ourLog.trace("Going to try to start next search"); - Optional newSearch = mySearchCacheSvc.tryToMarkSearchAsInProgress(search); + Optional newSearch = mySearchCacheSvc.tryToMarkSearchAsInProgress(search, theRequestPartitionId); if (newSearch.isPresent()) { ourLog.trace("Launching new search"); search = newSearch.get(); @@ -440,7 +438,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc { } @Override - public Optional getSearchTotal(String theUuid, @Nullable RequestDetails theRequestDetails) { + public Optional getSearchTotal(String theUuid, @Nullable RequestDetails theRequestDetails, RequestPartitionId theRequestPartitionId) { SearchTask task = myIdToSearchTask.get(theUuid); if (task != null) { return Optional.ofNullable(task.awaitInitialSync()); @@ -450,7 +448,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc { * In case there is no running search, if the total is listed as accurate we know one is coming * so let's wait a bit for it to show up */ - Optional search = myTxService.withRequest(theRequestDetails).execute(() -> mySearchCacheSvc.fetchByUuid(theUuid)); + Optional search = myTxService.withRequest(theRequestDetails).execute(() -> mySearchCacheSvc.fetchByUuid(theUuid, theRequestPartitionId)); if (search.isPresent()) { Optional searchParameterMap = search.get().getSearchParameterMap(); if (searchParameterMap.isPresent() && searchParameterMap.get().getSearchTotalMode() == SearchTotalModeEnum.ACCURATE) { @@ -461,7 +459,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc { return Optional.of(search.get().getTotalCount()); } } - search = mySearchCacheSvc.fetchByUuid(theUuid); + search = mySearchCacheSvc.fetchByUuid(theUuid, theRequestPartitionId); } } } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/StaleSearchDeletingSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/StaleSearchDeletingSvcImpl.java index 96f67adcbcf..9d75460050a 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/StaleSearchDeletingSvcImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/StaleSearchDeletingSvcImpl.java @@ -19,6 +19,7 @@ */ package ca.uhn.fhir.jpa.search; +import ca.uhn.fhir.interceptor.model.RequestPartitionId; import ca.uhn.fhir.jpa.api.config.JpaStorageSettings; import ca.uhn.fhir.jpa.model.sched.HapiJob; import ca.uhn.fhir.jpa.model.sched.IHasScheduledJobs; @@ -50,7 +51,7 @@ public class StaleSearchDeletingSvcImpl implements IStaleSearchDeletingSvc, IHas @Override @Transactional(propagation = Propagation.NEVER) public void pollForStaleSearchesAndDeleteThem() { - mySearchCacheSvc.pollForStaleSearchesAndDeleteThem(); + mySearchCacheSvc.pollForStaleSearchesAndDeleteThem(RequestPartitionId.allPartitions()); } @Override diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/tasks/SearchTask.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/tasks/SearchTask.java index 1e2c6b18680..bb9ca5838c6 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/tasks/SearchTask.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/tasks/SearchTask.java @@ -474,7 +474,7 @@ public class SearchTask implements Callable { } private void doSaveSearch() { - Search newSearch = mySearchCacheSvc.save(mySearch); + Search newSearch = mySearchCacheSvc.save(mySearch, myRequestPartitionId); // mySearchDao.save is not supposed to return null, but in unit tests // it can if the mock search dao isn't set up to handle that diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/cache/DatabaseSearchCacheSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/cache/DatabaseSearchCacheSvcImpl.java index 03f5dbb705e..43618b428f9 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/cache/DatabaseSearchCacheSvcImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/cache/DatabaseSearchCacheSvcImpl.java @@ -25,6 +25,8 @@ import ca.uhn.fhir.jpa.api.config.JpaStorageSettings; import ca.uhn.fhir.jpa.dao.data.ISearchDao; import ca.uhn.fhir.jpa.dao.data.ISearchIncludeDao; import ca.uhn.fhir.jpa.dao.data.ISearchResultDao; +import ca.uhn.fhir.jpa.dao.tx.HapiTransactionService; +import ca.uhn.fhir.jpa.dao.tx.IHapiTransactionService; import ca.uhn.fhir.jpa.entity.Search; import ca.uhn.fhir.jpa.model.search.SearchStatusEnum; import ca.uhn.fhir.system.HapiSystemProperties; @@ -38,11 +40,8 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Slice; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; -import org.springframework.transaction.support.TransactionTemplate; import java.time.Instant; import java.util.Collection; @@ -58,7 +57,7 @@ public class DatabaseSearchCacheSvcImpl implements ISearchCacheSvc { */ public static final int DEFAULT_MAX_RESULTS_TO_DELETE_IN_ONE_STMT = 500; public static final int DEFAULT_MAX_RESULTS_TO_DELETE_IN_ONE_PAS = 20000; - public static final long SEARCH_CLEANUP_JOB_INTERVAL_MILLIS = 10 * DateUtils.MILLIS_PER_SECOND; + public static final long SEARCH_CLEANUP_JOB_INTERVAL_MILLIS = DateUtils.MILLIS_PER_MINUTE; public static final int DEFAULT_MAX_DELETE_CANDIDATES_TO_FIND = 2000; private static final Logger ourLog = LoggerFactory.getLogger(DatabaseSearchCacheSvcImpl.class); private static int ourMaximumResultsToDeleteInOneStatement = DEFAULT_MAX_RESULTS_TO_DELETE_IN_ONE_STMT; @@ -78,7 +77,7 @@ public class DatabaseSearchCacheSvcImpl implements ISearchCacheSvc { @Autowired private ISearchIncludeDao mySearchIncludeDao; @Autowired - private PlatformTransactionManager myTxManager; + private IHapiTransactionService myTransactionService; @Autowired private JpaStorageSettings myStorageSettings; @@ -87,45 +86,49 @@ public class DatabaseSearchCacheSvcImpl implements ISearchCacheSvc { myCutoffSlack = theCutoffSlack; } - @Transactional(propagation = Propagation.REQUIRED) @Override - public Search save(Search theSearch) { - Search newSearch = mySearchDao.save(theSearch); - return newSearch; + public Search save(Search theSearch, RequestPartitionId theRequestPartitionId) { + return myTransactionService + .withSystemRequestOnPartition(theRequestPartitionId) + .execute(() -> mySearchDao.save(theSearch)); } @Override @Transactional(propagation = Propagation.REQUIRED) - public Optional fetchByUuid(String theUuid) { + public Optional fetchByUuid(String theUuid, RequestPartitionId theRequestPartitionId) { Validate.notBlank(theUuid); - return mySearchDao.findByUuidAndFetchIncludes(theUuid); + return myTransactionService + .withSystemRequestOnPartition(theRequestPartitionId) + .execute(() -> mySearchDao.findByUuidAndFetchIncludes(theUuid)); } void setSearchDaoForUnitTest(ISearchDao theSearchDao) { mySearchDao = theSearchDao; } - void setTxManagerForUnitTest(PlatformTransactionManager theTxManager) { - myTxManager = theTxManager; + void setTransactionServiceForUnitTest(IHapiTransactionService theTransactionService) { + myTransactionService = theTransactionService; } @Override - public Optional tryToMarkSearchAsInProgress(Search theSearch) { + public Optional tryToMarkSearchAsInProgress(Search theSearch, RequestPartitionId theRequestPartitionId) { ourLog.trace("Going to try to change search status from {} to {}", theSearch.getStatus(), SearchStatusEnum.LOADING); try { - TransactionTemplate txTemplate = new TransactionTemplate(myTxManager); - txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); - txTemplate.afterPropertiesSet(); - return txTemplate.execute(t -> { - Search search = mySearchDao.findById(theSearch.getId()).orElse(theSearch); - if (search.getStatus() != SearchStatusEnum.PASSCMPLET) { - throw new IllegalStateException(Msg.code(1167) + "Can't change to LOADING because state is " + search.getStatus()); - } - search.setStatus(SearchStatusEnum.LOADING); - Search newSearch = mySearchDao.save(search); - return Optional.of(newSearch); - }); + return myTransactionService + .withSystemRequest() + .withRequestPartitionId(theRequestPartitionId) + .withPropagation(Propagation.REQUIRES_NEW) + .execute(t -> { + Search search = mySearchDao.findById(theSearch.getId()).orElse(theSearch); + + if (search.getStatus() != SearchStatusEnum.PASSCMPLET) { + throw new IllegalStateException(Msg.code(1167) + "Can't change to LOADING because state is " + search.getStatus()); + } + search.setStatus(SearchStatusEnum.LOADING); + Search newSearch = mySearchDao.save(search); + return Optional.of(newSearch); + }); } catch (Exception e) { ourLog.warn("Failed to activate search: {}", e.toString()); ourLog.trace("Failed to activate search", e); @@ -135,6 +138,8 @@ public class DatabaseSearchCacheSvcImpl implements ISearchCacheSvc { @Override public Optional findCandidatesForReuse(String theResourceType, String theQueryString, Instant theCreatedAfter, RequestPartitionId theRequestPartitionId) { + HapiTransactionService.requireTransaction(); + String queryString = Search.createSearchQueryStringForStorage(theQueryString, theRequestPartitionId); int hashCode = queryString.hashCode(); @@ -151,9 +156,10 @@ public class DatabaseSearchCacheSvcImpl implements ISearchCacheSvc { return Optional.empty(); } - @Transactional(propagation = Propagation.NEVER) @Override - public void pollForStaleSearchesAndDeleteThem() { + public void pollForStaleSearchesAndDeleteThem(RequestPartitionId theRequestPartitionId) { + HapiTransactionService.noTransactionAllowed(); + if (!myStorageSettings.isExpireSearchResults()) { return; } @@ -170,38 +176,49 @@ public class DatabaseSearchCacheSvcImpl implements ISearchCacheSvc { ourLog.debug("Searching for searches which are before {}", cutoff); - TransactionTemplate tt = new TransactionTemplate(myTxManager); - // Mark searches as deleted if they should be - final Slice toMarkDeleted = tt.execute(theStatus -> - mySearchDao.findWhereCreatedBefore(cutoff, new Date(), PageRequest.of(0, ourMaximumSearchesToCheckForDeletionCandidacy)) - ); + final Slice toMarkDeleted = myTransactionService + .withSystemRequestOnPartition(theRequestPartitionId) + .execute(theStatus -> + mySearchDao.findWhereCreatedBefore(cutoff, new Date(), PageRequest.of(0, ourMaximumSearchesToCheckForDeletionCandidacy)) + ); assert toMarkDeleted != null; for (final Long nextSearchToDelete : toMarkDeleted) { ourLog.debug("Deleting search with PID {}", nextSearchToDelete); - tt.execute(t -> { - mySearchDao.updateDeleted(nextSearchToDelete, true); - return null; - }); + myTransactionService + .withSystemRequest() + .withRequestPartitionId(theRequestPartitionId) + .execute(t -> { + mySearchDao.updateDeleted(nextSearchToDelete, true); + return null; + }); } // Delete searches that are marked as deleted - final Slice toDelete = tt.execute(theStatus -> - mySearchDao.findDeleted(PageRequest.of(0, ourMaximumSearchesToCheckForDeletionCandidacy)) - ); + final Slice toDelete = myTransactionService + .withSystemRequestOnPartition(theRequestPartitionId) + .execute(theStatus -> + mySearchDao.findDeleted(PageRequest.of(0, ourMaximumSearchesToCheckForDeletionCandidacy)) + ); assert toDelete != null; for (final Long nextSearchToDelete : toDelete) { ourLog.debug("Deleting search with PID {}", nextSearchToDelete); - tt.execute(t -> { - deleteSearch(nextSearchToDelete); - return null; - }); + myTransactionService + .withSystemRequest() + .withRequestPartitionId(theRequestPartitionId) + .execute(t -> { + deleteSearch(nextSearchToDelete); + return null; + }); } int count = toDelete.getContent().size(); if (count > 0) { if (ourLog.isDebugEnabled() || HapiSystemProperties.isTestModeEnabled()) { - Long total = tt.execute(t -> mySearchDao.count()); + Long total = myTransactionService + .withSystemRequest() + .withRequestPartitionId(theRequestPartitionId) + .execute(t -> mySearchDao.count()); ourLog.debug("Deleted {} searches, {} remaining", count, total); } } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/cache/ISearchCacheSvc.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/cache/ISearchCacheSvc.java index 49da515bf45..b78113cc84b 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/cache/ISearchCacheSvc.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/cache/ISearchCacheSvc.java @@ -34,7 +34,7 @@ public interface ISearchCacheSvc { * @param theSearch The search to store * @return Returns a copy of the search as it was saved. Callers should use the returned Search object for any further processing. */ - Search save(Search theSearch); + Search save(Search theSearch, RequestPartitionId theRequestPartitionId); /** * Fetch a search using its UUID. The search should be fully loaded when it is returned (i.e. includes are fetched, so that access to its @@ -43,7 +43,7 @@ public interface ISearchCacheSvc { * @param theUuid The search UUID * @return The search if it exists */ - Optional fetchByUuid(String theUuid); + Optional fetchByUuid(String theUuid, RequestPartitionId theRequestPartitionId); /** * TODO: this is perhaps an inappropriate responsibility for this service @@ -59,7 +59,7 @@ public interface ISearchCacheSvc { * succeeded in marking it). If the search doesn't exist or some other error occurred, an exception will be thrown * instead of {@link Optional#empty()} */ - Optional tryToMarkSearchAsInProgress(Search theSearch); + Optional tryToMarkSearchAsInProgress(Search theSearch, RequestPartitionId theRequestPartitionId); /** * Look for any existing searches matching the given resource type and query string. @@ -82,5 +82,5 @@ public interface ISearchCacheSvc { * if they have some other mechanism for expiring stale results other than manually looking for them * and deleting them. */ - void pollForStaleSearchesAndDeleteThem(); + void pollForStaleSearchesAndDeleteThem(RequestPartitionId theRequestPartitionId); } diff --git a/hapi-fhir-jpaserver-elastic-test-utilities/pom.xml b/hapi-fhir-jpaserver-elastic-test-utilities/pom.xml index a1c1c437e1f..8ccce2ad972 100644 --- a/hapi-fhir-jpaserver-elastic-test-utilities/pom.xml +++ b/hapi-fhir-jpaserver-elastic-test-utilities/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-ips/pom.xml b/hapi-fhir-jpaserver-ips/pom.xml index 9c48b491964..20a62036ad1 100644 --- a/hapi-fhir-jpaserver-ips/pom.xml +++ b/hapi-fhir-jpaserver-ips/pom.xml @@ -3,7 +3,8 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT + ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-mdm/pom.xml b/hapi-fhir-jpaserver-mdm/pom.xml index c2a6689b63e..e799c3abdab 100644 --- a/hapi-fhir-jpaserver-mdm/pom.xml +++ b/hapi-fhir-jpaserver-mdm/pom.xml @@ -6,7 +6,8 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT + ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-model/pom.xml b/hapi-fhir-jpaserver-model/pom.xml index 750fee29f61..0b04919d349 100644 --- a/hapi-fhir-jpaserver-model/pom.xml +++ b/hapi-fhir-jpaserver-model/pom.xml @@ -5,7 +5,8 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT + ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-searchparam/pom.xml b/hapi-fhir-jpaserver-searchparam/pom.xml index 8e946c05556..1b1d1974fe8 100755 --- a/hapi-fhir-jpaserver-searchparam/pom.xml +++ b/hapi-fhir-jpaserver-searchparam/pom.xml @@ -5,7 +5,8 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT + ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-subscription/pom.xml b/hapi-fhir-jpaserver-subscription/pom.xml index 498dca07b61..769de666558 100644 --- a/hapi-fhir-jpaserver-subscription/pom.xml +++ b/hapi-fhir-jpaserver-subscription/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-test-dstu2/pom.xml b/hapi-fhir-jpaserver-test-dstu2/pom.xml index 1c75570d80e..ed11b71f83d 100644 --- a/hapi-fhir-jpaserver-test-dstu2/pom.xml +++ b/hapi-fhir-jpaserver-test-dstu2/pom.xml @@ -6,7 +6,8 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT + ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-test-dstu2/src/test/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImplTest.java b/hapi-fhir-jpaserver-test-dstu2/src/test/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImplTest.java index 416dc6cf5b1..a3e94a48969 100644 --- a/hapi-fhir-jpaserver-test-dstu2/src/test/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImplTest.java +++ b/hapi-fhir-jpaserver-test-dstu2/src/test/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImplTest.java @@ -134,7 +134,6 @@ public class SearchCoordinatorSvcImplTest extends BaseSearchSvc { mySearchBuilderFactory, mySynchronousSearchSvc, myPersistedJpaBundleProviderFactory, - myPartitionHelperSvc, null, // search param registry mySearchStrategyFactory, myExceptionSvc, @@ -187,7 +186,7 @@ public class SearchCoordinatorSvcImplTest extends BaseSearchSvc { when(mySearchBuilder.createQuery(any(), any(), any(), nullable(RequestPartitionId.class))).thenReturn(iter); doAnswer(loadPids()).when(mySearchBuilder).loadResourcesByPid(any(Collection.class), any(Collection.class), any(List.class), anyBoolean(), any()); - when(mySearchCacheSvc.save(any())).thenAnswer(t -> { + when(mySearchCacheSvc.save(any(), any())).thenAnswer(t -> { Search search = t.getArgument(0, Search.class); myCurrentSearch = search; return search; @@ -207,7 +206,7 @@ public class SearchCoordinatorSvcImplTest extends BaseSearchSvc { assertEquals("799", resources.get(789).getIdElement().getValueAsString()); ArgumentCaptor searchCaptor = ArgumentCaptor.forClass(Search.class); - verify(mySearchCacheSvc, atLeastOnce()).save(searchCaptor.capture()); + verify(mySearchCacheSvc, atLeastOnce()).save(searchCaptor.capture(), any()); assertEquals(790, allResults.size()); assertEquals(10, allResults.get(0).getId()); @@ -224,10 +223,10 @@ public class SearchCoordinatorSvcImplTest extends BaseSearchSvc { myCurrentSearch.setStatus(SearchStatusEnum.PASSCMPLET); myCurrentSearch.setNumFound(10); - when(mySearchCacheSvc.fetchByUuid(any())).thenAnswer(t -> Optional.ofNullable(myCurrentSearch)); + when(mySearchCacheSvc.fetchByUuid(any(), any())).thenAnswer(t -> Optional.ofNullable(myCurrentSearch)); - when(mySearchCacheSvc.tryToMarkSearchAsInProgress(any())).thenAnswer(t -> { - when(mySearchCacheSvc.fetchByUuid(any())).thenAnswer(t2 -> Optional.empty()); + when(mySearchCacheSvc.tryToMarkSearchAsInProgress(any(), any())).thenAnswer(t -> { + when(mySearchCacheSvc.fetchByUuid(any(), any())).thenAnswer(t2 -> Optional.empty()); return Optional.empty(); }); @@ -248,7 +247,7 @@ public class SearchCoordinatorSvcImplTest extends BaseSearchSvc { myCurrentSearch.setStatus(SearchStatusEnum.PASSCMPLET); myCurrentSearch.setNumFound(10); - when(mySearchCacheSvc.fetchByUuid(any())).thenAnswer(t -> { + when(mySearchCacheSvc.fetchByUuid(any(), any())).thenAnswer(t -> { sleepAtLeast(100); return Optional.ofNullable(myCurrentSearch); }); @@ -373,7 +372,7 @@ public class SearchCoordinatorSvcImplTest extends BaseSearchSvc { List pids = createPidSequence(800); IResultIterator iter = new SlowIterator(pids.iterator(), 2); when(mySearchBuilder.createQuery(same(params), any(), any(), nullable(RequestPartitionId.class))).thenReturn(iter); - when(mySearchCacheSvc.save(any())).thenAnswer(t -> { + when(mySearchCacheSvc.save(any(), any())).thenAnswer(t -> { ourLog.info("Saving search"); return t.getArgument(0, Search.class); }); @@ -386,7 +385,7 @@ public class SearchCoordinatorSvcImplTest extends BaseSearchSvc { assertEquals(790, result.size()); ArgumentCaptor searchCaptor = ArgumentCaptor.forClass(Search.class); - verify(mySearchCacheSvc, atLeast(1)).save(searchCaptor.capture()); + verify(mySearchCacheSvc, atLeast(1)).save(searchCaptor.capture(), any()); Search search = searchCaptor.getValue(); assertEquals(SearchTypeEnum.SEARCH, search.getSearchType()); @@ -450,7 +449,7 @@ public class SearchCoordinatorSvcImplTest extends BaseSearchSvc { search.setStatus(SearchStatusEnum.LOADING); search.setSearchParameterMap(new SearchParameterMap()); - when(mySearchCacheSvc.fetchByUuid(eq(uuid))).thenReturn(Optional.of(search)); + when(mySearchCacheSvc.fetchByUuid(eq(uuid), any())).thenReturn(Optional.of(search)); doAnswer(loadPids()).when(mySearchBuilder).loadResourcesByPid(any(Collection.class), any(Collection.class), any(List.class), anyBoolean(), any()); PersistedJpaBundleProvider provider; @@ -567,7 +566,7 @@ public class SearchCoordinatorSvcImplTest extends BaseSearchSvc { search.setStatus(SearchStatusEnum.FINISHED); search.setNumFound(100); search.setTotalCount(100); - when(mySearchCacheSvc.fetchByUuid(eq("0000-1111"))).thenReturn(Optional.of(search)); + when(mySearchCacheSvc.fetchByUuid(eq("0000-1111"), any())).thenReturn(Optional.of(search)); when(mySearchResultCacheSvc.fetchResultPids(any(), anyInt(), anyInt(), any(), any())).thenReturn(null); @@ -594,9 +593,9 @@ public class SearchCoordinatorSvcImplTest extends BaseSearchSvc { search.setStatus(SearchStatusEnum.PASSCMPLET); search.setNumFound(5); search.setSearchParameterMap(new SearchParameterMap()); - when(mySearchCacheSvc.fetchByUuid(eq("0000-1111"))).thenReturn(Optional.of(search)); + when(mySearchCacheSvc.fetchByUuid(eq("0000-1111"), any())).thenReturn(Optional.of(search)); - when(mySearchCacheSvc.tryToMarkSearchAsInProgress(any())).thenAnswer(t -> { + when(mySearchCacheSvc.tryToMarkSearchAsInProgress(any(), any())).thenAnswer(t -> { search.setStatus(SearchStatusEnum.LOADING); return Optional.of(search); }); diff --git a/hapi-fhir-jpaserver-test-dstu3/pom.xml b/hapi-fhir-jpaserver-test-dstu3/pom.xml index 6a819d4a95b..af7dac0133b 100644 --- a/hapi-fhir-jpaserver-test-dstu3/pom.xml +++ b/hapi-fhir-jpaserver-test-dstu3/pom.xml @@ -6,7 +6,8 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT + ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-test-r4/pom.xml b/hapi-fhir-jpaserver-test-r4/pom.xml index 596d7dbb6f2..13e6ff0daaa 100644 --- a/hapi-fhir-jpaserver-test-r4/pom.xml +++ b/hapi-fhir-jpaserver-test-r4/pom.xml @@ -6,7 +6,8 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT + ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4Test.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4Test.java index 5688d527f30..1b88a86ec28 100644 --- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4Test.java +++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4Test.java @@ -4281,7 +4281,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test { search.setStatus(SearchStatusEnum.FAILED); search.setFailureCode(500); search.setFailureMessage("FOO"); - mySearchCacheSvc.save(search); + mySearchCacheSvc.save(search, RequestPartitionId.defaultPartition()); }); IBundleProvider results = myEncounterDao.search(map); diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/SearchCoordinatorSvcImplTest.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/SearchCoordinatorSvcImplTest.java index 601d6d3e55f..18657d1d5b0 100644 --- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/SearchCoordinatorSvcImplTest.java +++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/SearchCoordinatorSvcImplTest.java @@ -1,5 +1,6 @@ package ca.uhn.fhir.jpa.dao.r4; +import ca.uhn.fhir.interceptor.model.RequestPartitionId; import ca.uhn.fhir.jpa.api.svc.ISearchCoordinatorSvc; import ca.uhn.fhir.jpa.dao.data.ISearchDao; import ca.uhn.fhir.jpa.dao.data.ISearchResultDao; @@ -85,7 +86,7 @@ public class SearchCoordinatorSvcImplTest extends BaseJpaR4Test { assertEquals(30, mySearchResultDao.count()); }); - myDatabaseCacheSvc.pollForStaleSearchesAndDeleteThem(); + myDatabaseCacheSvc.pollForStaleSearchesAndDeleteThem(RequestPartitionId.allPartitions()); runInTransaction(()->{ // We should delete up to 10, but 3 don't get deleted since they have too many results to delete in one pass assertEquals(13, mySearchDao.count()); @@ -94,7 +95,7 @@ public class SearchCoordinatorSvcImplTest extends BaseJpaR4Test { assertEquals(15, mySearchResultDao.count()); }); - myDatabaseCacheSvc.pollForStaleSearchesAndDeleteThem(); + myDatabaseCacheSvc.pollForStaleSearchesAndDeleteThem(RequestPartitionId.allPartitions()); runInTransaction(()->{ // Once again we attempt to delete 10, but the first 3 don't get deleted and still remain // (total is 6 because 3 weren't deleted, and they blocked another 3 that might have been) @@ -103,7 +104,7 @@ public class SearchCoordinatorSvcImplTest extends BaseJpaR4Test { assertEquals(0, mySearchResultDao.count()); }); - myDatabaseCacheSvc.pollForStaleSearchesAndDeleteThem(); + myDatabaseCacheSvc.pollForStaleSearchesAndDeleteThem(RequestPartitionId.allPartitions()); runInTransaction(()->{ assertEquals(0, mySearchDao.count()); assertEquals(0, mySearchDao.countDeleted()); diff --git a/hapi-fhir-jpaserver-test-r4b/pom.xml b/hapi-fhir-jpaserver-test-r4b/pom.xml index e44617ae0d6..acbeb94438a 100644 --- a/hapi-fhir-jpaserver-test-r4b/pom.xml +++ b/hapi-fhir-jpaserver-test-r4b/pom.xml @@ -6,7 +6,8 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT + ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-test-r5/pom.xml b/hapi-fhir-jpaserver-test-r5/pom.xml index 782c760a67f..86fa3e3fa66 100644 --- a/hapi-fhir-jpaserver-test-r5/pom.xml +++ b/hapi-fhir-jpaserver-test-r5/pom.xml @@ -6,7 +6,8 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT + ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-test-utilities/pom.xml b/hapi-fhir-jpaserver-test-utilities/pom.xml index 9b787c8772b..593166773e7 100644 --- a/hapi-fhir-jpaserver-test-utilities/pom.xml +++ b/hapi-fhir-jpaserver-test-utilities/pom.xml @@ -6,7 +6,8 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT + ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/Dstu3ValidationTestUtil.java b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/Dstu3ValidationTestUtil.java index a369f94b1f8..30163111846 100644 --- a/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/Dstu3ValidationTestUtil.java +++ b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/Dstu3ValidationTestUtil.java @@ -1,3 +1,22 @@ +/*- + * #%L + * HAPI FHIR JPA Server Test Utilities + * %% + * Copyright (C) 2014 - 2023 Smile CDR, Inc. + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ package ca.uhn.fhir.jpa.test; import ca.uhn.fhir.context.FhirContext; diff --git a/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/R4ValidationTestUtil.java b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/R4ValidationTestUtil.java index 340dc2352ed..cbfdf665dcf 100644 --- a/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/R4ValidationTestUtil.java +++ b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/R4ValidationTestUtil.java @@ -1,3 +1,22 @@ +/*- + * #%L + * HAPI FHIR JPA Server Test Utilities + * %% + * Copyright (C) 2014 - 2023 Smile CDR, Inc. + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ package ca.uhn.fhir.jpa.test; import ca.uhn.fhir.context.FhirContext; diff --git a/hapi-fhir-jpaserver-test-utilities/src/test/java/ca/uhn/fhir/jpa/search/cache/DatabaseSearchCacheSvcImplTest.java b/hapi-fhir-jpaserver-test-utilities/src/test/java/ca/uhn/fhir/jpa/search/cache/DatabaseSearchCacheSvcImplTest.java index 40a8049bc91..f171a48e21a 100644 --- a/hapi-fhir-jpaserver-test-utilities/src/test/java/ca/uhn/fhir/jpa/search/cache/DatabaseSearchCacheSvcImplTest.java +++ b/hapi-fhir-jpaserver-test-utilities/src/test/java/ca/uhn/fhir/jpa/search/cache/DatabaseSearchCacheSvcImplTest.java @@ -1,6 +1,8 @@ package ca.uhn.fhir.jpa.search.cache; +import ca.uhn.fhir.interceptor.model.RequestPartitionId; import ca.uhn.fhir.jpa.dao.data.ISearchDao; +import ca.uhn.fhir.jpa.dao.tx.NonTransactionalHapiTransactionService; import ca.uhn.fhir.jpa.entity.Search; import ca.uhn.fhir.jpa.model.search.SearchStatusEnum; import org.hibernate.HibernateException; @@ -9,7 +11,6 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.transaction.PlatformTransactionManager; import java.util.Optional; @@ -30,14 +31,11 @@ public class DatabaseSearchCacheSvcImplTest { @Mock private ISearchDao mySearchDao; - @Mock - private PlatformTransactionManager myTxManager; - @BeforeEach public void before() { mySvc = new DatabaseSearchCacheSvcImpl(); mySvc.setSearchDaoForUnitTest(mySearchDao); - mySvc.setTxManagerForUnitTest(myTxManager); + mySvc.setTransactionServiceForUnitTest(new NonTransactionalHapiTransactionService()); } @Test @@ -48,7 +46,7 @@ public class DatabaseSearchCacheSvcImplTest { when(mySearchDao.save(any())).thenReturn(updated); Search search = new Search(); - Optional outcome = mySvc.tryToMarkSearchAsInProgress(search); + Optional outcome = mySvc.tryToMarkSearchAsInProgress(search, RequestPartitionId.allPartitions()); assertTrue(outcome.isPresent()); verify(mySearchDao, times(1)).save(any()); @@ -63,7 +61,7 @@ public class DatabaseSearchCacheSvcImplTest { when(mySearchDao.save(any())).thenThrow(new HibernateException("FOO")); Search search = new Search(); - Optional outcome = mySvc.tryToMarkSearchAsInProgress(search); + Optional outcome = mySvc.tryToMarkSearchAsInProgress(search, RequestPartitionId.allPartitions()); assertFalse(outcome.isPresent()); verify(mySearchDao, times(1)).save(any()); } @@ -75,7 +73,7 @@ public class DatabaseSearchCacheSvcImplTest { when(mySearchDao.findById(any())).thenReturn(Optional.of(updated)); Search search = new Search(); - Optional outcome = mySvc.tryToMarkSearchAsInProgress(search); + Optional outcome = mySvc.tryToMarkSearchAsInProgress(search, RequestPartitionId.allPartitions()); assertFalse(outcome.isPresent()); verify(mySearchDao, never()).save(any()); } diff --git a/hapi-fhir-jpaserver-uhnfhirtest/pom.xml b/hapi-fhir-jpaserver-uhnfhirtest/pom.xml index 23a6fa4d01e..8845e47a848 100644 --- a/hapi-fhir-jpaserver-uhnfhirtest/pom.xml +++ b/hapi-fhir-jpaserver-uhnfhirtest/pom.xml @@ -5,7 +5,8 @@ ca.uhn.hapi.fhir hapi-fhir - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT + ../pom.xml diff --git a/hapi-fhir-server-mdm/pom.xml b/hapi-fhir-server-mdm/pom.xml index 1edb123e287..18c787a80cd 100644 --- a/hapi-fhir-server-mdm/pom.xml +++ b/hapi-fhir-server-mdm/pom.xml @@ -7,7 +7,8 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT + ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-server-openapi/pom.xml b/hapi-fhir-server-openapi/pom.xml index e2bc1485350..f657f31381d 100644 --- a/hapi-fhir-server-openapi/pom.xml +++ b/hapi-fhir-server-openapi/pom.xml @@ -5,7 +5,8 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT + ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-server/pom.xml b/hapi-fhir-server/pom.xml index a657043e0e1..d33cf86ad70 100644 --- a/hapi-fhir-server/pom.xml +++ b/hapi-fhir-server/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.5.10-SNAPSHOT + 6.5.11-SNAPSHOT ../hapi-deployable-pom/pom.xml @@ -44,6 +44,11 @@ httpcore + + com.googlecode.owasp-java-html-sanitizer + owasp-java-html-sanitizer + +