diff --git a/hapi-deployable-pom/pom.xml b/hapi-deployable-pom/pom.xml index 005f3056e26c..9e4e8f7ab23b 100644 --- a/hapi-deployable-pom/pom.xml +++ b/hapi-deployable-pom/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 7.4.1-SNAPSHOT + 7.4.2 ../pom.xml diff --git a/hapi-fhir-android/pom.xml b/hapi-fhir-android/pom.xml index 8c0f9dacee41..0afd895c646e 100644 --- a/hapi-fhir-android/pom.xml +++ b/hapi-fhir-android/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-base/pom.xml b/hapi-fhir-base/pom.xml index e1d8f4273d7f..524e6a59e493 100644 --- a/hapi-fhir-base/pom.xml +++ b/hapi-fhir-base/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/TaskChunker.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/TaskChunker.java index 7d4b80f3d08b..9514e0597404 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/TaskChunker.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/TaskChunker.java @@ -20,10 +20,12 @@ * #L% */ +import com.google.common.collect.Streams; import jakarta.annotation.Nonnull; import java.util.ArrayList; import java.util.Collection; +import java.util.Iterator; import java.util.List; import java.util.function.Consumer; import java.util.stream.Stream; @@ -57,4 +59,9 @@ public void chunk(Collection theInput, int theChunkSize, Consumer> th public Stream> chunk(Stream theStream, int theChunkSize) { return StreamUtil.partition(theStream, theChunkSize); } + + @Nonnull + public void chunk(Iterator theIterator, int theChunkSize, Consumer> theListConsumer) { + chunk(Streams.stream(theIterator), theChunkSize).forEach(theListConsumer); + } } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/VersionEnum.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/VersionEnum.java index 303564d139ce..911e7fc4f820 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/VersionEnum.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/VersionEnum.java @@ -159,7 +159,8 @@ public enum VersionEnum { V7_3_0, V7_4_0, - V7_4_1; + V7_4_1, + V7_4_2; public static VersionEnum latestVersion() { VersionEnum[] values = VersionEnum.values(); diff --git a/hapi-fhir-base/src/test/java/ca/uhn/fhir/util/TaskChunkerTest.java b/hapi-fhir-base/src/test/java/ca/uhn/fhir/util/TaskChunkerTest.java index d815fde6b31f..aff2b3b9b89d 100644 --- a/hapi-fhir-base/src/test/java/ca/uhn/fhir/util/TaskChunkerTest.java +++ b/hapi-fhir-base/src/test/java/ca/uhn/fhir/util/TaskChunkerTest.java @@ -3,14 +3,21 @@ import jakarta.annotation.Nonnull; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; import java.util.List; import java.util.function.Consumer; import java.util.stream.IntStream; +import java.util.stream.Stream; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.times; @@ -43,8 +50,32 @@ public void testChunk() { @Nonnull private static List newIntRangeList(int startInclusive, int endExclusive) { - List input = IntStream.range(startInclusive, endExclusive).boxed().toList(); - return input; + return IntStream.range(startInclusive, endExclusive).boxed().toList(); + } + + @ParameterizedTest + @MethodSource("testIteratorChunkArguments") + void testIteratorChunk(List theListToChunk, List> theExpectedChunks) { + // given + Iterator iter = theListToChunk.iterator(); + ArrayList> result = new ArrayList<>(); + + // when + new TaskChunker().chunk(iter, 3, result::add); + + // then + assertEquals(theExpectedChunks, result); + } + + public static Stream testIteratorChunkArguments() { + return Stream.of( + Arguments.of(Collections.emptyList(), Collections.emptyList()), + Arguments.of(List.of(1), List.of(List.of(1))), + Arguments.of(List.of(1,2), List.of(List.of(1,2))), + Arguments.of(List.of(1,2,3), List.of(List.of(1,2,3))), + Arguments.of(List.of(1,2,3,4), List.of(List.of(1,2,3), List.of(4))), + Arguments.of(List.of(1,2,3,4,5,6,7,8,9), List.of(List.of(1,2,3), List.of(4,5,6), List.of(7,8,9))) + ); } } diff --git a/hapi-fhir-bom/pom.xml b/hapi-fhir-bom/pom.xml index 906098eb6420..b4079d8a0864 100644 --- a/hapi-fhir-bom/pom.xml +++ b/hapi-fhir-bom/pom.xml @@ -4,7 +4,7 @@ 4.0.0 ca.uhn.hapi.fhir hapi-fhir-bom - 7.4.1-SNAPSHOT + 7.4.2 pom HAPI FHIR BOM @@ -12,7 +12,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-checkstyle/pom.xml b/hapi-fhir-checkstyle/pom.xml index f027b336b833..7ad09bb0708f 100644 --- a/hapi-fhir-checkstyle/pom.xml +++ b/hapi-fhir-checkstyle/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 7.4.1-SNAPSHOT + 7.4.2 ../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 855f41860e46..0245bcd3db8d 100644 --- a/hapi-fhir-cli/hapi-fhir-cli-api/pom.xml +++ b/hapi-fhir-cli/hapi-fhir-cli-api/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../../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 89250efe714d..9c2f1a3d595b 100644 --- a/hapi-fhir-cli/hapi-fhir-cli-app/pom.xml +++ b/hapi-fhir-cli/hapi-fhir-cli-app/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-fhir-cli - 7.4.1-SNAPSHOT + 7.4.2 ../pom.xml diff --git a/hapi-fhir-cli/pom.xml b/hapi-fhir-cli/pom.xml index d4aea81234c4..bbd84177c99b 100644 --- a/hapi-fhir-cli/pom.xml +++ b/hapi-fhir-cli/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 7.4.1-SNAPSHOT + 7.4.2 ../pom.xml diff --git a/hapi-fhir-client-okhttp/pom.xml b/hapi-fhir-client-okhttp/pom.xml index ef3c39aeb501..1a29096463f0 100644 --- a/hapi-fhir-client-okhttp/pom.xml +++ b/hapi-fhir-client-okhttp/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-client/pom.xml b/hapi-fhir-client/pom.xml index ea74fb375a02..69fa498a6339 100644 --- a/hapi-fhir-client/pom.xml +++ b/hapi-fhir-client/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-converter/pom.xml b/hapi-fhir-converter/pom.xml index 225914875af3..9772f589e947 100644 --- a/hapi-fhir-converter/pom.xml +++ b/hapi-fhir-converter/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-dist/pom.xml b/hapi-fhir-dist/pom.xml index a2cc60ab86f8..3764f62dfa4a 100644 --- a/hapi-fhir-dist/pom.xml +++ b/hapi-fhir-dist/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 7.4.1-SNAPSHOT + 7.4.2 ../pom.xml diff --git a/hapi-fhir-docs/pom.xml b/hapi-fhir-docs/pom.xml index a3a1261d1d11..079c50c9f202 100644 --- a/hapi-fhir-docs/pom.xml +++ b/hapi-fhir-docs/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/7_4_2/upgrade.md b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/7_4_2/upgrade.md new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/7_4_2/version.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/7_4_2/version.yaml new file mode 100644 index 000000000000..d29029549395 --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/7_4_2/version.yaml @@ -0,0 +1,3 @@ +--- +release-date: "2024-09-20" +codename: "Copernicus" diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/7_6_0/6216-fulltext-searching-not-returning-expected-results.yml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/7_6_0/6216-fulltext-searching-not-returning-expected-results.yml new file mode 100644 index 000000000000..f1c3c8080e01 --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/7_6_0/6216-fulltext-searching-not-returning-expected-results.yml @@ -0,0 +1,8 @@ +--- +type: fix +issue: 6216 +jira: SMILE-8806 +title: "Previously, searches combining the `_text` query parameter (using Lucene/Elasticsearch) with query parameters +using the database (e.g. `identifier` or `date`) could miss matches when more than 500 results match the `_text` query +parameter. This has been fixed, but may be slow if many results match the `_text` query and must be checked against the +database parameters." diff --git a/hapi-fhir-jacoco/pom.xml b/hapi-fhir-jacoco/pom.xml index 2fee8ad64975..f8efc4c409ce 100644 --- a/hapi-fhir-jacoco/pom.xml +++ b/hapi-fhir-jacoco/pom.xml @@ -11,7 +11,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jaxrsserver-base/pom.xml b/hapi-fhir-jaxrsserver-base/pom.xml index e1f1bd4e88da..91a30044bde5 100644 --- a/hapi-fhir-jaxrsserver-base/pom.xml +++ b/hapi-fhir-jaxrsserver-base/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpa/pom.xml b/hapi-fhir-jpa/pom.xml index d00e40ac1a70..5330bb876b5c 100644 --- a/hapi-fhir-jpa/pom.xml +++ b/hapi-fhir-jpa/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-base/pom.xml b/hapi-fhir-jpaserver-base/pom.xml index 1fb97d000eba..d9700c5d9bcc 100644 --- a/hapi-fhir-jpaserver-base/pom.xml +++ b/hapi-fhir-jpaserver-base/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FulltextSearchSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FulltextSearchSvcImpl.java index 0e436fccf108..5c45b2ca8757 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FulltextSearchSvcImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FulltextSearchSvcImpl.java @@ -32,6 +32,7 @@ import ca.uhn.fhir.jpa.dao.search.ExtendedHSearchSearchBuilder; import ca.uhn.fhir.jpa.dao.search.IHSearchSortHelper; import ca.uhn.fhir.jpa.dao.search.LastNOperation; +import ca.uhn.fhir.jpa.dao.search.SearchScrollQueryExecutorAdaptor; import ca.uhn.fhir.jpa.model.dao.JpaPid; import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.search.ExtendedHSearchBuilderConsumeAdvancedQueryClausesParams; @@ -40,6 +41,7 @@ import ca.uhn.fhir.jpa.search.autocomplete.ValueSetAutocompleteOptions; import ca.uhn.fhir.jpa.search.autocomplete.ValueSetAutocompleteSearch; import ca.uhn.fhir.jpa.search.builder.ISearchQueryExecutor; +import ca.uhn.fhir.jpa.search.builder.SearchBuilder; import ca.uhn.fhir.jpa.search.builder.SearchQueryExecutors; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.extractor.ISearchParamExtractor; @@ -183,6 +185,19 @@ public ISearchQueryExecutor searchNotScrolled( return doSearch(theResourceName, theParams, null, theMaxResultsToFetch, theRequestDetails); } + @Transactional + @Override + public ISearchQueryExecutor searchScrolled( + String theResourceType, SearchParameterMap theParams, RequestDetails theRequestDetails) { + validateHibernateSearchIsEnabled(); + + SearchQueryOptionsStep searchQueryOptionsStep = + getSearchQueryOptionsStep(theResourceType, theParams, null); + logQuery(searchQueryOptionsStep, theRequestDetails); + + return new SearchScrollQueryExecutorAdaptor(searchQueryOptionsStep.scroll(SearchBuilder.getMaximumPageSize())); + } + // keep this in sync with supportsSomeOf(); @SuppressWarnings("rawtypes") private ISearchQueryExecutor doSearch( diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/IFulltextSearchSvc.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/IFulltextSearchSvc.java index 6890b9bc26fa..52dd75899471 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/IFulltextSearchSvc.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/IFulltextSearchSvc.java @@ -62,6 +62,17 @@ ISearchQueryExecutor searchNotScrolled( Integer theMaxResultsToFetch, RequestDetails theRequestDetails); + /** + * Query the index for a complete iterator of ALL results. (scrollable search result). + * + * @param theResourceName e.g. Patient + * @param theParams The search query + * @param theRequestDetails The request details + * @return Iterator of result PIDs + */ + ISearchQueryExecutor searchScrolled( + String theResourceName, SearchParameterMap theParams, RequestDetails theRequestDetails); + /** * Autocomplete search for NIH $expand contextDirection=existing * @param theOptions operation options diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/SearchBuilder.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/SearchBuilder.java index 943d3f9abb90..bb50e0dd6130 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/SearchBuilder.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/SearchBuilder.java @@ -101,7 +101,6 @@ import ca.uhn.fhir.util.UrlUtil; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Lists; -import com.google.common.collect.Streams; import com.healthmarketscience.sqlbuilder.Condition; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; @@ -141,7 +140,9 @@ import static ca.uhn.fhir.jpa.model.util.JpaConstants.UNDESIRED_RESOURCE_LINKAGES_FOR_EVERYTHING_ON_PATIENT_INSTANCE; import static ca.uhn.fhir.jpa.search.builder.QueryStack.LOCATION_POSITION; import static ca.uhn.fhir.jpa.search.builder.QueryStack.SearchForIdsParams.with; +import static ca.uhn.fhir.jpa.util.InClauseNormalizer.*; import static java.util.Objects.requireNonNull; +import static org.apache.commons.collections4.CollectionUtils.isNotEmpty; import static org.apache.commons.lang3.StringUtils.defaultString; import static org.apache.commons.lang3.StringUtils.isBlank; import static org.apache.commons.lang3.StringUtils.isNotBlank; @@ -205,9 +206,6 @@ public class SearchBuilder implements ISearchBuilder { @Autowired(required = false) private IElasticsearchSvc myIElasticsearchSvc; - @Autowired - private FhirContext myCtx; - @Autowired private IJpaStorageResourceParser myJpaStorageResourceParser; @@ -332,8 +330,7 @@ public Long createCountQuery( init(theParams, theSearchUuid, theRequestPartitionId); if (checkUseHibernateSearch()) { - long count = myFulltextSearchSvc.count(myResourceName, theParams.clone()); - return count; + return myFulltextSearchSvc.count(myResourceName, theParams.clone()); } List queries = createQuery(theParams.clone(), null, null, null, true, theRequest, null); @@ -404,8 +401,16 @@ private List createQuery( fulltextMatchIds = queryHibernateSearchForEverythingPids(theRequest); resultCount = fulltextMatchIds.size(); } else { - fulltextExecutor = myFulltextSearchSvc.searchNotScrolled( - myResourceName, myParams, myMaxResultsToFetch, theRequest); + // todo performance MB - some queries must intersect with JPA (e.g. they have a chain, or we haven't + // enabled SP indexing). + // and some queries don't need JPA. We only need the scroll when we need to intersect with JPA. + // It would be faster to have a non-scrolled search in this case, since creating the scroll requires + // extra work in Elastic. + // if (eligibleToSkipJPAQuery) fulltextExecutor = myFulltextSearchSvc.searchNotScrolled( ... + + // we might need to intersect with JPA. So we might need to traverse ALL results from lucene, not just + // a page. + fulltextExecutor = myFulltextSearchSvc.searchScrolled(myResourceName, myParams, theRequest); } if (fulltextExecutor == null) { @@ -457,7 +462,8 @@ private List createQuery( // We break the pids into chunks that fit in the 1k limit for jdbc bind params. new QueryChunker() .chunk( - Streams.stream(fulltextExecutor).collect(Collectors.toList()), + fulltextExecutor, + SearchBuilder.getMaximumPageSize(), t -> doCreateChunkedQueries( theParams, t, theOffset, sort, theCountOnlyFlag, theRequest, queries)); } @@ -560,8 +566,9 @@ private void doCreateChunkedQueries( boolean theCount, RequestDetails theRequest, ArrayList theQueries) { + if (thePids.size() < getMaximumPageSize()) { - normalizeIdListForLastNInClause(thePids); + thePids = normalizeIdListForInClause(thePids); } createChunkedQuery(theParams, sort, theOffset, thePids.size(), theCount, theRequest, thePids, theQueries); } @@ -885,41 +892,7 @@ private boolean isPotentiallyContainedReferenceParameterExistsAtRoot(SearchParam && theParams.values().stream() .flatMap(Collection::stream) .flatMap(Collection::stream) - .anyMatch(t -> t instanceof ReferenceParam); - } - - private List normalizeIdListForLastNInClause(List lastnResourceIds) { - /* - The following is a workaround to a known issue involving Hibernate. If queries are used with "in" clauses with large and varying - numbers of parameters, this can overwhelm Hibernate's QueryPlanCache and deplete heap space. See the following link for more info: - https://stackoverflow.com/questions/31557076/spring-hibernate-query-plan-cache-memory-usage. - - Normalizing the number of parameters in the "in" clause stabilizes the size of the QueryPlanCache, so long as the number of - arguments never exceeds the maximum specified below. - */ - int listSize = lastnResourceIds.size(); - - if (listSize > 1 && listSize < 10) { - padIdListWithPlaceholders(lastnResourceIds, 10); - } else if (listSize > 10 && listSize < 50) { - padIdListWithPlaceholders(lastnResourceIds, 50); - } else if (listSize > 50 && listSize < 100) { - padIdListWithPlaceholders(lastnResourceIds, 100); - } else if (listSize > 100 && listSize < 200) { - padIdListWithPlaceholders(lastnResourceIds, 200); - } else if (listSize > 200 && listSize < 500) { - padIdListWithPlaceholders(lastnResourceIds, 500); - } else if (listSize > 500 && listSize < 800) { - padIdListWithPlaceholders(lastnResourceIds, 800); - } - - return lastnResourceIds; - } - - private void padIdListWithPlaceholders(List theIdList, int preferredListSize) { - while (theIdList.size() < preferredListSize) { - theIdList.add(-1L); - } + .anyMatch(ReferenceParam.class::isInstance); } private void createSort(QueryStack theQueryStack, SortSpec theSort, SearchParameterMap theParams) { @@ -1154,7 +1127,7 @@ private void doLoadPids( List versionlessPids = JpaPid.toLongList(thePids); if (versionlessPids.size() < getMaximumPageSize()) { - versionlessPids = normalizeIdListForLastNInClause(versionlessPids); + versionlessPids = normalizeIdListForInClause(versionlessPids); } // -- get the resource from the searchView @@ -1243,7 +1216,7 @@ private Map> getPidToTagMap(List thePidList) Map> tagMap = new HashMap<>(); // -- no tags - if (thePidList.size() == 0) return tagMap; + if (thePidList.isEmpty()) return tagMap; // -- get all tags for the idList Collection tagList = myResourceTagDao.findByResourceIds(thePidList); @@ -1383,7 +1356,6 @@ public Set loadIncludes(SearchBuilderLoadIncludesParameters theP EntityManager entityManager = theParameters.getEntityManager(); Integer maxCount = theParameters.getMaxCount(); FhirContext fhirContext = theParameters.getFhirContext(); - DateRangeParam lastUpdated = theParameters.getLastUpdated(); RequestDetails request = theParameters.getRequestDetails(); String searchIdOrDescription = theParameters.getSearchIdOrDescription(); List desiredResourceTypes = theParameters.getDesiredResourceTypes(); @@ -1922,11 +1894,10 @@ Set calculateIndexUriIdentityHashesForResourceTypes(Set theTargetR } assert !targetResourceTypes.isEmpty(); - Set identityHashesForTypes = targetResourceTypes.stream() + return targetResourceTypes.stream() .map(type -> BaseResourceIndexedSearchParam.calculateHashIdentity( myPartitionSettings, myRequestPartitionId, type, "url")) .collect(Collectors.toSet()); - return identityHashesForTypes; } private List> partition(Collection theNextRoundMatches, int theMaxLoad) { @@ -2506,7 +2477,7 @@ private void initializeIteratorQuery(Integer theOffset, Integer theMaxResultsToF private void retrieveNextIteratorQuery() { close(); - if (myQueryList != null && myQueryList.size() > 0) { + if (isNotEmpty(myQueryList)) { myResultsIterator = myQueryList.remove(0); myHasNextIteratorQuery = true; } else { diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/InClauseNormalizer.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/InClauseNormalizer.java new file mode 100644 index 000000000000..8d8227ac4f91 --- /dev/null +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/InClauseNormalizer.java @@ -0,0 +1,84 @@ +/*- + * #%L + * HAPI FHIR JPA Server + * %% + * Copyright (C) 2014 - 2024 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.util; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/* + This class encapsulate the implementation providing a workaround to a known issue involving Hibernate. If queries are used with "in" clauses with large and varying + numbers of parameters, this can overwhelm Hibernate's QueryPlanCache and deplete heap space. See the following link for more info: + https://stackoverflow.com/questions/31557076/spring-hibernate-query-plan-cache-memory-usage. + + Normalizing the number of parameters in the "in" clause stabilizes the size of the QueryPlanCache, so long as the number of + arguments never exceeds the maximum specified below. +*/ +public class InClauseNormalizer { + + public static List normalizeIdListForInClause(List theResourceIds) { + + List retVal = theResourceIds; + + int listSize = theResourceIds.size(); + + if (listSize > 1 && listSize < 10) { + retVal = padIdListWithPlaceholders(theResourceIds, 10); + } else if (listSize > 10 && listSize < 50) { + retVal = padIdListWithPlaceholders(theResourceIds, 50); + } else if (listSize > 50 && listSize < 100) { + retVal = padIdListWithPlaceholders(theResourceIds, 100); + } else if (listSize > 100 && listSize < 200) { + retVal = padIdListWithPlaceholders(theResourceIds, 200); + } else if (listSize > 200 && listSize < 500) { + retVal = padIdListWithPlaceholders(theResourceIds, 500); + } else if (listSize > 500 && listSize < 800) { + retVal = padIdListWithPlaceholders(theResourceIds, 800); + } + + return retVal; + } + + private static List padIdListWithPlaceholders(List theIdList, int preferredListSize) { + List retVal = theIdList; + + if (isUnmodifiableList(theIdList)) { + retVal = new ArrayList<>(preferredListSize); + retVal.addAll(theIdList); + } + + while (retVal.size() < preferredListSize) { + retVal.add(-1L); + } + + return retVal; + } + + private static boolean isUnmodifiableList(List theList) { + try { + theList.addAll(Collections.emptyList()); + } catch (Exception e) { + return true; + } + return false; + } + + private InClauseNormalizer() {} +} diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/util/InClauseNormalizerTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/util/InClauseNormalizerTest.java new file mode 100644 index 000000000000..bd2ed0603ee9 --- /dev/null +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/util/InClauseNormalizerTest.java @@ -0,0 +1,72 @@ +package ca.uhn.fhir.util; + +import ca.uhn.fhir.jpa.util.InClauseNormalizer; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + +import static java.util.Collections.nCopies; +import static java.util.Collections.unmodifiableList; +import static org.assertj.core.api.Assertions.assertThat; + +public class InClauseNormalizerTest { + private static final Long ourResourceId = 1L; + private static final Long ourPaddingValue = -1L; + + @ParameterizedTest + @MethodSource("arguments") + public void testNormalizeUnmodifiableList_willCreateNewListAndPadToSize(int theInitialListSize, int theExpectedNormalizedListSize) { + List initialList = new ArrayList<>(nCopies(theInitialListSize, ourResourceId)); + initialList = unmodifiableList(initialList); + + List normalizedList = InClauseNormalizer.normalizeIdListForInClause(initialList); + + assertNormalizedList(initialList, normalizedList, theInitialListSize, theExpectedNormalizedListSize); + } + + @ParameterizedTest + @MethodSource("arguments") + public void testNormalizeListToSizeAndPad(int theInitialListSize, int theExpectedNormalizedListSize) { + List initialList = new ArrayList<>(nCopies(theInitialListSize, ourResourceId)); + + List normalizedList = InClauseNormalizer.normalizeIdListForInClause(initialList); + + assertNormalizedList(initialList, normalizedList, theInitialListSize, theExpectedNormalizedListSize); + } + + private void assertNormalizedList(List theInitialList, List theNormalizedList, int theInitialListSize, int theExpectedNormalizedListSize) { + List expectedPaddedSubList = new ArrayList<>(nCopies(theExpectedNormalizedListSize - theInitialListSize, ourPaddingValue)); + + assertThat(theNormalizedList).startsWith(listToArray(theInitialList)); + assertThat(theNormalizedList).hasSize(theExpectedNormalizedListSize); + assertThat(theNormalizedList).endsWith(listToArray(expectedPaddedSubList)); + } + + static Long[] listToArray(List theList) { + return theList.toArray(new Long[0]); + } + + private static Stream arguments(){ + return Stream.of( + Arguments.of(0, 0), + Arguments.of(1, 1), + Arguments.of(2, 10), + Arguments.of(10, 10), + Arguments.of(12, 50), + Arguments.of(50, 50), + Arguments.of(51, 100), + Arguments.of(100, 100), + Arguments.of(150, 200), + Arguments.of(300, 500), + Arguments.of(500, 500), + Arguments.of(700, 800), + Arguments.of(800, 800), + Arguments.of(801, 801) + ); + } + +} diff --git a/hapi-fhir-jpaserver-elastic-test-utilities/pom.xml b/hapi-fhir-jpaserver-elastic-test-utilities/pom.xml index db4eabb47776..55a0c88459ca 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 - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-elastic-test-utilities/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchLastNIT.java b/hapi-fhir-jpaserver-elastic-test-utilities/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchLastNIT.java index 970a016c16cc..50c269f56b5c 100644 --- a/hapi-fhir-jpaserver-elastic-test-utilities/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchLastNIT.java +++ b/hapi-fhir-jpaserver-elastic-test-utilities/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchLastNIT.java @@ -56,8 +56,6 @@ public void reset() { @Mock private IHSearchEventListener mySearchEventListener; - - @Test public void testLastNChunking() { @@ -108,7 +106,6 @@ public void testLastNChunking() { secondQueryPattern.append("\\).*"); assertThat(queries.get(1).toUpperCase().replaceAll(" , ", ",")).matches(secondQueryPattern.toString()); assertThat(queries.get(3).toUpperCase().replaceAll(" , ", ",")).matches(secondQueryPattern.toString()); - } @Test diff --git a/hapi-fhir-jpaserver-hfql/pom.xml b/hapi-fhir-jpaserver-hfql/pom.xml index 129f4ca6bc7d..3f114fe05b76 100644 --- a/hapi-fhir-jpaserver-hfql/pom.xml +++ b/hapi-fhir-jpaserver-hfql/pom.xml @@ -3,7 +3,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-ips/pom.xml b/hapi-fhir-jpaserver-ips/pom.xml index d55991741bdf..7ebf68cf1697 100644 --- a/hapi-fhir-jpaserver-ips/pom.xml +++ b/hapi-fhir-jpaserver-ips/pom.xml @@ -3,7 +3,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-mdm/pom.xml b/hapi-fhir-jpaserver-mdm/pom.xml index 5d7dc2d6aafd..e15e444a0618 100644 --- a/hapi-fhir-jpaserver-mdm/pom.xml +++ b/hapi-fhir-jpaserver-mdm/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-model/pom.xml b/hapi-fhir-jpaserver-model/pom.xml index 4ac804a7f302..8046e477b73f 100644 --- a/hapi-fhir-jpaserver-model/pom.xml +++ b/hapi-fhir-jpaserver-model/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-searchparam/pom.xml b/hapi-fhir-jpaserver-searchparam/pom.xml index 4f0708007a97..7ad96309c18d 100755 --- a/hapi-fhir-jpaserver-searchparam/pom.xml +++ b/hapi-fhir-jpaserver-searchparam/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-subscription/pom.xml b/hapi-fhir-jpaserver-subscription/pom.xml index f0e02994c777..451c3693b2ad 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 - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-test-dstu2/pom.xml b/hapi-fhir-jpaserver-test-dstu2/pom.xml index 6528863ca82f..521f3fb8e5e8 100644 --- a/hapi-fhir-jpaserver-test-dstu2/pom.xml +++ b/hapi-fhir-jpaserver-test-dstu2/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-test-dstu3/pom.xml b/hapi-fhir-jpaserver-test-dstu3/pom.xml index 1befc33f12d8..5587c600e18b 100644 --- a/hapi-fhir-jpaserver-test-dstu3/pom.xml +++ b/hapi-fhir-jpaserver-test-dstu3/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-test-r4/pom.xml b/hapi-fhir-jpaserver-test-r4/pom.xml index 6b461933e2fa..88f44c2e8032 100644 --- a/hapi-fhir-jpaserver-test-r4/pom.xml +++ b/hapi-fhir-jpaserver-test-r4/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSearchDaoR4Test.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSearchDaoR4Test.java index 875475b3d085..0a4211234fd3 100644 --- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSearchDaoR4Test.java +++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSearchDaoR4Test.java @@ -1,8 +1,8 @@ package ca.uhn.fhir.jpa.dao.r4; -import static org.junit.jupiter.api.Assertions.assertEquals; import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc; import ca.uhn.fhir.jpa.model.dao.JpaPid; +import ca.uhn.fhir.jpa.search.builder.SearchBuilder; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.test.BaseJpaR4Test; import ca.uhn.fhir.rest.api.Constants; @@ -12,6 +12,9 @@ import ca.uhn.fhir.rest.param.StringAndListParam; import ca.uhn.fhir.rest.param.StringOrListParam; import ca.uhn.fhir.rest.param.StringParam; +import ca.uhn.fhir.rest.param.TokenAndListParam; +import ca.uhn.fhir.rest.param.TokenOrListParam; +import ca.uhn.fhir.rest.param.TokenParam; import org.hl7.fhir.r4.model.Organization; import org.hl7.fhir.r4.model.Patient; import org.junit.jupiter.api.Test; @@ -19,9 +22,11 @@ import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.transaction.support.TransactionSynchronizationManager; +import java.util.ArrayList; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; public class FhirSearchDaoR4Test extends BaseJpaR4Test { @@ -51,11 +56,11 @@ public void testSearchReturnsExpectedPatientsWhenContentTypeUsed() { patient.addName().addGiven(content).setFamily("hirasawa"); id1 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless().getIdPartAsLong(); } - Long id2; + { Patient patient = new Patient(); patient.addName().addGiven("mio").setFamily("akiyama"); - id2 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless().getIdPartAsLong(); + myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless().getIdPartAsLong(); } SearchParameterMap params = new SearchParameterMap(); @@ -257,4 +262,105 @@ public void testNarrativeSearch() { } } + @Test + public void testSearchNarrativeWithLuceneSearch() { + final int numberOfPatientsToCreate = SearchBuilder.getMaximumPageSize() + 10; + List expectedActivePatientIds = new ArrayList<>(numberOfPatientsToCreate); + + for (int i = 0; i < numberOfPatientsToCreate; i++) + { + Patient patient = new Patient(); + patient.getText().setDivAsString("
AAAS

FOO

CCC
"); + expectedActivePatientIds.add(myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless().getIdPart()); + } + + { + Patient patient = new Patient(); + patient.getText().setDivAsString("
AAAB

FOO

CCC
"); + myPatientDao.create(patient, mySrd); + } + { + Patient patient = new Patient(); + patient.getText().setDivAsString("
ZZYZXY
"); + myPatientDao.create(patient, mySrd); + } + + SearchParameterMap map = new SearchParameterMap().setLoadSynchronous(true); + map.add(Constants.PARAM_TEXT, new StringParam("AAAS")); + + IBundleProvider searchResultBundle = myPatientDao.search(map, mySrd); + List resourceIdsFromSearchResult = searchResultBundle.getAllResourceIds(); + + assertThat(resourceIdsFromSearchResult).containsExactlyInAnyOrderElementsOf(expectedActivePatientIds); + } + + @Test + public void testLuceneNarrativeSearchQueryIntersectingJpaQuery() { + final int numberOfPatientsToCreate = SearchBuilder.getMaximumPageSize() + 10; + List expectedActivePatientIds = new ArrayList<>(numberOfPatientsToCreate); + + // create active and non-active patients with the same narrative + for (int i = 0; i < numberOfPatientsToCreate; i++) + { + Patient activePatient = new Patient(); + activePatient.getText().setDivAsString("
AAAS

FOO

CCC
"); + activePatient.setActive(true); + String patientId = myPatientDao.create(activePatient, mySrd).getId().toUnqualifiedVersionless().getIdPart(); + expectedActivePatientIds.add(patientId); + + Patient nonActivePatient = new Patient(); + nonActivePatient.getText().setDivAsString("
AAAS

FOO

CCC
"); + nonActivePatient.setActive(false); + myPatientDao.create(nonActivePatient, mySrd); + } + + SearchParameterMap map = new SearchParameterMap().setLoadSynchronous(true); + + TokenAndListParam tokenAndListParam = new TokenAndListParam(); + tokenAndListParam.addAnd(new TokenOrListParam().addOr(new TokenParam().setValue("true"))); + + map.add("active", tokenAndListParam); + map.add(Constants.PARAM_TEXT, new StringParam("AAAS")); + + IBundleProvider searchResultBundle = myPatientDao.search(map, mySrd); + List resourceIdsFromSearchResult = searchResultBundle.getAllResourceIds(); + + assertThat(resourceIdsFromSearchResult).containsExactlyInAnyOrderElementsOf(expectedActivePatientIds); + } + + @Test + public void testLuceneContentSearchQueryIntersectingJpaQuery() { + final int numberOfPatientsToCreate = SearchBuilder.getMaximumPageSize() + 10; + final String patientFamilyName = "Flanders"; + List expectedActivePatientIds = new ArrayList<>(numberOfPatientsToCreate); + + // create active and non-active patients with the same narrative + for (int i = 0; i < numberOfPatientsToCreate; i++) + { + Patient activePatient = new Patient(); + activePatient.addName().setFamily(patientFamilyName); + activePatient.setActive(true); + String patientId = myPatientDao.create(activePatient, mySrd).getId().toUnqualifiedVersionless().getIdPart(); + expectedActivePatientIds.add(patientId); + + Patient nonActivePatient = new Patient(); + nonActivePatient.addName().setFamily(patientFamilyName); + nonActivePatient.setActive(false); + myPatientDao.create(nonActivePatient, mySrd); + } + + SearchParameterMap map = new SearchParameterMap().setLoadSynchronous(true); + + TokenAndListParam tokenAndListParam = new TokenAndListParam(); + tokenAndListParam.addAnd(new TokenOrListParam().addOr(new TokenParam().setValue("true"))); + + map.add("active", tokenAndListParam); + map.add(Constants.PARAM_CONTENT, new StringParam(patientFamilyName)); + + IBundleProvider searchResultBundle = myPatientDao.search(map, mySrd); + List resourceIdsFromSearchResult = searchResultBundle.getAllResourceIds(); + + assertThat(resourceIdsFromSearchResult).containsExactlyInAnyOrderElementsOf(expectedActivePatientIds); + } + } diff --git a/hapi-fhir-jpaserver-test-r4b/pom.xml b/hapi-fhir-jpaserver-test-r4b/pom.xml index dd1f11404ab0..df21384ce66c 100644 --- a/hapi-fhir-jpaserver-test-r4b/pom.xml +++ b/hapi-fhir-jpaserver-test-r4b/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-test-r5/pom.xml b/hapi-fhir-jpaserver-test-r5/pom.xml index 503c1ce57d39..e64f1a56b6fc 100644 --- a/hapi-fhir-jpaserver-test-r5/pom.xml +++ b/hapi-fhir-jpaserver-test-r5/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-test-utilities/pom.xml b/hapi-fhir-jpaserver-test-utilities/pom.xml index 320991d858f9..76ae41a5d07f 100644 --- a/hapi-fhir-jpaserver-test-utilities/pom.xml +++ b/hapi-fhir-jpaserver-test-utilities/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/embedded/OracleCondition.java b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/embedded/OracleCondition.java new file mode 100644 index 000000000000..ddefa1a127cd --- /dev/null +++ b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/embedded/OracleCondition.java @@ -0,0 +1,57 @@ +/*- + * #%L + * HAPI FHIR JPA Server Test Utilities + * %% + * Copyright (C) 2014 - 2024 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.embedded; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.SystemUtils; +import org.junit.jupiter.api.extension.ConditionEvaluationResult; +import org.junit.jupiter.api.extension.ExecutionCondition; +import org.junit.jupiter.api.extension.ExtensionContext; + +public class OracleCondition implements ExecutionCondition { + + public static final String ENABLED_MSG = "Environment is able to run Oracle using TestContainers."; + public static final String DISABLED_MSG = "Environment is not able to run Oracle using TestContainers. If you " + + "are a Mac user, please ensure Colima is running. See: https://java.testcontainers.org/supported_docker_environment/#using-colima."; + + @Override + public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext theExtensionContext) { + return canUseOracle() + ? ConditionEvaluationResult.enabled(ENABLED_MSG) + : ConditionEvaluationResult.disabled(DISABLED_MSG); + } + + public static boolean canUseOracle() { + if (!isMac()) { + return true; + } + return isColimaConfigured(); + } + + private static boolean isMac() { + return SystemUtils.IS_OS_MAC || SystemUtils.IS_OS_MAC_OSX; + } + + private static boolean isColimaConfigured() { + return StringUtils.isNotBlank(System.getenv("TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE")) + && StringUtils.isNotBlank(System.getenv("DOCKER_HOST")) + && System.getenv("DOCKER_HOST").contains("colima"); + } +} diff --git a/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/embedded/annotation/OracleTest.java b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/embedded/annotation/OracleTest.java new file mode 100644 index 000000000000..3420c16f52f9 --- /dev/null +++ b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/embedded/annotation/OracleTest.java @@ -0,0 +1,33 @@ +/*- + * #%L + * HAPI FHIR JPA Server Test Utilities + * %% + * Copyright (C) 2014 - 2024 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.embedded.annotation; + +import ca.uhn.fhir.jpa.embedded.OracleCondition; +import org.junit.jupiter.api.extension.ExtendWith; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@ExtendWith(OracleCondition.class) +public @interface OracleTest {} diff --git a/hapi-fhir-jpaserver-uhnfhirtest/pom.xml b/hapi-fhir-jpaserver-uhnfhirtest/pom.xml index 775fd57c3797..9a2ae338463b 100644 --- a/hapi-fhir-jpaserver-uhnfhirtest/pom.xml +++ b/hapi-fhir-jpaserver-uhnfhirtest/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 7.4.1-SNAPSHOT + 7.4.2 ../pom.xml diff --git a/hapi-fhir-server-cds-hooks/pom.xml b/hapi-fhir-server-cds-hooks/pom.xml index 5e89c12b870f..05c98e4aec21 100644 --- a/hapi-fhir-server-cds-hooks/pom.xml +++ b/hapi-fhir-server-cds-hooks/pom.xml @@ -7,7 +7,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-server-mdm/pom.xml b/hapi-fhir-server-mdm/pom.xml index 13f99916464a..e3cc886ca90a 100644 --- a/hapi-fhir-server-mdm/pom.xml +++ b/hapi-fhir-server-mdm/pom.xml @@ -7,7 +7,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-server-openapi/pom.xml b/hapi-fhir-server-openapi/pom.xml index 09ffbe27d3e3..1472c92d3408 100644 --- a/hapi-fhir-server-openapi/pom.xml +++ b/hapi-fhir-server-openapi/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-server/pom.xml b/hapi-fhir-server/pom.xml index 3ebed6546625..a730118fe3ef 100644 --- a/hapi-fhir-server/pom.xml +++ b/hapi-fhir-server/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-serviceloaders/hapi-fhir-caching-api/pom.xml b/hapi-fhir-serviceloaders/hapi-fhir-caching-api/pom.xml index fdcf4d4c233f..563eaf4003c7 100644 --- a/hapi-fhir-serviceloaders/hapi-fhir-caching-api/pom.xml +++ b/hapi-fhir-serviceloaders/hapi-fhir-caching-api/pom.xml @@ -7,7 +7,7 @@ hapi-fhir-serviceloaders ca.uhn.hapi.fhir - 7.4.1-SNAPSHOT + 7.4.2 ../pom.xml diff --git a/hapi-fhir-serviceloaders/hapi-fhir-caching-caffeine/pom.xml b/hapi-fhir-serviceloaders/hapi-fhir-caching-caffeine/pom.xml index 576856e5c298..eeb32c140f65 100644 --- a/hapi-fhir-serviceloaders/hapi-fhir-caching-caffeine/pom.xml +++ b/hapi-fhir-serviceloaders/hapi-fhir-caching-caffeine/pom.xml @@ -7,7 +7,7 @@ hapi-fhir-serviceloaders ca.uhn.hapi.fhir - 7.4.1-SNAPSHOT + 7.4.2 ../pom.xml @@ -21,7 +21,7 @@ ca.uhn.hapi.fhir hapi-fhir-caching-api - 7.4.1-SNAPSHOT + 7.4.2 diff --git a/hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml b/hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml index eb7942c38c3f..59edb6e15359 100644 --- a/hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml +++ b/hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml @@ -7,7 +7,7 @@ hapi-fhir-serviceloaders ca.uhn.hapi.fhir - 7.4.1-SNAPSHOT + 7.4.2 ../pom.xml diff --git a/hapi-fhir-serviceloaders/hapi-fhir-caching-testing/pom.xml b/hapi-fhir-serviceloaders/hapi-fhir-caching-testing/pom.xml index 5ec4cda505df..cb8ca6c737f8 100644 --- a/hapi-fhir-serviceloaders/hapi-fhir-caching-testing/pom.xml +++ b/hapi-fhir-serviceloaders/hapi-fhir-caching-testing/pom.xml @@ -7,7 +7,7 @@ hapi-fhir ca.uhn.hapi.fhir - 7.4.1-SNAPSHOT + 7.4.2 ../../pom.xml diff --git a/hapi-fhir-serviceloaders/pom.xml b/hapi-fhir-serviceloaders/pom.xml index 10219e2b9f5d..6025e234e09d 100644 --- a/hapi-fhir-serviceloaders/pom.xml +++ b/hapi-fhir-serviceloaders/pom.xml @@ -5,7 +5,7 @@ hapi-deployable-pom ca.uhn.hapi.fhir - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml index e2f3103c6cd1..40b227304d16 100644 --- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml +++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml index 81dde395ec37..435f4237abf8 100644 --- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml +++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir-spring-boot-samples - 7.4.1-SNAPSHOT + 7.4.2 hapi-fhir-spring-boot-sample-client-apache diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml index 1ebe8ab9ad73..1ddaac2bf5ec 100644 --- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml +++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir-spring-boot-samples - 7.4.1-SNAPSHOT + 7.4.2 diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml index 740b474ddfdd..3c649e711f07 100644 --- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml +++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir-spring-boot-samples - 7.4.1-SNAPSHOT + 7.4.2 diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml index 758d5fde732c..0ac5a3d280a3 100644 --- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml +++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir-spring-boot - 7.4.1-SNAPSHOT + 7.4.2 diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml index 8eafe938b362..b1323067915c 100644 --- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml +++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-spring-boot/pom.xml b/hapi-fhir-spring-boot/pom.xml index 7a9242c92a77..0241e9f24919 100644 --- a/hapi-fhir-spring-boot/pom.xml +++ b/hapi-fhir-spring-boot/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 7.4.1-SNAPSHOT + 7.4.2 ../pom.xml diff --git a/hapi-fhir-sql-migrate/pom.xml b/hapi-fhir-sql-migrate/pom.xml index f1b62f621dcf..fcd7725953aa 100644 --- a/hapi-fhir-sql-migrate/pom.xml +++ b/hapi-fhir-sql-migrate/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-storage-batch2-jobs/pom.xml b/hapi-fhir-storage-batch2-jobs/pom.xml index 2bc8156be5cb..babc52f63a62 100644 --- a/hapi-fhir-storage-batch2-jobs/pom.xml +++ b/hapi-fhir-storage-batch2-jobs/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-storage-batch2-test-utilities/pom.xml b/hapi-fhir-storage-batch2-test-utilities/pom.xml index 9e37fe49b618..1892ee436e11 100644 --- a/hapi-fhir-storage-batch2-test-utilities/pom.xml +++ b/hapi-fhir-storage-batch2-test-utilities/pom.xml @@ -7,7 +7,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-storage-batch2/pom.xml b/hapi-fhir-storage-batch2/pom.xml index 4ba1810add5e..52022b2174ce 100644 --- a/hapi-fhir-storage-batch2/pom.xml +++ b/hapi-fhir-storage-batch2/pom.xml @@ -7,7 +7,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-storage-cr/pom.xml b/hapi-fhir-storage-cr/pom.xml index 8fb7f1e87626..73dda4a4634e 100644 --- a/hapi-fhir-storage-cr/pom.xml +++ b/hapi-fhir-storage-cr/pom.xml @@ -7,7 +7,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-storage-mdm/pom.xml b/hapi-fhir-storage-mdm/pom.xml index f80c7e842f70..d1b9510559f7 100644 --- a/hapi-fhir-storage-mdm/pom.xml +++ b/hapi-fhir-storage-mdm/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-storage-test-utilities/pom.xml b/hapi-fhir-storage-test-utilities/pom.xml index e71a0f922fae..3038dbcfec7c 100644 --- a/hapi-fhir-storage-test-utilities/pom.xml +++ b/hapi-fhir-storage-test-utilities/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-storage/pom.xml b/hapi-fhir-storage/pom.xml index a48033299654..af679415eee6 100644 --- a/hapi-fhir-storage/pom.xml +++ b/hapi-fhir-storage/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-dstu2.1/pom.xml b/hapi-fhir-structures-dstu2.1/pom.xml index 9a82af997b86..b97f19c27a35 100644 --- a/hapi-fhir-structures-dstu2.1/pom.xml +++ b/hapi-fhir-structures-dstu2.1/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-dstu2/pom.xml b/hapi-fhir-structures-dstu2/pom.xml index f889d3ab9021..92f65cfaa77b 100644 --- a/hapi-fhir-structures-dstu2/pom.xml +++ b/hapi-fhir-structures-dstu2/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-dstu3/pom.xml b/hapi-fhir-structures-dstu3/pom.xml index 8b1c57d5952e..0ee625afaeae 100644 --- a/hapi-fhir-structures-dstu3/pom.xml +++ b/hapi-fhir-structures-dstu3/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-hl7org-dstu2/pom.xml b/hapi-fhir-structures-hl7org-dstu2/pom.xml index 99f53ab535d4..7b87f6ecc809 100644 --- a/hapi-fhir-structures-hl7org-dstu2/pom.xml +++ b/hapi-fhir-structures-hl7org-dstu2/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-r4/pom.xml b/hapi-fhir-structures-r4/pom.xml index 5b2c42a0440d..d7f4be7ba62b 100644 --- a/hapi-fhir-structures-r4/pom.xml +++ b/hapi-fhir-structures-r4/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-r4b/pom.xml b/hapi-fhir-structures-r4b/pom.xml index 9b44a4fd756d..eb5f5d2e008f 100644 --- a/hapi-fhir-structures-r4b/pom.xml +++ b/hapi-fhir-structures-r4b/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-r5/pom.xml b/hapi-fhir-structures-r5/pom.xml index 098fd4704f23..30d8a0caf795 100644 --- a/hapi-fhir-structures-r5/pom.xml +++ b/hapi-fhir-structures-r5/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-test-utilities/pom.xml b/hapi-fhir-test-utilities/pom.xml index dd56c0fd9376..bd5bfca11db0 100644 --- a/hapi-fhir-test-utilities/pom.xml +++ b/hapi-fhir-test-utilities/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-testpage-overlay/pom.xml b/hapi-fhir-testpage-overlay/pom.xml index 92957ec1d7f6..f4bfcc88b87a 100644 --- a/hapi-fhir-testpage-overlay/pom.xml +++ b/hapi-fhir-testpage-overlay/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 7.4.1-SNAPSHOT + 7.4.2 ../pom.xml diff --git a/hapi-fhir-validation-resources-dstu2.1/pom.xml b/hapi-fhir-validation-resources-dstu2.1/pom.xml index a2e0d75295bb..7798412276f2 100644 --- a/hapi-fhir-validation-resources-dstu2.1/pom.xml +++ b/hapi-fhir-validation-resources-dstu2.1/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-validation-resources-dstu2/pom.xml b/hapi-fhir-validation-resources-dstu2/pom.xml index 6b5e818f3f61..53dc9fe8365a 100644 --- a/hapi-fhir-validation-resources-dstu2/pom.xml +++ b/hapi-fhir-validation-resources-dstu2/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-validation-resources-dstu3/pom.xml b/hapi-fhir-validation-resources-dstu3/pom.xml index af14cdafd9ea..914b101a23d5 100644 --- a/hapi-fhir-validation-resources-dstu3/pom.xml +++ b/hapi-fhir-validation-resources-dstu3/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-validation-resources-r4/pom.xml b/hapi-fhir-validation-resources-r4/pom.xml index 69369af9653a..7cce1ca4791a 100644 --- a/hapi-fhir-validation-resources-r4/pom.xml +++ b/hapi-fhir-validation-resources-r4/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-validation-resources-r4b/pom.xml b/hapi-fhir-validation-resources-r4b/pom.xml index 360b6f233683..db6e77f70153 100644 --- a/hapi-fhir-validation-resources-r4b/pom.xml +++ b/hapi-fhir-validation-resources-r4b/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-validation-resources-r5/pom.xml b/hapi-fhir-validation-resources-r5/pom.xml index ed1ef2e87ab4..fa444d4e3a4f 100644 --- a/hapi-fhir-validation-resources-r5/pom.xml +++ b/hapi-fhir-validation-resources-r5/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-validation/pom.xml b/hapi-fhir-validation/pom.xml index fd508168e6d8..ad3915637c6e 100644 --- a/hapi-fhir-validation/pom.xml +++ b/hapi-fhir-validation/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 7.4.1-SNAPSHOT + 7.4.2 ../hapi-deployable-pom/pom.xml diff --git a/hapi-tinder-plugin/pom.xml b/hapi-tinder-plugin/pom.xml index fd3a194d4fb0..cb5eb8aeda22 100644 --- a/hapi-tinder-plugin/pom.xml +++ b/hapi-tinder-plugin/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 7.4.1-SNAPSHOT + 7.4.2 ../pom.xml diff --git a/hapi-tinder-test/pom.xml b/hapi-tinder-test/pom.xml index 307d028c281c..c366acca2afa 100644 --- a/hapi-tinder-test/pom.xml +++ b/hapi-tinder-test/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-fhir - 7.4.1-SNAPSHOT + 7.4.2 ../pom.xml diff --git a/pom.xml b/pom.xml index bbcf35907cf9..77ad31f4db55 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ ca.uhn.hapi.fhir hapi-fhir pom - 7.4.1-SNAPSHOT + 7.4.2 HAPI-FHIR An open-source implementation of the FHIR specification in Java. diff --git a/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml b/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml index 03a5dcad1bb0..2d7d8c471664 100644 --- a/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml +++ b/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml @@ -7,7 +7,7 @@ ca.uhn.hapi.fhir hapi-fhir - 7.4.1-SNAPSHOT + 7.4.2 ../../pom.xml diff --git a/tests/hapi-fhir-base-test-mindeps-client/pom.xml b/tests/hapi-fhir-base-test-mindeps-client/pom.xml index ac6092305327..c850a3387fc7 100644 --- a/tests/hapi-fhir-base-test-mindeps-client/pom.xml +++ b/tests/hapi-fhir-base-test-mindeps-client/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-fhir - 7.4.1-SNAPSHOT + 7.4.2 ../../pom.xml diff --git a/tests/hapi-fhir-base-test-mindeps-server/pom.xml b/tests/hapi-fhir-base-test-mindeps-server/pom.xml index 990d8d4450bd..8272601262e2 100644 --- a/tests/hapi-fhir-base-test-mindeps-server/pom.xml +++ b/tests/hapi-fhir-base-test-mindeps-server/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 7.4.1-SNAPSHOT + 7.4.2 ../../pom.xml