extends B
return myTransactionProcessor.transaction(theRequestDetails, theRequest, true);
}
+ /**
+ * Prefetch entities into the Hibernate session.
+ *
+ * When processing several resources (e.g. transaction bundle, $reindex chunk, etc.)
+ * it would be slow to fetch each piece of a resource (e.g. all token index rows)
+ * one resource at a time.
+ * Instead, we fetch all the linked resources for the entire batch and populate the Hibernate Session.
+ *
+ * @param theResolvedIds the pids
+ * @param thePreFetchIndexes Should resource indexes be loaded
+ */
+ @SuppressWarnings("rawtypes")
@Override
public void preFetchResources(
List
theResolvedIds, boolean thePreFetchIndexes) {
HapiTransactionService.requireTransaction();
List pids = theResolvedIds.stream().map(t -> ((JpaPid) t).getId()).collect(Collectors.toList());
- new QueryChunker().chunk(pids, ids -> {
+ new QueryChunker().chunk(pids, idChunk -> {
/*
* Pre-fetch the resources we're touching in this transaction in mass - this reduced the
@@ -200,117 +205,110 @@ public abstract class BaseHapiFhirSystemDao extends B
*
* However, for realistic average workloads, this should reduce the number of round trips.
*/
- if (ids.size() >= 2) {
- List loadedResourceTableEntries = new ArrayList<>();
- preFetchIndexes(ids, "forcedId", "myForcedId", loadedResourceTableEntries);
-
- List entityIds;
+ if (idChunk.size() >= 2) {
+ List entityChunk = prefetchResourceTableHistoryAndProvenance(idChunk);
if (thePreFetchIndexes) {
- entityIds = loadedResourceTableEntries.stream()
- .filter(ResourceTable::isParamsStringPopulated)
- .map(ResourceTable::getId)
- .collect(Collectors.toList());
- if (entityIds.size() > 0) {
- preFetchIndexes(entityIds, "string", "myParamsString", null);
- }
- entityIds = loadedResourceTableEntries.stream()
- .filter(ResourceTable::isParamsTokenPopulated)
- .map(ResourceTable::getId)
- .collect(Collectors.toList());
- if (entityIds.size() > 0) {
- preFetchIndexes(entityIds, "token", "myParamsToken", null);
- }
+ prefetchByField("string", "myParamsString", ResourceTable::isParamsStringPopulated, entityChunk);
+ prefetchByField("token", "myParamsToken", ResourceTable::isParamsTokenPopulated, entityChunk);
+ prefetchByField("date", "myParamsDate", ResourceTable::isParamsDatePopulated, entityChunk);
+ prefetchByField(
+ "quantity", "myParamsQuantity", ResourceTable::isParamsQuantityPopulated, entityChunk);
+ prefetchByField("resourceLinks", "myResourceLinks", ResourceTable::isHasLinks, entityChunk);
- entityIds = loadedResourceTableEntries.stream()
- .filter(ResourceTable::isParamsDatePopulated)
- .map(ResourceTable::getId)
- .collect(Collectors.toList());
- if (entityIds.size() > 0) {
- preFetchIndexes(entityIds, "date", "myParamsDate", null);
- }
+ prefetchByJoinClause(
+ "tags",
+ // fetch the TagResources and the actual TagDefinitions
+ "LEFT JOIN FETCH r.myTags t LEFT JOIN FETCH t.myTag",
+ BaseHasResource::isHasTags,
+ entityChunk);
- entityIds = loadedResourceTableEntries.stream()
- .filter(ResourceTable::isParamsQuantityPopulated)
- .map(ResourceTable::getId)
- .collect(Collectors.toList());
- if (entityIds.size() > 0) {
- preFetchIndexes(entityIds, "quantity", "myParamsQuantity", null);
- }
-
- entityIds = loadedResourceTableEntries.stream()
- .filter(ResourceTable::isHasLinks)
- .map(ResourceTable::getId)
- .collect(Collectors.toList());
- if (entityIds.size() > 0) {
- preFetchIndexes(entityIds, "resourceLinks", "myResourceLinks", null);
- }
-
- entityIds = loadedResourceTableEntries.stream()
- .filter(BaseHasResource::isHasTags)
- .map(ResourceTable::getId)
- .collect(Collectors.toList());
- if (entityIds.size() > 0) {
- myResourceTagDao.findByResourceIds(entityIds);
- preFetchIndexes(entityIds, "tags", "myTags", null);
- }
-
- entityIds = loadedResourceTableEntries.stream()
- .map(ResourceTable::getId)
- .collect(Collectors.toList());
if (myStorageSettings.getIndexMissingFields() == JpaStorageSettings.IndexEnabledEnum.ENABLED) {
- preFetchIndexes(entityIds, "searchParamPresence", "mySearchParamPresents", null);
+ prefetchByField("searchParamPresence", "mySearchParamPresents", r -> true, entityChunk);
}
}
-
- new QueryChunker()
- .chunk(loadedResourceTableEntries, SearchBuilder.getMaximumPageSize() / 2, entries -> {
- Map entities =
- entries.stream().collect(Collectors.toMap(ResourceTable::getId, t -> t));
-
- CriteriaBuilder b = myEntityManager.getCriteriaBuilder();
- CriteriaQuery q = b.createQuery(ResourceHistoryTable.class);
- Root from = q.from(ResourceHistoryTable.class);
-
- from.fetch("myProvenance", JoinType.LEFT);
-
- List orPredicates = new ArrayList<>();
- for (ResourceTable next : entries) {
- Predicate resId = b.equal(from.get("myResourceId"), next.getId());
- Predicate resVer = b.equal(from.get("myResourceVersion"), next.getVersion());
- orPredicates.add(b.and(resId, resVer));
- }
- q.where(b.or(orPredicates.toArray(EMPTY_PREDICATE_ARRAY)));
- List resultList =
- myEntityManager.createQuery(q).getResultList();
- for (ResourceHistoryTable next : resultList) {
- ResourceTable nextEntity = entities.get(next.getResourceId());
- if (nextEntity != null) {
- nextEntity.setCurrentVersionEntity(next);
- }
- }
- });
}
});
}
- private void preFetchIndexes(
- List theIds,
- String typeDesc,
- String fieldName,
- @Nullable List theEntityListToPopulate) {
- new QueryChunker().chunk(theIds, ids -> {
- TypedQuery query = myEntityManager.createQuery(
- "FROM ResourceTable r LEFT JOIN FETCH r." + fieldName + " WHERE r.myId IN ( :IDS )",
- ResourceTable.class);
- query.setParameter("IDS", ids);
- List indexFetchOutcome = query.getResultList();
- ourLog.debug("Pre-fetched {} {}} indexes", indexFetchOutcome.size(), typeDesc);
- if (theEntityListToPopulate != null) {
- theEntityListToPopulate.addAll(indexFetchOutcome);
- }
- });
+ @Nonnull
+ private List prefetchResourceTableHistoryAndProvenance(List idChunk) {
+ assert idChunk.size() < SearchConstants.MAX_PAGE_SIZE : "assume pre-chunked";
+
+ Query query = myEntityManager.createQuery("select r, h "
+ + " FROM ResourceTable r "
+ + " LEFT JOIN fetch ResourceHistoryTable h "
+ + " on r.myVersion = h.myResourceVersion and r.id = h.myResourceId "
+ + " left join fetch h.myProvenance "
+ + " WHERE r.myId IN ( :IDS ) ");
+ query.setParameter("IDS", idChunk);
+
+ @SuppressWarnings("unchecked")
+ Stream queryResultStream = query.getResultStream();
+ return queryResultStream
+ .map(nextPair -> {
+ // Store the matching ResourceHistoryTable in the transient slot on ResourceTable
+ ResourceTable result = (ResourceTable) nextPair[0];
+ ResourceHistoryTable currentVersion = (ResourceHistoryTable) nextPair[1];
+ result.setCurrentVersionEntity(currentVersion);
+ return result;
+ })
+ .collect(Collectors.toList());
+ }
+
+ /**
+ * Prefetch a join field for the active subset of some ResourceTable entities.
+ * Convenience wrapper around prefetchByJoinClause() for simple fields.
+ *
+ * @param theDescription for logging
+ * @param theJpaFieldName the join field from ResourceTable
+ * @param theEntityPredicate select which ResourceTable entities need this join
+ * @param theEntities the ResourceTable entities to consider
+ */
+ private void prefetchByField(
+ String theDescription,
+ String theJpaFieldName,
+ Predicate theEntityPredicate,
+ List theEntities) {
+
+ String joinClause = "LEFT JOIN FETCH r." + theJpaFieldName;
+
+ prefetchByJoinClause(theDescription, joinClause, theEntityPredicate, theEntities);
+ }
+
+ /**
+ * Prefetch a join field for the active subset of some ResourceTable entities.
+ *
+ * @param theDescription for logging
+ * @param theJoinClause the JPA join expression to add to `ResourceTable r`
+ * @param theEntityPredicate selects which entities need this prefetch
+ * @param theEntities the ResourceTable entities to consider
+ */
+ private void prefetchByJoinClause(
+ String theDescription,
+ String theJoinClause,
+ Predicate theEntityPredicate,
+ List theEntities) {
+
+ // Which entities need this prefetch?
+ List idSubset = theEntities.stream()
+ .filter(theEntityPredicate)
+ .map(ResourceTable::getId)
+ .collect(Collectors.toList());
+
+ if (idSubset.isEmpty()) {
+ // nothing to do
+ return;
+ }
+
+ String jqlQuery = "FROM ResourceTable r " + theJoinClause + " WHERE r.myId IN ( :IDS )";
+
+ TypedQuery query = myEntityManager.createQuery(jqlQuery, ResourceTable.class);
+ query.setParameter("IDS", idSubset);
+ List indexFetchOutcome = query.getResultList();
+
+ ourLog.debug("Pre-fetched {} {} indexes", indexFetchOutcome.size(), theDescription);
}
@Nullable
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IForcedIdDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IForcedIdDao.java
deleted file mode 100644
index 601a4af0101..00000000000
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IForcedIdDao.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * #%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.dao.data;
-
-import ca.uhn.fhir.jpa.model.entity.ForcedId;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.data.jpa.repository.Modifying;
-import org.springframework.data.jpa.repository.Query;
-import org.springframework.data.repository.query.Param;
-import org.springframework.stereotype.Repository;
-
-/**
- * Legacy forced_id implementation.
- *
- * @deprecated we now have a fhir_id column directly on HFJ_RESOURCE.
- * No runtime code should query this table except for deletions by PK.
- * To be deleted in 2024 (zero-downtime).
- */
-@Deprecated(since = "6.10")
-@Repository
-public interface IForcedIdDao extends JpaRepository, IHapiFhirJpaRepository {
-
- @Modifying
- @Query("DELETE FROM ForcedId t WHERE t.myId = :pid")
- void deleteByPid(@Param("pid") Long theId);
-}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceLinkDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceLinkDao.java
index 641db53d0bf..f848f23eb1a 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceLinkDao.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceLinkDao.java
@@ -43,7 +43,6 @@ public interface IResourceLinkDao extends JpaRepository, IHa
* Loads a collection of ResourceLink entities by PID, but also eagerly fetches
* the target resources and their forced IDs
*/
- @Query(
- "SELECT t FROM ResourceLink t LEFT JOIN FETCH t.myTargetResource tr LEFT JOIN FETCH tr.myForcedId WHERE t.myId in :pids")
+ @Query("SELECT t FROM ResourceLink t LEFT JOIN FETCH t.myTargetResource tr WHERE t.myId in :pids")
List findByPidAndFetchTargetDetails(@Param("pids") List thePids);
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceTableDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceTableDao.java
index a054d4b06ec..21f233891e5 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceTableDao.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceTableDao.java
@@ -177,25 +177,26 @@ public interface IResourceTableDao
@Query("SELECT t.myId, t.myResourceType, t.myVersion FROM ResourceTable t WHERE t.myId IN ( :pid )")
Collection getResourceVersionsForPid(@Param("pid") List pid);
- @Query(
- "SELECT t FROM ResourceTable t LEFT JOIN FETCH t.myForcedId WHERE t.myPartitionId.myPartitionId IS NULL AND t.myId = :pid")
+ @Query("SELECT t FROM ResourceTable t WHERE t.myPartitionId.myPartitionId IS NULL AND t.myId = :pid")
Optional readByPartitionIdNull(@Param("pid") Long theResourceId);
- @Query(
- "SELECT t FROM ResourceTable t LEFT JOIN FETCH t.myForcedId WHERE t.myPartitionId.myPartitionId = :partitionId AND t.myId = :pid")
+ @Query("SELECT t FROM ResourceTable t WHERE t.myPartitionId.myPartitionId = :partitionId AND t.myId = :pid")
Optional readByPartitionId(
@Param("partitionId") int thePartitionId, @Param("pid") Long theResourceId);
@Query(
- "SELECT t FROM ResourceTable t LEFT JOIN FETCH t.myForcedId WHERE (t.myPartitionId.myPartitionId IS NULL OR t.myPartitionId.myPartitionId IN (:partitionIds)) AND t.myId = :pid")
+ "SELECT t FROM ResourceTable t WHERE (t.myPartitionId.myPartitionId IS NULL OR t.myPartitionId.myPartitionId IN (:partitionIds)) AND t.myId = :pid")
Optional readByPartitionIdsOrNull(
@Param("partitionIds") Collection thrValues, @Param("pid") Long theResourceId);
- @Query(
- "SELECT t FROM ResourceTable t LEFT JOIN FETCH t.myForcedId WHERE t.myPartitionId.myPartitionId IN (:partitionIds) AND t.myId = :pid")
+ @Query("SELECT t FROM ResourceTable t WHERE t.myPartitionId.myPartitionId IN (:partitionIds) AND t.myId = :pid")
Optional readByPartitionIds(
@Param("partitionIds") Collection thrValues, @Param("pid") Long theResourceId);
- @Query("SELECT t FROM ResourceTable t LEFT JOIN FETCH t.myForcedId WHERE t.myId IN :pids")
+ @Query("SELECT t FROM ResourceTable t WHERE t.myId IN :pids")
List findAllByIdAndLoadForcedIds(@Param("pids") List thePids);
+
+ @Query("SELECT t FROM ResourceTable t where t.myResourceType = :restype and t.myFhirId = :fhirId")
+ Optional findByTypeAndFhirId(
+ @Param("restype") String theResourceName, @Param("fhirId") String theFhirId);
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermValueSetDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermValueSetDao.java
index d31c7134f4b..cc5fb0795e5 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermValueSetDao.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermValueSetDao.java
@@ -53,9 +53,7 @@ public interface ITermValueSetDao extends JpaRepository, IHa
* The current TermValueSet is not necessarily the last uploaded anymore, but the current VS resource
* is pointed by a specific ForcedId, so we locate current ValueSet as the one pointing to current VS resource
*/
- @Query(
- value =
- "SELECT vs FROM ForcedId f, TermValueSet vs where f.myForcedId = :forcedId and vs.myResource = f.myResource")
+ @Query(value = "SELECT vs FROM TermValueSet vs where vs.myResource.myFhirId = :forcedId ")
Optional findTermValueSetByForcedId(@Param("forcedId") String theForcedId);
@Query("SELECT vs FROM TermValueSet vs WHERE vs.myUrl = :url AND vs.myVersion IS NULL")
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/expunge/ExpungeEverythingService.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/expunge/ExpungeEverythingService.java
index 6c254ac71a8..b6427e80f75 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/expunge/ExpungeEverythingService.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/expunge/ExpungeEverythingService.java
@@ -47,7 +47,6 @@ import ca.uhn.fhir.jpa.entity.TermConceptProperty;
import ca.uhn.fhir.jpa.entity.TermValueSet;
import ca.uhn.fhir.jpa.entity.TermValueSetConcept;
import ca.uhn.fhir.jpa.entity.TermValueSetConceptDesignation;
-import ca.uhn.fhir.jpa.model.entity.ForcedId;
import ca.uhn.fhir.jpa.model.entity.NpmPackageEntity;
import ca.uhn.fhir.jpa.model.entity.NpmPackageVersionEntity;
import ca.uhn.fhir.jpa.model.entity.NpmPackageVersionResourceEntity;
@@ -174,7 +173,6 @@ public class ExpungeEverythingService implements IExpungeEverythingService {
expungeEverythingByTypeWithoutPurging(theRequest, BulkImportJobFileEntity.class, requestPartitionId));
counter.addAndGet(
expungeEverythingByTypeWithoutPurging(theRequest, BulkImportJobEntity.class, requestPartitionId));
- counter.addAndGet(expungeEverythingByTypeWithoutPurging(theRequest, ForcedId.class, requestPartitionId));
counter.addAndGet(expungeEverythingByTypeWithoutPurging(
theRequest, ResourceIndexedSearchParamDate.class, requestPartitionId));
counter.addAndGet(expungeEverythingByTypeWithoutPurging(
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/expunge/JpaResourceExpungeService.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/expunge/JpaResourceExpungeService.java
index 450f412690b..4e8e3ea7e83 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/expunge/JpaResourceExpungeService.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/expunge/JpaResourceExpungeService.java
@@ -27,7 +27,6 @@ import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
import ca.uhn.fhir.jpa.dao.IJpaStorageResourceParser;
-import ca.uhn.fhir.jpa.dao.data.IForcedIdDao;
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryProvenanceDao;
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryTableDao;
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryTagDao;
@@ -46,7 +45,6 @@ import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
import ca.uhn.fhir.jpa.dao.data.IResourceTagDao;
import ca.uhn.fhir.jpa.dao.data.ISearchParamPresentDao;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
-import ca.uhn.fhir.jpa.model.entity.ForcedId;
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.util.MemoryCacheService;
@@ -79,9 +77,6 @@ import java.util.concurrent.atomic.AtomicInteger;
public class JpaResourceExpungeService implements IResourceExpungeService {
private static final Logger ourLog = LoggerFactory.getLogger(JpaResourceExpungeService.class);
- @Autowired
- private IForcedIdDao myForcedIdDao;
-
@Autowired
private IResourceTableDao myResourceTableDao;
@@ -323,11 +318,6 @@ public class JpaResourceExpungeService implements IResourceExpungeService {
init680();
init680_Part2();
init700();
+ init720();
+ }
+
+ protected void init720() {
+ // Start of migrations from 7.0 to 7.2
+
+ Builder version = forVersion(VersionEnum.V7_2_0);
+
+ // allow null codes in concept map targets
+ version.onTable("TRM_CONCEPT_MAP_GRP_ELM_TGT")
+ .modifyColumn("20240327.1", "TARGET_CODE")
+ .nullable()
+ .withType(ColumnTypeEnum.STRING, 500);
+
+ // Stop writing to hfj_forced_id https://github.com/hapifhir/hapi-fhir/pull/5817
+ Builder.BuilderWithTableName forcedId = version.onTable("HFJ_FORCED_ID");
+ forcedId.dropForeignKey("20240402.1", "FK_FORCEDID_RESOURCE", "HFJ_RESOURCE");
+ forcedId.dropIndex("20240402.2", "IDX_FORCEDID_RESID");
+ forcedId.dropIndex("20240402.3", "IDX_FORCEDID_TYPE_FID");
+ forcedId.dropIndex("20240402.4", "IDX_FORCEID_FID");
}
protected void init700() {
@@ -1398,9 +1418,9 @@ public class HapiFhirJpaMigrationTasks extends BaseMigrationTasks {
.addIndex("20211210.4", "FK_FORCEDID_RESOURCE")
.unique(true)
.withColumns("RESOURCE_PID")
- .doNothing() // This migration was added in error, as this table already has a unique constraint on
// RESOURCE_PID and every database creates an index on anything that is unique.
- .onlyAppliesToPlatforms(NON_AUTOMATIC_FK_INDEX_PLATFORMS);
+ .onlyAppliesToPlatforms(NON_AUTOMATIC_FK_INDEX_PLATFORMS)
+ .doNothing(); // This migration was added in error, as this table already has a unique constraint on
}
private void init570() {
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermConceptClientMappingSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermConceptClientMappingSvcImpl.java
index 7cfdfe5245a..d17ced8b4cb 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermConceptClientMappingSvcImpl.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermConceptClientMappingSvcImpl.java
@@ -51,6 +51,7 @@ import org.hibernate.ScrollMode;
import org.hibernate.ScrollableResults;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.Coding;
+import org.hl7.fhir.r4.model.Enumerations;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -416,6 +417,10 @@ public class TermConceptClientMappingSvcImpl implements ITermConceptClientMappin
theTranslationResult.setResult(false);
msg = myContext.getLocalizer().getMessage(TermConceptMappingSvcImpl.class, "noMatchesFound");
theTranslationResult.setMessage(msg);
+ } else if (isOnlyNegativeMatches(theTranslationResult)) {
+ theTranslationResult.setResult(false);
+ msg = myContext.getLocalizer().getMessage(TermConceptMappingSvcImpl.class, "onlyNegativeMatchesFound");
+ theTranslationResult.setMessage(msg);
} else {
theTranslationResult.setResult(true);
msg = myContext.getLocalizer().getMessage(TermConceptMappingSvcImpl.class, "matchesFound");
@@ -423,6 +428,21 @@ public class TermConceptClientMappingSvcImpl implements ITermConceptClientMappin
}
}
+ /**
+ * Evaluates whether a translation result contains any positive matches or only negative ones. This is required
+ * because the FHIR specification states
+ * that the result field "can only be true if at least one returned match has an equivalence which is not unmatched
+ * or disjoint".
+ * @param theTranslationResult the translation result to be evaluated
+ * @return true if all the potential matches in the result have a negative valence (i.e., "unmatched" and "disjoint")
+ */
+ private boolean isOnlyNegativeMatches(TranslateConceptResults theTranslationResult) {
+ return theTranslationResult.getResults().stream()
+ .map(TranslateConceptResult::getEquivalence)
+ .allMatch(t -> StringUtils.equals(Enumerations.ConceptMapEquivalence.UNMATCHED.toCode(), t)
+ || StringUtils.equals(Enumerations.ConceptMapEquivalence.DISJOINT.toCode(), t));
+ }
+
private boolean alreadyContainsMapping(
List elements, TranslateConceptResult translationMatch) {
for (TranslateConceptResult nextExistingElement : elements) {
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermConceptMappingSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermConceptMappingSvcImpl.java
index 73f2069e178..bb4e00383dc 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermConceptMappingSvcImpl.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermConceptMappingSvcImpl.java
@@ -41,6 +41,7 @@ import org.hl7.fhir.r4.model.BooleanType;
import org.hl7.fhir.r4.model.CodeType;
import org.hl7.fhir.r4.model.Coding;
import org.hl7.fhir.r4.model.ConceptMap;
+import org.hl7.fhir.r4.model.Enumerations;
import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r4.model.Parameters;
import org.hl7.fhir.r4.model.StringType;
@@ -218,13 +219,17 @@ public class TermConceptMappingSvcImpl extends TermConceptClientMappingSvcImpl i
if (element.hasTarget()) {
TermConceptMapGroupElementTarget termConceptMapGroupElementTarget;
for (ConceptMap.TargetElementComponent elementTarget : element.getTarget()) {
- if (isBlank(elementTarget.getCode())) {
+ if (isBlank(elementTarget.getCode())
+ && elementTarget.getEquivalence()
+ != Enumerations.ConceptMapEquivalence.UNMATCHED) {
continue;
}
termConceptMapGroupElementTarget = new TermConceptMapGroupElementTarget();
termConceptMapGroupElementTarget.setConceptMapGroupElement(termConceptMapGroupElement);
- termConceptMapGroupElementTarget.setCode(elementTarget.getCode());
- termConceptMapGroupElementTarget.setDisplay(elementTarget.getDisplay());
+ if (isNotBlank(elementTarget.getCode())) {
+ termConceptMapGroupElementTarget.setCode(elementTarget.getCode());
+ termConceptMapGroupElementTarget.setDisplay(elementTarget.getDisplay());
+ }
termConceptMapGroupElementTarget.setEquivalence(elementTarget.getEquivalence());
termConceptMapGroupElement
.getConceptMapGroupElementTargets()
diff --git a/hapi-fhir-jpaserver-base/src/main/resources/ca/uhn/fhir/jpa/docs/database/hapifhirpostgres94-init01.sql b/hapi-fhir-jpaserver-base/src/main/resources/ca/uhn/fhir/jpa/docs/database/hapifhirpostgres94-init01.sql
index bd7125b4b87..2677ad6a743 100644
--- a/hapi-fhir-jpaserver-base/src/main/resources/ca/uhn/fhir/jpa/docs/database/hapifhirpostgres94-init01.sql
+++ b/hapi-fhir-jpaserver-base/src/main/resources/ca/uhn/fhir/jpa/docs/database/hapifhirpostgres94-init01.sql
@@ -1,5 +1,5 @@
--- we can't use convering index until the autovacuum runs for those rows, which kills index performance
+-- we can't use covering index until the autovacuum runs for those rows, which kills index performance
ALTER TABLE hfj_resource SET (autovacuum_vacuum_scale_factor = 0.01);
ALTER TABLE hfj_forced_id SET (autovacuum_vacuum_scale_factor = 0.01);
ALTER TABLE hfj_res_link SET (autovacuum_vacuum_scale_factor = 0.01);
diff --git a/hapi-fhir-jpaserver-elastic-test-utilities/pom.xml b/hapi-fhir-jpaserver-elastic-test-utilities/pom.xml
index e969a0be649..17c3a08aa50 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-hfql/pom.xml b/hapi-fhir-jpaserver-hfql/pom.xml
index 6de7d563dd7..99bed5fc6d0 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-ips/pom.xml b/hapi-fhir-jpaserver-ips/pom.xml
index dbb537202f7..eb66d27cfac 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-mdm/pom.xml b/hapi-fhir-jpaserver-mdm/pom.xml
index 6441a09562d..2a8ed1e5e9b 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-model/pom.xml b/hapi-fhir-jpaserver-model/pom.xml
index b44506f53ab..23b8a5f67c5 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/BaseHasResource.java b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/BaseHasResource.java
index 5da18587c48..aee59d74ff4 100644
--- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/BaseHasResource.java
+++ b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/BaseHasResource.java
@@ -29,7 +29,6 @@ import jakarta.persistence.Enumerated;
import jakarta.persistence.MappedSuperclass;
import jakarta.persistence.Temporal;
import jakarta.persistence.TemporalType;
-import jakarta.persistence.Transient;
import org.hibernate.annotations.OptimisticLock;
import java.util.Collection;
@@ -65,22 +64,6 @@ public abstract class BaseHasResource extends BasePartitionable
@OptimisticLock(excluded = true)
private Date myUpdated;
- /**
- * This is stored as an optimization to avoid needing to query for this
- * after an update
- */
- @Transient
- // TODO MB forced_id delete this in step 3
- private transient String myTransientForcedId;
-
- public String getTransientForcedId() {
- return myTransientForcedId;
- }
-
- public void setTransientForcedId(String theTransientForcedId) {
- myTransientForcedId = theTransientForcedId;
- }
-
public abstract BaseTag addTag(TagDefinition theDef);
@Override
@@ -97,13 +80,6 @@ public abstract class BaseHasResource extends BasePartitionable
myFhirVersion = theFhirVersion;
}
- public abstract ForcedId getForcedId();
-
- public abstract void setForcedId(ForcedId theForcedId);
-
- @Override
- public abstract Long getId();
-
public void setDeleted(Date theDate) {
myDeleted = theDate;
}
@@ -129,12 +105,6 @@ public abstract class BaseHasResource extends BasePartitionable
myPublished = thePublished.getValue();
}
- @Override
- public abstract Long getResourceId();
-
- @Override
- public abstract String getResourceType();
-
public abstract Collection extends BaseTag> getTags();
@Override
@@ -151,9 +121,6 @@ public abstract class BaseHasResource extends BasePartitionable
myUpdated = theUpdated;
}
- @Override
- public abstract long getVersion();
-
@Override
public boolean isHasTags() {
return myHasTags;
diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ForcedId.java b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ForcedId.java
index 9c69541511a..cab74929dfd 100644
--- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ForcedId.java
+++ b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ForcedId.java
@@ -21,51 +21,24 @@ package ca.uhn.fhir.jpa.model.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
-import jakarta.persistence.FetchType;
-import jakarta.persistence.ForeignKey;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
-import jakarta.persistence.Index;
-import jakarta.persistence.JoinColumn;
-import jakarta.persistence.OneToOne;
import jakarta.persistence.SequenceGenerator;
import jakarta.persistence.Table;
-import jakarta.persistence.UniqueConstraint;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.hibernate.annotations.ColumnDefault;
+/**
+ * The old way we handled client-assigned resource ids.
+ * Replaced by {@link ResourceTable#myFhirId}.
+ * @deprecated This is unused, and only kept for history and upgrade migration testing.
+ */
@Entity()
-@Table(
- name = ForcedId.HFJ_FORCED_ID,
- uniqueConstraints = {
- @UniqueConstraint(
- name = "IDX_FORCEDID_RESID",
- columnNames = {"RESOURCE_PID"}),
-
- /*
- * This index is called IDX_FORCEDID_TYPE_FID and guarantees
- * uniqueness of RESOURCE_TYPE,FORCED_ID. This doesn't make sense
- * for partitioned servers, so we replace it on those servers
- * with IDX_FORCEDID_TYPE_PFID covering
- * PARTITION_ID,RESOURCE_TYPE,FORCED_ID
- */
- @UniqueConstraint(
- name = ForcedId.IDX_FORCEDID_TYPE_FID,
- columnNames = {"RESOURCE_TYPE", "FORCED_ID"})
- },
- indexes = {
- /*
- * NB: We previously had indexes named
- * - IDX_FORCEDID_TYPE_FORCEDID
- * - IDX_FORCEDID_TYPE_RESID
- * so don't reuse these names
- */
- @Index(name = "IDX_FORCEID_FID", columnList = "FORCED_ID"),
- // @Index(name = "IDX_FORCEID_RESID", columnList = "RESOURCE_PID"),
- })
-public class ForcedId extends BasePartitionable {
+@Table(name = ForcedId.HFJ_FORCED_ID)
+@Deprecated(since = "7.1", forRemoval = true)
+class ForcedId extends BasePartitionable {
public static final int MAX_FORCED_ID_LENGTH = 100;
public static final String IDX_FORCEDID_TYPE_FID = "IDX_FORCEDID_TYPE_FID";
@@ -80,14 +53,6 @@ public class ForcedId extends BasePartitionable {
@Column(name = "PID")
private Long myId;
- @JoinColumn(
- name = "RESOURCE_PID",
- nullable = false,
- updatable = false,
- foreignKey = @ForeignKey(name = "FK_FORCEDID_RESOURCE"))
- @OneToOne(fetch = FetchType.LAZY)
- private ResourceTable myResource;
-
@Column(name = "RESOURCE_PID", nullable = false, updatable = false, insertable = false)
private Long myResourcePid;
@@ -112,10 +77,6 @@ public class ForcedId extends BasePartitionable {
myForcedId = theForcedId;
}
- public void setResource(ResourceTable theResource) {
- myResource = theResource;
- }
-
public String getResourceType() {
return myResourceType;
}
diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceHistoryTable.java b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceHistoryTable.java
index 49ad436112c..6348ce579b3 100644
--- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceHistoryTable.java
+++ b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceHistoryTable.java
@@ -22,7 +22,26 @@ package ca.uhn.fhir.jpa.model.entity;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.api.Constants;
-import jakarta.persistence.*;
+import jakarta.persistence.CascadeType;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.EnumType;
+import jakarta.persistence.Enumerated;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.ForeignKey;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.Index;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.Lob;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.OneToMany;
+import jakarta.persistence.OneToOne;
+import jakarta.persistence.SequenceGenerator;
+import jakarta.persistence.Table;
+import jakarta.persistence.Transient;
+import jakarta.persistence.UniqueConstraint;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.hibernate.Length;
@@ -111,6 +130,12 @@ public class ResourceHistoryTable extends BaseHasResource implements Serializabl
@Transient
private transient ResourceHistoryProvenanceEntity myNewHistoryProvenanceEntity;
+ /**
+ * This is stored as an optimization to avoid needing to fetch ResourceTable
+ * to access the resource id.
+ */
+ @Transient
+ private transient String myTransientForcedId;
/**
* Constructor
@@ -280,16 +305,6 @@ public class ResourceHistoryTable extends BaseHasResource implements Serializabl
return new IdDt(getResourceType() + '/' + resourceIdPart + '/' + Constants.PARAM_HISTORY + '/' + getVersion());
}
- @Override
- public ForcedId getForcedId() {
- return getResourceTable().getForcedId();
- }
-
- @Override
- public void setForcedId(ForcedId theForcedId) {
- getResourceTable().setForcedId(theForcedId);
- }
-
/**
* Returns true
if there is a populated resource text (i.e.
* either {@link #getResource()} or {@link #getResourceTextVc()} return a non null
@@ -311,4 +326,12 @@ public class ResourceHistoryTable extends BaseHasResource implements Serializabl
}
return myNewHistoryProvenanceEntity;
}
+
+ public String getTransientForcedId() {
+ return myTransientForcedId;
+ }
+
+ public void setTransientForcedId(String theTransientForcedId) {
+ myTransientForcedId = theTransientForcedId;
+ }
}
diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceTable.java b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceTable.java
index 4aad4fa503a..39f85198aec 100644
--- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceTable.java
+++ b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceTable.java
@@ -38,7 +38,6 @@ import jakarta.persistence.Id;
import jakarta.persistence.Index;
import jakarta.persistence.NamedEntityGraph;
import jakarta.persistence.OneToMany;
-import jakarta.persistence.OneToOne;
import jakarta.persistence.PostPersist;
import jakarta.persistence.PrePersist;
import jakarta.persistence.PreUpdate;
@@ -420,15 +419,6 @@ public class ResourceTable extends BaseHasResource implements Serializable, IBas
@Transient
private transient boolean myVersionUpdatedInCurrentTransaction;
- @OneToOne(
- optional = true,
- fetch = FetchType.EAGER,
- cascade = {},
- orphanRemoval = false,
- mappedBy = "myResource")
- @OptimisticLock(excluded = true)
- private ForcedId myForcedId;
-
@Transient
private volatile String myCreatedByMatchUrl;
@@ -889,10 +879,9 @@ public class ResourceTable extends BaseHasResource implements Serializable, IBas
retVal.setResourceId(myId);
retVal.setResourceType(myResourceType);
- retVal.setTransientForcedId(getTransientForcedId());
+ retVal.setTransientForcedId(getFhirId());
retVal.setFhirVersion(getFhirVersion());
retVal.setResourceTable(this);
- retVal.setForcedId(getForcedId());
retVal.setPartitionId(getPartitionId());
retVal.setHasTags(isHasTags());
@@ -923,6 +912,7 @@ public class ResourceTable extends BaseHasResource implements Serializable, IBas
public String toString() {
ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
b.append("pid", myId);
+ b.append("fhirId", myFhirId);
b.append("resourceType", myResourceType);
b.append("version", myVersion);
if (getPartitionId() != null) {
@@ -970,16 +960,6 @@ public class ResourceTable extends BaseHasResource implements Serializable, IBas
return JpaPid.fromId(getId());
}
- @Override
- public ForcedId getForcedId() {
- return myForcedId;
- }
-
- @Override
- public void setForcedId(ForcedId theForcedId) {
- myForcedId = theForcedId;
- }
-
@Override
public IdDt getIdDt() {
IdDt retVal = new IdDt();
@@ -997,10 +977,6 @@ public class ResourceTable extends BaseHasResource implements Serializable, IBas
String resourceId;
if (myFhirId != null && !myFhirId.isEmpty()) {
resourceId = myFhirId;
- } else if (getTransientForcedId() != null) {
- resourceId = getTransientForcedId();
- } else if (myForcedId != null) {
- resourceId = myForcedId.getForcedId();
} else {
Long id = this.getResourceId();
resourceId = Long.toString(id);
diff --git a/hapi-fhir-jpaserver-model/src/test/java/ca/uhn/fhir/jpa/model/entity/ResourceTableTest.java b/hapi-fhir-jpaserver-model/src/test/java/ca/uhn/fhir/jpa/model/entity/ResourceTableTest.java
index a5ccb698720..e3534ba81d6 100644
--- a/hapi-fhir-jpaserver-model/src/test/java/ca/uhn/fhir/jpa/model/entity/ResourceTableTest.java
+++ b/hapi-fhir-jpaserver-model/src/test/java/ca/uhn/fhir/jpa/model/entity/ResourceTableTest.java
@@ -25,17 +25,15 @@ public class ResourceTableTest {
@ParameterizedTest
@CsvSource(value={
+ "123, null, Patient/123/_history/1",
"123, 123, Patient/123/_history/1",
- ", 123, Patient/123/_history/1",
- "null, 456, Patient/456/_history/1"
+ "123, 456, Patient/456/_history/1"
},nullValues={"null"})
- public void testPopulateId(String theFhirId, String theForcedId, String theExpected) {
+ public void testPopulateId(Long theResId, String theFhirId, String theExpected) {
// Given
ResourceTable t = new ResourceTable();
+ t.setId(theResId);
t.setFhirId(theFhirId);
- ForcedId forcedId = new ForcedId();
- forcedId.setForcedId(theForcedId);
- t.setForcedId(forcedId);
t.setResourceType(new Patient().getResourceType().name());
t.setVersionForUnitTest(1);
diff --git a/hapi-fhir-jpaserver-searchparam/pom.xml b/hapi-fhir-jpaserver-searchparam/pom.xml
index 751edb8b63f..1cbb7748009 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-subscription/pom.xml b/hapi-fhir-jpaserver-subscription/pom.xml
index 4e05e2edf03..cc08fd09695 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.1.7-SNAPSHOT
+ 7.1.8-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 d51a8940bc0..1ced5f66cf1 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-test-dstu2/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoDstu2Test.java b/hapi-fhir-jpaserver-test-dstu2/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoDstu2Test.java
index aa2c0803c9e..c27ecc6bc2d 100644
--- a/hapi-fhir-jpaserver-test-dstu2/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoDstu2Test.java
+++ b/hapi-fhir-jpaserver-test-dstu2/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoDstu2Test.java
@@ -6,7 +6,6 @@ import ca.uhn.fhir.jpa.api.model.HistoryCountModeEnum;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
import ca.uhn.fhir.jpa.dao.BaseStorageDao;
import ca.uhn.fhir.jpa.dao.DaoTestUtils;
-import ca.uhn.fhir.jpa.dao.data.IForcedIdDao;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamString;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamToken;
@@ -82,7 +81,6 @@ import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
-import org.springframework.beans.factory.annotation.Autowired;
import java.io.IOException;
import java.util.ArrayList;
@@ -112,8 +110,6 @@ import static org.junit.jupiter.api.Assertions.fail;
public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu2Test.class);
- @Autowired
- private IForcedIdDao myForcedIdDao;
@AfterEach
public final void after() {
@@ -995,9 +991,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
idv2 = myPatientDao.update(patient, mySrd).getId();
}
- runInTransaction(() -> {
- ourLog.info("Forced IDs:\n{}", myForcedIdDao.findAll().stream().map(t -> t.toString()).collect(Collectors.joining("\n")));
- });
+ logAllResources();
List patients = toList(myPatientDao.history(idv1.toVersionless(), null, null, null, mySrd));
assertTrue(patients.size() == 2);
diff --git a/hapi-fhir-jpaserver-test-dstu2/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderLanguageParamDstu2Test.java b/hapi-fhir-jpaserver-test-dstu2/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderLanguageParamDstu2Test.java
new file mode 100644
index 00000000000..a69593a0490
--- /dev/null
+++ b/hapi-fhir-jpaserver-test-dstu2/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderLanguageParamDstu2Test.java
@@ -0,0 +1,67 @@
+package ca.uhn.fhir.jpa.provider;
+
+import ca.uhn.fhir.i18n.Msg;
+import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
+import ca.uhn.fhir.model.primitive.CodeDt;
+import ca.uhn.fhir.rest.api.Constants;
+import ca.uhn.fhir.rest.gclient.TokenClientParam;
+import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
+import ca.uhn.fhir.model.dstu2.resource.Patient;
+import ca.uhn.fhir.model.dstu2.resource.Bundle;
+import org.hl7.fhir.instance.model.api.IIdType;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.Matchers.containsString;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+public class ResourceProviderLanguageParamDstu2Test extends BaseResourceProviderDstu2Test {
+
+ @SuppressWarnings("unused")
+ @Test
+ public void testSearchWithLanguageParamEnabled() {
+ myStorageSettings.setLanguageSearchParameterEnabled(true);
+ mySearchParamRegistry.forceRefresh();
+
+ Patient pat = new Patient();
+ pat.setLanguage(new CodeDt("en"));
+ IIdType patId = myPatientDao.create(pat, mySrd).getId().toUnqualifiedVersionless();
+
+ Patient pat2 = new Patient();
+ pat.setLanguage(new CodeDt("fr"));
+ IIdType patId2 = myPatientDao.create(pat2, mySrd).getId().toUnqualifiedVersionless();
+
+ List foundResources;
+ Bundle result;
+
+ result = myClient
+ .search()
+ .forResource(Patient.class)
+ .where(new TokenClientParam(Constants.PARAM_LANGUAGE).exactly().code("en"))
+ .returnBundle(Bundle.class)
+ .execute();
+
+ foundResources = toUnqualifiedVersionlessIdValues(result);
+ assertThat(foundResources, contains(patId.getValue()));
+ }
+
+ @SuppressWarnings("unused")
+ @Test
+ public void testSearchWithLanguageParamDisabled() {
+ myStorageSettings.setLanguageSearchParameterEnabled(new JpaStorageSettings().isLanguageSearchParameterEnabled());
+ mySearchParamRegistry.forceRefresh();
+
+ InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> {
+ myClient
+ .search()
+ .forResource(Patient.class)
+ .where(new TokenClientParam(Constants.PARAM_LANGUAGE).exactly().code("en"))
+ .returnBundle(Bundle.class)
+ .execute();
+ });
+ assertThat(exception.getMessage(), containsString(Msg.code(1223)));
+ }
+}
diff --git a/hapi-fhir-jpaserver-test-dstu3/pom.xml b/hapi-fhir-jpaserver-test-dstu3/pom.xml
index 7fa9c4fbb06..7868b2b95a2 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-test-dstu3/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3Test.java b/hapi-fhir-jpaserver-test-dstu3/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3Test.java
index 7b2b699d85f..336d1ac0478 100644
--- a/hapi-fhir-jpaserver-test-dstu3/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3Test.java
+++ b/hapi-fhir-jpaserver-test-dstu3/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3Test.java
@@ -626,16 +626,9 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
.getSingleResult();
assertNotNull(readBackView, "found search view");
- // verify the forced id join still works
- if (readBackResource.getForcedId() != null) {
- assertEquals(myExpectedId, readBackResource.getForcedId().getForcedId(),
- "legacy join populated");
- assertEquals(myExpectedId, readBackView.getFhirId(),
- "legacy join populated");
- } else {
- assertEquals(IdStrategyEnum.SEQUENTIAL_NUMERIC, theServerIdStrategy,
- "hfj_forced_id join column is only empty when using server-assigned ids");
- } }
+ assertEquals(myExpectedId, readBackView.getFhirId(),
+ "fhir_id populated");
+ }
}
@Test
diff --git a/hapi-fhir-jpaserver-test-dstu3/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderLanguageParamDstu3Test.java b/hapi-fhir-jpaserver-test-dstu3/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderLanguageParamDstu3Test.java
new file mode 100644
index 00000000000..523467c83d4
--- /dev/null
+++ b/hapi-fhir-jpaserver-test-dstu3/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderLanguageParamDstu3Test.java
@@ -0,0 +1,84 @@
+package ca.uhn.fhir.jpa.provider.dstu3;
+
+import ca.uhn.fhir.i18n.Msg;
+import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
+import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
+import ca.uhn.fhir.rest.api.Constants;
+import ca.uhn.fhir.rest.api.server.IBundleProvider;
+import ca.uhn.fhir.rest.gclient.TokenClientParam;
+import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
+import org.hl7.fhir.instance.model.api.IIdType;
+import org.hl7.fhir.dstu3.model.Bundle;
+import org.hl7.fhir.dstu3.model.Patient;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.Matchers.containsString;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+public class ResourceProviderLanguageParamDstu3Test extends BaseResourceProviderDstu3Test {
+
+ @SuppressWarnings("unused")
+ @Test
+ public void testSearchWithLanguageParamEnabled() {
+ myStorageSettings.setLanguageSearchParameterEnabled(true);
+ mySearchParamRegistry.forceRefresh();
+
+ Patient pat = new Patient();
+ pat.setLanguage("en");
+ IIdType patId = myPatientDao.create(pat, mySrd).getId().toUnqualifiedVersionless();
+
+ Patient pat2 = new Patient();
+ pat.setLanguage("fr");
+ IIdType patId2 = myPatientDao.create(pat2, mySrd).getId().toUnqualifiedVersionless();
+
+ SearchParameterMap map;
+ IBundleProvider results;
+ List foundResources;
+ Bundle result;
+
+ result = myClient
+ .search()
+ .forResource(Patient.class)
+ .where(new TokenClientParam(Constants.PARAM_LANGUAGE).exactly().code("en"))
+ .returnBundle(Bundle.class)
+ .execute();
+
+ foundResources = toUnqualifiedVersionlessIdValues(result);
+ assertThat(foundResources, contains(patId.getValue()));
+ }
+
+ @SuppressWarnings("unused")
+ @Test
+ public void testSearchWithLanguageParamDisabled() {
+ myStorageSettings.setLanguageSearchParameterEnabled(new JpaStorageSettings().isLanguageSearchParameterEnabled());
+ mySearchParamRegistry.forceRefresh();
+
+ Patient pat = new Patient();
+ pat.setLanguage("en");
+ IIdType patId = myPatientDao.create(pat, mySrd).getId().toUnqualifiedVersionless();
+
+ Patient pat2 = new Patient();
+ pat.setLanguage("fr");
+ IIdType patId2 = myPatientDao.create(pat2, mySrd).getId().toUnqualifiedVersionless();
+
+ SearchParameterMap map;
+ IBundleProvider results;
+ List foundResources;
+ Bundle result;
+
+
+ InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> {
+ myClient
+ .search()
+ .forResource(Patient.class)
+ .where(new TokenClientParam(Constants.PARAM_LANGUAGE).exactly().code("en"))
+ .returnBundle(Bundle.class)
+ .execute();
+ });
+ assertThat(exception.getMessage(), containsString(Msg.code(1223)));
+ }
+}
diff --git a/hapi-fhir-jpaserver-test-r4/pom.xml b/hapi-fhir-jpaserver-test-r4/pom.xml
index 8bec81531a4..9a9709161a5 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/batch2/Batch2CoordinatorIT.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/batch2/Batch2CoordinatorIT.java
index 6b600251e3a..cc51d896f46 100644
--- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/batch2/Batch2CoordinatorIT.java
+++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/batch2/Batch2CoordinatorIT.java
@@ -321,6 +321,61 @@ public class Batch2CoordinatorIT extends BaseJpaR4Test {
}
}
+ @Test
+ public void reductionStepFailing_willFailJob() throws InterruptedException {
+ // setup
+ String jobId = new Exception().getStackTrace()[0].getMethodName();
+ int totalChunks = 3;
+ AtomicInteger chunkCounter = new AtomicInteger();
+ String error = "this is an error";
+
+ buildAndDefine3StepReductionJob(jobId, new IReductionStepHandler() {
+
+ @Override
+ public void firstStep(StepExecutionDetails theStep, IJobDataSink theDataSink) {
+ for (int i = 0; i < totalChunks; i++) {
+ theDataSink.accept(new FirstStepOutput());
+ }
+ }
+
+ @Override
+ public void secondStep(StepExecutionDetails theStep, IJobDataSink theDataSink) {
+ SecondStepOutput output = new SecondStepOutput();
+ theDataSink.accept(output);
+ }
+
+ @Override
+ public void reductionStepConsume(ChunkExecutionDetails theChunkDetails, IJobDataSink theDataSink) {
+ chunkCounter.getAndIncrement();
+ }
+
+ @Override
+ public void reductionStepRun(StepExecutionDetails theStepExecutionDetails, IJobDataSink theDataSink) {
+ // always throw
+ throw new RuntimeException(error);
+ }
+ });
+
+ // test
+ JobInstanceStartRequest request = buildRequest(jobId);
+ myFirstStepLatch.setExpectedCount(1);
+ Batch2JobStartResponse startResponse = myJobCoordinator.startInstance(new SystemRequestDetails(), request);
+ String instanceId = startResponse.getInstanceId();
+ assertNotNull(instanceId);
+
+ // waiting for job to end (any status - but we'll verify failed later)
+ myBatch2JobHelper.awaitJobHasStatus(instanceId, StatusEnum.getEndedStatuses().toArray(new StatusEnum[0]));
+
+ // verify
+ Optional instanceOp = myJobPersistence.fetchInstance(instanceId);
+ assertTrue(instanceOp.isPresent());
+ JobInstance jobInstance = instanceOp.get();
+
+ assertEquals(totalChunks, chunkCounter.get());
+
+ assertEquals(StatusEnum.FAILED, jobInstance.getStatus());
+ }
+
@Test
public void testJobWithReductionStepFiresCompletionHandler() throws InterruptedException {
// setup
diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/bulk/imprt2/ConsumeFilesStepR4Test.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/bulk/imprt2/ConsumeFilesStepR4Test.java
index 5462f896a3c..2076cf970fa 100644
--- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/bulk/imprt2/ConsumeFilesStepR4Test.java
+++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/bulk/imprt2/ConsumeFilesStepR4Test.java
@@ -3,7 +3,6 @@ package ca.uhn.fhir.jpa.bulk.imprt2;
import ca.uhn.fhir.batch2.api.JobExecutionFailedException;
import ca.uhn.fhir.batch2.jobs.imprt.ConsumeFilesStep;
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
-import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
import ca.uhn.fhir.jpa.dao.r4.BasePartitioningR4Test;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.IdType;
@@ -84,7 +83,7 @@ public class ConsumeFilesStepR4Test extends BasePartitioningR4Test {
// Validate
- assertEquals(7, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
+ assertEquals(6, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
assertEquals(0, myCaptureQueriesListener.countInsertQueriesForCurrentThread(), myCaptureQueriesListener.getInsertQueriesForCurrentThread().stream().map(t->t.getSql(true, false)).collect(Collectors.joining("\n")));
assertEquals(0, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
@@ -145,9 +144,9 @@ public class ConsumeFilesStepR4Test extends BasePartitioningR4Test {
// Validate
if (partitionEnabled) {
- assertEquals(8, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
- } else {
assertEquals(7, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
+ } else {
+ assertEquals(6, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
}
assertEquals(2, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
assertEquals(4, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
@@ -190,7 +189,7 @@ public class ConsumeFilesStepR4Test extends BasePartitioningR4Test {
assertThat(myCaptureQueriesListener.getSelectQueries().get(0).getSql(true, false),
either(containsString("rt1_0.RES_TYPE='Patient' and rt1_0.FHIR_ID='B' and rt1_0.PARTITION_ID is null or rt1_0.RES_TYPE='Patient' and rt1_0.FHIR_ID='A' and rt1_0.PARTITION_ID is null"))
.or(containsString("rt1_0.RES_TYPE='Patient' and rt1_0.FHIR_ID='A' and rt1_0.PARTITION_ID is null or rt1_0.RES_TYPE='Patient' and rt1_0.FHIR_ID='B' and rt1_0.PARTITION_ID is null")));
- assertEquals(52, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
+ assertEquals(50, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
assertEquals(0, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
assertEquals(1, myCaptureQueriesListener.countCommits());
diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDaoTest.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDaoTest.java
index c68d4a77b1d..7eb90f46452 100644
--- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDaoTest.java
+++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDaoTest.java
@@ -19,7 +19,6 @@ import ca.uhn.fhir.jpa.dao.tx.HapiTransactionService;
import ca.uhn.fhir.jpa.dao.tx.IHapiTransactionService;
import ca.uhn.fhir.jpa.delete.DeleteConflictService;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
-import ca.uhn.fhir.jpa.model.entity.ForcedId;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc;
import ca.uhn.fhir.jpa.search.ResourceSearchUrlSvc;
@@ -227,7 +226,8 @@ class BaseHapiFhirResourceDaoTest {
RequestPartitionId partitionId = Mockito.mock(RequestPartitionId.class);
JpaPid jpaPid = JpaPid.fromIdAndVersion(123L, 1L);
ResourceTable entity = new ResourceTable();
- entity.setForcedId(new ForcedId());
+ entity.setId(123L);
+ entity.setFhirId("456");
// mock
when(myRequestPartitionHelperSvc.determineReadPartitionForRequestForRead(
diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/BasePartitioningR4Test.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/BasePartitioningR4Test.java
index e91e3421bf2..374b7e3d565 100644
--- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/BasePartitioningR4Test.java
+++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/BasePartitioningR4Test.java
@@ -7,7 +7,6 @@ import ca.uhn.fhir.interceptor.model.RequestPartitionId;
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
import ca.uhn.fhir.jpa.entity.PartitionEntity;
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
-import ca.uhn.fhir.jpa.model.entity.ForcedId;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.partition.IPartitionLookupSvc;
@@ -30,6 +29,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import static ca.uhn.fhir.jpa.model.entity.ResourceTable.IDX_RES_TYPE_FHIR_ID;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -61,13 +61,6 @@ public abstract class BasePartitioningR4Test extends BaseJpaR4SystemTest {
mySrdInterceptorService.unregisterInterceptorsIf(t -> t instanceof MyReadWriteInterceptor);
- if (myHaveDroppedForcedIdUniqueConstraint) {
- runInTransaction(() -> {
- myEntityManager.createNativeQuery("delete from HFJ_FORCED_ID").executeUpdate();
- myEntityManager.createNativeQuery("alter table HFJ_FORCED_ID add constraint IDX_FORCEDID_TYPE_FID unique (RESOURCE_TYPE, FORCED_ID)");
- });
- }
-
myStorageSettings.setIndexMissingFields(new JpaStorageSettings().getIndexMissingFields());
myStorageSettings.setAutoCreatePlaceholderReferenceTargets(new JpaStorageSettings().isAutoCreatePlaceholderReferenceTargets());
myStorageSettings.setMassIngestionMode(new JpaStorageSettings().isMassIngestionMode());
@@ -106,6 +99,18 @@ public abstract class BasePartitioningR4Test extends BaseJpaR4SystemTest {
}
+ @Override
+ public void afterPurgeDatabase() {
+ super.afterPurgeDatabase();
+
+ if (myHaveDroppedForcedIdUniqueConstraint) {
+ runInTransaction(() -> {
+ myEntityManager.createNativeQuery("delete from HFJ_RESOURCE").executeUpdate();
+ myEntityManager.createNativeQuery("alter table " + ResourceTable.HFJ_RESOURCE +
+ " add constraint " + IDX_RES_TYPE_FHIR_ID + " unique (RES_TYPE, FHIR_ID)").executeUpdate();
+ });
+ }
+ }
protected void createUniqueCompositeSp() {
addCreateDefaultPartition();
addReadDefaultPartition(); // one for search param validation
@@ -137,8 +142,7 @@ public abstract class BasePartitioningR4Test extends BaseJpaR4SystemTest {
protected void dropForcedIdUniqueConstraint() {
runInTransaction(() -> {
- myEntityManager.createNativeQuery("alter table " + ForcedId.HFJ_FORCED_ID + " drop constraint " + ForcedId.IDX_FORCEDID_TYPE_FID).executeUpdate();
- myEntityManager.createNativeQuery("alter table " + ResourceTable.HFJ_RESOURCE + " drop constraint " + ResourceTable.IDX_RES_TYPE_FHIR_ID).executeUpdate();
+ myEntityManager.createNativeQuery("alter table " + ResourceTable.HFJ_RESOURCE + " drop constraint " + IDX_RES_TYPE_FHIR_ID).executeUpdate();
});
myHaveDroppedForcedIdUniqueConstraint = true;
}
diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4QueryCountTest.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4QueryCountTest.java
index 9e24d3e728a..abba1fbe50c 100644
--- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4QueryCountTest.java
+++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4QueryCountTest.java
@@ -20,7 +20,6 @@ import ca.uhn.fhir.jpa.dao.data.ISearchParamPresentDao;
import ca.uhn.fhir.jpa.entity.TermValueSet;
import ca.uhn.fhir.jpa.entity.TermValueSetPreExpansionStatusEnum;
import ca.uhn.fhir.jpa.interceptor.ForceOffsetSearchModeInterceptor;
-import ca.uhn.fhir.jpa.model.entity.ForcedId;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.provider.BaseResourceProviderR4Test;
@@ -47,6 +46,7 @@ import ca.uhn.fhir.test.utilities.ProxyUtil;
import ca.uhn.fhir.test.utilities.server.HashMapResourceProviderExtension;
import ca.uhn.fhir.test.utilities.server.RestfulServerExtension;
import ca.uhn.fhir.util.BundleBuilder;
+import jakarta.annotation.Nonnull;
import org.hamcrest.CoreMatchers;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
@@ -90,7 +90,6 @@ import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Slice;
import org.springframework.util.comparator.ComparableComparator;
-import jakarta.annotation.Nonnull;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
@@ -150,7 +149,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
@Autowired
private ISubscriptionTriggeringSvc mySubscriptionTriggeringSvc;
@Autowired
- private ResourceModifiedSubmitterSvc myResourceModifiedSubmitterSvc;;
+ private ResourceModifiedSubmitterSvc myResourceModifiedSubmitterSvc;
@Autowired
private ReindexStep myReindexStep;
@Autowired
@@ -221,7 +220,6 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
runInTransaction(() -> assertThat(myResourceTableDao.findAll(), not(empty())));
runInTransaction(() -> assertThat(myResourceHistoryTableDao.findAll(), not(empty())));
- runInTransaction(() -> assertThat(myForcedIdDao.findAll(), not(empty())));
logAllResources();
@@ -242,11 +240,10 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
assertEquals(47, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
assertEquals(0, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
assertEquals(0, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
- assertEquals(85, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
+ assertEquals(80, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
runInTransaction(() -> assertThat(myResourceTableDao.findAll(), empty()));
runInTransaction(() -> assertThat(myResourceHistoryTableDao.findAll(), empty()));
- runInTransaction(() -> assertThat(myForcedIdDao.findAll(), empty()));
}
@@ -328,7 +325,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
myCaptureQueriesListener.clear();
Group group = createGroup(patientList.subList(0, initialPatientsCount));
- assertQueryCount(31, 0, 4, 0);
+ assertQueryCount(31, 0, 3, 0);
myCaptureQueriesListener.clear();
group = updateGroup(group, patientList.subList(initialPatientsCount, allPatientsCount));
@@ -350,7 +347,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
myCaptureQueriesListener.clear();
Group group = createGroup(patientList);
- assertQueryCount(31, 0, 4, 0);
+ assertQueryCount(31, 0, 3, 0);
// Make a change to the group, but don't touch any references in it
myCaptureQueriesListener.clear();
@@ -672,7 +669,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
myCaptureQueriesListener.logUpdateQueriesForCurrentThread();
assertEquals(0, myCaptureQueriesListener.getUpdateQueriesForCurrentThread().size());
myCaptureQueriesListener.logInsertQueriesForCurrentThread();
- assertEquals(4, myCaptureQueriesListener.getInsertQueriesForCurrentThread().size());
+ assertEquals(3, myCaptureQueriesListener.getInsertQueriesForCurrentThread().size());
myCaptureQueriesListener.logDeleteQueriesForCurrentThread();
assertEquals(0, myCaptureQueriesListener.getDeleteQueriesForCurrentThread().size());
@@ -705,24 +702,20 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
assertEquals(0, myCaptureQueriesListener.getSelectQueriesForCurrentThread().size());
myCaptureQueriesListener.logUpdateQueriesForCurrentThread();
- assertEquals(4, myCaptureQueriesListener.getInsertQueriesForCurrentThread().size());
+ assertEquals(3, myCaptureQueriesListener.getInsertQueriesForCurrentThread().size());
myCaptureQueriesListener.logDeleteQueriesForCurrentThread();
assertEquals(0, myCaptureQueriesListener.getUpdateQueriesForCurrentThread().size());
myCaptureQueriesListener.logInsertQueriesForCurrentThread();
assertEquals(0, myCaptureQueriesListener.getDeleteQueriesForCurrentThread().size());
runInTransaction(() -> {
- List allForcedIds = myForcedIdDao.findAll();
- for (ForcedId next : allForcedIds) {
- assertNotNull(next.getResourceId());
- assertNotNull(next.getForcedId());
- }
-
List resources = myResourceTableDao.findAll();
String versions = "Resource Versions:\n * " + resources.stream().map(t -> "Resource " + t.getIdDt() + " has version: " + t.getVersion()).collect(Collectors.joining("\n * "));
for (ResourceTable next : resources) {
assertEquals(1, next.getVersion(), versions);
+ assertNotNull(next.getResourceId());
+ assertNotNull(next.getFhirId());
}
});
@@ -771,22 +764,18 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
myCaptureQueriesListener.logUpdateQueriesForCurrentThread();
assertEquals(0, myCaptureQueriesListener.getUpdateQueriesForCurrentThread().size());
myCaptureQueriesListener.logInsertQueriesForCurrentThread();
- assertEquals(4, myCaptureQueriesListener.getInsertQueriesForCurrentThread().size());
+ assertEquals(3, myCaptureQueriesListener.getInsertQueriesForCurrentThread().size());
myCaptureQueriesListener.logDeleteQueriesForCurrentThread();
assertEquals(0, myCaptureQueriesListener.getDeleteQueriesForCurrentThread().size());
runInTransaction(() -> {
- List allForcedIds = myForcedIdDao.findAll();
- for (ForcedId next : allForcedIds) {
- assertNotNull(next.getResourceId());
- assertNotNull(next.getForcedId());
- }
-
List resources = myResourceTableDao.findAll();
String versions = "Resource Versions:\n * " + resources.stream().map(t -> "Resource " + t.getIdDt() + " has version: " + t.getVersion()).collect(Collectors.joining("\n * "));
for (ResourceTable next : resources) {
assertEquals(1, next.getVersion(), versions);
+ assertNotNull(next.getResourceId());
+ assertNotNull(next.getFhirId());
}
});
@@ -819,7 +808,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
myCaptureQueriesListener.logUpdateQueriesForCurrentThread();
assertEquals(0, myCaptureQueriesListener.getUpdateQueriesForCurrentThread().size());
myCaptureQueriesListener.logInsertQueriesForCurrentThread();
- assertEquals(4, myCaptureQueriesListener.getInsertQueriesForCurrentThread().size());
+ assertEquals(3, myCaptureQueriesListener.getInsertQueriesForCurrentThread().size());
myCaptureQueriesListener.logDeleteQueriesForCurrentThread();
assertEquals(0, myCaptureQueriesListener.getDeleteQueriesForCurrentThread().size());
}
@@ -838,7 +827,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
DeleteMethodOutcome outcome = myPatientDao.deleteByUrl("Patient?active=true", new SystemRequestDetails());
// Validate
- assertEquals(13, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
+ assertEquals(12, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
assertEquals(10, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
assertEquals(10, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
assertEquals(30, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
@@ -856,7 +845,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
withFamily("Family" + i),
withTag("http://foo", "blah"));
}
- List pids = runInTransaction(() -> myForcedIdDao
+ List pids = runInTransaction(() -> myResourceTableDao
.findAll()
.stream()
.map(t -> new TypedPidJson(t.getResourceType(), Long.toString(t.getResourceId())))
@@ -874,7 +863,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
assertEquals(1, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
assertEquals(0, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
assertEquals(0, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
- assertEquals(29, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
+ assertEquals(28, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
assertEquals(10, outcome.getRecordsProcessed());
runInTransaction(()-> assertEquals(0, myResourceTableDao.count()));
}
@@ -1037,10 +1026,10 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
@ParameterizedTest
@CsvSource({
// OptimisticLock OptimizeMode ExpectedSelect ExpectedUpdate
- " false, CURRENT_VERSION, 2, 0",
- " true, CURRENT_VERSION, 12, 0",
- " false, ALL_VERSIONS, 12, 0",
- " true, ALL_VERSIONS, 22, 0",
+ " false, CURRENT_VERSION, 1, 0",
+ " true, CURRENT_VERSION, 11, 0",
+ " false, ALL_VERSIONS, 11, 0",
+ " true, ALL_VERSIONS, 21, 0",
})
public void testReindexJob_OptimizeStorage(boolean theOptimisticLock, ReindexParameters.OptimizeStorageModeEnum theOptimizeStorageModeEnum, int theExpectedSelectCount, int theExpectedUpdateCount) {
// Setup
@@ -1839,7 +1828,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
myCaptureQueriesListener.logSelectQueries();
assertEquals(1, myCaptureQueriesListener.countSelectQueries());
myCaptureQueriesListener.logInsertQueries();
- assertEquals(21, myCaptureQueriesListener.countInsertQueries());
+ assertEquals(18, myCaptureQueriesListener.countInsertQueries());
myCaptureQueriesListener.logUpdateQueries();
assertEquals(0, myCaptureQueriesListener.countUpdateQueries());
assertEquals(0, myCaptureQueriesListener.countDeleteQueries());
@@ -1852,7 +1841,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
outcome = mySystemDao.transaction(mySrd, input.get());
ourLog.debug("Resp: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
myCaptureQueriesListener.logSelectQueries();
- assertEquals(5, myCaptureQueriesListener.countSelectQueries());
+ assertEquals(4, myCaptureQueriesListener.countSelectQueries());
myCaptureQueriesListener.logInsertQueries();
assertEquals(2, myCaptureQueriesListener.countInsertQueries());
myCaptureQueriesListener.logUpdateQueries();
@@ -1868,7 +1857,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
outcome = mySystemDao.transaction(mySrd, input.get());
ourLog.debug("Resp: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
myCaptureQueriesListener.logSelectQueries();
- assertEquals(5, myCaptureQueriesListener.countSelectQueries());
+ assertEquals(4, myCaptureQueriesListener.countSelectQueries());
myCaptureQueriesListener.logInsertQueries();
assertEquals(2, myCaptureQueriesListener.countInsertQueries());
myCaptureQueriesListener.logUpdateQueries();
@@ -1925,7 +1914,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
// Search for IDs and Search for tag definition
assertEquals(3, myCaptureQueriesListener.countSelectQueries());
myCaptureQueriesListener.logInsertQueries();
- assertEquals(29, myCaptureQueriesListener.countInsertQueries());
+ assertEquals(26, myCaptureQueriesListener.countInsertQueries());
myCaptureQueriesListener.logUpdateQueries();
assertEquals(0, myCaptureQueriesListener.countUpdateQueries());
assertEquals(0, myCaptureQueriesListener.countDeleteQueries());
@@ -1938,7 +1927,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
outcome = mySystemDao.transaction(mySrd, input.get());
ourLog.debug("Resp: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
myCaptureQueriesListener.logSelectQueries();
- assertEquals(9, myCaptureQueriesListener.countSelectQueries());
+ assertEquals(7, myCaptureQueriesListener.countSelectQueries());
myCaptureQueriesListener.logInsertQueries();
assertEquals(7, myCaptureQueriesListener.countInsertQueries());
myCaptureQueriesListener.logUpdateQueries();
@@ -1954,7 +1943,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
outcome = mySystemDao.transaction(mySrd, input.get());
ourLog.debug("Resp: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
myCaptureQueriesListener.logSelectQueries();
- assertEquals(7, myCaptureQueriesListener.countSelectQueries());
+ assertEquals(5, myCaptureQueriesListener.countSelectQueries());
myCaptureQueriesListener.logInsertQueries();
assertEquals(5, myCaptureQueriesListener.countInsertQueries());
myCaptureQueriesListener.logUpdateQueries();
@@ -2250,7 +2239,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
outcome = mySystemDao.transaction(mySrd, input.get());
ourLog.debug("Resp: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
myCaptureQueriesListener.logSelectQueries();
- assertEquals(9, myCaptureQueriesListener.countSelectQueries());
+ assertEquals(8, myCaptureQueriesListener.countSelectQueries());
myCaptureQueriesListener.logInsertQueries();
assertEquals(4, myCaptureQueriesListener.countInsertQueries());
myCaptureQueriesListener.logUpdateQueries();
@@ -2267,7 +2256,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
outcome = mySystemDao.transaction(mySrd, input.get());
ourLog.debug("Resp: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
myCaptureQueriesListener.logSelectQueries();
- assertEquals(8, myCaptureQueriesListener.countSelectQueries());
+ assertEquals(7, myCaptureQueriesListener.countSelectQueries());
myCaptureQueriesListener.logInsertQueries();
assertEquals(4, myCaptureQueriesListener.countInsertQueries());
myCaptureQueriesListener.logUpdateQueries();
@@ -2282,7 +2271,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
outcome = mySystemDao.transaction(mySrd, input.get());
ourLog.debug("Resp: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
myCaptureQueriesListener.logSelectQueries();
- assertEquals(6, myCaptureQueriesListener.countSelectQueries());
+ assertEquals(5, myCaptureQueriesListener.countSelectQueries());
myCaptureQueriesListener.logInsertQueries();
assertEquals(4, myCaptureQueriesListener.countInsertQueries());
myCaptureQueriesListener.logUpdateQueries();
@@ -2453,7 +2442,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
assertEquals(1, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
myCaptureQueriesListener.logInsertQueriesForCurrentThread();
- assertEquals(7, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
+ assertEquals(6, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
myCaptureQueriesListener.logUpdateQueriesForCurrentThread();
assertEquals(0, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
@@ -3000,7 +2989,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
myCaptureQueriesListener.logSelectQueries();
assertEquals(17, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
- assertEquals(6607, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
+ assertEquals(6189, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
assertEquals(418, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
assertEquals(2, myCaptureQueriesListener.countCommits());
@@ -3368,7 +3357,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
myCaptureQueriesListener.clear();
mySystemDao.transaction(new SystemRequestDetails(), supplier.get());
assertEquals(2, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
- assertEquals(30, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
+ assertEquals(29, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
assertEquals(1, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
@@ -3376,7 +3365,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
myCaptureQueriesListener.clear();
Bundle outcome = mySystemDao.transaction(new SystemRequestDetails(), supplier.get());
- assertEquals(8, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
+ assertEquals(6, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
myCaptureQueriesListener.logInsertQueries();
assertEquals(4, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
assertEquals(6, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
@@ -3399,7 +3388,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
myCaptureQueriesListener.clear();
outcome = mySystemDao.transaction(new SystemRequestDetails(), supplier.get());
- assertEquals(8, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
+ assertEquals(6, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
myCaptureQueriesListener.logInsertQueries();
assertEquals(4, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
assertEquals(6, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
@@ -3451,7 +3440,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
mySystemDao.transaction(new SystemRequestDetails(), loadResourceFromClasspath(Bundle.class, "r4/transaction-perf-bundle.json"));
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
assertEquals(2, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
- assertEquals(125, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
+ assertEquals(120, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
myCaptureQueriesListener.logUpdateQueriesForCurrentThread();
assertEquals(1, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
@@ -3460,7 +3449,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
myCaptureQueriesListener.clear();
mySystemDao.transaction(new SystemRequestDetails(), loadResourceFromClasspath(Bundle.class, "r4/transaction-perf-bundle-smallchanges.json"));
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
- assertEquals(8, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
+ assertEquals(6, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
assertEquals(2, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
assertEquals(5, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchOptimizedTest.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchOptimizedTest.java
index 1e15bc49293..a329330178d 100644
--- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchOptimizedTest.java
+++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchOptimizedTest.java
@@ -31,9 +31,7 @@ import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.test.utilities.ProxyUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
-import org.checkerframework.checker.units.qual.A;
import org.hl7.fhir.instance.model.api.IAnyResource;
-import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.BodyStructure;
import org.hl7.fhir.r4.model.CodeableConcept;
@@ -1238,12 +1236,11 @@ public class FhirResourceDaoR4SearchOptimizedTest extends BaseJpaR4Test {
myPatientDao.update(p).getId().toUnqualifiedVersionless();
assertEquals(1, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
- assertEquals(4, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
+ assertEquals(3, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
runInTransaction(() -> {
assertEquals(1, myResourceTableDao.count());
assertEquals(1, myResourceHistoryTableDao.count());
- assertEquals(1, myForcedIdDao.count());
assertEquals(1, myResourceIndexedSearchParamTokenDao.count());
});
@@ -1264,7 +1261,6 @@ public class FhirResourceDaoR4SearchOptimizedTest extends BaseJpaR4Test {
runInTransaction(() -> {
assertEquals(1, myResourceTableDao.count());
assertEquals(2, myResourceHistoryTableDao.count());
- assertEquals(1, myForcedIdDao.count());
assertEquals(1, myResourceIndexedSearchParamTokenDao.count());
});
diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/PartitioningSqlR4Test.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/PartitioningSqlR4Test.java
index 42004dba52f..07c474b0ff0 100644
--- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/PartitioningSqlR4Test.java
+++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/PartitioningSqlR4Test.java
@@ -15,7 +15,6 @@ import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
import ca.uhn.fhir.jpa.batch.models.Batch2JobStartResponse;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
-import ca.uhn.fhir.jpa.model.entity.ForcedId;
import ca.uhn.fhir.jpa.model.entity.PartitionablePartitionId;
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTag;
@@ -589,13 +588,13 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
myPatientDao.update(p, mySrd);
runInTransaction(() -> {
- // HFJ_FORCED_ID
- List forcedIds = myForcedIdDao.findAll();
- assertEquals(2, forcedIds.size());
- assertEquals(myPartitionId, forcedIds.get(0).getPartitionId().getPartitionId().intValue());
- assertLocalDateFromDbMatches(myPartitionDate, forcedIds.get(0).getPartitionId().getPartitionDate());
- assertEquals(myPartitionId, forcedIds.get(1).getPartitionId().getPartitionId().intValue());
- assertLocalDateFromDbMatches(myPartitionDate, forcedIds.get(1).getPartitionId().getPartitionDate());
+ ResourceTable orgResourceTable = myResourceTableDao.findByTypeAndFhirId("Organization", "org").orElseThrow(IllegalArgumentException::new);
+ assertEquals(myPartitionId, orgResourceTable.getPartitionId().getPartitionId().intValue());
+ assertLocalDateFromDbMatches(myPartitionDate, orgResourceTable.getPartitionId().getPartitionDate());
+
+ ResourceTable patientResourceTable = myResourceTableDao.findByTypeAndFhirId("Patient", "pat").orElseThrow(IllegalArgumentException::new);
+ assertEquals(myPartitionId, patientResourceTable.getPartitionId().getPartitionId().intValue());
+ assertLocalDateFromDbMatches(myPartitionDate, patientResourceTable.getPartitionId().getPartitionDate());
});
}
@@ -615,11 +614,11 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
myPatientDao.update(p, mySrd);
runInTransaction(() -> {
- // HFJ_FORCED_ID
- List forcedIds = myForcedIdDao.findAll();
- assertEquals(2, forcedIds.size());
- assertEquals(null, forcedIds.get(0).getPartitionId());
- assertEquals(null, forcedIds.get(1).getPartitionId());
+ ResourceTable orgResourceTable = myResourceTableDao.findByTypeAndFhirId("Organization", "org").orElseThrow(IllegalArgumentException::new);
+ assertNull(orgResourceTable.getPartitionId());
+
+ ResourceTable patientResourceTable = myResourceTableDao.findByTypeAndFhirId("Patient", "pat").orElseThrow(IllegalArgumentException::new);
+ assertNull(patientResourceTable.getPartitionId());
});
}
@@ -639,13 +638,13 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
myPatientDao.update(p, mySrd);
runInTransaction(() -> {
- // HFJ_FORCED_ID
- List forcedIds = myForcedIdDao.findAll();
- assertEquals(2, forcedIds.size());
- assertEquals(null, forcedIds.get(0).getPartitionId().getPartitionId());
- assertLocalDateFromDbMatches(myPartitionDate, forcedIds.get(0).getPartitionId().getPartitionDate());
- assertEquals(null, forcedIds.get(1).getPartitionId().getPartitionId());
- assertLocalDateFromDbMatches(myPartitionDate, forcedIds.get(1).getPartitionId().getPartitionDate());
+ ResourceTable orgResourceTable = myResourceTableDao.findByTypeAndFhirId("Organization", "org").orElseThrow(IllegalArgumentException::new);
+ assertNull(orgResourceTable.getPartitionId().getPartitionId());
+ assertLocalDateFromDbMatches(myPartitionDate, orgResourceTable.getPartitionId().getPartitionDate());
+
+ ResourceTable patientResourceTable = myResourceTableDao.findByTypeAndFhirId("Patient", "pat").orElseThrow(IllegalArgumentException::new);
+ assertNull(patientResourceTable.getPartitionId().getPartitionId());
+ assertLocalDateFromDbMatches(myPartitionDate, patientResourceTable.getPartitionId().getPartitionDate());
});
}
@@ -876,8 +875,8 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
ourLog.info("Search SQL:\n{}", searchSql);
// Only the read columns should be used, no criteria use partition
- assertEquals(2, StringUtils.countMatches(searchSql, "PARTITION_ID,"));
- assertEquals(2, StringUtils.countMatches(searchSql, "PARTITION_ID"));
+ assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID,"));
+ assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID"));
}
{
addReadAllPartitions();
@@ -888,8 +887,8 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
ourLog.info("Search SQL:\n{}", searchSql);
// Only the read columns should be used, no criteria use partition
- assertEquals(2, StringUtils.countMatches(searchSql, "PARTITION_ID,"));
- assertEquals(2, StringUtils.countMatches(searchSql, "PARTITION_ID"));
+ assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID,"));
+ assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID"));
}
}
@@ -910,7 +909,7 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
ourLog.info("Search SQL:\n{}", searchSql);
// Only the read columns should be used, no criteria use partition
- assertEquals(2, StringUtils.countMatches(searchSql, "PARTITION_ID,"), searchSql);
+ assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID,"), searchSql);
assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID='1'"), searchSql);
}
@@ -954,7 +953,7 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
// Only the read columns should be used, but no selectors on partition ID
String searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true, true);
- assertEquals(2, StringUtils.countMatches(searchSql, "PARTITION_ID,"), searchSql);
+ assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID,"), searchSql);
assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID in ("), searchSql);
}
@@ -967,7 +966,7 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
// Only the read columns should be used, but no selectors on partition ID
String searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true, true);
- assertEquals(2, StringUtils.countMatches(searchSql, "PARTITION_ID,"), searchSql);
+ assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID,"), searchSql);
assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID is null"), searchSql);
}
@@ -1008,7 +1007,7 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
// Only the read columns should be used, but no selectors on partition ID
String searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true, true);
- assertEquals(2, StringUtils.countMatches(searchSql, "PARTITION_ID,"), searchSql);
+ assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID,"), searchSql);
assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID in ("), searchSql);
}
@@ -1022,7 +1021,7 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
// Only the read columns should be used, but no selectors on partition ID
String searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true, true);
- assertEquals(2, StringUtils.countMatches(searchSql, "PARTITION_ID,"), searchSql);
+ assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID,"), searchSql);
assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID is null"), searchSql);
}
@@ -1064,7 +1063,7 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
ourLog.info("Search SQL:\n{}", searchSql);
// Only the read columns should be used, no criteria use partition
- assertEquals(2, StringUtils.countMatches(searchSql, "PARTITION_ID,"));
+ assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID,"));
assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID is null"));
}
@@ -2843,7 +2842,7 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
outcome = mySystemDao.transaction(mySrd, input.get());
ourLog.debug("Resp: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
- assertEquals(9, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
+ assertEquals(8, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
myCaptureQueriesListener.logInsertQueriesForCurrentThread();
assertEquals(4, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
myCaptureQueriesListener.logUpdateQueriesForCurrentThread();
@@ -2860,7 +2859,7 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
outcome = mySystemDao.transaction(mySrd, input.get());
ourLog.debug("Resp: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
- assertEquals(8, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
+ assertEquals(7, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
myCaptureQueriesListener.logInsertQueriesForCurrentThread();
assertEquals(4, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
myCaptureQueriesListener.logUpdateQueriesForCurrentThread();
@@ -2875,7 +2874,7 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
outcome = mySystemDao.transaction(mySrd, input.get());
ourLog.debug("Resp: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
- assertEquals(6, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
+ assertEquals(5, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
myCaptureQueriesListener.logInsertQueriesForCurrentThread();
assertEquals(4, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
myCaptureQueriesListener.logUpdateQueriesForCurrentThread();
@@ -2899,7 +2898,7 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
myCaptureQueriesListener.logSelectQueries();
assertEquals(18, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
- assertEquals(6607, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
+ assertEquals(6189, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
assertEquals(418, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
assertEquals(2, myCaptureQueriesListener.countCommits());
@@ -2925,7 +2924,7 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
output = mySystemDao.transaction(requestDetails, input);
myCaptureQueriesListener.logSelectQueries();
- assertEquals(29, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
+ assertEquals(26, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
assertEquals(0, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
assertEquals(0, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/interceptor/PatientIdPartitionInterceptorTest.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/interceptor/PatientIdPartitionInterceptorTest.java
index 7d428f9c67b..1bb39a2816b 100644
--- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/interceptor/PatientIdPartitionInterceptorTest.java
+++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/interceptor/PatientIdPartitionInterceptorTest.java
@@ -27,8 +27,6 @@ import ca.uhn.fhir.util.MultimapCollector;
import com.google.common.base.Charsets;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Multimap;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpPost;
import org.apache.commons.io.IOUtils;
import org.apache.http.Header;
import org.apache.http.client.methods.CloseableHttpResponse;
@@ -47,7 +45,6 @@ import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.mock.mockito.SpyBean;
import java.io.IOException;
import java.util.List;
@@ -64,8 +61,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.verify;
public class PatientIdPartitionInterceptorTest extends BaseResourceProviderR4Test {
public static final int ALTERNATE_DEFAULT_ID = -1;
@@ -355,7 +350,6 @@ public class PatientIdPartitionInterceptorTest extends BaseResourceProviderR4Tes
org.setName("name 2");
logAllResources();
- logAllForcedIds();
myOrganizationDao.update(org);
diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ExpungeR4Test.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ExpungeR4Test.java
index 49a9b96a5a2..87b8c10b1d8 100644
--- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ExpungeR4Test.java
+++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ExpungeR4Test.java
@@ -18,16 +18,15 @@ import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.model.util.UcumServiceUtil;
-import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
import ca.uhn.fhir.jpa.provider.BaseResourceProviderR4Test;
import ca.uhn.fhir.jpa.search.PersistedJpaSearchFirstPageBundleProvider;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
+import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
import ca.uhn.fhir.rest.param.ReferenceParam;
import ca.uhn.fhir.rest.param.TokenParam;
-import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
@@ -379,7 +378,6 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
runInTransaction(() -> assertThat(myResourceTableDao.findAll(), not(empty())));
runInTransaction(() -> assertThat(myResourceHistoryTableDao.findAll(), not(empty())));
- runInTransaction(() -> assertThat(myForcedIdDao.findAll(), not(empty())));
myPatientDao.expunge(new ExpungeOptions()
.setExpungeDeletedResources(true)
@@ -387,7 +385,6 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
runInTransaction(() -> assertThat(myResourceTableDao.findAll(), empty()));
runInTransaction(() -> assertThat(myResourceHistoryTableDao.findAll(), empty()));
- runInTransaction(() -> assertThat(myForcedIdDao.findAll(), empty()));
}
@@ -409,7 +406,6 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
runInTransaction(() -> assertThat(myResourceTableDao.findAll(), not(empty())));
runInTransaction(() -> assertThat(myResourceHistoryTableDao.findAll(), not(empty())));
- runInTransaction(() -> assertThat(myForcedIdDao.findAll(), not(empty())));
// Test
myCaptureQueriesListener.clear();
@@ -421,11 +417,10 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
assertEquals(8, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
assertEquals(0, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
assertEquals(0, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
- assertEquals(9, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
+ assertEquals(8, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
runInTransaction(() -> assertThat(myResourceTableDao.findAll(), empty()));
runInTransaction(() -> assertThat(myResourceHistoryTableDao.findAll(), empty()));
- runInTransaction(() -> assertThat(myForcedIdDao.findAll(), empty()));
}
@@ -749,7 +744,6 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
.setExpungeOldVersions(true), null);
runInTransaction(() -> assertThat(myResourceTableDao.findAll(), empty()));
runInTransaction(() -> assertThat(myResourceHistoryTableDao.findAll(), empty()));
- runInTransaction(() -> assertThat(myForcedIdDao.findAll(), empty()));
// Create again with the same forced ID
p = new Patient();
@@ -788,7 +782,6 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
.setExpungeOldVersions(true), null);
runInTransaction(() -> assertThat(myResourceTableDao.findAll(), empty()));
runInTransaction(() -> assertThat(myResourceHistoryTableDao.findAll(), empty()));
- runInTransaction(() -> assertThat(myForcedIdDao.findAll(), empty()));
}
@@ -1061,6 +1054,5 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
assertThat(myTermConceptDao.findAll(), empty());
assertThat(myResourceTableDao.findAll(), empty());
assertThat(myResourceHistoryTableDao.findAll(), empty());
- assertThat(myForcedIdDao.findAll(), empty());
}
}
diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderLanguageParamR4Test.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderLanguageParamR4Test.java
new file mode 100644
index 00000000000..6d89e6b7564
--- /dev/null
+++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderLanguageParamR4Test.java
@@ -0,0 +1,67 @@
+package ca.uhn.fhir.jpa.provider.r4;
+
+import ca.uhn.fhir.i18n.Msg;
+import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
+import ca.uhn.fhir.jpa.provider.BaseResourceProviderR4Test;
+import ca.uhn.fhir.rest.api.Constants;
+import ca.uhn.fhir.rest.gclient.TokenClientParam;
+import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
+import org.hl7.fhir.instance.model.api.IIdType;
+import org.hl7.fhir.r4.model.Bundle;
+import org.hl7.fhir.r4.model.Patient;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.Matchers.containsString;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+public class ResourceProviderLanguageParamR4Test extends BaseResourceProviderR4Test {
+
+ @SuppressWarnings("unused")
+ @Test
+ public void testSearchWithLanguageParamEnabled() {
+ myStorageSettings.setLanguageSearchParameterEnabled(true);
+ mySearchParamRegistry.forceRefresh();
+
+ Patient pat = new Patient();
+ pat.setLanguage("en");
+ IIdType patId = myPatientDao.create(pat, mySrd).getId().toUnqualifiedVersionless();
+
+ Patient pat2 = new Patient();
+ pat.setLanguage("fr");
+ IIdType patId2 = myPatientDao.create(pat2, mySrd).getId().toUnqualifiedVersionless();
+
+ List foundResources;
+ Bundle result;
+
+ result = myClient
+ .search()
+ .forResource(Patient.class)
+ .where(new TokenClientParam(Constants.PARAM_LANGUAGE).exactly().code("en"))
+ .returnBundle(Bundle.class)
+ .execute();
+
+ foundResources = toUnqualifiedVersionlessIdValues(result);
+ assertThat(foundResources, contains(patId.getValue()));
+ }
+
+ @SuppressWarnings("unused")
+ @Test
+ public void testSearchWithLanguageParamDisabled() {
+ myStorageSettings.setLanguageSearchParameterEnabled(new JpaStorageSettings().isLanguageSearchParameterEnabled());
+ mySearchParamRegistry.forceRefresh();
+
+ InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> {
+ myClient
+ .search()
+ .forResource(Patient.class)
+ .where(new TokenClientParam(Constants.PARAM_LANGUAGE).exactly().code("en"))
+ .returnBundle(Bundle.class)
+ .execute();
+ });
+ assertThat(exception.getMessage(), containsString(Msg.code(1223)));
+ }
+}
diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ConceptMapTest.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ConceptMapTest.java
index 99f8296c05e..1dcca3249da 100644
--- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ConceptMapTest.java
+++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ConceptMapTest.java
@@ -307,6 +307,86 @@ public class ResourceProviderR4ConceptMapTest extends BaseResourceProviderR4Test
assertFalse(hasParameterByName(respParams, "match"));
}
+ @Test
+ public void testTranslateByCodeSystemsAndSourceCodeMappedToCodelessTarget() {
+ // ensure that the current behaviour when a target does not have a code is preserved, and no matches returned
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId, mySrd);
+
+ ourLog.debug("ConceptMap:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ Parameters inParams = new Parameters();
+ inParams.addParameter().setName("system").setValue(new UriType(CS_URL_4));
+ inParams.addParameter().setName("targetsystem").setValue(new UriType(CS_URL_3));
+ inParams.addParameter().setName("code").setValue(new CodeType("89012"));
+
+ ourLog.debug("Request Parameters:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
+
+ Parameters respParams = myClient
+ .operation()
+ .onType(ConceptMap.class)
+ .named("translate")
+ .withParameters(inParams)
+ .execute();
+
+ ourLog.debug("Response Parameters\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
+
+ ParametersParameterComponent param = getParameterByName(respParams, "result");
+ assertFalse(((BooleanType) param.getValue()).booleanValue());
+
+ param = getParameterByName(respParams, "message");
+ assertEquals("No Matches found", ((StringType) param.getValue()).getValueAsString());
+
+ assertFalse(hasParameterByName(respParams, "match"));
+ }
+
+ @Test
+ public void testTranslateByCodeSystemsAndSourceCodeWithEquivalenceUnmatched() {
+ // the equivalence code 'unmatched' is an exception - it does not normally have a target code,
+ // so it will be included in the collection of matches even if there is no code present
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId, mySrd);
+
+ ourLog.debug("ConceptMap:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ Parameters inParams = new Parameters();
+ inParams.addParameter().setName("system").setValue(new UriType(CS_URL_4));
+ inParams.addParameter().setName("targetsystem").setValue(new UriType(CS_URL_3));
+ inParams.addParameter().setName("code").setValue(new CodeType("89123"));
+
+ ourLog.debug("Request Parameters:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
+
+ Parameters respParams = myClient
+ .operation()
+ .onType(ConceptMap.class)
+ .named("translate")
+ .withParameters(inParams)
+ .execute();
+
+ ourLog.debug("Response Parameters\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
+
+ ParametersParameterComponent param = getParameterByName(respParams, "result");
+ assertFalse(((BooleanType) param.getValue()).booleanValue());
+
+ param = getParameterByName(respParams, "message");
+ assertEquals("Only negative matches found", ((StringType) param.getValue()).getValueAsString());
+
+ assertEquals(1, getNumberOfParametersByName(respParams, "match"));
+
+ param = getParameterByName(respParams, "match");
+ assertEquals(3, param.getPart().size());
+ ParametersParameterComponent part = getPartByName(param, "equivalence");
+ assertEquals("unmatched", ((CodeType) part.getValue()).getCode());
+ part = getPartByName(param, "concept");
+ Coding coding = (Coding) part.getValue();
+ assertNull(coding.getCode());
+ assertNull(coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_3, coding.getSystem());
+ assertEquals("Version 1", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+ }
+
+
@Test
public void testTranslateUsingPredicatesWithCodeOnly() {
ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ServerCapabilityStatementProviderJpaR4Test.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ServerCapabilityStatementProviderJpaR4Test.java
index 51632c5c249..5cabad60eb3 100644
--- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ServerCapabilityStatementProviderJpaR4Test.java
+++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ServerCapabilityStatementProviderJpaR4Test.java
@@ -346,7 +346,7 @@ public class ServerCapabilityStatementProviderJpaR4Test extends BaseResourceProv
CapabilityStatement cs = myClient.capabilities().ofType(CapabilityStatement.class).execute();
for (CapabilityStatement.CapabilityStatementRestResourceComponent nextResource : cs.getRestFirstRep().getResource()) {
for (CapabilityStatement.CapabilityStatementRestResourceSearchParamComponent nextSp : nextResource.getSearchParam()) {
- if (nextSp.getName().equals("_has") || nextSp.getName().equals("_list")) {
+ if (nextSp.getName().equals("_has") || nextSp.getName().equals("_list") || nextSp.getName().equals("_language")) {
if (nextSp.getDefinition() == null) {
continue;
}
diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/reindex/ReindexStepTest.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/reindex/ReindexStepTest.java
index 81ad6c198c7..c619cc0b410 100644
--- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/reindex/ReindexStepTest.java
+++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/reindex/ReindexStepTest.java
@@ -64,7 +64,7 @@ public class ReindexStepTest extends BaseJpaR4Test {
// Verify
assertEquals(2, outcome.getRecordsProcessed());
- assertEquals(6, myCaptureQueriesListener.logSelectQueries().size());
+ assertEquals(5, myCaptureQueriesListener.logSelectQueries().size());
assertEquals(0, myCaptureQueriesListener.countInsertQueries());
myCaptureQueriesListener.logUpdateQueries();
assertEquals(0, myCaptureQueriesListener.countUpdateQueries());
@@ -95,7 +95,7 @@ public class ReindexStepTest extends BaseJpaR4Test {
// Verify
assertEquals(2, outcome.getRecordsProcessed());
- assertEquals(8, myCaptureQueriesListener.logSelectQueries().size());
+ assertEquals(7, myCaptureQueriesListener.logSelectQueries().size());
assertEquals(0, myCaptureQueriesListener.countInsertQueries());
assertEquals(0, myCaptureQueriesListener.countUpdateQueries());
assertEquals(0, myCaptureQueriesListener.countDeleteQueries());
@@ -128,7 +128,7 @@ public class ReindexStepTest extends BaseJpaR4Test {
// Verify
assertEquals(2, outcome.getRecordsProcessed());
- assertEquals(6, myCaptureQueriesListener.logSelectQueries().size());
+ assertEquals(5, myCaptureQueriesListener.logSelectQueries().size());
// name, family, phonetic, deceased, active
assertEquals(5, myCaptureQueriesListener.countInsertQueries());
assertEquals(0, myCaptureQueriesListener.countUpdateQueries());
@@ -196,7 +196,7 @@ public class ReindexStepTest extends BaseJpaR4Test {
// Verify
assertEquals(2, outcome.getRecordsProcessed());
- assertEquals(10, myCaptureQueriesListener.logSelectQueries().size());
+ assertEquals(9, myCaptureQueriesListener.logSelectQueries().size());
assertEquals(0, myCaptureQueriesListener.countInsertQueries());
assertEquals(4, myCaptureQueriesListener.countUpdateQueries());
assertEquals(0, myCaptureQueriesListener.countDeleteQueries());
@@ -241,7 +241,7 @@ public class ReindexStepTest extends BaseJpaR4Test {
// Verify
assertEquals(4, outcome.getRecordsProcessed());
- assertEquals(9, myCaptureQueriesListener.logSelectQueries().size());
+ assertEquals(8, myCaptureQueriesListener.logSelectQueries().size());
assertEquals(5, myCaptureQueriesListener.countInsertQueries());
assertEquals(2, myCaptureQueriesListener.countUpdateQueries());
assertEquals(0, myCaptureQueriesListener.countDeleteQueries());
diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/term/TermConceptMappingSvcImplTest.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/term/TermConceptMappingSvcImplTest.java
index a4a18667b1c..7f49edb2daf 100644
--- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/term/TermConceptMappingSvcImplTest.java
+++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/term/TermConceptMappingSvcImplTest.java
@@ -18,8 +18,6 @@ import org.hl7.fhir.r4.model.Coding;
import org.hl7.fhir.r4.model.ConceptMap;
import org.hl7.fhir.r4.model.Enumerations;
import org.hl7.fhir.r4.model.IdType;
-import org.hl7.fhir.r4.model.StringType;
-import org.hl7.fhir.r4.model.UriType;
import org.hl7.fhir.r4.model.codesystems.HttpVerb;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
@@ -27,11 +25,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
-import org.springframework.transaction.TransactionStatus;
-import org.springframework.transaction.support.TransactionCallbackWithoutResult;
-import org.springframework.transaction.support.TransactionTemplate;
-import jakarta.annotation.Nonnull;
import java.util.Collections;
import java.util.List;
@@ -73,119 +67,130 @@ public class TermConceptMappingSvcImplTest extends BaseTermR4Test {
@Test
public void testByCodeSystemsAndSourceCodeOneToMany() {
createAndPersistConceptMap();
- ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId, mySrd);
ourLog.debug("ConceptMap:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
- new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
- @Override
- protected void doInTransactionWithoutResult(@Nonnull TransactionStatus theStatus) {
- TranslationRequest translationRequest = new TranslationRequest();
- translationRequest.getCodeableConcept().addCoding()
- .setSystem(CS_URL)
- .setCode("12345");
- translationRequest.setTargetSystem(CS_URL_3);
+ runInTransaction(() -> {
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL)
+ .setCode("12345");
+ translationRequest.setTargetSystem(CS_URL_3);
- List targets = myConceptMappingSvc.translate(translationRequest).getResults();
- assertNotNull(targets);
- assertEquals(2, targets.size());
- assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
+ List targets = myConceptMappingSvc.translate(translationRequest).getResults();
+ assertNotNull(targets);
+ assertEquals(2, targets.size());
+ assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
- TranslateConceptResult target = targets.get(0);
+ TranslateConceptResult target = targets.get(0);
- ourLog.info("target(0):\n" + target.toString());
+ ourLog.info("target(0):\n" + target.toString());
- assertEquals("56789", target.getCode());
- assertEquals("Target Code 56789", target.getDisplay());
- assertEquals(CS_URL_3, target.getSystem());
- assertEquals("Version 4", target.getSystemVersion());
- assertEquals(Enumerations.ConceptMapEquivalence.EQUAL.toCode(), target.getEquivalence());
- assertEquals(VS_URL_2, target.getValueSet());
- assertEquals(CM_URL, target.getConceptMapUrl());
+ assertEquals("56789", target.getCode());
+ assertEquals("Target Code 56789", target.getDisplay());
+ assertEquals(CS_URL_3, target.getSystem());
+ assertEquals("Version 4", target.getSystemVersion());
+ assertEquals(Enumerations.ConceptMapEquivalence.EQUAL.toCode(), target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
- target = targets.get(1);
+ target = targets.get(1);
- ourLog.info("target(1):\n" + target.toString());
+ ourLog.info("target(1):\n" + target.toString());
- assertEquals("67890", target.getCode());
- assertEquals("Target Code 67890", target.getDisplay());
- assertEquals(CS_URL_3, target.getSystem());
- assertEquals("Version 4", target.getSystemVersion());
- assertEquals(Enumerations.ConceptMapEquivalence.WIDER.toCode(), target.getEquivalence());
- assertEquals(VS_URL_2, target.getValueSet());
- assertEquals(CM_URL, target.getConceptMapUrl());
+ assertEquals("67890", target.getCode());
+ assertEquals("Target Code 67890", target.getDisplay());
+ assertEquals(CS_URL_3, target.getSystem());
+ assertEquals("Version 4", target.getSystemVersion());
+ assertEquals(Enumerations.ConceptMapEquivalence.WIDER.toCode(), target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
- // Test caching.
- targets = myConceptMappingSvc.translate(translationRequest).getResults();
- assertNotNull(targets);
- assertEquals(2, targets.size());
- assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
- }
+ // Test caching.
+ targets = myConceptMappingSvc.translate(translationRequest).getResults();
+ assertNotNull(targets);
+ assertEquals(2, targets.size());
+ assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
});
}
@Test
public void testByCodeSystemsAndSourceCodeOneToOne() {
createAndPersistConceptMap();
- ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId, mySrd);
ourLog.debug("ConceptMap:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
- new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
- @Override
- protected void doInTransactionWithoutResult(@Nonnull TransactionStatus theStatus) {
- TranslationRequest translationRequest = new TranslationRequest();
- translationRequest.getCodeableConcept().addCoding()
- .setSystem(CS_URL)
- .setCode("12345");
- translationRequest.setTargetSystem(CS_URL_2);
+ runInTransaction(() -> {
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL)
+ .setCode("12345");
+ translationRequest.setTargetSystem(CS_URL_2);
- List targets = myConceptMappingSvc.translate(translationRequest).getResults();
- assertNotNull(targets);
- assertEquals(1, targets.size());
- assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
+ List targets = myConceptMappingSvc.translate(translationRequest).getResults();
+ assertNotNull(targets);
+ assertEquals(1, targets.size());
+ assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
- TranslateConceptResult target = targets.get(0);
+ TranslateConceptResult target = targets.get(0);
- ourLog.info("ConceptMap.group.element.target:\n" + target.toString());
+ ourLog.info("ConceptMap.group.element.target:\n" + target.toString());
- assertEquals("34567", target.getCode());
- assertEquals("Target Code 34567", target.getDisplay());
- assertEquals(CS_URL_2, target.getSystem());
- assertEquals("Version 2", target.getSystemVersion());
- assertEquals(Enumerations.ConceptMapEquivalence.EQUAL.toCode(), target.getEquivalence());
- assertEquals(VS_URL_2, target.getValueSet());
- assertEquals(CM_URL, target.getConceptMapUrl());
+ assertEquals("34567", target.getCode());
+ assertEquals("Target Code 34567", target.getDisplay());
+ assertEquals(CS_URL_2, target.getSystem());
+ assertEquals("Version 2", target.getSystemVersion());
+ assertEquals(Enumerations.ConceptMapEquivalence.EQUAL.toCode(), target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
- // Test caching.
- targets = myConceptMappingSvc.translate(translationRequest).getResults();
- assertNotNull(targets);
- assertEquals(1, targets.size());
- assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
- }
+ // Test caching.
+ targets = myConceptMappingSvc.translate(translationRequest).getResults();
+ assertNotNull(targets);
+ assertEquals(1, targets.size());
+ assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
});
}
@Test
public void testByCodeSystemsAndSourceCodeUnmapped() {
createAndPersistConceptMap();
- ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId, mySrd);
ourLog.debug("ConceptMap:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
- new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
- @Override
- protected void doInTransactionWithoutResult(@Nonnull TransactionStatus theStatus) {
- TranslationRequest translationRequest = new TranslationRequest();
- translationRequest.getCodeableConcept().addCoding()
- .setSystem(CS_URL)
- .setCode("BOGUS");
- translationRequest.setTargetSystem(CS_URL_3);
+ runInTransaction(() -> {
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL)
+ .setCode("BOGUS");
+ translationRequest.setTargetSystem(CS_URL_3);
- List targets = myConceptMappingSvc.translate(translationRequest).getResults();
- assertNotNull(targets);
- assertTrue(targets.isEmpty());
- }
+ List targets = myConceptMappingSvc.translate(translationRequest).getResults();
+ assertNotNull(targets);
+ assertTrue(targets.isEmpty());
+ });
+ }
+
+ @Test
+ public void testByCodeSystemsAndSourceCodeMatchedWithoutCode() {
+ createAndPersistConceptMap();
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId, mySrd);
+
+ ourLog.debug("ConceptMap:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ runInTransaction(() -> {
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL_4)
+ .setCode("89012");
+ translationRequest.setTargetSystem(CS_URL_3);
+
+ List targets = myConceptMappingSvc.translate(translationRequest).getResults();
+ assertNotNull(targets);
+ assertTrue(targets.isEmpty());
});
}
@@ -208,7 +213,7 @@ public class TermConceptMappingSvcImplTest extends BaseTermR4Test {
.addTarget()
.setCode("999");
- myConceptMapDao.create(conceptMap);
+ myConceptMapDao.create(conceptMap, mySrd);
TranslationRequest translationRequest = new TranslationRequest()
.addCode(CS_URL, "12345")
@@ -222,954 +227,903 @@ public class TermConceptMappingSvcImplTest extends BaseTermR4Test {
@Test
public void testUsingPredicatesWithCodeOnly() {
createAndPersistConceptMap();
- ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId, mySrd);
ourLog.debug("ConceptMap:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
- new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
- @Override
- protected void doInTransactionWithoutResult(@Nonnull TransactionStatus theStatus) {
- /*
- * Provided:
- * source code
- */
- TranslationRequest translationRequest = new TranslationRequest();
- translationRequest.getCodeableConcept().addCoding()
- .setCode("12345");
+ runInTransaction(() -> {
+ /*
+ * Provided:
+ * source code
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setCode("12345");
- List targets = myConceptMappingSvc.translate(translationRequest).getResults();
- assertNotNull(targets);
- assertEquals(3, targets.size());
- assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
+ List targets = myConceptMappingSvc.translate(translationRequest).getResults();
+ assertNotNull(targets);
+ assertEquals(3, targets.size());
+ assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
- TranslateConceptResult target = targets.get(0);
+ TranslateConceptResult target = targets.get(0);
- ourLog.info("target(0):\n" + target.toString());
+ ourLog.info("target(0):\n" + target.toString());
- assertEquals("34567", target.getCode());
- assertEquals("Target Code 34567", target.getDisplay());
- assertEquals(CS_URL_2, target.getSystem());
- assertEquals("Version 2", target.getSystemVersion());
- assertEquals(Enumerations.ConceptMapEquivalence.EQUAL.toCode(), target.getEquivalence());
- assertEquals(VS_URL_2, target.getValueSet());
- assertEquals(CM_URL, target.getConceptMapUrl());
+ assertEquals("34567", target.getCode());
+ assertEquals("Target Code 34567", target.getDisplay());
+ assertEquals(CS_URL_2, target.getSystem());
+ assertEquals("Version 2", target.getSystemVersion());
+ assertEquals(Enumerations.ConceptMapEquivalence.EQUAL.toCode(), target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
- target = targets.get(1);
+ target = targets.get(1);
- ourLog.info("target(1):\n" + target.toString());
+ ourLog.info("target(1):\n" + target.toString());
- assertEquals("56789", target.getCode());
- assertEquals("Target Code 56789", target.getDisplay());
- assertEquals(CS_URL_3, target.getSystem());
- assertEquals("Version 4", target.getSystemVersion());
- assertEquals(Enumerations.ConceptMapEquivalence.EQUAL.toCode(), target.getEquivalence());
- assertEquals(VS_URL_2, target.getValueSet());
- assertEquals(CM_URL, target.getConceptMapUrl());
+ assertEquals("56789", target.getCode());
+ assertEquals("Target Code 56789", target.getDisplay());
+ assertEquals(CS_URL_3, target.getSystem());
+ assertEquals("Version 4", target.getSystemVersion());
+ assertEquals(Enumerations.ConceptMapEquivalence.EQUAL.toCode(), target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
- target = targets.get(2);
+ target = targets.get(2);
- ourLog.info("target(2):\n" + target.toString());
+ ourLog.info("target(2):\n" + target.toString());
- assertEquals("67890", target.getCode());
- assertEquals("Target Code 67890", target.getDisplay());
- assertEquals(CS_URL_3, target.getSystem());
- assertEquals("Version 4", target.getSystemVersion());
- assertEquals(Enumerations.ConceptMapEquivalence.WIDER.toCode(), target.getEquivalence());
- assertEquals(VS_URL_2, target.getValueSet());
- assertEquals(CM_URL, target.getConceptMapUrl());
+ assertEquals("67890", target.getCode());
+ assertEquals("Target Code 67890", target.getDisplay());
+ assertEquals(CS_URL_3, target.getSystem());
+ assertEquals("Version 4", target.getSystemVersion());
+ assertEquals(Enumerations.ConceptMapEquivalence.WIDER.toCode(), target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
- // Test caching.
- targets = myConceptMappingSvc.translate(translationRequest).getResults();
- assertNotNull(targets);
- assertEquals(3, targets.size());
- assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
- }
+ // Test caching.
+ targets = myConceptMappingSvc.translate(translationRequest).getResults();
+ assertNotNull(targets);
+ assertEquals(3, targets.size());
+ assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
});
}
@Test
public void testUsingPredicatesWithSourceAndTargetSystem2() {
createAndPersistConceptMap();
- ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId, mySrd);
ourLog.debug("ConceptMap:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
- new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
- @Override
- protected void doInTransactionWithoutResult(@Nonnull TransactionStatus theStatus) {
- /*
- * Provided:
- * source code
- * source code system
- * target code system #2
- */
- TranslationRequest translationRequest = new TranslationRequest();
- translationRequest.getCodeableConcept().addCoding()
- .setSystem(CS_URL)
- .setCode("12345");
- translationRequest.setTargetSystem(CS_URL_2);
+ runInTransaction(() -> {
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * target code system #2
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL)
+ .setCode("12345");
+ translationRequest.setTargetSystem(CS_URL_2);
- List targets = myConceptMappingSvc.translate(translationRequest).getResults();
- assertNotNull(targets);
- assertEquals(1, targets.size());
- assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
+ List targets = myConceptMappingSvc.translate(translationRequest).getResults();
+ assertNotNull(targets);
+ assertEquals(1, targets.size());
+ assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
- TranslateConceptResult target = targets.get(0);
+ TranslateConceptResult target = targets.get(0);
- ourLog.info("target:\n" + target.toString());
+ ourLog.info("target:\n" + target.toString());
- assertEquals("34567", target.getCode());
- assertEquals("Target Code 34567", target.getDisplay());
- assertEquals(CS_URL_2, target.getSystem());
- assertEquals("Version 2", target.getSystemVersion());
- assertEquals(Enumerations.ConceptMapEquivalence.EQUAL.toCode(), target.getEquivalence());
- assertEquals(VS_URL_2, target.getValueSet());
- assertEquals(CM_URL, target.getConceptMapUrl());
+ assertEquals("34567", target.getCode());
+ assertEquals("Target Code 34567", target.getDisplay());
+ assertEquals(CS_URL_2, target.getSystem());
+ assertEquals("Version 2", target.getSystemVersion());
+ assertEquals(Enumerations.ConceptMapEquivalence.EQUAL.toCode(), target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
- // Test caching.
- targets = myConceptMappingSvc.translate(translationRequest).getResults();
- assertNotNull(targets);
- assertEquals(1, targets.size());
- assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
- }
+ // Test caching.
+ targets = myConceptMappingSvc.translate(translationRequest).getResults();
+ assertNotNull(targets);
+ assertEquals(1, targets.size());
+ assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
});
}
@Test
public void testUsingPredicatesWithSourceAndTargetSystem3() {
createAndPersistConceptMap();
- ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId, mySrd);
ourLog.debug("ConceptMap:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
- new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
- @Override
- protected void doInTransactionWithoutResult(@Nonnull TransactionStatus theStatus) {
- /*
- * Provided:
- * source code
- * source code system
- * target code system #3
- */
- TranslationRequest translationRequest = new TranslationRequest();
- translationRequest.getCodeableConcept().addCoding()
- .setSystem(CS_URL)
- .setCode("12345");
- translationRequest.setTargetSystem(CS_URL_3);
+ runInTransaction(() -> {
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * target code system #3
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL)
+ .setCode("12345");
+ translationRequest.setTargetSystem(CS_URL_3);
- List targets = myConceptMappingSvc.translate(translationRequest).getResults();
- assertNotNull(targets);
- assertEquals(2, targets.size());
- assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
+ List targets = myConceptMappingSvc.translate(translationRequest).getResults();
+ assertNotNull(targets);
+ assertEquals(2, targets.size());
+ assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
- TranslateConceptResult target = targets.get(0);
+ TranslateConceptResult target = targets.get(0);
- ourLog.info("target(0):\n" + target.toString());
+ ourLog.info("target(0):\n" + target.toString());
- assertEquals("56789", target.getCode());
- assertEquals("Target Code 56789", target.getDisplay());
- assertEquals(CS_URL_3, target.getSystem());
- assertEquals("Version 4", target.getSystemVersion());
- assertEquals(Enumerations.ConceptMapEquivalence.EQUAL.toCode(), target.getEquivalence());
- assertEquals(VS_URL_2, target.getValueSet());
- assertEquals(CM_URL, target.getConceptMapUrl());
+ assertEquals("56789", target.getCode());
+ assertEquals("Target Code 56789", target.getDisplay());
+ assertEquals(CS_URL_3, target.getSystem());
+ assertEquals("Version 4", target.getSystemVersion());
+ assertEquals(Enumerations.ConceptMapEquivalence.EQUAL.toCode(), target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
- target = targets.get(1);
+ target = targets.get(1);
- ourLog.info("target(1):\n" + target.toString());
+ ourLog.info("target(1):\n" + target.toString());
- assertEquals("67890", target.getCode());
- assertEquals("Target Code 67890", target.getDisplay());
- assertEquals(CS_URL_3, target.getSystem());
- assertEquals("Version 4", target.getSystemVersion());
- assertEquals(Enumerations.ConceptMapEquivalence.WIDER.toCode(), target.getEquivalence());
- assertEquals(VS_URL_2, target.getValueSet());
- assertEquals(CM_URL, target.getConceptMapUrl());
+ assertEquals("67890", target.getCode());
+ assertEquals("Target Code 67890", target.getDisplay());
+ assertEquals(CS_URL_3, target.getSystem());
+ assertEquals("Version 4", target.getSystemVersion());
+ assertEquals(Enumerations.ConceptMapEquivalence.WIDER.toCode(), target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
- // Test caching.
- targets = myConceptMappingSvc.translate(translationRequest).getResults();
- assertNotNull(targets);
- assertEquals(2, targets.size());
- assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
- }
+ // Test caching.
+ targets = myConceptMappingSvc.translate(translationRequest).getResults();
+ assertNotNull(targets);
+ assertEquals(2, targets.size());
+ assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
});
}
@Test
public void testUsingPredicatesWithSourceSystem() {
createAndPersistConceptMap();
- ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId, mySrd);
ourLog.debug("ConceptMap:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
- new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
- @Override
- protected void doInTransactionWithoutResult(@Nonnull TransactionStatus theStatus) {
- /*
- * Provided:
- * source code
- * source code system
- */
- TranslationRequest translationRequest = new TranslationRequest();
- translationRequest.getCodeableConcept().addCoding()
- .setSystem(CS_URL)
- .setCode("12345");
+ runInTransaction(() -> {
+ /*
+ * Provided:
+ * source code
+ * source code system
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL)
+ .setCode("12345");
- List targets = myConceptMappingSvc.translate(translationRequest).getResults();
- assertNotNull(targets);
- assertEquals(3, targets.size());
- assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
+ List targets = myConceptMappingSvc.translate(translationRequest).getResults();
+ assertNotNull(targets);
+ assertEquals(3, targets.size());
+ assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
- TranslateConceptResult target = targets.get(0);
+ TranslateConceptResult target = targets.get(0);
- ourLog.info("target(0):\n" + target.toString());
+ ourLog.info("target(0):\n" + target.toString());
- assertEquals("34567", target.getCode());
- assertEquals("Target Code 34567", target.getDisplay());
- assertEquals(CS_URL_2, target.getSystem());
- assertEquals("Version 2", target.getSystemVersion());
- assertEquals(Enumerations.ConceptMapEquivalence.EQUAL.toCode(), target.getEquivalence());
- assertEquals(VS_URL_2, target.getValueSet());
- assertEquals(CM_URL, target.getConceptMapUrl());
+ assertEquals("34567", target.getCode());
+ assertEquals("Target Code 34567", target.getDisplay());
+ assertEquals(CS_URL_2, target.getSystem());
+ assertEquals("Version 2", target.getSystemVersion());
+ assertEquals(Enumerations.ConceptMapEquivalence.EQUAL.toCode(), target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
- target = targets.get(1);
+ target = targets.get(1);
- ourLog.info("target(1):\n" + target.toString());
+ ourLog.info("target(1):\n" + target.toString());
- assertEquals("56789", target.getCode());
- assertEquals("Target Code 56789", target.getDisplay());
- assertEquals(CS_URL_3, target.getSystem());
- assertEquals("Version 4", target.getSystemVersion());
- assertEquals(Enumerations.ConceptMapEquivalence.EQUAL.toCode(), target.getEquivalence());
- assertEquals(VS_URL_2, target.getValueSet());
- assertEquals(CM_URL, target.getConceptMapUrl());
+ assertEquals("56789", target.getCode());
+ assertEquals("Target Code 56789", target.getDisplay());
+ assertEquals(CS_URL_3, target.getSystem());
+ assertEquals("Version 4", target.getSystemVersion());
+ assertEquals(Enumerations.ConceptMapEquivalence.EQUAL.toCode(), target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
- target = targets.get(2);
+ target = targets.get(2);
- ourLog.info("target(2):\n" + target.toString());
+ ourLog.info("target(2):\n" + target.toString());
- assertEquals("67890", target.getCode());
- assertEquals("Target Code 67890", target.getDisplay());
- assertEquals(CS_URL_3, target.getSystem());
- assertEquals("Version 4", target.getSystemVersion());
- assertEquals(Enumerations.ConceptMapEquivalence.WIDER.toCode(), target.getEquivalence());
- assertEquals(VS_URL_2, target.getValueSet());
- assertEquals(CM_URL, target.getConceptMapUrl());
+ assertEquals("67890", target.getCode());
+ assertEquals("Target Code 67890", target.getDisplay());
+ assertEquals(CS_URL_3, target.getSystem());
+ assertEquals("Version 4", target.getSystemVersion());
+ assertEquals(Enumerations.ConceptMapEquivalence.WIDER.toCode(), target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
- // Test caching.
- targets = myConceptMappingSvc.translate(translationRequest).getResults();
- assertNotNull(targets);
- assertEquals(3, targets.size());
- assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
- }
+ // Test caching.
+ targets = myConceptMappingSvc.translate(translationRequest).getResults();
+ assertNotNull(targets);
+ assertEquals(3, targets.size());
+ assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
});
}
@Test
public void testUsingPredicatesWithSourceSystemAndVersion1() {
createAndPersistConceptMap();
- ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId, mySrd);
ourLog.debug("ConceptMap:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
- new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
- @Override
- protected void doInTransactionWithoutResult(@Nonnull TransactionStatus theStatus) {
- /*
- * Provided:
- * source code
- * source code system
- * source code system version #1
- */
- TranslationRequest translationRequest = new TranslationRequest();
- translationRequest.getCodeableConcept().addCoding()
- .setSystem(CS_URL)
- .setCode("12345")
- .setVersion("Version 1");
+ runInTransaction(() -> {
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * source code system version #1
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL)
+ .setCode("12345")
+ .setVersion("Version 1");
- List targets = myConceptMappingSvc.translate(translationRequest).getResults();
- assertNotNull(targets);
- assertEquals(1, targets.size());
- assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
+ List targets = myConceptMappingSvc.translate(translationRequest).getResults();
+ assertNotNull(targets);
+ assertEquals(1, targets.size());
+ assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
- TranslateConceptResult target = targets.get(0);
+ TranslateConceptResult target = targets.get(0);
- ourLog.info("target:\n" + target.toString());
+ ourLog.info("target:\n" + target.toString());
- assertEquals("34567", target.getCode());
- assertEquals("Target Code 34567", target.getDisplay());
- assertEquals(CS_URL_2, target.getSystem());
- assertEquals("Version 2", target.getSystemVersion());
- assertEquals(Enumerations.ConceptMapEquivalence.EQUAL.toCode(), target.getEquivalence());
- assertEquals(VS_URL_2, target.getValueSet());
- assertEquals(CM_URL, target.getConceptMapUrl());
+ assertEquals("34567", target.getCode());
+ assertEquals("Target Code 34567", target.getDisplay());
+ assertEquals(CS_URL_2, target.getSystem());
+ assertEquals("Version 2", target.getSystemVersion());
+ assertEquals(Enumerations.ConceptMapEquivalence.EQUAL.toCode(), target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
- // Test caching.
- targets = myConceptMappingSvc.translate(translationRequest).getResults();
- assertNotNull(targets);
- assertEquals(1, targets.size());
- assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
- }
+ // Test caching.
+ targets = myConceptMappingSvc.translate(translationRequest).getResults();
+ assertNotNull(targets);
+ assertEquals(1, targets.size());
+ assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
});
}
@Test
public void testUsingPredicatesWithSourceSystemAndVersion3() {
createAndPersistConceptMap();
- ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId, mySrd);
ourLog.debug("ConceptMap:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
- new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
- @Override
- protected void doInTransactionWithoutResult(@Nonnull TransactionStatus theStatus) {
- /*
- * Provided:
- * source code
- * source code system
- * source code system version #3
- */
- TranslationRequest translationRequest = new TranslationRequest();
- translationRequest.getCodeableConcept().addCoding()
- .setSystem(CS_URL)
- .setCode("12345")
- .setVersion("Version 3");
+ runInTransaction(() -> {
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * source code system version #3
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL)
+ .setCode("12345")
+ .setVersion("Version 3");
- List targets = myConceptMappingSvc.translate(translationRequest).getResults();
- assertNotNull(targets);
- assertEquals(2, targets.size());
- assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
+ List targets = myConceptMappingSvc.translate(translationRequest).getResults();
+ assertNotNull(targets);
+ assertEquals(2, targets.size());
+ assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
- TranslateConceptResult target = targets.get(0);
+ TranslateConceptResult target = targets.get(0);
- ourLog.info("target(0):\n" + target.toString());
+ ourLog.info("target(0):\n" + target.toString());
- assertEquals("56789", target.getCode());
- assertEquals("Target Code 56789", target.getDisplay());
- assertEquals(CS_URL_3, target.getSystem());
- assertEquals("Version 4", target.getSystemVersion());
- assertEquals(Enumerations.ConceptMapEquivalence.EQUAL.toCode(), target.getEquivalence());
- assertEquals(VS_URL_2, target.getValueSet());
- assertEquals(CM_URL, target.getConceptMapUrl());
+ assertEquals("56789", target.getCode());
+ assertEquals("Target Code 56789", target.getDisplay());
+ assertEquals(CS_URL_3, target.getSystem());
+ assertEquals("Version 4", target.getSystemVersion());
+ assertEquals(Enumerations.ConceptMapEquivalence.EQUAL.toCode(), target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
- target = targets.get(1);
+ target = targets.get(1);
- ourLog.info("target(1):\n" + target.toString());
+ ourLog.info("target(1):\n" + target.toString());
- assertEquals("67890", target.getCode());
- assertEquals("Target Code 67890", target.getDisplay());
- assertEquals(CS_URL_3, target.getSystem());
- assertEquals("Version 4", target.getSystemVersion());
- assertEquals(Enumerations.ConceptMapEquivalence.WIDER.toCode(), target.getEquivalence());
- assertEquals(VS_URL_2, target.getValueSet());
- assertEquals(CM_URL, target.getConceptMapUrl());
+ assertEquals("67890", target.getCode());
+ assertEquals("Target Code 67890", target.getDisplay());
+ assertEquals(CS_URL_3, target.getSystem());
+ assertEquals("Version 4", target.getSystemVersion());
+ assertEquals(Enumerations.ConceptMapEquivalence.WIDER.toCode(), target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
- // Test caching.
- targets = myConceptMappingSvc.translate(translationRequest).getResults();
- assertNotNull(targets);
- assertEquals(2, targets.size());
- assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
- }
+ // Test caching.
+ targets = myConceptMappingSvc.translate(translationRequest).getResults();
+ assertNotNull(targets);
+ assertEquals(2, targets.size());
+ assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
});
}
@Test
public void testUsingPredicatesWithSourceValueSet() {
createAndPersistConceptMap();
- ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId, mySrd);
ourLog.debug("ConceptMap:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
- new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
- @Override
- protected void doInTransactionWithoutResult(@Nonnull TransactionStatus theStatus) {
- /*
- * Provided:
- * source code
- * source value set
- */
- TranslationRequest translationRequest = new TranslationRequest();
- translationRequest.getCodeableConcept().addCoding()
- .setCode("12345");
- translationRequest.setSource(VS_URL);
+ runInTransaction(() -> {
+ /*
+ * Provided:
+ * source code
+ * source value set
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setCode("12345");
+ translationRequest.setSource(VS_URL);
- List targets = myConceptMappingSvc.translate(translationRequest).getResults();
- assertNotNull(targets);
- assertEquals(3, targets.size());
- assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
+ List targets = myConceptMappingSvc.translate(translationRequest).getResults();
+ assertNotNull(targets);
+ assertEquals(3, targets.size());
+ assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
- TranslateConceptResult target = targets.get(0);
+ TranslateConceptResult target = targets.get(0);
- ourLog.info("target(0):\n" + target.toString());
+ ourLog.info("target(0):\n" + target.toString());
- assertEquals("34567", target.getCode());
- assertEquals("Target Code 34567", target.getDisplay());
- assertEquals(CS_URL_2, target.getSystem());
- assertEquals("Version 2", target.getSystemVersion());
- assertEquals(Enumerations.ConceptMapEquivalence.EQUAL.toCode(), target.getEquivalence());
- assertEquals(VS_URL_2, target.getValueSet());
- assertEquals(CM_URL, target.getConceptMapUrl());
+ assertEquals("34567", target.getCode());
+ assertEquals("Target Code 34567", target.getDisplay());
+ assertEquals(CS_URL_2, target.getSystem());
+ assertEquals("Version 2", target.getSystemVersion());
+ assertEquals(Enumerations.ConceptMapEquivalence.EQUAL.toCode(), target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
- target = targets.get(1);
+ target = targets.get(1);
- ourLog.info("target(1):\n" + target.toString());
+ ourLog.info("target(1):\n" + target.toString());
- assertEquals("56789", target.getCode());
- assertEquals("Target Code 56789", target.getDisplay());
- assertEquals(CS_URL_3, target.getSystem());
- assertEquals("Version 4", target.getSystemVersion());
- assertEquals(Enumerations.ConceptMapEquivalence.EQUAL.toCode(), target.getEquivalence());
- assertEquals(VS_URL_2, target.getValueSet());
- assertEquals(CM_URL, target.getConceptMapUrl());
+ assertEquals("56789", target.getCode());
+ assertEquals("Target Code 56789", target.getDisplay());
+ assertEquals(CS_URL_3, target.getSystem());
+ assertEquals("Version 4", target.getSystemVersion());
+ assertEquals(Enumerations.ConceptMapEquivalence.EQUAL.toCode(), target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
- target = targets.get(2);
+ target = targets.get(2);
- ourLog.info("target(2):\n" + target.toString());
+ ourLog.info("target(2):\n" + target.toString());
- assertEquals("67890", target.getCode());
- assertEquals("Target Code 67890", target.getDisplay());
- assertEquals(CS_URL_3, target.getSystem());
- assertEquals("Version 4", target.getSystemVersion());
- assertEquals(Enumerations.ConceptMapEquivalence.WIDER.toCode(), target.getEquivalence());
- assertEquals(VS_URL_2, target.getValueSet());
- assertEquals(CM_URL, target.getConceptMapUrl());
+ assertEquals("67890", target.getCode());
+ assertEquals("Target Code 67890", target.getDisplay());
+ assertEquals(CS_URL_3, target.getSystem());
+ assertEquals("Version 4", target.getSystemVersion());
+ assertEquals(Enumerations.ConceptMapEquivalence.WIDER.toCode(), target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
- // Test caching.
- targets = myConceptMappingSvc.translate(translationRequest).getResults();
- assertNotNull(targets);
- assertEquals(3, targets.size());
- assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
- }
+ // Test caching.
+ targets = myConceptMappingSvc.translate(translationRequest).getResults();
+ assertNotNull(targets);
+ assertEquals(3, targets.size());
+ assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
});
}
@Test
public void testUsingPredicatesWithTargetValueSet() {
createAndPersistConceptMap();
- ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId, mySrd);
ourLog.debug("ConceptMap:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
- new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
- @Override
- protected void doInTransactionWithoutResult(@Nonnull TransactionStatus theStatus) {
- /*
- * Provided:
- * source code
- * target value set
- */
- TranslationRequest translationRequest = new TranslationRequest();
- translationRequest.getCodeableConcept().addCoding()
- .setCode("12345");
- translationRequest.setTarget(VS_URL_2);
+ runInTransaction(() -> {
+ /*
+ * Provided:
+ * source code
+ * target value set
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setCode("12345");
+ translationRequest.setTarget(VS_URL_2);
- List targets = myConceptMappingSvc.translate(translationRequest).getResults();
- assertNotNull(targets);
- assertEquals(3, targets.size());
- assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
+ List targets = myConceptMappingSvc.translate(translationRequest).getResults();
+ assertNotNull(targets);
+ assertEquals(3, targets.size());
+ assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
- TranslateConceptResult target = targets.get(0);
+ TranslateConceptResult target = targets.get(0);
- ourLog.info("target(0):\n" + target.toString());
+ ourLog.info("target(0):\n" + target.toString());
- assertEquals("34567", target.getCode());
- assertEquals("Target Code 34567", target.getDisplay());
- assertEquals(CS_URL_2, target.getSystem());
- assertEquals("Version 2", target.getSystemVersion());
- assertEquals(Enumerations.ConceptMapEquivalence.EQUAL.toCode(), target.getEquivalence());
- assertEquals(VS_URL_2, target.getValueSet());
- assertEquals(CM_URL, target.getConceptMapUrl());
+ assertEquals("34567", target.getCode());
+ assertEquals("Target Code 34567", target.getDisplay());
+ assertEquals(CS_URL_2, target.getSystem());
+ assertEquals("Version 2", target.getSystemVersion());
+ assertEquals(Enumerations.ConceptMapEquivalence.EQUAL.toCode(), target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
- target = targets.get(1);
+ target = targets.get(1);
- ourLog.info("target(1):\n" + target.toString());
+ ourLog.info("target(1):\n" + target.toString());
- assertEquals("56789", target.getCode());
- assertEquals("Target Code 56789", target.getDisplay());
- assertEquals(CS_URL_3, target.getSystem());
- assertEquals("Version 4", target.getSystemVersion());
- assertEquals(Enumerations.ConceptMapEquivalence.EQUAL.toCode(), target.getEquivalence());
- assertEquals(VS_URL_2, target.getValueSet());
- assertEquals(CM_URL, target.getConceptMapUrl());
+ assertEquals("56789", target.getCode());
+ assertEquals("Target Code 56789", target.getDisplay());
+ assertEquals(CS_URL_3, target.getSystem());
+ assertEquals("Version 4", target.getSystemVersion());
+ assertEquals(Enumerations.ConceptMapEquivalence.EQUAL.toCode(), target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
- target = targets.get(2);
+ target = targets.get(2);
- ourLog.info("target(2):\n" + target.toString());
+ ourLog.info("target(2):\n" + target.toString());
- assertEquals("67890", target.getCode());
- assertEquals("Target Code 67890", target.getDisplay());
- assertEquals(CS_URL_3, target.getSystem());
- assertEquals("Version 4", target.getSystemVersion());
- assertEquals(Enumerations.ConceptMapEquivalence.WIDER.toCode(), target.getEquivalence());
- assertEquals(VS_URL_2, target.getValueSet());
- assertEquals(CM_URL, target.getConceptMapUrl());
+ assertEquals("67890", target.getCode());
+ assertEquals("Target Code 67890", target.getDisplay());
+ assertEquals(CS_URL_3, target.getSystem());
+ assertEquals("Version 4", target.getSystemVersion());
+ assertEquals(Enumerations.ConceptMapEquivalence.WIDER.toCode(), target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
- // Test caching.
- targets = myConceptMappingSvc.translate(translationRequest).getResults();
- assertNotNull(targets);
- assertEquals(3, targets.size());
- assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
- }
+ // Test caching.
+ targets = myConceptMappingSvc.translate(translationRequest).getResults();
+ assertNotNull(targets);
+ assertEquals(3, targets.size());
+ assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationCache());
});
}
@Test
public void testWithReverse() {
createAndPersistConceptMap();
- ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId, mySrd);
ourLog.debug("ConceptMap:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
- new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
- @Override
- protected void doInTransactionWithoutResult(@Nonnull TransactionStatus theStatus) {
- /*
- * Provided:
- * source code
- * source code system
- * target code system
- * reverse = true
- */
- TranslationRequest translationRequest = new TranslationRequest();
- translationRequest.getCodeableConcept().addCoding()
- .setSystem(CS_URL_2)
- .setCode("34567");
- translationRequest.setTargetSystem(CS_URL_4);
- translationRequest.setReverse(true);
+ runInTransaction(() -> {
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * target code system
+ * reverse = true
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL_2)
+ .setCode("34567");
+ translationRequest.setTargetSystem(CS_URL_4);
+ translationRequest.setReverse(true);
- TranslateConceptResults elements = myConceptMappingSvc.translateWithReverse(translationRequest);
- assertNotNull(elements);
- assertEquals(1, elements.size());
- assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationWithReverseCache());
+ TranslateConceptResults elements = myConceptMappingSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertEquals(1, elements.size());
+ assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationWithReverseCache());
- TranslateConceptResult element = elements.getResults().get(0);
+ TranslateConceptResult element = elements.getResults().get(0);
- ourLog.info("element:\n" + element.toString());
+ ourLog.info("element:\n" + element.toString());
- assertEquals("78901", element.getCode());
- assertEquals("Source Code 78901", element.getDisplay());
- assertEquals(CS_URL_4, element.getSystem());
- assertEquals("Version 5", element.getSystemVersion());
- assertEquals(VS_URL, element.getValueSet());
- assertEquals(CM_URL, element.getConceptMapUrl());
+ assertEquals("78901", element.getCode());
+ assertEquals("Source Code 78901", element.getDisplay());
+ assertEquals(CS_URL_4, element.getSystem());
+ assertEquals("Version 5", element.getSystemVersion());
+ assertEquals(VS_URL, element.getValueSet());
+ assertEquals(CM_URL, element.getConceptMapUrl());
- // Test caching.
- elements = myConceptMappingSvc.translateWithReverse(translationRequest);
- assertNotNull(elements);
- assertEquals(1, elements.size());
- assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationWithReverseCache());
- }
+ // Test caching.
+ elements = myConceptMappingSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertEquals(1, elements.size());
+ assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationWithReverseCache());
});
}
@Test
public void testWithReverseByCodeSystemsAndSourceCodeUnmapped() {
createAndPersistConceptMap();
- ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId, mySrd);
ourLog.debug("ConceptMap:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
- new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
- @Override
- protected void doInTransactionWithoutResult(@Nonnull TransactionStatus theStatus) {
- TranslationRequest translationRequest = new TranslationRequest();
- translationRequest.getCodeableConcept().addCoding()
- .setSystem(CS_URL_3)
- .setCode("BOGUS");
- translationRequest.setTargetSystem(CS_URL);
+ runInTransaction(() -> {
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL_3)
+ .setCode("BOGUS");
+ translationRequest.setTargetSystem(CS_URL);
- TranslateConceptResults elements = myConceptMappingSvc.translateWithReverse(translationRequest);
- assertNotNull(elements);
- assertTrue(elements.isEmpty());
- }
+ TranslateConceptResults elements = myConceptMappingSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertTrue(elements.isEmpty());
});
}
@Test
public void testWithReverseUsingPredicatesWithCodeOnly() {
createAndPersistConceptMap();
- ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId, mySrd);
ourLog.debug("ConceptMap:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
- new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
- @Override
- protected void doInTransactionWithoutResult(@Nonnull TransactionStatus theStatus) {
- /*
- * Provided:
- * source code
- * reverse = true
- */
- TranslationRequest translationRequest = new TranslationRequest();
- translationRequest.getCodeableConcept().addCoding()
- .setCode("34567");
- translationRequest.setReverse(true);
+ runInTransaction(() -> {
+ /*
+ * Provided:
+ * source code
+ * reverse = true
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setCode("34567");
+ translationRequest.setReverse(true);
- TranslateConceptResults elements = myConceptMappingSvc.translateWithReverse(translationRequest);
- assertNotNull(elements);
- assertEquals(2, elements.size());
- assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationWithReverseCache());
+ TranslateConceptResults elements = myConceptMappingSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertEquals(2, elements.size());
+ assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationWithReverseCache());
- TranslateConceptResult element = elements.getResults().get(0);
+ TranslateConceptResult element = elements.getResults().get(0);
- ourLog.info("element:\n" + element.toString());
+ ourLog.info("element:\n" + element.toString());
- assertEquals("12345", element.getCode());
- assertEquals("Source Code 12345", element.getDisplay());
- assertEquals(CS_URL, element.getSystem());
- assertEquals("Version 1", element.getSystemVersion());
- assertEquals(VS_URL, element.getValueSet());
- assertEquals(CM_URL, element.getConceptMapUrl());
+ assertEquals("12345", element.getCode());
+ assertEquals("Source Code 12345", element.getDisplay());
+ assertEquals(CS_URL, element.getSystem());
+ assertEquals("Version 1", element.getSystemVersion());
+ assertEquals(VS_URL, element.getValueSet());
+ assertEquals(CM_URL, element.getConceptMapUrl());
- element = elements.getResults().get(1);
+ element = elements.getResults().get(1);
- ourLog.info("element:\n" + element.toString());
+ ourLog.info("element:\n" + element.toString());
- assertEquals("78901", element.getCode());
- assertEquals("Source Code 78901", element.getDisplay());
- assertEquals(CS_URL_4, element.getSystem());
- assertEquals("Version 5", element.getSystemVersion());
- assertEquals(VS_URL, element.getValueSet());
- assertEquals(CM_URL, element.getConceptMapUrl());
+ assertEquals("78901", element.getCode());
+ assertEquals("Source Code 78901", element.getDisplay());
+ assertEquals(CS_URL_4, element.getSystem());
+ assertEquals("Version 5", element.getSystemVersion());
+ assertEquals(VS_URL, element.getValueSet());
+ assertEquals(CM_URL, element.getConceptMapUrl());
- // Test caching.
- elements = myConceptMappingSvc.translateWithReverse(translationRequest);
- assertNotNull(elements);
- assertEquals(2, elements.size());
- assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationWithReverseCache());
- }
+ // Test caching.
+ elements = myConceptMappingSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertEquals(2, elements.size());
+ assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationWithReverseCache());
});
}
@Test
public void testWithReverseUsingPredicatesWithSourceAndTargetSystem1() {
createAndPersistConceptMap();
- ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId, mySrd);
ourLog.debug("ConceptMap:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
- new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
- @Override
- protected void doInTransactionWithoutResult(@Nonnull TransactionStatus theStatus) {
- /*
- * Provided:
- * source code
- * source code system
- * target code system #1
- * reverse = true
- */
- TranslationRequest translationRequest = new TranslationRequest();
- translationRequest.getCodeableConcept().addCoding()
- .setSystem(CS_URL_2)
- .setCode("34567");
- translationRequest.setTargetSystem(CS_URL);
- translationRequest.setReverse(true);
+ runInTransaction(() -> {
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * target code system #1
+ * reverse = true
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL_2)
+ .setCode("34567");
+ translationRequest.setTargetSystem(CS_URL);
+ translationRequest.setReverse(true);
- TranslateConceptResults elements = myConceptMappingSvc.translateWithReverse(translationRequest);
- assertNotNull(elements);
- assertEquals(1, elements.size());
- assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationWithReverseCache());
+ TranslateConceptResults elements = myConceptMappingSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertEquals(1, elements.size());
+ assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationWithReverseCache());
- TranslateConceptResult element = elements.getResults().get(0);
+ TranslateConceptResult element = elements.getResults().get(0);
- ourLog.info("element:\n" + element.toString());
+ ourLog.info("element:\n" + element.toString());
- assertEquals("12345", element.getCode());
- assertEquals("Source Code 12345", element.getDisplay());
- assertEquals(CS_URL, element.getSystem());
- assertEquals("Version 1", element.getSystemVersion());
- assertEquals(VS_URL, element.getValueSet());
- assertEquals(CM_URL, element.getConceptMapUrl());
+ assertEquals("12345", element.getCode());
+ assertEquals("Source Code 12345", element.getDisplay());
+ assertEquals(CS_URL, element.getSystem());
+ assertEquals("Version 1", element.getSystemVersion());
+ assertEquals(VS_URL, element.getValueSet());
+ assertEquals(CM_URL, element.getConceptMapUrl());
- // Test caching.
- elements = myConceptMappingSvc.translateWithReverse(translationRequest);
- assertNotNull(elements);
- assertEquals(1, elements.size());
- assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationWithReverseCache());
- }
+ // Test caching.
+ elements = myConceptMappingSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertEquals(1, elements.size());
+ assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationWithReverseCache());
});
}
@Test
public void testWithReverseUsingPredicatesWithSourceAndTargetSystem4() {
createAndPersistConceptMap();
- ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId, mySrd);
ourLog.debug("ConceptMap:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
- new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
- @Override
- protected void doInTransactionWithoutResult(@Nonnull TransactionStatus theStatus) {
- /*
- * Provided:
- * source code
- * source code system
- * target code system #4
- * reverse = true
- */
- TranslationRequest translationRequest = new TranslationRequest();
- translationRequest.getCodeableConcept().addCoding()
- .setSystem(CS_URL_2)
- .setCode("34567");
- translationRequest.setTargetSystem(CS_URL_4);
- translationRequest.setReverse(true);
+ runInTransaction(() -> {
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * target code system #4
+ * reverse = true
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL_2)
+ .setCode("34567");
+ translationRequest.setTargetSystem(CS_URL_4);
+ translationRequest.setReverse(true);
- TranslateConceptResults elements = myConceptMappingSvc.translateWithReverse(translationRequest);
- assertNotNull(elements);
- assertEquals(1, elements.size());
- assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationWithReverseCache());
+ TranslateConceptResults elements = myConceptMappingSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertEquals(1, elements.size());
+ assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationWithReverseCache());
- TranslateConceptResult element = elements.getResults().get(0);
+ TranslateConceptResult element = elements.getResults().get(0);
- ourLog.info("element:\n" + element.toString());
+ ourLog.info("element:\n" + element.toString());
- assertEquals("78901", element.getCode());
- assertEquals("Source Code 78901", element.getDisplay());
- assertEquals(CS_URL_4, element.getSystem());
- assertEquals("Version 5", element.getSystemVersion());
- assertEquals(VS_URL, element.getValueSet());
- assertEquals(CM_URL, element.getConceptMapUrl());
+ assertEquals("78901", element.getCode());
+ assertEquals("Source Code 78901", element.getDisplay());
+ assertEquals(CS_URL_4, element.getSystem());
+ assertEquals("Version 5", element.getSystemVersion());
+ assertEquals(VS_URL, element.getValueSet());
+ assertEquals(CM_URL, element.getConceptMapUrl());
- // Test caching.
- elements = myConceptMappingSvc.translateWithReverse(translationRequest);
- assertNotNull(elements);
- assertEquals(1, elements.size());
- assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationWithReverseCache());
- }
+ // Test caching.
+ elements = myConceptMappingSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertEquals(1, elements.size());
+ assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationWithReverseCache());
});
}
@Test
public void testWithReverseUsingPredicatesWithSourceSystem() {
createAndPersistConceptMap();
- ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId, mySrd);
ourLog.debug("ConceptMap:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
- new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
- @Override
- protected void doInTransactionWithoutResult(@Nonnull TransactionStatus theStatus) {
- /*
- * Provided:
- * source code
- * source code system
- * reverse = true
- */
- TranslationRequest translationRequest = new TranslationRequest();
- translationRequest.getCodeableConcept().addCoding()
- .setSystem(CS_URL_2)
- .setCode("34567");
- translationRequest.setReverse(true);
+ runInTransaction(() -> {
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * reverse = true
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL_2)
+ .setCode("34567");
+ translationRequest.setReverse(true);
- TranslateConceptResults elements = myConceptMappingSvc.translateWithReverse(translationRequest);
- assertNotNull(elements);
- assertEquals(2, elements.size());
- assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationWithReverseCache());
+ TranslateConceptResults elements = myConceptMappingSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertEquals(2, elements.size());
+ assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationWithReverseCache());
- TranslateConceptResult element = elements.getResults().get(0);
+ TranslateConceptResult element = elements.getResults().get(0);
- ourLog.info("element:\n" + element.toString());
+ ourLog.info("element:\n" + element.toString());
- assertEquals("12345", element.getCode());
- assertEquals("Source Code 12345", element.getDisplay());
- assertEquals(CS_URL, element.getSystem());
- assertEquals("Version 1", element.getSystemVersion());
- assertEquals(VS_URL, element.getValueSet());
- assertEquals(CM_URL, element.getConceptMapUrl());
+ assertEquals("12345", element.getCode());
+ assertEquals("Source Code 12345", element.getDisplay());
+ assertEquals(CS_URL, element.getSystem());
+ assertEquals("Version 1", element.getSystemVersion());
+ assertEquals(VS_URL, element.getValueSet());
+ assertEquals(CM_URL, element.getConceptMapUrl());
- element = elements.getResults().get(1);
+ element = elements.getResults().get(1);
- ourLog.info("element:\n" + element.toString());
+ ourLog.info("element:\n" + element.toString());
- assertEquals("78901", element.getCode());
- assertEquals("Source Code 78901", element.getDisplay());
- assertEquals(CS_URL_4, element.getSystem());
- assertEquals("Version 5", element.getSystemVersion());
- assertEquals(VS_URL, element.getValueSet());
- assertEquals(CM_URL, element.getConceptMapUrl());
+ assertEquals("78901", element.getCode());
+ assertEquals("Source Code 78901", element.getDisplay());
+ assertEquals(CS_URL_4, element.getSystem());
+ assertEquals("Version 5", element.getSystemVersion());
+ assertEquals(VS_URL, element.getValueSet());
+ assertEquals(CM_URL, element.getConceptMapUrl());
- // Test caching.
- elements = myConceptMappingSvc.translateWithReverse(translationRequest);
- assertNotNull(elements);
- assertEquals(2, elements.size());
- assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationWithReverseCache());
- }
+ // Test caching.
+ elements = myConceptMappingSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertEquals(2, elements.size());
+ assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationWithReverseCache());
});
}
@Test
public void testWithReverseUsingPredicatesWithSourceSystemAndVersion() {
createAndPersistConceptMap();
- ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId, mySrd);
ourLog.debug("ConceptMap:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
- new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
- @Override
- protected void doInTransactionWithoutResult(@Nonnull TransactionStatus theStatus) {
- /*
- * Provided:
- * source code
- * source code system
- * source code system version
- * reverse = true
- */
- TranslationRequest translationRequest = new TranslationRequest();
- translationRequest.getCodeableConcept().addCoding()
- .setSystem(CS_URL_2)
- .setCode("34567")
- .setVersion("Version 2");
- translationRequest.setReverse(true);
+ runInTransaction(() -> {
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * source code system version
+ * reverse = true
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL_2)
+ .setCode("34567")
+ .setVersion("Version 2");
+ translationRequest.setReverse(true);
- TranslateConceptResults elements = myConceptMappingSvc.translateWithReverse(translationRequest);
- assertNotNull(elements);
- assertEquals(2, elements.size());
- assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationWithReverseCache());
+ TranslateConceptResults elements = myConceptMappingSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertEquals(2, elements.size());
+ assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationWithReverseCache());
- TranslateConceptResult element = elements.getResults().get(0);
+ TranslateConceptResult element = elements.getResults().get(0);
- ourLog.info("element:\n" + element.toString());
+ ourLog.info("element:\n" + element.toString());
- assertEquals("12345", element.getCode());
- assertEquals("Source Code 12345", element.getDisplay());
- assertEquals(CS_URL, element.getSystem());
- assertEquals("Version 1", element.getSystemVersion());
- assertEquals(VS_URL, element.getValueSet());
- assertEquals(CM_URL, element.getConceptMapUrl());
+ assertEquals("12345", element.getCode());
+ assertEquals("Source Code 12345", element.getDisplay());
+ assertEquals(CS_URL, element.getSystem());
+ assertEquals("Version 1", element.getSystemVersion());
+ assertEquals(VS_URL, element.getValueSet());
+ assertEquals(CM_URL, element.getConceptMapUrl());
- element = elements.getResults().get(1);
+ element = elements.getResults().get(1);
- ourLog.info("element:\n" + element.toString());
+ ourLog.info("element:\n" + element.toString());
- assertEquals("78901", element.getCode());
- assertEquals("Source Code 78901", element.getDisplay());
- assertEquals(CS_URL_4, element.getSystem());
- assertEquals("Version 5", element.getSystemVersion());
- assertEquals(VS_URL, element.getValueSet());
- assertEquals(CM_URL, element.getConceptMapUrl());
+ assertEquals("78901", element.getCode());
+ assertEquals("Source Code 78901", element.getDisplay());
+ assertEquals(CS_URL_4, element.getSystem());
+ assertEquals("Version 5", element.getSystemVersion());
+ assertEquals(VS_URL, element.getValueSet());
+ assertEquals(CM_URL, element.getConceptMapUrl());
- // Test caching.
- elements = myConceptMappingSvc.translateWithReverse(translationRequest);
- assertNotNull(elements);
- assertEquals(2, elements.size());
- assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationWithReverseCache());
- }
+ // Test caching.
+ elements = myConceptMappingSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertEquals(2, elements.size());
+ assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationWithReverseCache());
});
}
@Test
public void testWithReverseUsingPredicatesWithSourceValueSet() {
createAndPersistConceptMap();
- ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId, mySrd);
ourLog.debug("ConceptMap:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
- new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
- @Override
- protected void doInTransactionWithoutResult(@Nonnull TransactionStatus theStatus) {
- /*
- * Provided:
- * source code
- * source value set
- * reverse = true
- */
- TranslationRequest translationRequest = new TranslationRequest();
- translationRequest.getCodeableConcept().addCoding()
- .setCode("34567");
- translationRequest.setSource(VS_URL_2);
- translationRequest.setReverse(true);
+ runInTransaction(() -> {
+ /*
+ * Provided:
+ * source code
+ * source value set
+ * reverse = true
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setCode("34567");
+ translationRequest.setSource(VS_URL_2);
+ translationRequest.setReverse(true);
- TranslateConceptResults elements = myConceptMappingSvc.translateWithReverse(translationRequest);
- assertNotNull(elements);
- assertEquals(2, elements.size());
- assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationWithReverseCache());
+ TranslateConceptResults elements = myConceptMappingSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertEquals(2, elements.size());
+ assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationWithReverseCache());
- TranslateConceptResult element = elements.getResults().get(0);
+ TranslateConceptResult element = elements.getResults().get(0);
- ourLog.info("element:\n" + element.toString());
+ ourLog.info("element:\n" + element.toString());
- assertEquals("12345", element.getCode());
- assertEquals("Source Code 12345", element.getDisplay());
- assertEquals(CS_URL, element.getSystem());
- assertEquals("Version 1", element.getSystemVersion());
- assertEquals(VS_URL, element.getValueSet());
- assertEquals(CM_URL, element.getConceptMapUrl());
+ assertEquals("12345", element.getCode());
+ assertEquals("Source Code 12345", element.getDisplay());
+ assertEquals(CS_URL, element.getSystem());
+ assertEquals("Version 1", element.getSystemVersion());
+ assertEquals(VS_URL, element.getValueSet());
+ assertEquals(CM_URL, element.getConceptMapUrl());
- element = elements.getResults().get(1);
+ element = elements.getResults().get(1);
- ourLog.info("element:\n" + element.toString());
+ ourLog.info("element:\n" + element.toString());
- assertEquals("78901", element.getCode());
- assertEquals("Source Code 78901", element.getDisplay());
- assertEquals(CS_URL_4, element.getSystem());
- assertEquals("Version 5", element.getSystemVersion());
- assertEquals(VS_URL, element.getValueSet());
- assertEquals(CM_URL, element.getConceptMapUrl());
+ assertEquals("78901", element.getCode());
+ assertEquals("Source Code 78901", element.getDisplay());
+ assertEquals(CS_URL_4, element.getSystem());
+ assertEquals("Version 5", element.getSystemVersion());
+ assertEquals(VS_URL, element.getValueSet());
+ assertEquals(CM_URL, element.getConceptMapUrl());
- // Test caching.
- elements = myConceptMappingSvc.translateWithReverse(translationRequest);
- assertNotNull(elements);
- assertEquals(2, elements.size());
- assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationWithReverseCache());
- }
+ // Test caching.
+ elements = myConceptMappingSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertEquals(2, elements.size());
+ assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationWithReverseCache());
});
}
@Test
public void testWithReverseUsingPredicatesWithTargetValueSet() {
createAndPersistConceptMap();
- ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId, mySrd);
ourLog.debug("ConceptMap:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
- new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
- @Override
- protected void doInTransactionWithoutResult(@Nonnull TransactionStatus theStatus) {
- /*
- * Provided:
- * source code
- * target value set
- * reverse = true
- */
- TranslationRequest translationRequest = new TranslationRequest();
- translationRequest.getCodeableConcept().addCoding()
- .setCode("34567");
- translationRequest.setTarget(VS_URL);
- translationRequest.setReverse(true);
+ runInTransaction(() -> {
+ /*
+ * Provided:
+ * source code
+ * target value set
+ * reverse = true
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setCode("34567");
+ translationRequest.setTarget(VS_URL);
+ translationRequest.setReverse(true);
- TranslateConceptResults elements = myConceptMappingSvc.translateWithReverse(translationRequest);
- assertNotNull(elements);
- assertEquals(2, elements.size());
- assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationWithReverseCache());
+ TranslateConceptResults elements = myConceptMappingSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertEquals(2, elements.size());
+ assertFalse(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationWithReverseCache());
- TranslateConceptResult element = elements.getResults().get(0);
+ TranslateConceptResult element = elements.getResults().get(0);
- ourLog.info("element:\n" + element.toString());
+ ourLog.info("element:\n" + element.toString());
- assertEquals("12345", element.getCode());
- assertEquals("Source Code 12345", element.getDisplay());
- assertEquals(CS_URL, element.getSystem());
- assertEquals("Version 1", element.getSystemVersion());
- assertEquals(VS_URL, element.getValueSet());
- assertEquals(CM_URL, element.getConceptMapUrl());
+ assertEquals("12345", element.getCode());
+ assertEquals("Source Code 12345", element.getDisplay());
+ assertEquals(CS_URL, element.getSystem());
+ assertEquals("Version 1", element.getSystemVersion());
+ assertEquals(VS_URL, element.getValueSet());
+ assertEquals(CM_URL, element.getConceptMapUrl());
- element = elements.getResults().get(1);
+ element = elements.getResults().get(1);
- ourLog.info("element:\n" + element.toString());
+ ourLog.info("element:\n" + element.toString());
- assertEquals("78901", element.getCode());
- assertEquals("Source Code 78901", element.getDisplay());
- assertEquals(CS_URL_4, element.getSystem());
- assertEquals("Version 5", element.getSystemVersion());
- assertEquals(VS_URL, element.getValueSet());
- assertEquals(CM_URL, element.getConceptMapUrl());
+ assertEquals("78901", element.getCode());
+ assertEquals("Source Code 78901", element.getDisplay());
+ assertEquals(CS_URL_4, element.getSystem());
+ assertEquals("Version 5", element.getSystemVersion());
+ assertEquals(VS_URL, element.getValueSet());
+ assertEquals(CM_URL, element.getConceptMapUrl());
- // Test caching.
- elements = myConceptMappingSvc.translateWithReverse(translationRequest);
- assertNotNull(elements);
- assertEquals(2, elements.size());
- assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationWithReverseCache());
- }
+ // Test caching.
+ elements = myConceptMappingSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertEquals(2, elements.size());
+ assertTrue(TermConceptMappingSvcImpl.isOurLastResultsFromTranslationWithReverseCache());
});
}
@@ -1203,358 +1157,316 @@ public class TermConceptMappingSvcImplTest extends BaseTermR4Test {
@Test
public void testStoreTermConceptMapAndChildren() {
createAndPersistConceptMap();
- ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+ ConceptMap originalConceptMap = myConceptMapDao.read(myConceptMapId, mySrd);
- ourLog.debug("ConceptMap:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+ ourLog.debug("ConceptMap:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(originalConceptMap));
- new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
- @Override
- protected void doInTransactionWithoutResult(@Nonnull TransactionStatus theStatus) {
- Pageable page = PageRequest.of(0, 1);
- List optionalConceptMap = myTermConceptMapDao.getTermConceptMapEntitiesByUrlOrderByMostRecentUpdate(page, CM_URL);
- assertEquals(1, optionalConceptMap.size());
+ runInTransaction(() -> {
+ Pageable page = PageRequest.of(0, 1);
+ List optionalConceptMap = myTermConceptMapDao.getTermConceptMapEntitiesByUrlOrderByMostRecentUpdate(page, CM_URL);
+ assertEquals(1, optionalConceptMap.size());
- TermConceptMap conceptMap = optionalConceptMap.get(0);
+ TermConceptMap conceptMap = optionalConceptMap.get(0);
- ourLog.info("ConceptMap:\n" + conceptMap.toString());
+ ourLog.info("ConceptMap:\n" + conceptMap.toString());
- assertEquals(VS_URL, conceptMap.getSource());
- assertEquals(VS_URL_2, conceptMap.getTarget());
- assertEquals(CM_URL, conceptMap.getUrl());
- assertEquals(3, conceptMap.getConceptMapGroups().size());
+ assertEquals(VS_URL, conceptMap.getSource());
+ assertEquals(VS_URL_2, conceptMap.getTarget());
+ assertEquals(CM_URL, conceptMap.getUrl());
+ assertEquals(4, conceptMap.getConceptMapGroups().size());
- TermConceptMapGroup group = conceptMap.getConceptMapGroups().get(0);
+ TermConceptMapGroup group = conceptMap.getConceptMapGroups().get(0);
- ourLog.info("ConceptMap.group(0):\n" + group.toString());
+ ourLog.info("ConceptMap.group(0):\n" + group.toString());
- assertEquals(CS_URL, group.getSource());
- assertEquals("Version 1", group.getSourceVersion());
- assertEquals(VS_URL, group.getSourceValueSet());
- assertEquals(CS_URL_2, group.getTarget());
- assertEquals("Version 2", group.getTargetVersion());
- assertEquals(VS_URL_2, group.getTargetValueSet());
- assertEquals(CM_URL, group.getConceptMapUrl());
- assertEquals(2, group.getConceptMapGroupElements().size());
+ assertGroupHasValues(
+ CS_URL,"Version 1", CS_URL_2, "Version 2", group);
+ assertEquals(VS_URL, group.getSourceValueSet());
+ assertEquals(VS_URL_2, group.getTargetValueSet());
+ assertEquals(2, group.getConceptMapGroupElements().size());
- TermConceptMapGroupElement element = group.getConceptMapGroupElements().get(0);
+ TermConceptMapGroupElement element = group.getConceptMapGroupElements().get(0);
- ourLog.info("ConceptMap.group(0).element(0):\n" + element.toString());
+ ourLog.info("ConceptMap.group(0).element(0):\n" + element.toString());
- assertEquals("12345", element.getCode());
- assertEquals("Source Code 12345", element.getDisplay());
- assertEquals(CS_URL, element.getSystem());
- assertEquals("Version 1", element.getSystemVersion());
- assertEquals(VS_URL, element.getValueSet());
- assertEquals(CM_URL, element.getConceptMapUrl());
- assertEquals(1, element.getConceptMapGroupElementTargets().size());
+ assertElementHasValues(
+ "12345", "Source Code 12345", CS_URL, "Version 1", element);
+ assertEquals(1, element.getConceptMapGroupElementTargets().size());
- TermConceptMapGroupElementTarget target = element.getConceptMapGroupElementTargets().get(0);
+ TermConceptMapGroupElementTarget target = element.getConceptMapGroupElementTargets().get(0);
- ourLog.info("ConceptMap.group(0).element(0).target(0):\n" + target.toString());
+ ourLog.info("ConceptMap.group(0).element(0).target(0):\n" + target.toString());
- assertEquals("34567", target.getCode());
- assertEquals("Target Code 34567", target.getDisplay());
- assertEquals(CS_URL_2, target.getSystem());
- assertEquals("Version 2", target.getSystemVersion());
- assertEquals(Enumerations.ConceptMapEquivalence.EQUAL, target.getEquivalence());
- assertEquals(VS_URL_2, target.getValueSet());
- assertEquals(CM_URL, target.getConceptMapUrl());
+ assertTargetHasValues(
+ "34567", "Target Code 34567", CS_URL_2, "Version 2", Enumerations.ConceptMapEquivalence.EQUAL, target);
- element = group.getConceptMapGroupElements().get(1);
+ element = group.getConceptMapGroupElements().get(1);
- ourLog.info("ConceptMap.group(0).element(1):\n" + element.toString());
+ ourLog.info("ConceptMap.group(0).element(1):\n" + element.toString());
- assertEquals("23456", element.getCode());
- assertEquals("Source Code 23456", element.getDisplay());
- assertEquals(CS_URL, element.getSystem());
- assertEquals("Version 1", element.getSystemVersion());
- assertEquals(VS_URL, element.getValueSet());
- assertEquals(CM_URL, element.getConceptMapUrl());
+ assertElementHasValues(
+ "23456", "Source Code 23456", CS_URL, "Version 1", element);
- assertEquals(2, element.getConceptMapGroupElementTargets().size());
+ assertEquals(2, element.getConceptMapGroupElementTargets().size());
- target = element.getConceptMapGroupElementTargets().get(0);
- ourLog.info("ConceptMap.group(0).element(1).target(0):\n" + target.toString());
- assertEquals("45678", target.getCode());
- assertEquals("Target Code 45678", target.getDisplay());
- assertEquals(CS_URL_2, target.getSystem());
- assertEquals("Version 2", target.getSystemVersion());
- assertEquals(Enumerations.ConceptMapEquivalence.WIDER, target.getEquivalence());
- assertEquals(VS_URL_2, target.getValueSet());
- assertEquals(CM_URL, target.getConceptMapUrl());
+ target = element.getConceptMapGroupElementTargets().get(0);
+ ourLog.info("ConceptMap.group(0).element(1).target(0):\n" + target.toString());
+ assertTargetHasValues(
+ "45678", "Target Code 45678", CS_URL_2, "Version 2", Enumerations.ConceptMapEquivalence.WIDER, target);
- // We had deliberately added a duplicate, and here it is...
- target = element.getConceptMapGroupElementTargets().get(1);
- ourLog.info("ConceptMap.group(0).element(1).target(1):\n" + target.toString());
- assertEquals("45678", target.getCode());
- assertEquals("Target Code 45678", target.getDisplay());
- assertEquals(CS_URL_2, target.getSystem());
- assertEquals("Version 2", target.getSystemVersion());
- assertEquals(Enumerations.ConceptMapEquivalence.WIDER, target.getEquivalence());
- assertEquals(VS_URL_2, target.getValueSet());
- assertEquals(CM_URL, target.getConceptMapUrl());
+ // We had deliberately added a duplicate, and here it is...
+ target = element.getConceptMapGroupElementTargets().get(1);
+ ourLog.info("ConceptMap.group(0).element(1).target(1):\n" + target.toString());
+ assertTargetHasValues(
+ "45678", "Target Code 45678", CS_URL_2, "Version 2", Enumerations.ConceptMapEquivalence.WIDER, target);
- group = conceptMap.getConceptMapGroups().get(1);
+ group = conceptMap.getConceptMapGroups().get(1);
- ourLog.info("ConceptMap.group(1):\n" + group.toString());
+ ourLog.info("ConceptMap.group(1):\n" + group.toString());
- assertEquals(CS_URL, group.getSource());
- assertEquals("Version 3", group.getSourceVersion());
- assertEquals(CS_URL_3, group.getTarget());
- assertEquals("Version 4", group.getTargetVersion());
- assertEquals(CM_URL, group.getConceptMapUrl());
- assertEquals(1, group.getConceptMapGroupElements().size());
+ assertGroupHasValues(
+ CS_URL, "Version 3", CS_URL_3, "Version 4", group);
+ assertEquals(1, group.getConceptMapGroupElements().size());
- element = group.getConceptMapGroupElements().get(0);
+ element = group.getConceptMapGroupElements().get(0);
- ourLog.info("ConceptMap.group(1).element(0):\n" + element.toString());
+ ourLog.info("ConceptMap.group(1).element(0):\n" + element.toString());
- assertEquals("12345", element.getCode());
- assertEquals("Source Code 12345", element.getDisplay());
- assertEquals(CS_URL, element.getSystem());
- assertEquals("Version 3", element.getSystemVersion());
- assertEquals(VS_URL, element.getValueSet());
- assertEquals(CM_URL, element.getConceptMapUrl());
- assertEquals(2, element.getConceptMapGroupElementTargets().size());
+ assertElementHasValues(
+ "12345", "Source Code 12345", CS_URL, "Version 3", element);
+ assertEquals(2, element.getConceptMapGroupElementTargets().size());
- target = element.getConceptMapGroupElementTargets().get(0);
+ target = element.getConceptMapGroupElementTargets().get(0);
- ourLog.info("ConceptMap.group(1).element(0).target(0):\n" + target.toString());
+ ourLog.info("ConceptMap.group(1).element(0).target(0):\n" + target.toString());
- assertEquals("56789", target.getCode());
- assertEquals("Target Code 56789", target.getDisplay());
- assertEquals(CS_URL_3, target.getSystem());
- assertEquals("Version 4", target.getSystemVersion());
- assertEquals(Enumerations.ConceptMapEquivalence.EQUAL, target.getEquivalence());
- assertEquals(VS_URL_2, target.getValueSet());
- assertEquals(CM_URL, target.getConceptMapUrl());
+ assertTargetHasValues(
+ "56789", "Target Code 56789", CS_URL_3, "Version 4", Enumerations.ConceptMapEquivalence.EQUAL, target);
- target = element.getConceptMapGroupElementTargets().get(1);
+ target = element.getConceptMapGroupElementTargets().get(1);
- ourLog.info("ConceptMap.group(1).element(0).target(1):\n" + target.toString());
+ ourLog.info("ConceptMap.group(1).element(0).target(1):\n" + target.toString());
- assertEquals("67890", target.getCode());
- assertEquals("Target Code 67890", target.getDisplay());
- assertEquals(CS_URL_3, target.getSystem());
- assertEquals("Version 4", target.getSystemVersion());
- assertEquals(Enumerations.ConceptMapEquivalence.WIDER, target.getEquivalence());
- assertEquals(VS_URL_2, target.getValueSet());
- assertEquals(CM_URL, target.getConceptMapUrl());
+ assertTargetHasValues(
+ "67890", "Target Code 67890", CS_URL_3, "Version 4", Enumerations.ConceptMapEquivalence.WIDER, target);
- group = conceptMap.getConceptMapGroups().get(2);
+ group = conceptMap.getConceptMapGroups().get(2);
- ourLog.info("ConceptMap.group(2):\n" + group.toString());
+ ourLog.info("ConceptMap.group(2):\n" + group.toString());
- assertEquals(CS_URL_4, group.getSource());
- assertEquals("Version 5", group.getSourceVersion());
- assertEquals(CS_URL_2, group.getTarget());
- assertEquals("Version 2", group.getTargetVersion());
- assertEquals(CM_URL, group.getConceptMapUrl());
- assertEquals(1, group.getConceptMapGroupElements().size());
+ assertGroupHasValues(
+ CS_URL_4, "Version 5", CS_URL_2, "Version 2", group);
+ assertEquals(1, group.getConceptMapGroupElements().size());
- element = group.getConceptMapGroupElements().get(0);
+ element = group.getConceptMapGroupElements().get(0);
- ourLog.info("ConceptMap.group(2).element(0):\n" + element.toString());
+ ourLog.info("ConceptMap.group(2).element(0):\n" + element.toString());
- assertEquals("78901", element.getCode());
- assertEquals("Source Code 78901", element.getDisplay());
- assertEquals(CS_URL_4, element.getSystem());
- assertEquals("Version 5", element.getSystemVersion());
- assertEquals(VS_URL, element.getValueSet());
- assertEquals(CM_URL, element.getConceptMapUrl());
- assertEquals(1, element.getConceptMapGroupElementTargets().size());
+ assertElementHasValues(
+ "78901", "Source Code 78901", CS_URL_4, "Version 5", element);
+ assertEquals(1, element.getConceptMapGroupElementTargets().size());
- target = element.getConceptMapGroupElementTargets().get(0);
+ target = element.getConceptMapGroupElementTargets().get(0);
- ourLog.info("ConceptMap.group(2).element(0).target(0):\n" + target.toString());
-
- assertEquals("34567", target.getCode());
- assertEquals("Target Code 34567", target.getDisplay());
- assertEquals(CS_URL_2, target.getSystem());
- assertEquals("Version 2", target.getSystemVersion());
- assertEquals(Enumerations.ConceptMapEquivalence.NARROWER, target.getEquivalence());
- assertEquals(VS_URL_2, target.getValueSet());
- assertEquals(CM_URL, target.getConceptMapUrl());
- }
+ ourLog.info("ConceptMap.group(2).element(0).target(0):\n" + target.toString());
});
}
+ @Test
+ public void testStoreTermConceptMapAndChildren_handleUnmappedElements() {
+ createAndPersistConceptMap();
+ ConceptMap originalConceptMap = myConceptMapDao.read(myConceptMapId, mySrd);
+
+ ourLog.debug("ConceptMap:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(originalConceptMap));
+
+ runInTransaction(() -> {
+ Pageable page = PageRequest.of(0, 1);
+ List optionalConceptMap = myTermConceptMapDao.getTermConceptMapEntitiesByUrlOrderByMostRecentUpdate(page, CM_URL);
+ assertEquals(1, optionalConceptMap.size());
+
+ TermConceptMap conceptMap = optionalConceptMap.get(0);
+ TermConceptMapGroup group = conceptMap.getConceptMapGroups().get(3);
+
+ ourLog.info("ConceptMap.group(3):\n" + group.toString());
+
+ assertGroupHasValues(
+ CS_URL_4, "Version 1", CS_URL_3, "Version 1", group);
+ assertEquals(2, group.getConceptMapGroupElements().size());
+
+ TermConceptMapGroupElement element = group.getConceptMapGroupElements().get(0);
+
+ ourLog.info("ConceptMap.group(3).element(0):\n" + element.toString());
+
+ assertElementHasValues(
+ "89012", "Source Code 89012", CS_URL_4, "Version 1", element);
+ assertEquals(0, element.getConceptMapGroupElementTargets().size());
+
+ element = group.getConceptMapGroupElements().get(1);
+
+ ourLog.info("ConceptMap.group(3).element(1):\n" + element.toString());
+
+ assertElementHasValues(
+ "89123", "Source Code 89123", CS_URL_4, "Version 1", element);
+ assertEquals(1, element.getConceptMapGroupElementTargets().size());
+
+ TermConceptMapGroupElementTarget target = element.getConceptMapGroupElementTargets().get(0);
+
+ ourLog.info("ConceptMap.group(3).element(1).target(0):\n" + target.toString());
+
+ assertTargetHasValues(
+ null, null, CS_URL_3, "Version 1", Enumerations.ConceptMapEquivalence.UNMATCHED, target);
+ });
+ }
+
+ private void assertGroupHasValues(String theExpectedSourceCodeSystem,
+ String theExpectedSourceCodeSystemVersion,
+ String theExpectedTargetCodeSystem,
+ String theExpectedTargetCodeSystemVersion,
+ TermConceptMapGroup group) {
+ assertEquals(theExpectedSourceCodeSystem, group.getSource());
+ assertEquals(theExpectedSourceCodeSystemVersion, group.getSourceVersion());
+ assertEquals(theExpectedTargetCodeSystem, group.getTarget());
+ assertEquals(theExpectedTargetCodeSystemVersion, group.getTargetVersion());
+ assertEquals(CM_URL, group.getConceptMapUrl());
+ }
+
+ private void assertElementHasValues(String theExpectedCode,
+ String theExpectedDisplayText,
+ String theExpectedCodeSystem,
+ String theExpectedCodeSystemVersion,
+ TermConceptMapGroupElement element) {
+ assertEquals(theExpectedCode, element.getCode());
+ assertEquals(theExpectedDisplayText, element.getDisplay());
+ assertEquals(theExpectedCodeSystem, element.getSystem());
+ assertEquals(theExpectedCodeSystemVersion, element.getSystemVersion());
+ assertEquals(VS_URL, element.getValueSet());
+ assertEquals(CM_URL, element.getConceptMapUrl());
+ }
+
+ private void assertTargetHasValues(String theExpectedCode,
+ String theExpectedDisplayText,
+ String theExpectedCodeSystem,
+ String theExpectedCodeSystemVersion,
+ Enumerations.ConceptMapEquivalence theExpectedEquivalence,
+ TermConceptMapGroupElementTarget target) {
+ assertEquals(theExpectedCode, target.getCode());
+ assertEquals(theExpectedDisplayText, target.getDisplay());
+ assertEquals(theExpectedCodeSystem, target.getSystem());
+ assertEquals(theExpectedCodeSystemVersion, target.getSystemVersion());
+ assertEquals(theExpectedEquivalence, target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
+ }
+
@Test
public void testStoreTermConceptMapAndChildrenWithClientAssignedId() {
createAndPersistConceptMap();
- ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+ ConceptMap originalConceptMap = myConceptMapDao.read(myConceptMapId, mySrd);
- ourLog.debug("ConceptMap:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+ ourLog.debug("ConceptMap:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(originalConceptMap));
- new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
- @Override
- protected void doInTransactionWithoutResult(@Nonnull TransactionStatus theStatus) {
- Pageable page = PageRequest.of(0, 1);
- List optionalConceptMap = myTermConceptMapDao.getTermConceptMapEntitiesByUrlOrderByMostRecentUpdate(page, CM_URL);
- assertEquals(1, optionalConceptMap.size());
+ runInTransaction(() -> {
+ Pageable page = PageRequest.of(0, 1);
+ List optionalConceptMap = myTermConceptMapDao.getTermConceptMapEntitiesByUrlOrderByMostRecentUpdate(page, CM_URL);
+ assertEquals(1, optionalConceptMap.size());
- TermConceptMap conceptMap = optionalConceptMap.get(0);
+ TermConceptMap conceptMap = optionalConceptMap.get(0);
- ourLog.info("ConceptMap:\n" + conceptMap.toString());
+ ourLog.info("ConceptMap:\n" + conceptMap.toString());
- assertEquals(VS_URL, conceptMap.getSource());
- assertEquals(VS_URL_2, conceptMap.getTarget());
- assertEquals(CM_URL, conceptMap.getUrl());
- assertEquals(3, conceptMap.getConceptMapGroups().size());
+ assertEquals(VS_URL, conceptMap.getSource());
+ assertEquals(VS_URL_2, conceptMap.getTarget());
+ assertEquals(CM_URL, conceptMap.getUrl());
+ assertEquals(4, conceptMap.getConceptMapGroups().size());
- TermConceptMapGroup group = conceptMap.getConceptMapGroups().get(0);
+ TermConceptMapGroup group = conceptMap.getConceptMapGroups().get(0);
- ourLog.info("ConceptMap.group(0):\n" + group.toString());
+ ourLog.info("ConceptMap.group(0):\n" + group.toString());
- assertEquals(CS_URL, group.getSource());
- assertEquals("Version 1", group.getSourceVersion());
- assertEquals(VS_URL, group.getSourceValueSet());
- assertEquals(CS_URL_2, group.getTarget());
- assertEquals("Version 2", group.getTargetVersion());
- assertEquals(VS_URL_2, group.getTargetValueSet());
- assertEquals(CM_URL, group.getConceptMapUrl());
- assertEquals(2, group.getConceptMapGroupElements().size());
+ assertEquals(CS_URL, group.getSource());
+ assertEquals("Version 1", group.getSourceVersion());
+ assertEquals(VS_URL, group.getSourceValueSet());
+ assertEquals(CS_URL_2, group.getTarget());
+ assertEquals("Version 2", group.getTargetVersion());
+ assertEquals(VS_URL_2, group.getTargetValueSet());
+ assertEquals(CM_URL, group.getConceptMapUrl());
+ assertEquals(2, group.getConceptMapGroupElements().size());
- TermConceptMapGroupElement element = group.getConceptMapGroupElements().get(0);
+ TermConceptMapGroupElement element = group.getConceptMapGroupElements().get(0);
- ourLog.info("ConceptMap.group(0).element(0):\n" + element.toString());
+ ourLog.info("ConceptMap.group(0).element(0):\n" + element.toString());
- assertEquals("12345", element.getCode());
- assertEquals("Source Code 12345", element.getDisplay());
- assertEquals(CS_URL, element.getSystem());
- assertEquals("Version 1", element.getSystemVersion());
- assertEquals(VS_URL, element.getValueSet());
- assertEquals(CM_URL, element.getConceptMapUrl());
- assertEquals(1, element.getConceptMapGroupElementTargets().size());
+ assertElementHasValues("12345", "Source Code 12345", CS_URL, "Version 1", element);
+ assertEquals(1, element.getConceptMapGroupElementTargets().size());
- TermConceptMapGroupElementTarget target = element.getConceptMapGroupElementTargets().get(0);
+ TermConceptMapGroupElementTarget target = element.getConceptMapGroupElementTargets().get(0);
- ourLog.info("ConceptMap.group(0).element(0).target(0):\n" + target.toString());
+ ourLog.info("ConceptMap.group(0).element(0).target(0):\n" + target.toString());
- assertEquals("34567", target.getCode());
- assertEquals("Target Code 34567", target.getDisplay());
- assertEquals(CS_URL_2, target.getSystem());
- assertEquals("Version 2", target.getSystemVersion());
- assertEquals(Enumerations.ConceptMapEquivalence.EQUAL, target.getEquivalence());
- assertEquals(VS_URL_2, target.getValueSet());
- assertEquals(CM_URL, target.getConceptMapUrl());
+ assertTargetHasValues("34567", "Target Code 34567", CS_URL_2, "Version 2", Enumerations.ConceptMapEquivalence.EQUAL, target);
- element = group.getConceptMapGroupElements().get(1);
+ element = group.getConceptMapGroupElements().get(1);
- ourLog.info("ConceptMap.group(0).element(1):\n" + element.toString());
+ ourLog.info("ConceptMap.group(0).element(1):\n" + element.toString());
- assertEquals("23456", element.getCode());
- assertEquals("Source Code 23456", element.getDisplay());
- assertEquals(CS_URL, element.getSystem());
- assertEquals("Version 1", element.getSystemVersion());
- assertEquals(VS_URL, element.getValueSet());
- assertEquals(CM_URL, element.getConceptMapUrl());
+ assertElementHasValues("23456", "Source Code 23456", CS_URL, "Version 1", element);
- assertEquals(2, element.getConceptMapGroupElementTargets().size());
+ assertEquals(2, element.getConceptMapGroupElementTargets().size());
- target = element.getConceptMapGroupElementTargets().get(0);
- ourLog.info("ConceptMap.group(0).element(1).target(0):\n" + target.toString());
- assertEquals("45678", target.getCode());
- assertEquals("Target Code 45678", target.getDisplay());
- assertEquals(CS_URL_2, target.getSystem());
- assertEquals("Version 2", target.getSystemVersion());
- assertEquals(Enumerations.ConceptMapEquivalence.WIDER, target.getEquivalence());
- assertEquals(VS_URL_2, target.getValueSet());
- assertEquals(CM_URL, target.getConceptMapUrl());
+ target = element.getConceptMapGroupElementTargets().get(0);
+ ourLog.info("ConceptMap.group(0).element(1).target(0):\n" + target.toString());
+ assertTargetHasValues("45678", "Target Code 45678", CS_URL_2, "Version 2", Enumerations.ConceptMapEquivalence.WIDER, target);
- // We had deliberately added a duplicate, and here it is...
- target = element.getConceptMapGroupElementTargets().get(1);
- ourLog.info("ConceptMap.group(0).element(1).target(1):\n" + target.toString());
- assertEquals("45678", target.getCode());
- assertEquals("Target Code 45678", target.getDisplay());
- assertEquals(CS_URL_2, target.getSystem());
- assertEquals("Version 2", target.getSystemVersion());
- assertEquals(Enumerations.ConceptMapEquivalence.WIDER, target.getEquivalence());
- assertEquals(VS_URL_2, target.getValueSet());
- assertEquals(CM_URL, target.getConceptMapUrl());
+ // We had deliberately added a duplicate, and here it is...
+ target = element.getConceptMapGroupElementTargets().get(1);
+ ourLog.info("ConceptMap.group(0).element(1).target(1):\n" + target.toString());
+ assertTargetHasValues("45678", "Target Code 45678", CS_URL_2, "Version 2", Enumerations.ConceptMapEquivalence.WIDER, target);
- group = conceptMap.getConceptMapGroups().get(1);
+ group = conceptMap.getConceptMapGroups().get(1);
- ourLog.info("ConceptMap.group(1):\n" + group.toString());
+ ourLog.info("ConceptMap.group(1):\n" + group.toString());
- assertEquals(CS_URL, group.getSource());
- assertEquals("Version 3", group.getSourceVersion());
- assertEquals(CS_URL_3, group.getTarget());
- assertEquals("Version 4", group.getTargetVersion());
- assertEquals(CM_URL, group.getConceptMapUrl());
- assertEquals(1, group.getConceptMapGroupElements().size());
+ assertGroupHasValues(CS_URL, "Version 3", CS_URL_3, "Version 4", group);
+ assertEquals(1, group.getConceptMapGroupElements().size());
- element = group.getConceptMapGroupElements().get(0);
+ element = group.getConceptMapGroupElements().get(0);
- ourLog.info("ConceptMap.group(1).element(0):\n" + element.toString());
+ ourLog.info("ConceptMap.group(1).element(0):\n" + element.toString());
- assertEquals("12345", element.getCode());
- assertEquals("Source Code 12345", element.getDisplay());
- assertEquals(CS_URL, element.getSystem());
- assertEquals("Version 3", element.getSystemVersion());
- assertEquals(VS_URL, element.getValueSet());
- assertEquals(CM_URL, element.getConceptMapUrl());
- assertEquals(2, element.getConceptMapGroupElementTargets().size());
+ assertElementHasValues("12345", "Source Code 12345", CS_URL, "Version 3", element);
+ assertEquals(2, element.getConceptMapGroupElementTargets().size());
- target = element.getConceptMapGroupElementTargets().get(0);
+ target = element.getConceptMapGroupElementTargets().get(0);
- ourLog.info("ConceptMap.group(1).element(0).target(0):\n" + target.toString());
+ ourLog.info("ConceptMap.group(1).element(0).target(0):\n" + target.toString());
- assertEquals("56789", target.getCode());
- assertEquals("Target Code 56789", target.getDisplay());
- assertEquals(CS_URL_3, target.getSystem());
- assertEquals("Version 4", target.getSystemVersion());
- assertEquals(Enumerations.ConceptMapEquivalence.EQUAL, target.getEquivalence());
- assertEquals(VS_URL_2, target.getValueSet());
- assertEquals(CM_URL, target.getConceptMapUrl());
+ assertTargetHasValues("56789", "Target Code 56789", CS_URL_3, "Version 4", Enumerations.ConceptMapEquivalence.EQUAL, target);
- target = element.getConceptMapGroupElementTargets().get(1);
+ target = element.getConceptMapGroupElementTargets().get(1);
- ourLog.info("ConceptMap.group(1).element(0).target(1):\n" + target.toString());
+ ourLog.info("ConceptMap.group(1).element(0).target(1):\n" + target.toString());
- assertEquals("67890", target.getCode());
- assertEquals("Target Code 67890", target.getDisplay());
- assertEquals(CS_URL_3, target.getSystem());
- assertEquals("Version 4", target.getSystemVersion());
- assertEquals(Enumerations.ConceptMapEquivalence.WIDER, target.getEquivalence());
- assertEquals(VS_URL_2, target.getValueSet());
- assertEquals(CM_URL, target.getConceptMapUrl());
+ assertTargetHasValues("67890", "Target Code 67890", CS_URL_3, "Version 4", Enumerations.ConceptMapEquivalence.WIDER, target);
- group = conceptMap.getConceptMapGroups().get(2);
+ group = conceptMap.getConceptMapGroups().get(2);
- ourLog.info("ConceptMap.group(2):\n" + group.toString());
+ ourLog.info("ConceptMap.group(2):\n" + group.toString());
- assertEquals(CS_URL_4, group.getSource());
- assertEquals("Version 5", group.getSourceVersion());
- assertEquals(CS_URL_2, group.getTarget());
- assertEquals("Version 2", group.getTargetVersion());
- assertEquals(CM_URL, group.getConceptMapUrl());
- assertEquals(1, group.getConceptMapGroupElements().size());
+ assertGroupHasValues(CS_URL_4, "Version 5", CS_URL_2, "Version 2", group);
+ assertEquals(1, group.getConceptMapGroupElements().size());
- element = group.getConceptMapGroupElements().get(0);
+ element = group.getConceptMapGroupElements().get(0);
- ourLog.info("ConceptMap.group(2).element(0):\n" + element.toString());
+ ourLog.info("ConceptMap.group(2).element(0):\n" + element.toString());
- assertEquals("78901", element.getCode());
- assertEquals("Source Code 78901", element.getDisplay());
- assertEquals(CS_URL_4, element.getSystem());
- assertEquals("Version 5", element.getSystemVersion());
- assertEquals(VS_URL, element.getValueSet());
- assertEquals(CM_URL, element.getConceptMapUrl());
- assertEquals(1, element.getConceptMapGroupElementTargets().size());
+ assertElementHasValues("78901", "Source Code 78901", CS_URL_4, "Version 5", element);
+ assertEquals(1, element.getConceptMapGroupElementTargets().size());
- target = element.getConceptMapGroupElementTargets().get(0);
+ target = element.getConceptMapGroupElementTargets().get(0);
- ourLog.info("ConceptMap.group(2).element(0).target(0):\n" + target.toString());
+ ourLog.info("ConceptMap.group(2).element(0).target(0):\n" + target.toString());
- assertEquals("34567", target.getCode());
- assertEquals("Target Code 34567", target.getDisplay());
- assertEquals(CS_URL_2, target.getSystem());
- assertEquals("Version 2", target.getSystemVersion());
- assertEquals(Enumerations.ConceptMapEquivalence.NARROWER, target.getEquivalence());
- assertEquals(VS_URL_2, target.getValueSet());
- assertEquals(CM_URL, target.getConceptMapUrl());
- }
+ assertTargetHasValues("34567", "Target Code 34567", CS_URL_2, "Version 2", Enumerations.ConceptMapEquivalence.NARROWER, target);
});
}
@@ -1670,19 +1582,13 @@ public class TermConceptMappingSvcImplTest extends BaseTermR4Test {
private void persistConceptMap(ConceptMap theConceptMap, HttpVerb theVerb) {
switch (theVerb) {
case POST:
- new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
- @Override
- protected void doInTransactionWithoutResult(@Nonnull TransactionStatus theStatus) {
- myConceptMapId = myConceptMapDao.create(theConceptMap, mySrd).getId().toUnqualifiedVersionless();
- }
+ runInTransaction(() -> {
+ myConceptMapId = myConceptMapDao.create(theConceptMap, mySrd).getId().toUnqualifiedVersionless();
});
break;
case PUT:
- new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
- @Override
- protected void doInTransactionWithoutResult(@Nonnull TransactionStatus theStatus) {
- myConceptMapId = myConceptMapDao.update(theConceptMap, mySrd).getId().toUnqualifiedVersionless();
- }
+ runInTransaction(() -> {
+ myConceptMapId = myConceptMapDao.update(theConceptMap, mySrd).getId().toUnqualifiedVersionless();
});
break;
default:
diff --git a/hapi-fhir-jpaserver-test-r4b/pom.xml b/hapi-fhir-jpaserver-test-r4b/pom.xml
index 77be64734fc..9013e0c6b72 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-test-r4b/src/test/java/ca/uhn/fhir/jpa/dao/r4b/BaseJpaR4BTest.java b/hapi-fhir-jpaserver-test-r4b/src/test/java/ca/uhn/fhir/jpa/dao/r4b/BaseJpaR4BTest.java
index 0a275e83112..afb2d993192 100644
--- a/hapi-fhir-jpaserver-test-r4b/src/test/java/ca/uhn/fhir/jpa/dao/r4b/BaseJpaR4BTest.java
+++ b/hapi-fhir-jpaserver-test-r4b/src/test/java/ca/uhn/fhir/jpa/dao/r4b/BaseJpaR4BTest.java
@@ -18,7 +18,6 @@ import ca.uhn.fhir.jpa.binary.interceptor.BinaryStorageInterceptor;
import ca.uhn.fhir.jpa.binary.provider.BinaryAccessProvider;
import ca.uhn.fhir.jpa.bulk.export.api.IBulkDataExportJobSchedulingHelper;
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
-import ca.uhn.fhir.jpa.dao.data.IForcedIdDao;
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryTableDao;
import ca.uhn.fhir.jpa.dao.data.IResourceIndexedComboStringUniqueDao;
import ca.uhn.fhir.jpa.dao.data.IResourceIndexedSearchParamDateDao;
@@ -64,6 +63,7 @@ import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory;
import ca.uhn.fhir.test.utilities.ITestDataBuilder;
import ca.uhn.fhir.validation.FhirValidator;
import ca.uhn.fhir.validation.ValidationResult;
+import jakarta.persistence.EntityManager;
import org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
@@ -124,7 +124,6 @@ import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.Transactional;
-import jakarta.persistence.EntityManager;
import java.io.IOException;
import java.util.List;
import java.util.Optional;
@@ -280,8 +279,6 @@ public abstract class BaseJpaR4BTest extends BaseJpaTest implements ITestDataBui
@Autowired
protected IResourceHistoryTableDao myResourceHistoryTableDao;
@Autowired
- protected IForcedIdDao myForcedIdDao;
- @Autowired
@Qualifier("myCoverageDaoR4B")
protected IFhirResourceDao myCoverageDao;
@Autowired
diff --git a/hapi-fhir-jpaserver-test-r4b/src/test/java/ca/uhn/fhir/jpa/provider/r4b/ResourceProviderLanguageParamR4BTest.java b/hapi-fhir-jpaserver-test-r4b/src/test/java/ca/uhn/fhir/jpa/provider/r4b/ResourceProviderLanguageParamR4BTest.java
new file mode 100644
index 00000000000..1d18ea0ce3b
--- /dev/null
+++ b/hapi-fhir-jpaserver-test-r4b/src/test/java/ca/uhn/fhir/jpa/provider/r4b/ResourceProviderLanguageParamR4BTest.java
@@ -0,0 +1,66 @@
+package ca.uhn.fhir.jpa.provider.r4b;
+
+import ca.uhn.fhir.i18n.Msg;
+import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
+import ca.uhn.fhir.rest.api.Constants;
+import ca.uhn.fhir.rest.gclient.TokenClientParam;
+import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
+import org.hl7.fhir.instance.model.api.IIdType;
+import org.hl7.fhir.r4b.model.Bundle;
+import org.hl7.fhir.r4b.model.Patient;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.Matchers.containsString;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+public class ResourceProviderLanguageParamR4BTest extends BaseResourceProviderR4BTest {
+
+ @SuppressWarnings("unused")
+ @Test
+ public void testSearchWithLanguageParamEnabled() {
+ myStorageSettings.setLanguageSearchParameterEnabled(true);
+ mySearchParamRegistry.forceRefresh();
+
+ Patient pat = new Patient();
+ pat.setLanguage("en");
+ IIdType patId = myPatientDao.create(pat, mySrd).getId().toUnqualifiedVersionless();
+
+ Patient pat2 = new Patient();
+ pat.setLanguage("fr");
+ IIdType patId2 = myPatientDao.create(pat2, mySrd).getId().toUnqualifiedVersionless();
+
+ List foundResources;
+ Bundle result;
+
+ result = myClient
+ .search()
+ .forResource(Patient.class)
+ .where(new TokenClientParam(Constants.PARAM_LANGUAGE).exactly().code("en"))
+ .returnBundle(Bundle.class)
+ .execute();
+
+ foundResources = toUnqualifiedVersionlessIdValues(result);
+ assertThat(foundResources, contains(patId.getValue()));
+ }
+
+ @SuppressWarnings("unused")
+ @Test
+ public void testSearchWithLanguageParamDisabled() {
+ myStorageSettings.setLanguageSearchParameterEnabled(new JpaStorageSettings().isLanguageSearchParameterEnabled());
+ mySearchParamRegistry.forceRefresh();
+
+ InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> {
+ myClient
+ .search()
+ .forResource(Patient.class)
+ .where(new TokenClientParam(Constants.PARAM_LANGUAGE).exactly().code("en"))
+ .returnBundle(Bundle.class)
+ .execute();
+ });
+ assertThat(exception.getMessage(), containsString(Msg.code(1223)));
+ }
+}
diff --git a/hapi-fhir-jpaserver-test-r5/pom.xml b/hapi-fhir-jpaserver-test-r5/pom.xml
index 545c9c2fbb4..f91d4266b1a 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-test-r5/src/test/java/ca/uhn/fhir/jpa/dao/r5/BaseJpaR5Test.java b/hapi-fhir-jpaserver-test-r5/src/test/java/ca/uhn/fhir/jpa/dao/r5/BaseJpaR5Test.java
index 75a846ccb87..d6c38965bbb 100644
--- a/hapi-fhir-jpaserver-test-r5/src/test/java/ca/uhn/fhir/jpa/dao/r5/BaseJpaR5Test.java
+++ b/hapi-fhir-jpaserver-test-r5/src/test/java/ca/uhn/fhir/jpa/dao/r5/BaseJpaR5Test.java
@@ -19,7 +19,6 @@ import ca.uhn.fhir.jpa.binary.interceptor.BinaryStorageInterceptor;
import ca.uhn.fhir.jpa.binary.provider.BinaryAccessProvider;
import ca.uhn.fhir.jpa.bulk.export.api.IBulkDataExportJobSchedulingHelper;
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
-import ca.uhn.fhir.jpa.dao.data.IForcedIdDao;
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryProvenanceDao;
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryTableDao;
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryTagDao;
@@ -72,6 +71,7 @@ import ca.uhn.fhir.rest.server.BasePagingProvider;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory;
import ca.uhn.fhir.test.utilities.ITestDataBuilder;
+import jakarta.persistence.EntityManager;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r5.model.AllergyIntolerance;
@@ -134,7 +134,6 @@ import org.springframework.test.util.AopTestUtils;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.Transactional;
-import jakarta.persistence.EntityManager;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@@ -303,8 +302,6 @@ public abstract class BaseJpaR5Test extends BaseJpaTest implements ITestDataBuil
@Autowired
protected IResourceHistoryProvenanceDao myResourceHistoryProvenanceDao;
@Autowired
- protected IForcedIdDao myForcedIdDao;
- @Autowired
@Qualifier("myCoverageDaoR5")
protected IFhirResourceDao myCoverageDao;
@Autowired
diff --git a/hapi-fhir-jpaserver-test-r5/src/test/java/ca/uhn/fhir/jpa/dao/r5/FhirSystemDaoTransactionR5Test.java b/hapi-fhir-jpaserver-test-r5/src/test/java/ca/uhn/fhir/jpa/dao/r5/FhirSystemDaoTransactionR5Test.java
index f5d7992b1fc..2fe8d2762ca 100644
--- a/hapi-fhir-jpaserver-test-r5/src/test/java/ca/uhn/fhir/jpa/dao/r5/FhirSystemDaoTransactionR5Test.java
+++ b/hapi-fhir-jpaserver-test-r5/src/test/java/ca/uhn/fhir/jpa/dao/r5/FhirSystemDaoTransactionR5Test.java
@@ -4,6 +4,7 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
import ca.uhn.fhir.util.BundleBuilder;
+import jakarta.annotation.Nonnull;
import org.hl7.fhir.r5.model.BooleanType;
import org.hl7.fhir.r5.model.Bundle;
import org.hl7.fhir.r5.model.CodeType;
@@ -20,7 +21,6 @@ import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.ValueSource;
-import jakarta.annotation.Nonnull;
import java.io.IOException;
import java.util.UUID;
@@ -28,7 +28,6 @@ import static org.apache.commons.lang3.StringUtils.countMatches;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.endsWith;
-import static org.hamcrest.Matchers.in;
import static org.hamcrest.Matchers.matchesPattern;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
@@ -151,7 +150,7 @@ public class FhirSystemDaoTransactionR5Test extends BaseJpaR5Test {
// Verify
- assertEquals(theMatchUrlCacheEnabled ? 4 : 5, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
+ assertEquals(theMatchUrlCacheEnabled ? 3 : 4, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
assertEquals(0, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
assertEquals(0, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
@@ -203,7 +202,7 @@ public class FhirSystemDaoTransactionR5Test extends BaseJpaR5Test {
// Verify
- assertEquals(theMatchUrlCacheEnabled ? 4 : 5, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
+ assertEquals(theMatchUrlCacheEnabled ? 3 : 4, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
assertEquals(0, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
assertEquals(0, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
diff --git a/hapi-fhir-jpaserver-test-r5/src/test/java/ca/uhn/fhir/jpa/dao/r5/UpliftedRefchainsAndChainedSortingR5Test.java b/hapi-fhir-jpaserver-test-r5/src/test/java/ca/uhn/fhir/jpa/dao/r5/UpliftedRefchainsAndChainedSortingR5Test.java
index 453b541eebb..5cf0e2a4127 100644
--- a/hapi-fhir-jpaserver-test-r5/src/test/java/ca/uhn/fhir/jpa/dao/r5/UpliftedRefchainsAndChainedSortingR5Test.java
+++ b/hapi-fhir-jpaserver-test-r5/src/test/java/ca/uhn/fhir/jpa/dao/r5/UpliftedRefchainsAndChainedSortingR5Test.java
@@ -401,7 +401,7 @@ public class UpliftedRefchainsAndChainedSortingR5Test extends BaseJpaR5Test {
// 1- Resolve resource forced IDs, and 2- Resolve Practitioner/PR1 reference
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
- assertEquals(10, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
+ assertEquals(9, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
// Verify correct indexes are written
@@ -441,7 +441,7 @@ public class UpliftedRefchainsAndChainedSortingR5Test extends BaseJpaR5Test {
bb.addTransactionUpdateEntry(newEncounter(ENCOUNTER_E2, p2Id));
bb.addTransactionCreateEntry(newPatientP1_HomerSimpson().setId(p1Id)).conditional("identifier=http://system|200");
bb.addTransactionCreateEntry(newPatientP2_MargeSimpson().setId(p2Id)).conditional("identifier=http://system|300");
- ;
+
Bundle requestBundle = bb.getBundleTyped();
myCaptureQueriesListener.clear();
@@ -496,7 +496,7 @@ public class UpliftedRefchainsAndChainedSortingR5Test extends BaseJpaR5Test {
bb.addTransactionUpdateEntry(newEncounter(ENCOUNTER_E2, p2Id));
bb.addTransactionCreateEntry(new Patient().addIdentifier(new Identifier().setSystem("http://system").setValue("200")).setId(p1Id)).conditional("identifier=http://system|200");
bb.addTransactionCreateEntry(new Patient().addIdentifier(new Identifier().setSystem("http://system").setValue("300")).setId(p2Id)).conditional("identifier=http://system|300");
- ;
+
Bundle requestBundle = bb.getBundleTyped();
myCaptureQueriesListener.clear();
diff --git a/hapi-fhir-jpaserver-test-r5/src/test/java/ca/uhn/fhir/jpa/provider/r5/ResourceProviderLanguageParamR5Test.java b/hapi-fhir-jpaserver-test-r5/src/test/java/ca/uhn/fhir/jpa/provider/r5/ResourceProviderLanguageParamR5Test.java
new file mode 100644
index 00000000000..4f0ceb0fc92
--- /dev/null
+++ b/hapi-fhir-jpaserver-test-r5/src/test/java/ca/uhn/fhir/jpa/provider/r5/ResourceProviderLanguageParamR5Test.java
@@ -0,0 +1,66 @@
+package ca.uhn.fhir.jpa.provider.r5;
+
+import ca.uhn.fhir.i18n.Msg;
+import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
+import ca.uhn.fhir.rest.api.Constants;
+import ca.uhn.fhir.rest.gclient.TokenClientParam;
+import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
+import org.hl7.fhir.instance.model.api.IIdType;
+import org.hl7.fhir.r5.model.Bundle;
+import org.hl7.fhir.r5.model.Patient;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.Matchers.containsString;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+public class ResourceProviderLanguageParamR5Test extends BaseResourceProviderR5Test {
+
+ @SuppressWarnings("unused")
+ @Test
+ public void testSearchWithLanguageParamEnabled() {
+ myStorageSettings.setLanguageSearchParameterEnabled(true);
+ mySearchParamRegistry.forceRefresh();
+
+ Patient pat = new Patient();
+ pat.setLanguage("en");
+ IIdType patId = myPatientDao.create(pat, mySrd).getId().toUnqualifiedVersionless();
+
+ Patient pat2 = new Patient();
+ pat.setLanguage("fr");
+ IIdType patId2 = myPatientDao.create(pat2, mySrd).getId().toUnqualifiedVersionless();
+
+ List foundResources;
+ Bundle result;
+
+ result = myClient
+ .search()
+ .forResource(Patient.class)
+ .where(new TokenClientParam(Constants.PARAM_LANGUAGE).exactly().code("en"))
+ .returnBundle(Bundle.class)
+ .execute();
+
+ foundResources = toUnqualifiedVersionlessIdValues(result);
+ assertThat(foundResources, contains(patId.getValue()));
+ }
+
+ @SuppressWarnings("unused")
+ @Test
+ public void testSearchWithLanguageParamDisabled() {
+ myStorageSettings.setLanguageSearchParameterEnabled(new JpaStorageSettings().isLanguageSearchParameterEnabled());
+ mySearchParamRegistry.forceRefresh();
+
+ InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> {
+ myClient
+ .search()
+ .forResource(Patient.class)
+ .where(new TokenClientParam(Constants.PARAM_LANGUAGE).exactly().code("en"))
+ .returnBundle(Bundle.class)
+ .execute();
+ });
+ assertThat(exception.getMessage(), containsString(Msg.code(1223)));
+ }
+}
diff --git a/hapi-fhir-jpaserver-test-utilities/pom.xml b/hapi-fhir-jpaserver-test-utilities/pom.xml
index d92fba3b123..72fcdec2607 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/BaseJpaR4Test.java b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/BaseJpaR4Test.java
index 531291487e4..33d536600c1 100644
--- a/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/BaseJpaR4Test.java
+++ b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/BaseJpaR4Test.java
@@ -20,8 +20,6 @@
package ca.uhn.fhir.jpa.test;
import ca.uhn.fhir.batch2.jobs.export.BulkDataExportProvider;
-import ca.uhn.fhir.batch2.jobs.reindex.ReindexAppCtx;
-import ca.uhn.fhir.batch2.model.JobInstance;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.interceptor.api.IInterceptorService;
@@ -45,7 +43,6 @@ import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
import ca.uhn.fhir.jpa.dao.TestDaoSearch;
import ca.uhn.fhir.jpa.dao.data.IBatch2JobInstanceRepository;
import ca.uhn.fhir.jpa.dao.data.IBatch2WorkChunkRepository;
-import ca.uhn.fhir.jpa.dao.data.IForcedIdDao;
import ca.uhn.fhir.jpa.dao.data.IMdmLinkJpaRepository;
import ca.uhn.fhir.jpa.dao.data.IPartitionDao;
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryProvenanceDao;
@@ -116,6 +113,7 @@ import ca.uhn.fhir.test.utilities.ITestDataBuilder;
import ca.uhn.fhir.util.UrlUtil;
import ca.uhn.fhir.validation.FhirValidator;
import ca.uhn.fhir.validation.ValidationResult;
+import jakarta.persistence.EntityManager;
import org.hl7.fhir.common.hapi.validation.support.CachingValidationSupport;
import org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator;
import org.hl7.fhir.instance.model.api.IBaseResource;
@@ -208,7 +206,6 @@ import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.util.AopTestUtils;
import org.springframework.transaction.PlatformTransactionManager;
-import jakarta.persistence.EntityManager;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@@ -935,6 +932,28 @@ public abstract class BaseJpaR4Test extends BaseJpaTest implements ITestDataBuil
target.setDisplay("Target Code 34567");
target.setEquivalence(ConceptMapEquivalence.NARROWER);
+ group = conceptMap.addGroup();
+ group.setSource(CS_URL_4);
+ group.setSourceVersion("Version 1");
+ group.setTarget(CS_URL_3);
+ group.setTargetVersion("Version 1");
+
+ // This one should not show up in the results because it doesn't have a code
+ element = group.addElement();
+ element.setCode("89012");
+ element.setDisplay("Source Code 89012");
+
+ target = element.addTarget();
+ target.setEquivalence(ConceptMapEquivalence.DISJOINT);
+
+ // This one should show up in the results because unmatched targets are allowed to be codeless
+ element = group.addElement();
+ element.setCode("89123");
+ element.setDisplay("Source Code 89123");
+
+ target = element.addTarget();
+ target.setEquivalence(ConceptMapEquivalence.UNMATCHED);
+
return conceptMap;
}
diff --git a/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/BaseJpaTest.java b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/BaseJpaTest.java
index b0012b2a279..107e77268da 100644
--- a/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/BaseJpaTest.java
+++ b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/BaseJpaTest.java
@@ -36,7 +36,6 @@ import ca.uhn.fhir.jpa.config.JpaConfig;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
import ca.uhn.fhir.jpa.dao.JpaPersistedResourceValidationSupport;
-import ca.uhn.fhir.jpa.dao.data.IForcedIdDao;
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryTableDao;
import ca.uhn.fhir.jpa.dao.data.IResourceIndexedComboTokensNonUniqueDao;
import ca.uhn.fhir.jpa.dao.data.IResourceIndexedSearchParamCoordsDao;
@@ -61,7 +60,6 @@ import ca.uhn.fhir.jpa.entity.TermConceptProperty;
import ca.uhn.fhir.jpa.entity.TermValueSet;
import ca.uhn.fhir.jpa.entity.TermValueSetConcept;
import ca.uhn.fhir.jpa.entity.TermValueSetConceptDesignation;
-import ca.uhn.fhir.jpa.model.entity.ForcedId;
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedComboTokenNonUnique;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamCoords;
@@ -99,6 +97,8 @@ import ca.uhn.fhir.util.ClasspathUtil;
import ca.uhn.fhir.util.FhirVersionIndependentConcept;
import ca.uhn.fhir.util.StopWatch;
import ca.uhn.fhir.util.TestUtil;
+import jakarta.annotation.Nonnull;
+import jakarta.persistence.EntityManager;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
@@ -129,8 +129,6 @@ import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
-import jakarta.annotation.Nonnull;
-import jakarta.persistence.EntityManager;
import java.io.IOException;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
@@ -257,8 +255,6 @@ public abstract class BaseJpaTest extends BaseTest {
@Autowired
private IResourceHistoryTableDao myResourceHistoryTableDao;
@Autowired
- protected IForcedIdDao myForcedIdDao;
- @Autowired
private DaoRegistry myDaoRegistry;
private final List myRegisteredInterceptors = new ArrayList<>(1);
@@ -517,14 +513,6 @@ public abstract class BaseJpaTest extends BaseTest {
});
}
- protected int logAllForcedIds() {
- return runInTransaction(() -> {
- List forcedIds = myForcedIdDao.findAll();
- ourLog.info("Resources:\n * {}", forcedIds.stream().map(ForcedId::toString).collect(Collectors.joining("\n * ")));
- return forcedIds.size();
- });
- }
-
protected void logAllDateIndexes() {
runInTransaction(() -> {
ourLog.info("Date indexes:\n * {}", myResourceIndexedSearchParamDateDao.findAll().stream().map(ResourceIndexedSearchParamDate::toString).collect(Collectors.joining("\n * ")));
diff --git a/hapi-fhir-jpaserver-test-utilities/src/main/resources/migration/releases/V7_2_0/data/H2_EMBEDDED.sql b/hapi-fhir-jpaserver-test-utilities/src/main/resources/migration/releases/V7_2_0/data/H2_EMBEDDED.sql
new file mode 100644
index 00000000000..e84689abc35
--- /dev/null
+++ b/hapi-fhir-jpaserver-test-utilities/src/main/resources/migration/releases/V7_2_0/data/H2_EMBEDDED.sql
@@ -0,0 +1 @@
+INSERT INTO TRM_CONCEPT_MAP_GRP_ELM_TGT (PID, TARGET_CODE, CONCEPT_MAP_URL, TARGET_DISPLAY, TARGET_EQUIVALENCE, SYSTEM_URL, SYSTEM_VERSION, VALUESET_URL, CONCEPT_MAP_GRP_ELM_PID) VALUES (61, NULL, NULL, 'PYRIDOXINE', 'UNMATCHED', NULL, NULL, NULL, 60);
diff --git a/hapi-fhir-jpaserver-test-utilities/src/main/resources/migration/releases/V7_2_0/data/MSSQL_2012.sql b/hapi-fhir-jpaserver-test-utilities/src/main/resources/migration/releases/V7_2_0/data/MSSQL_2012.sql
new file mode 100644
index 00000000000..e84689abc35
--- /dev/null
+++ b/hapi-fhir-jpaserver-test-utilities/src/main/resources/migration/releases/V7_2_0/data/MSSQL_2012.sql
@@ -0,0 +1 @@
+INSERT INTO TRM_CONCEPT_MAP_GRP_ELM_TGT (PID, TARGET_CODE, CONCEPT_MAP_URL, TARGET_DISPLAY, TARGET_EQUIVALENCE, SYSTEM_URL, SYSTEM_VERSION, VALUESET_URL, CONCEPT_MAP_GRP_ELM_PID) VALUES (61, NULL, NULL, 'PYRIDOXINE', 'UNMATCHED', NULL, NULL, NULL, 60);
diff --git a/hapi-fhir-jpaserver-test-utilities/src/main/resources/migration/releases/V7_2_0/data/ORACLE_12C.sql b/hapi-fhir-jpaserver-test-utilities/src/main/resources/migration/releases/V7_2_0/data/ORACLE_12C.sql
new file mode 100644
index 00000000000..e84689abc35
--- /dev/null
+++ b/hapi-fhir-jpaserver-test-utilities/src/main/resources/migration/releases/V7_2_0/data/ORACLE_12C.sql
@@ -0,0 +1 @@
+INSERT INTO TRM_CONCEPT_MAP_GRP_ELM_TGT (PID, TARGET_CODE, CONCEPT_MAP_URL, TARGET_DISPLAY, TARGET_EQUIVALENCE, SYSTEM_URL, SYSTEM_VERSION, VALUESET_URL, CONCEPT_MAP_GRP_ELM_PID) VALUES (61, NULL, NULL, 'PYRIDOXINE', 'UNMATCHED', NULL, NULL, NULL, 60);
diff --git a/hapi-fhir-jpaserver-test-utilities/src/main/resources/migration/releases/V7_2_0/data/POSTGRES_9_4.sql b/hapi-fhir-jpaserver-test-utilities/src/main/resources/migration/releases/V7_2_0/data/POSTGRES_9_4.sql
new file mode 100644
index 00000000000..e84689abc35
--- /dev/null
+++ b/hapi-fhir-jpaserver-test-utilities/src/main/resources/migration/releases/V7_2_0/data/POSTGRES_9_4.sql
@@ -0,0 +1 @@
+INSERT INTO TRM_CONCEPT_MAP_GRP_ELM_TGT (PID, TARGET_CODE, CONCEPT_MAP_URL, TARGET_DISPLAY, TARGET_EQUIVALENCE, SYSTEM_URL, SYSTEM_VERSION, VALUESET_URL, CONCEPT_MAP_GRP_ELM_PID) VALUES (61, NULL, NULL, 'PYRIDOXINE', 'UNMATCHED', NULL, NULL, NULL, 60);
diff --git a/hapi-fhir-jpaserver-test-utilities/src/test/java/ca/uhn/fhir/jpa/cache/ResourceVersionSvcTest.java b/hapi-fhir-jpaserver-test-utilities/src/test/java/ca/uhn/fhir/jpa/cache/ResourceVersionSvcTest.java
index 322f7f75fb4..427be9fba23 100644
--- a/hapi-fhir-jpaserver-test-utilities/src/test/java/ca/uhn/fhir/jpa/cache/ResourceVersionSvcTest.java
+++ b/hapi-fhir-jpaserver-test-utilities/src/test/java/ca/uhn/fhir/jpa/cache/ResourceVersionSvcTest.java
@@ -3,16 +3,17 @@ package ca.uhn.fhir.jpa.cache;
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
-import ca.uhn.fhir.jpa.cache.ResourcePersistentIdMap;
-import ca.uhn.fhir.jpa.cache.ResourceVersionSvcDaoImpl;
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
import ca.uhn.fhir.jpa.dao.index.IdHelperService;
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
-import ca.uhn.fhir.jpa.model.entity.ForcedId;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
+import jakarta.persistence.criteria.CriteriaBuilder;
+import jakarta.persistence.criteria.CriteriaQuery;
+import jakarta.persistence.criteria.Path;
+import jakarta.persistence.criteria.Root;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
@@ -23,11 +24,6 @@ import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
-import jakarta.persistence.TypedQuery;
-import jakarta.persistence.criteria.CriteriaBuilder;
-import jakarta.persistence.criteria.CriteriaQuery;
-import jakarta.persistence.criteria.Path;
-import jakarta.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -36,7 +32,6 @@ import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertSame;
-import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
@@ -85,8 +80,6 @@ public class ResourceVersionSvcTest {
CriteriaQuery criteriaQuery = Mockito.mock(CriteriaQuery.class);
Root from = Mockito.mock(Root.class);
Path path = Mockito.mock(Path.class);
-
- TypedQuery queryMock = Mockito.mock(TypedQuery.class);
}
/**
diff --git a/hapi-fhir-jpaserver-test-utilities/src/test/java/ca/uhn/fhir/jpa/embedded/HapiSchemaMigrationTest.java b/hapi-fhir-jpaserver-test-utilities/src/test/java/ca/uhn/fhir/jpa/embedded/HapiSchemaMigrationTest.java
index 29642613f88..b5fd1631e5b 100644
--- a/hapi-fhir-jpaserver-test-utilities/src/test/java/ca/uhn/fhir/jpa/embedded/HapiSchemaMigrationTest.java
+++ b/hapi-fhir-jpaserver-test-utilities/src/test/java/ca/uhn/fhir/jpa/embedded/HapiSchemaMigrationTest.java
@@ -83,7 +83,8 @@ public class HapiSchemaMigrationTest {
VersionEnum.V5_4_0,
VersionEnum.V5_5_0,
VersionEnum.V6_0_0,
- VersionEnum.V6_6_0
+ VersionEnum.V6_6_0,
+ VersionEnum.V7_2_0
);
int fromVersion = 0;
@@ -92,6 +93,7 @@ public class HapiSchemaMigrationTest {
for (int i = 0; i < allVersions.length; i++) {
toVersion = allVersions[i];
+ ourLog.info("Applying migrations for {}", toVersion);
migrate(theDriverType, dataSource, hapiMigrationStorageSvc, toVersion);
if (dataVersions.contains(toVersion)) {
myEmbeddedServersExtension.insertPersistenceTestData(theDriverType, toVersion);
diff --git a/hapi-fhir-jpaserver-uhnfhirtest/pom.xml b/hapi-fhir-jpaserver-uhnfhirtest/pom.xml
index a38b2b8c988..434fa5b7fd1 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../pom.xml
diff --git a/hapi-fhir-server-cds-hooks/pom.xml b/hapi-fhir-server-cds-hooks/pom.xml
index 4749239fb7f..4e2bbda8f5e 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-server-mdm/pom.xml b/hapi-fhir-server-mdm/pom.xml
index 366ceb47463..5d85b54408b 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/provider/MdmProviderLoader.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/provider/MdmProviderLoader.java
index aa1d32e72a3..8c64b2b898d 100644
--- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/provider/MdmProviderLoader.java
+++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/provider/MdmProviderLoader.java
@@ -32,6 +32,8 @@ import jakarta.annotation.PreDestroy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
+import java.util.function.Supplier;
+
@Service
public class MdmProviderLoader {
@Autowired
@@ -58,26 +60,28 @@ public class MdmProviderLoader {
@Autowired
private IInterceptorBroadcaster myInterceptorBroadcaster;
- private BaseMdmProvider myMdmProvider;
- private MdmLinkHistoryProviderDstu3Plus myMdmHistoryProvider;
+ private Supplier myMdmProviderSupplier;
+ private Supplier myMdmHistoryProviderSupplier;
public void loadProvider() {
switch (myFhirContext.getVersion().getVersion()) {
case DSTU3:
case R4:
case R5:
- myResourceProviderFactory.addSupplier(() -> new MdmProviderDstu3Plus(
+ // We store the supplier so that removeSupplier works properly
+ myMdmProviderSupplier = () -> new MdmProviderDstu3Plus(
myFhirContext,
myMdmControllerSvc,
myMdmControllerHelper,
myMdmSubmitSvc,
myInterceptorBroadcaster,
- myMdmSettings));
+ myMdmSettings);
+ // We store the supplier so that removeSupplier works properly
+ myResourceProviderFactory.addSupplier(myMdmProviderSupplier);
if (myStorageSettings.isNonResourceDbHistoryEnabled()) {
- myResourceProviderFactory.addSupplier(() -> {
- return new MdmLinkHistoryProviderDstu3Plus(
- myFhirContext, myMdmControllerSvc, myInterceptorBroadcaster);
- });
+ myMdmHistoryProviderSupplier = () -> new MdmLinkHistoryProviderDstu3Plus(
+ myFhirContext, myMdmControllerSvc, myInterceptorBroadcaster);
+ myResourceProviderFactory.addSupplier(myMdmHistoryProviderSupplier);
}
break;
default:
@@ -88,11 +92,11 @@ public class MdmProviderLoader {
@PreDestroy
public void unloadProvider() {
- if (myMdmProvider != null) {
- myResourceProviderFactory.removeSupplier(() -> myMdmProvider);
+ if (myMdmProviderSupplier != null) {
+ myResourceProviderFactory.removeSupplier(myMdmProviderSupplier);
}
- if (myMdmHistoryProvider != null) {
- myResourceProviderFactory.removeSupplier(() -> myMdmHistoryProvider);
+ if (myMdmHistoryProviderSupplier != null) {
+ myResourceProviderFactory.removeSupplier(myMdmHistoryProviderSupplier);
}
}
}
diff --git a/hapi-fhir-server-openapi/pom.xml b/hapi-fhir-server-openapi/pom.xml
index cfaae68b9d9..6371abe0514 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-server/pom.xml b/hapi-fhir-server/pom.xml
index 3d74ccc0870..03bba016e4a 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/IObservableSupplierSetObserver.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/IObservableSupplierSetObserver.java
new file mode 100644
index 00000000000..90bed1f2ada
--- /dev/null
+++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/IObservableSupplierSetObserver.java
@@ -0,0 +1,33 @@
+/*-
+ * #%L
+ * HAPI FHIR - Server Framework
+ * %%
+ * 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.rest.server.provider;
+
+import jakarta.annotation.Nonnull;
+
+import java.util.function.Supplier;
+
+/**
+ * See {@link ObservableSupplierSet}
+ */
+public interface IObservableSupplierSetObserver {
+ void update(@Nonnull Supplier theSupplier);
+
+ void remove(@Nonnull Supplier theSupplier);
+}
diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/IResourceProviderFactoryObserver.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/IResourceProviderFactoryObserver.java
index c8fba47fc8a..42b1d77be9a 100644
--- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/IResourceProviderFactoryObserver.java
+++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/IResourceProviderFactoryObserver.java
@@ -19,12 +19,7 @@
*/
package ca.uhn.fhir.rest.server.provider;
-import jakarta.annotation.Nonnull;
-
-import java.util.function.Supplier;
-
-public interface IResourceProviderFactoryObserver {
- void update(@Nonnull Supplier theSupplier);
-
- void remove(@Nonnull Supplier theSupplier);
-}
+/**
+ * See {@link ObservableSupplierSet}
+ */
+public interface IResourceProviderFactoryObserver extends IObservableSupplierSetObserver {}
diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/ObservableSupplierSet.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/ObservableSupplierSet.java
new file mode 100644
index 00000000000..f20eddb181b
--- /dev/null
+++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/ObservableSupplierSet.java
@@ -0,0 +1,123 @@
+/*-
+ * #%L
+ * HAPI FHIR - Server Framework
+ * %%
+ * 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.rest.server.provider;
+
+import jakarta.annotation.Nonnull;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.function.Supplier;
+
+/**
+ * This is a generic implementation of the Observer Design Pattern .
+ * We use this to pass sets of beans from exporting Spring application contexts to importing Spring application contexts. We defer
+ * resolving the observed beans via a Supplier to give the exporting context a chance to initialize the beans before they are used.
+ * @param the class of the Observer
+ *
+ * A typical usage pattern would be:
+ *
+ * Create {@link ObservableSupplierSet} in exporter context.
+ * Add all the suppliers in the exporter context.
+ * Attach the importer to the {@link ObservableSupplierSet}
+ * Importer calls {@link ObservableSupplierSet#getSupplierResults} and processes all the beans
+ * Some other service beans may add more suppliers later as a part of their initialization and the observer handlers will process them accordingly
+ * Those other service beans should call {@link ObservableSupplierSet#removeSupplier(Supplier)} in a @PreDestroy method so they are properly cleaned up if those services are shut down or restarted
+ *
+ *
+ */
+public class ObservableSupplierSet {
+ private static final Logger ourLog = LoggerFactory.getLogger(ObservableSupplierSet.class);
+
+ private final Set myObservers = Collections.synchronizedSet(new HashSet<>());
+
+ private final Set> mySuppliers = new LinkedHashSet<>();
+
+ /** Add a supplier and notify all observers
+ *
+ * @param theSupplier supplies the object to be observed
+ */
+ public void addSupplier(@Nonnull Supplier theSupplier) {
+ if (mySuppliers.add(theSupplier)) {
+ myObservers.forEach(observer -> observer.update(theSupplier));
+ }
+ }
+
+ /** Remove a supplier and notify all observers. CAUTION, you might think that this code would work, but it does not:
+ *
+ * observableSupplierSet.addSupplier(() -> myBean);
+ * ...
+ * observableSupplierSet.removeSupplier(() -> myBean);
+ *
+ * the removeSupplier in this example would fail because it is a different lambda instance from the first. Instead,
+ * you need to store the supplier between the add and remove:
+ *
+ * mySupplier = () -> myBean;
+ * observableSupplierSet.addSupplier(mySupplier);
+ * ...
+ * observableSupplierSet.removeSupplier(mySupplier);
+ *
+ *
+ * @param theSupplier the supplier to be removed
+ */
+ public void removeSupplier(@Nonnull Supplier theSupplier) {
+ if (mySuppliers.remove(theSupplier)) {
+ myObservers.forEach(observer -> observer.remove(theSupplier));
+ } else {
+ ourLog.warn("Failed to remove supplier", new RuntimeException());
+ }
+ }
+
+ /**
+ * Attach an observer to this observableSupplierSet. This observer will be notified every time a supplier is added or removed.
+ * @param theObserver the observer to be notified
+ */
+ public void attach(T theObserver) {
+ myObservers.add(theObserver);
+ }
+
+ /**
+ * Detach an observer from this observableSupplierSet, so it is no longer notified when suppliers are added and removed.
+ * @param theObserver the observer to be removed
+ */
+ public void detach(T theObserver) {
+ myObservers.remove(theObserver);
+ }
+
+ /**
+ *
+ * @return a list of get() being called on all suppliers.
+ */
+ protected List getSupplierResults() {
+ List retVal = new ArrayList<>();
+ for (Supplier next : mySuppliers) {
+ Object nextRp = next.get();
+ if (nextRp != null) {
+ retVal.add(nextRp);
+ }
+ }
+ return retVal;
+ }
+}
diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/ResourceProviderFactory.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/ResourceProviderFactory.java
index 809418c1241..dce86b45e30 100644
--- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/ResourceProviderFactory.java
+++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/ResourceProviderFactory.java
@@ -19,45 +19,16 @@
*/
package ca.uhn.fhir.rest.server.provider;
-import jakarta.annotation.Nonnull;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
-import java.util.function.Supplier;
-public class ResourceProviderFactory {
- private Set myObservers = Collections.synchronizedSet(new HashSet<>());
- private List> mySuppliers = new ArrayList<>();
-
- public void addSupplier(@Nonnull Supplier theSupplier) {
- mySuppliers.add(theSupplier);
- myObservers.forEach(observer -> observer.update(theSupplier));
- }
-
- public void removeSupplier(@Nonnull Supplier theSupplier) {
- mySuppliers.remove(theSupplier);
- myObservers.forEach(observer -> observer.remove(theSupplier));
- }
+/**
+ * This Factory stores FHIR Resource Provider instance suppliers that will be registered on a FHIR Endpoint later.
+ * See {@link ObservableSupplierSet}
+ */
+public class ResourceProviderFactory extends ObservableSupplierSet {
+ public ResourceProviderFactory() {}
public List createProviders() {
- List retVal = new ArrayList<>();
- for (Supplier next : mySuppliers) {
- Object nextRp = next.get();
- if (nextRp != null) {
- retVal.add(nextRp);
- }
- }
- return retVal;
- }
-
- public void attach(IResourceProviderFactoryObserver theObserver) {
- myObservers.add(theObserver);
- }
-
- public void detach(IResourceProviderFactoryObserver theObserver) {
- myObservers.remove(theObserver);
+ return super.getSupplierResults();
}
}
diff --git a/hapi-fhir-serviceloaders/hapi-fhir-caching-api/pom.xml b/hapi-fhir-serviceloaders/hapi-fhir-caching-api/pom.xml
index e51308bd2a7..41d0b9e5491 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../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 32680b37acb..47a646b0196 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../pom.xml
@@ -21,7 +21,7 @@
ca.uhn.hapi.fhir
hapi-fhir-caching-api
- 7.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
diff --git a/hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml b/hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml
index da34ff1770e..1bb5308eec9 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../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 3e09e7c0160..615bcaede67 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../../pom.xml
diff --git a/hapi-fhir-serviceloaders/pom.xml b/hapi-fhir-serviceloaders/pom.xml
index 3a7bdba7d54..4e9f671c79c 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../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 93b126309c1..5514a27054c 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../../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 7a250b4b4c5..638c3933040 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
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 a99bea8806d..d3e81bb97d3 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
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 e3b0cf47a83..6ec3497c477 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
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 f45a5e76eba..133fa52cfd8 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
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 d554053161d..e23fe9696d2 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-spring-boot/pom.xml b/hapi-fhir-spring-boot/pom.xml
index 8b56e169941..25eee371362 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../pom.xml
diff --git a/hapi-fhir-sql-migrate/pom.xml b/hapi-fhir-sql-migrate/pom.xml
index 0827041f3d5..e10a99c7db0 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/tasks/SchemaInitializationProviderTest.java b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/tasks/SchemaInitializationProviderTest.java
index c7b55ff0b53..5d0b04056dd 100644
--- a/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/tasks/SchemaInitializationProviderTest.java
+++ b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/tasks/SchemaInitializationProviderTest.java
@@ -24,9 +24,9 @@ public class SchemaInitializationProviderTest {
-- comment in a weird spot
references CDR_XACT_LOG;
- -- we can't use convering index until the autovacuum runs for those rows, which kills index performance
+ -- we can't use covering index until the autovacuum runs for those rows, which kills index performance
ALTER TABLE hfj_resource SET (autovacuum_vacuum_scale_factor = 0.01);
- ALTER TABLE hfj_forced_id SET (autovacuum_vacuum_scale_factor = 0.01);
+ ALTER TABLE hfj_spidx_token SET (autovacuum_vacuum_scale_factor = 0.01);
""";
List listToPopulate = new ArrayList<>();
svc.parseSqlFileIntoIndividualStatements(DriverTypeEnum.POSTGRES_9_4, listToPopulate, input);
@@ -35,7 +35,7 @@ public class SchemaInitializationProviderTest {
"create sequence foo",
"alter table if exists CDR_XACT_LOG_STEP add constraint FK_XACTLOGSTEP_XACTLOG foreign key (LOG_PID) references CDR_XACT_LOG",
"ALTER TABLE hfj_resource SET (autovacuum_vacuum_scale_factor = 0.01)",
- "ALTER TABLE hfj_forced_id SET (autovacuum_vacuum_scale_factor = 0.01)"
+ "ALTER TABLE hfj_spidx_token SET (autovacuum_vacuum_scale_factor = 0.01)"
));
}
diff --git a/hapi-fhir-storage-batch2-jobs/pom.xml b/hapi-fhir-storage-batch2-jobs/pom.xml
index bb38f3ccee7..814d926048b 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-storage-batch2-jobs/src/main/java/ca/uhn/fhir/batch2/jobs/export/BulkDataExportProvider.java b/hapi-fhir-storage-batch2-jobs/src/main/java/ca/uhn/fhir/batch2/jobs/export/BulkDataExportProvider.java
index 8882abc5c2e..05f5a95dbcc 100644
--- a/hapi-fhir-storage-batch2-jobs/src/main/java/ca/uhn/fhir/batch2/jobs/export/BulkDataExportProvider.java
+++ b/hapi-fhir-storage-batch2-jobs/src/main/java/ca/uhn/fhir/batch2/jobs/export/BulkDataExportProvider.java
@@ -37,7 +37,6 @@ import ca.uhn.fhir.jpa.batch.models.Batch2JobStartResponse;
import ca.uhn.fhir.jpa.bulk.export.model.BulkExportResponseJson;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc;
-import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Operation;
@@ -77,7 +76,6 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
@@ -293,11 +291,15 @@ public class BulkDataExportProvider {
*/
private void validateTargetsExists(
RequestDetails theRequestDetails, String theTargetResourceName, Iterable theIdParams) {
- RequestPartitionId partitionId = myRequestPartitionHelperService.determineReadPartitionForRequestForRead(
- theRequestDetails, theTargetResourceName, theIdParams.iterator().next());
- SystemRequestDetails requestDetails = new SystemRequestDetails().setRequestPartitionId(partitionId);
- for (IIdType nextId : theIdParams) {
- myDaoRegistry.getResourceDao(theTargetResourceName).read(nextId, requestDetails);
+ if (theIdParams.iterator().hasNext()) {
+ RequestPartitionId partitionId = myRequestPartitionHelperService.determineReadPartitionForRequestForRead(
+ theRequestDetails,
+ theTargetResourceName,
+ theIdParams.iterator().next());
+ SystemRequestDetails requestDetails = new SystemRequestDetails().setRequestPartitionId(partitionId);
+ for (IIdType nextId : theIdParams) {
+ myDaoRegistry.getResourceDao(theTargetResourceName).read(nextId, requestDetails);
+ }
}
}
@@ -364,26 +366,18 @@ public class BulkDataExportProvider {
@OperationParam(name = JpaConstants.PARAM_EXPORT_IDENTIFIER, min = 0, max = 1, typeName = "string")
IPrimitiveType theExportIdentifier,
ServletRequestDetails theRequestDetails) {
- validatePreferAsyncHeader(theRequestDetails, ProviderConstants.OPERATION_EXPORT);
- if (thePatient != null) {
- validateTargetsExists(
- theRequestDetails,
- "Patient",
- thePatient.stream().map(s -> new IdDt(s.getValue())).collect(Collectors.toList()));
- }
+ List> patientIds = thePatient != null ? thePatient : new ArrayList<>();
- BulkExportJobParameters BulkExportJobParameters = buildPatientBulkExportOptions(
+ doPatientExport(
+ theRequestDetails,
theOutputFormat,
theType,
theSince,
- theTypeFilter,
theExportIdentifier,
- thePatient,
- theTypePostFetchFilterUrl);
- validateResourceTypesAllContainPatientSearchParams(BulkExportJobParameters.getResourceTypes());
-
- startJob(theRequestDetails, BulkExportJobParameters);
+ theTypeFilter,
+ theTypePostFetchFilterUrl,
+ patientIds);
}
/**
@@ -417,9 +411,34 @@ public class BulkDataExportProvider {
@OperationParam(name = JpaConstants.PARAM_EXPORT_IDENTIFIER, min = 0, max = 1, typeName = "string")
IPrimitiveType theExportIdentifier,
ServletRequestDetails theRequestDetails) {
+
+ // call the type-level export to ensure spec compliance
+ patientExport(
+ theOutputFormat,
+ theType,
+ theSince,
+ theTypeFilter,
+ theTypePostFetchFilterUrl,
+ List.of(theIdParam),
+ theExportIdentifier,
+ theRequestDetails);
+ }
+
+ private void doPatientExport(
+ ServletRequestDetails theRequestDetails,
+ IPrimitiveType theOutputFormat,
+ IPrimitiveType theType,
+ IPrimitiveType theSince,
+ IPrimitiveType theExportIdentifier,
+ List> theTypeFilter,
+ List> theTypePostFetchFilterUrl,
+ List> thePatientIds) {
validatePreferAsyncHeader(theRequestDetails, ProviderConstants.OPERATION_EXPORT);
- validateTargetsExists(theRequestDetails, "Patient", List.of(theIdParam));
+ validateTargetsExists(
+ theRequestDetails,
+ "Patient",
+ thePatientIds.stream().map(c -> new IdType(c.getValue())).collect(Collectors.toList()));
BulkExportJobParameters BulkExportJobParameters = buildPatientBulkExportOptions(
theOutputFormat,
@@ -427,7 +446,7 @@ public class BulkDataExportProvider {
theSince,
theTypeFilter,
theExportIdentifier,
- theIdParam,
+ thePatientIds,
theTypePostFetchFilterUrl);
validateResourceTypesAllContainPatientSearchParams(BulkExportJobParameters.getResourceTypes());
@@ -670,31 +689,6 @@ public class BulkDataExportProvider {
return BulkExportJobParameters;
}
- private BulkExportJobParameters buildPatientBulkExportOptions(
- IPrimitiveType theOutputFormat,
- IPrimitiveType theType,
- IPrimitiveType theSince,
- List> theTypeFilter,
- IPrimitiveType theExportIdentifier,
- IIdType thePatientId,
- List> theTypePostFetchFilterUrl) {
- IPrimitiveType type = theType;
- if (type == null) {
- // set type to all patient compartment resources if it is null
- type = new StringDt(String.join(",", getPatientCompartmentResources()));
- }
- BulkExportJobParameters BulkExportJobParameters = buildBulkExportJobParameters(
- theOutputFormat,
- type,
- theSince,
- theTypeFilter,
- theExportIdentifier,
- ExportStyle.PATIENT,
- theTypePostFetchFilterUrl);
- BulkExportJobParameters.setPatientIds(Collections.singleton(thePatientId.getValue()));
- return BulkExportJobParameters;
- }
-
private BulkExportJobParameters buildBulkExportJobParameters(
IPrimitiveType theOutputFormat,
IPrimitiveType theType,
diff --git a/hapi-fhir-storage-batch2-test-utilities/pom.xml b/hapi-fhir-storage-batch2-test-utilities/pom.xml
index ce8ac389e76..59ba95cfeb2 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/AbstractIJobPersistenceSpecificationTest.java b/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/AbstractIJobPersistenceSpecificationTest.java
index 0f5c3f5017d..9b342fc419c 100644
--- a/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/AbstractIJobPersistenceSpecificationTest.java
+++ b/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/AbstractIJobPersistenceSpecificationTest.java
@@ -29,6 +29,7 @@ import ca.uhn.fhir.batch2.model.JobDefinition;
import ca.uhn.fhir.batch2.model.JobInstance;
import ca.uhn.fhir.batch2.model.JobWorkNotification;
import ca.uhn.fhir.batch2.model.StatusEnum;
+import ca.uhn.fhir.batch2.model.WorkChunk;
import ca.uhn.fhir.batch2.model.WorkChunkCreateEvent;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.util.StopWatch;
@@ -64,7 +65,7 @@ import static org.mockito.Mockito.verify;
* These tests are abstract, and do not depend on JPA.
* Test setups should use the public batch2 api to create scenarios.
*/
-public abstract class AbstractIJobPersistenceSpecificationTest implements IJobMaintenanceActions, IInProgressActionsTests, IInstanceStateTransitions, IWorkChunkCommon, WorkChunkTestConstants {
+public abstract class AbstractIJobPersistenceSpecificationTest implements IJobMaintenanceActions, IInProgressActionsTests, IInstanceStateTransitions, ITestFixture, IWorkChunkCommon, WorkChunkTestConstants {
private static final Logger ourLog = LoggerFactory.getLogger(AbstractIJobPersistenceSpecificationTest.class);
@@ -106,6 +107,11 @@ public abstract class AbstractIJobPersistenceSpecificationTest implements IJobMa
return builder.build();
}
+ @Override
+ public ITestFixture getTestManager() {
+ return this;
+ }
+
@AfterEach
public void after() {
myJobDefinitionRegistry.removeJobDefinition(JOB_DEFINITION_ID, JOB_DEF_VER);
@@ -179,6 +185,9 @@ public abstract class AbstractIJobPersistenceSpecificationTest implements IJobMa
return runInTransaction(() -> mySvc.fetchInstance(theInstanceId).orElseThrow());
}
+ @Override
+ public abstract void runMaintenancePass();
+
public TransactionTemplate newTxTemplate() {
TransactionTemplate retVal = new TransactionTemplate(getTxManager());
retVal.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
diff --git a/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/IInProgressActionsTests.java b/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/IInProgressActionsTests.java
index c1667424a7a..2aa85fc562d 100644
--- a/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/IInProgressActionsTests.java
+++ b/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/IInProgressActionsTests.java
@@ -1,3 +1,22 @@
+/*-
+ * #%L
+ * HAPI FHIR JPA Server - Batch2 specification tests
+ * %%
+ * 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.hapi.fhir.batch2.test;
import ca.uhn.fhir.batch2.model.WorkChunkCompletionEvent;
@@ -12,13 +31,13 @@ public interface IInProgressActionsTests extends IWorkChunkCommon, WorkChunkTest
@Test
default void processingOk_inProgressToSuccess_clearsDataSavesRecordCount() {
- String jobId = createAndStoreJobInstance(null);
- String myChunkId = createAndDequeueWorkChunk(jobId);
+ String jobId = getTestManager().createAndStoreJobInstance(null);
+ String myChunkId = getTestManager().createAndDequeueWorkChunk(jobId);
// execution ok
- getSvc().onWorkChunkCompletion(new WorkChunkCompletionEvent(myChunkId, 3, 0));
+ getTestManager().getSvc().onWorkChunkCompletion(new WorkChunkCompletionEvent(myChunkId, 3, 0));
// verify the db was updated
- var workChunkEntity = freshFetchWorkChunk(myChunkId);
+ var workChunkEntity = getTestManager().freshFetchWorkChunk(myChunkId);
assertEquals(WorkChunkStatusEnum.COMPLETED, workChunkEntity.getStatus());
assertNull(workChunkEntity.getData());
assertEquals(3, workChunkEntity.getRecordsProcessed());
@@ -35,6 +54,13 @@ public interface IInProgressActionsTests extends IWorkChunkCommon, WorkChunkTest
// verify the db was updated
var workChunkEntity = freshFetchWorkChunk(myChunkId);
+ String jobId = getTestManager().createAndStoreJobInstance(null);
+ String myChunkId = getTestManager().createAndDequeueWorkChunk(jobId);
+ // execution had a retryable error
+ getTestManager().getSvc().onWorkChunkError(new WorkChunkErrorEvent(myChunkId, ERROR_MESSAGE_A));
+
+ // verify the db was updated
+ var workChunkEntity = getTestManager().freshFetchWorkChunk(myChunkId);
assertEquals(WorkChunkStatusEnum.ERRORED, workChunkEntity.getStatus());
assertEquals(ERROR_MESSAGE_A, workChunkEntity.getErrorMessage());
assertEquals(1, workChunkEntity.getErrorCount());
@@ -42,13 +68,13 @@ public interface IInProgressActionsTests extends IWorkChunkCommon, WorkChunkTest
@Test
default void processingFailure_inProgressToFailed() {
- String jobId = createAndStoreJobInstance(null);
- String myChunkId = createAndDequeueWorkChunk(jobId);
+ String jobId = getTestManager().createAndStoreJobInstance(null);
+ String myChunkId = getTestManager().createAndDequeueWorkChunk(jobId);
// execution had a failure
- getSvc().onWorkChunkFailed(myChunkId, "some error");
+ getTestManager().getSvc().onWorkChunkFailed(myChunkId, "some error");
// verify the db was updated
- var workChunkEntity = freshFetchWorkChunk(myChunkId);
+ var workChunkEntity = getTestManager().freshFetchWorkChunk(myChunkId);
assertEquals(WorkChunkStatusEnum.FAILED, workChunkEntity.getStatus());
assertEquals("some error", workChunkEntity.getErrorMessage());
}
diff --git a/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/IInstanceStateTransitions.java b/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/IInstanceStateTransitions.java
index 95ce1e060e4..b44ba98e8fb 100644
--- a/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/IInstanceStateTransitions.java
+++ b/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/IInstanceStateTransitions.java
@@ -1,3 +1,22 @@
+/*-
+ * #%L
+ * HAPI FHIR JPA Server - Batch2 specification tests
+ * %%
+ * 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.hapi.fhir.batch2.test;
import ca.uhn.fhir.batch2.api.IJobPersistence;
@@ -20,6 +39,7 @@ import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.emptyString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.not;
+import static org.hamcrest.Matchers.equalTo;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
@@ -55,16 +75,16 @@ public interface IInstanceStateTransitions extends IWorkChunkCommon, WorkChunkTe
@Test
default void testCreateInstance_firstChunkDequeued_movesToInProgress() {
// given
- JobDefinition> jd = withJobDefinition(false);
- IJobPersistence.CreateResult createResult = newTxTemplate().execute(status->
- getSvc().onCreateWithFirstChunk(jd, "{}"));
+ JobDefinition> jd = getTestManager().withJobDefinition(false);
+ IJobPersistence.CreateResult createResult = getTestManager().newTxTemplate().execute(status->
+ getTestManager().getSvc().onCreateWithFirstChunk(jd, "{}"));
assertNotNull(createResult);
// when
- newTxTemplate().execute(status -> getSvc().onChunkDequeued(createResult.jobInstanceId));
+ getTestManager().newTxTemplate().execute(status -> getTestManager().getSvc().onChunkDequeued(createResult.jobInstanceId));
// then
- JobInstance jobInstance = freshFetchJobInstance(createResult.jobInstanceId);
+ JobInstance jobInstance = getTestManager().freshFetchJobInstance(createResult.jobInstanceId);
assertThat(jobInstance.getStatus(), equalTo(StatusEnum.IN_PROGRESS));
}
@@ -74,20 +94,20 @@ public interface IInstanceStateTransitions extends IWorkChunkCommon, WorkChunkTe
// given
JobInstance cancelledInstance = createInstance();
cancelledInstance.setStatus(theState);
- String instanceId1 = getSvc().storeNewInstance(cancelledInstance);
- getSvc().cancelInstance(instanceId1);
+ String instanceId1 = getTestManager().getSvc().storeNewInstance(cancelledInstance);
+ getTestManager().getSvc().cancelInstance(instanceId1);
JobInstance normalInstance = createInstance();
normalInstance.setStatus(theState);
- String instanceId2 = getSvc().storeNewInstance(normalInstance);
+ String instanceId2 = getTestManager().getSvc().storeNewInstance(normalInstance);
JobDefinitionRegistry jobDefinitionRegistry = new JobDefinitionRegistry();
- jobDefinitionRegistry.addJobDefinitionIfNotRegistered(withJobDefinition(false));
+ jobDefinitionRegistry.addJobDefinitionIfNotRegistered(getTestManager().withJobDefinition(false));
// when
- runInTransaction(()-> {
+ getTestManager().runInTransaction(()-> {
new JobInstanceProcessor(
- getSvc(),
+ getTestManager().getSvc(),
null,
instanceId1,
new JobChunkProgressAccumulator(),
@@ -97,7 +117,7 @@ public interface IInstanceStateTransitions extends IWorkChunkCommon, WorkChunkTe
});
// then
- JobInstance freshInstance1 = getSvc().fetchInstance(instanceId1).orElseThrow();
+ JobInstance freshInstance1 = getTestManager().getSvc().fetchInstance(instanceId1).orElseThrow();
if (theState.isCancellable()) {
assertEquals(StatusEnum.CANCELLED, freshInstance1.getStatus(), "cancel request processed");
assertThat(freshInstance1.getErrorMessage(), containsString("Job instance cancelled"));
@@ -105,17 +125,7 @@ public interface IInstanceStateTransitions extends IWorkChunkCommon, WorkChunkTe
assertEquals(theState, freshInstance1.getStatus(), "cancel request ignored - state unchanged");
assertNull(freshInstance1.getErrorMessage(), "no error message");
}
- JobInstance freshInstance2 = getSvc().fetchInstance(instanceId2).orElseThrow();
+ JobInstance freshInstance2 = getTestManager().getSvc().fetchInstance(instanceId2).orElseThrow();
assertEquals(theState, freshInstance2.getStatus(), "cancel request ignored - cancelled not set");
}
-
- default JobInstance createInstance() {
- JobInstance instance = new JobInstance();
- instance.setJobDefinitionId(JOB_DEFINITION_ID);
- instance.setStatus(StatusEnum.QUEUED);
- instance.setJobDefinitionVersion(JOB_DEF_VER);
- instance.setParameters(CHUNK_DATA);
- instance.setReport("TEST");
- return instance;
- }
}
diff --git a/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/ITestFixture.java b/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/ITestFixture.java
new file mode 100644
index 00000000000..fdb75990f0d
--- /dev/null
+++ b/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/ITestFixture.java
@@ -0,0 +1,84 @@
+/*-
+ * #%L
+ * HAPI FHIR JPA Server - Batch2 specification tests
+ * %%
+ * 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.hapi.fhir.batch2.test;
+
+import ca.uhn.fhir.batch2.api.IJobPersistence;
+import ca.uhn.fhir.batch2.model.JobDefinition;
+import ca.uhn.fhir.batch2.model.JobInstance;
+import ca.uhn.fhir.batch2.model.WorkChunk;
+import ca.uhn.hapi.fhir.batch2.test.support.TestJobParameters;
+import ca.uhn.test.concurrency.PointcutLatch;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.support.TransactionTemplate;
+
+public interface ITestFixture {
+
+ String createAndStoreJobInstance(JobDefinition> theJobDefinition);
+
+ String createAndDequeueWorkChunk(String theJobInstanceId);
+
+ WorkChunk freshFetchWorkChunk(String theChunkId);
+
+ String storeWorkChunk(String theJobDefinitionId, String theTargetStepId, String theInstanceId, int theSequence, String theSerializedData);
+
+ void runInTransaction(Runnable theRunnable);
+
+ void sleepUntilTimeChanges();
+
+ JobDefinition withJobDefinition(boolean theIsGatedJob);
+
+ TransactionTemplate newTxTemplate();
+
+ JobInstance freshFetchJobInstance(String theInstanceId);
+
+ void runMaintenancePass();
+
+ PlatformTransactionManager getTransactionManager();
+
+ IJobPersistence getSvc();
+
+ /**
+ * This assumes a creation of JOB_DEFINITION already
+ * @param theJobInstanceId
+ * @return
+ */
+ String createChunk(String theJobInstanceId);
+
+ /**
+ * Enable/disable the maintenance runner (So it doesn't run on a scheduler)
+ */
+ void enableMaintenanceRunner(boolean theToEnable);
+
+ /**
+ * Disables the workchunk message handler
+ * so that we do not actually send messages to the queue;
+ * useful if mocking state transitions and we don't want to test
+ * dequeuing.
+ * Returns a latch that will fire each time a message is sent.
+ */
+ PointcutLatch disableWorkChunkMessageHandler();
+
+ /**
+ *
+ * @param theSendingLatch the latch sent back from the disableWorkChunkMessageHandler method above
+ * @param theNumberOfTimes the number of invocations to expect
+ */
+ void verifyWorkChunkMessageHandlerCalled(PointcutLatch theSendingLatch, int theNumberOfTimes) throws InterruptedException;
+}
diff --git a/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/IWorkChunkCommon.java b/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/IWorkChunkCommon.java
index 99ce4bd9fd2..d9fabe6d0db 100644
--- a/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/IWorkChunkCommon.java
+++ b/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/IWorkChunkCommon.java
@@ -1,15 +1,26 @@
+/*-
+ * #%L
+ * HAPI FHIR JPA Server - Batch2 specification tests
+ * %%
+ * 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.hapi.fhir.batch2.test;
-import ca.uhn.fhir.batch2.api.IJobPersistence;
-import ca.uhn.fhir.batch2.channel.BatchJobSender;
-import ca.uhn.fhir.batch2.model.JobDefinition;
import ca.uhn.fhir.batch2.model.JobInstance;
-import ca.uhn.fhir.batch2.model.WorkChunk;
-import ca.uhn.hapi.fhir.batch2.test.support.JobMaintenanceStateInformation;
-import ca.uhn.hapi.fhir.batch2.test.support.TestJobParameters;
-import ca.uhn.test.concurrency.PointcutLatch;
-import org.springframework.transaction.PlatformTransactionManager;
-import org.springframework.transaction.support.TransactionTemplate;
+import ca.uhn.fhir.batch2.model.StatusEnum;
public interface IWorkChunkCommon extends WorkChunkTestConstants {
@@ -17,102 +28,15 @@ public interface IWorkChunkCommon extends WorkChunkTestConstants {
* Returns the concrete class that is implementing this stuff.
* Used primarily for structure
*/
- IWorkChunkCommon getTestManager();
-
- default String createAndStoreJobInstance(JobDefinition> theJobDefinition) {
- return getTestManager().createAndStoreJobInstance(theJobDefinition);
- }
-
- default String createAndDequeueWorkChunk(String theJobInstanceId) {
- return getTestManager().createAndDequeueWorkChunk(theJobInstanceId);
- }
-
- default WorkChunk freshFetchWorkChunk(String theChunkId) {
- return getTestManager().freshFetchWorkChunk(theChunkId);
- }
+ ITestFixture getTestManager();
default JobInstance createInstance() {
- return getTestManager().createInstance();
- }
-
- default String storeWorkChunk(String theJobDefinitionId, String theTargetStepId, String theInstanceId, int theSequence, String theSerializedData) {
- return getTestManager().storeWorkChunk(theJobDefinitionId, theTargetStepId, theInstanceId, theSequence, theSerializedData);
- }
-
- default void runInTransaction(Runnable theRunnable) {
- getTestManager().runInTransaction(theRunnable);
- }
-
- default void sleepUntilTimeChanges() {
- getTestManager().sleepUntilTimeChanges();
- }
-
- default JobDefinition withJobDefinition(boolean theIsGatedJob) {
- return getTestManager().withJobDefinition(theIsGatedJob);
- }
-
- default TransactionTemplate newTxTemplate() {
- return getTestManager().newTxTemplate();
- }
-
- default JobInstance freshFetchJobInstance(String theInstanceId) {
- return getTestManager().freshFetchJobInstance(theInstanceId);
- }
-
- default void runMaintenancePass() {
- getTestManager().runMaintenancePass();
- }
-
- default PlatformTransactionManager getTransactionManager() {
- return getTestManager().getTransactionManager();
- }
-
- default IJobPersistence getSvc() {
- return getTestManager().getSvc();
- }
-
- /**
- * This assumes a creation of JOB_DEFINITION already
- * @param theJobInstanceId
- * @return
- */
- default String createChunk(String theJobInstanceId) {
- return getTestManager().createChunk(theJobInstanceId);
- }
-
- /**
- * Enable/disable the maintenance runner (So it doesn't run on a scheduler)
- */
- default void enableMaintenanceRunner(boolean theToEnable) {
- getTestManager().enableMaintenanceRunner(theToEnable);
- }
-
- /**
- * Uses the JobMaintenanceState information and the format:
- * "step_number|initialstate,step_number|finalstate" to construct
- * an initial state for a test scenario
- */
- default void createChunksInStates(JobMaintenanceStateInformation theInitialState) {
- getTestManager().createChunksInStates(theInitialState);
- }
-
- /**
- * Disables the workchunk message handler
- * so that we do not actually send messages to the queue;
- * useful if mocking state transitions and we don't want to test
- * dequeuing.
- * Returns a latch that will fire each time a message is sent.
- */
- default PointcutLatch disableWorkChunkMessageHandler() {
- return getTestManager().disableWorkChunkMessageHandler();
- }
-
- /**
- *
- * @param theSendingLatch the latch sent back from the disableWorkChunkMessageHandler method above
- * @param theNumberOfTimes the number of invocations to expect
- */
- default void verifyWorkChunkMessageHandlerCalled(PointcutLatch theSendingLatch, int theNumberOfTimes) throws InterruptedException {
- getTestManager().verifyWorkChunkMessageHandlerCalled(theSendingLatch, theNumberOfTimes);
+ JobInstance instance = new JobInstance();
+ instance.setJobDefinitionId(JOB_DEFINITION_ID);
+ instance.setStatus(StatusEnum.QUEUED);
+ instance.setJobDefinitionVersion(JOB_DEF_VER);
+ instance.setParameters(CHUNK_DATA);
+ instance.setReport("TEST");
+ return instance;
}
}
diff --git a/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/IWorkChunkErrorActionsTests.java b/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/IWorkChunkErrorActionsTests.java
index 3f8286d1c52..adabfa120c7 100644
--- a/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/IWorkChunkErrorActionsTests.java
+++ b/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/IWorkChunkErrorActionsTests.java
@@ -1,3 +1,22 @@
+/*-
+ * #%L
+ * HAPI FHIR JPA Server - Batch2 specification tests
+ * %%
+ * 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.hapi.fhir.batch2.test;
import ca.uhn.fhir.batch2.model.WorkChunk;
@@ -18,18 +37,18 @@ public interface IWorkChunkErrorActionsTests extends IWorkChunkCommon, WorkChunk
*/
@Test
default void errorRetry_errorToInProgress() {
- String jobId = createAndStoreJobInstance(null);
- String myChunkId = createAndDequeueWorkChunk(jobId);
- getSvc().onWorkChunkError(new WorkChunkErrorEvent(myChunkId, FIRST_ERROR_MESSAGE));
+ String jobId = getTestManager().createAndStoreJobInstance(null);
+ String myChunkId = getTestManager().createAndDequeueWorkChunk(jobId);
+ getTestManager().getSvc().onWorkChunkError(new WorkChunkErrorEvent(myChunkId, FIRST_ERROR_MESSAGE));
// when consumer restarts chunk
- WorkChunk chunk = getSvc().onWorkChunkDequeue(myChunkId).orElseThrow(IllegalArgumentException::new);
+ WorkChunk chunk = getTestManager().getSvc().onWorkChunkDequeue(myChunkId).orElseThrow(IllegalArgumentException::new);
// then
assertEquals(WorkChunkStatusEnum.IN_PROGRESS, chunk.getStatus());
// verify the db state, error message, and error count
- var workChunkEntity = freshFetchWorkChunk(myChunkId);
+ var workChunkEntity = getTestManager().freshFetchWorkChunk(myChunkId);
assertEquals(WorkChunkStatusEnum.IN_PROGRESS, workChunkEntity.getStatus());
assertEquals(FIRST_ERROR_MESSAGE, workChunkEntity.getErrorMessage(), "Original error message kept");
assertEquals(1, workChunkEntity.getErrorCount(), "error count kept");
@@ -37,19 +56,19 @@ public interface IWorkChunkErrorActionsTests extends IWorkChunkCommon, WorkChunk
@Test
default void errorRetry_repeatError_increasesErrorCount() {
- String jobId = createAndStoreJobInstance(null);
- String myChunkId = createAndDequeueWorkChunk(jobId);
- getSvc().onWorkChunkError(new WorkChunkErrorEvent(myChunkId, FIRST_ERROR_MESSAGE));
+ String jobId = getTestManager().createAndStoreJobInstance(null);
+ String myChunkId = getTestManager().createAndDequeueWorkChunk(jobId);
+ getTestManager().getSvc().onWorkChunkError(new WorkChunkErrorEvent(myChunkId, FIRST_ERROR_MESSAGE));
// setup - the consumer is re-trying, and marks it IN_PROGRESS
- getSvc().onWorkChunkDequeue(myChunkId);
+ getTestManager().getSvc().onWorkChunkDequeue(myChunkId);
// when another error happens
- getSvc().onWorkChunkError(new WorkChunkErrorEvent(myChunkId, ERROR_MESSAGE_B));
+ getTestManager().getSvc().onWorkChunkError(new WorkChunkErrorEvent(myChunkId, ERROR_MESSAGE_B));
// verify the state, new message, and error count
- var workChunkEntity = freshFetchWorkChunk(myChunkId);
+ var workChunkEntity = getTestManager().freshFetchWorkChunk(myChunkId);
assertEquals(WorkChunkStatusEnum.ERRORED, workChunkEntity.getStatus());
assertEquals(ERROR_MESSAGE_B, workChunkEntity.getErrorMessage(), "new error message");
assertEquals(2, workChunkEntity.getErrorCount(), "error count inc");
@@ -57,18 +76,18 @@ public interface IWorkChunkErrorActionsTests extends IWorkChunkCommon, WorkChunk
@Test
default void errorThenRetryAndComplete_addsErrorCounts() {
- String jobId = createAndStoreJobInstance(null);
- String myChunkId = createAndDequeueWorkChunk(jobId);
- getSvc().onWorkChunkError(new WorkChunkErrorEvent(myChunkId, FIRST_ERROR_MESSAGE));
+ String jobId = getTestManager().createAndStoreJobInstance(null);
+ String myChunkId = getTestManager().createAndDequeueWorkChunk(jobId);
+ getTestManager().getSvc().onWorkChunkError(new WorkChunkErrorEvent(myChunkId, FIRST_ERROR_MESSAGE));
// setup - the consumer is re-trying, and marks it IN_PROGRESS
- getSvc().onWorkChunkDequeue(myChunkId);
+ getTestManager().getSvc().onWorkChunkDequeue(myChunkId);
// then it completes ok.
- getSvc().onWorkChunkCompletion(new WorkChunkCompletionEvent(myChunkId, 3, 1));
+ getTestManager().getSvc().onWorkChunkCompletion(new WorkChunkCompletionEvent(myChunkId, 3, 1));
// verify the state, new message, and error count
- var workChunkEntity = freshFetchWorkChunk(myChunkId);
+ var workChunkEntity = getTestManager().freshFetchWorkChunk(myChunkId);
assertEquals(WorkChunkStatusEnum.COMPLETED, workChunkEntity.getStatus());
assertEquals(FIRST_ERROR_MESSAGE, workChunkEntity.getErrorMessage(), "Error message kept.");
assertEquals(2, workChunkEntity.getErrorCount(), "error combined with earlier error");
@@ -77,28 +96,28 @@ public interface IWorkChunkErrorActionsTests extends IWorkChunkCommon, WorkChunk
@Test
default void errorRetry_maxErrors_movesToFailed() {
// we start with 1 error already
- String jobId = createAndStoreJobInstance(null);
- String myChunkId = createAndDequeueWorkChunk(jobId);
- getSvc().onWorkChunkError(new WorkChunkErrorEvent(myChunkId, FIRST_ERROR_MESSAGE));
+ String jobId = getTestManager().createAndStoreJobInstance(null);
+ String myChunkId = getTestManager().createAndDequeueWorkChunk(jobId);
+ getTestManager().getSvc().onWorkChunkError(new WorkChunkErrorEvent(myChunkId, FIRST_ERROR_MESSAGE));
// 2nd try
- getSvc().onWorkChunkDequeue(myChunkId);
- getSvc().onWorkChunkError(new WorkChunkErrorEvent(myChunkId, ERROR_MESSAGE_B));
- var chunk = freshFetchWorkChunk(myChunkId);
+ getTestManager().getSvc().onWorkChunkDequeue(myChunkId);
+ getTestManager().getSvc().onWorkChunkError(new WorkChunkErrorEvent(myChunkId, ERROR_MESSAGE_B));
+ var chunk = getTestManager().freshFetchWorkChunk(myChunkId);
assertEquals(WorkChunkStatusEnum.ERRORED, chunk.getStatus());
assertEquals(2, chunk.getErrorCount());
// 3rd try
- getSvc().onWorkChunkDequeue(myChunkId);
- getSvc().onWorkChunkError(new WorkChunkErrorEvent(myChunkId, ERROR_MESSAGE_B));
- chunk = freshFetchWorkChunk(myChunkId);
+ getTestManager().getSvc().onWorkChunkDequeue(myChunkId);
+ getTestManager().getSvc().onWorkChunkError(new WorkChunkErrorEvent(myChunkId, ERROR_MESSAGE_B));
+ chunk = getTestManager().freshFetchWorkChunk(myChunkId);
assertEquals(WorkChunkStatusEnum.ERRORED, chunk.getStatus());
assertEquals(3, chunk.getErrorCount());
// 4th try
- getSvc().onWorkChunkDequeue(myChunkId);
- getSvc().onWorkChunkError(new WorkChunkErrorEvent(myChunkId, ERROR_MESSAGE_C));
- chunk = freshFetchWorkChunk(myChunkId);
+ getTestManager().getSvc().onWorkChunkDequeue(myChunkId);
+ getTestManager().getSvc().onWorkChunkError(new WorkChunkErrorEvent(myChunkId, ERROR_MESSAGE_C));
+ chunk = getTestManager().freshFetchWorkChunk(myChunkId);
assertEquals(WorkChunkStatusEnum.FAILED, chunk.getStatus());
assertEquals(4, chunk.getErrorCount());
assertThat("Error message contains last error", chunk.getErrorMessage(), containsString(ERROR_MESSAGE_C));
diff --git a/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/IWorkChunkStateTransitions.java b/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/IWorkChunkStateTransitions.java
index 5be2ce0596d..4a5014e5ced 100644
--- a/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/IWorkChunkStateTransitions.java
+++ b/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/IWorkChunkStateTransitions.java
@@ -1,5 +1,27 @@
+/*-
+ * #%L
+ * HAPI FHIR JPA Server - Batch2 specification tests
+ * %%
+ * 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.hapi.fhir.batch2.test;
+import ca.uhn.fhir.batch2.model.WorkChunk;
+import ca.uhn.fhir.batch2.model.WorkChunkStatusEnum;
+
import ca.uhn.fhir.batch2.model.JobDefinition;
import ca.uhn.fhir.batch2.model.WorkChunk;
import ca.uhn.fhir.batch2.model.WorkChunkStatusEnum;
@@ -17,38 +39,38 @@ public interface IWorkChunkStateTransitions extends IWorkChunkCommon, WorkChunkT
@Test
default void chunkCreation_isQueued() {
- String jobInstanceId = createAndStoreJobInstance(null);
- String myChunkId = createChunk(jobInstanceId);
+ String jobInstanceId = getTestManager().createAndStoreJobInstance(null);
+ String myChunkId = getTestManager().createChunk(jobInstanceId);
- WorkChunk fetchedWorkChunk = freshFetchWorkChunk(myChunkId);
+ WorkChunk fetchedWorkChunk = getTestManager().freshFetchWorkChunk(myChunkId);
assertEquals(WorkChunkStatusEnum.READY, fetchedWorkChunk.getStatus(), "New chunks are READY");
}
@Test
default void chunkReceived_queuedToInProgress() throws InterruptedException {
- PointcutLatch sendLatch = disableWorkChunkMessageHandler();
+ PointcutLatch sendLatch = getTestManager().disableWorkChunkMessageHandler();
sendLatch.setExpectedCount(1);
- String jobInstanceId = createAndStoreJobInstance(null);
- String myChunkId = createChunk(jobInstanceId);
+ String jobInstanceId = getTestManager().createAndStoreJobInstance(null);
+ String myChunkId = getTestManager().createChunk(jobInstanceId);
- runMaintenancePass();
+ getTestManager().runMaintenancePass();
// the worker has received the chunk, and marks it started.
- WorkChunk chunk = getSvc().onWorkChunkDequeue(myChunkId).orElseThrow(IllegalArgumentException::new);
+ WorkChunk chunk = getTestManager().getSvc().onWorkChunkDequeue(myChunkId).orElseThrow(IllegalArgumentException::new);
assertEquals(WorkChunkStatusEnum.IN_PROGRESS, chunk.getStatus());
assertEquals(CHUNK_DATA, chunk.getData());
// verify the db was updated too
- WorkChunk fetchedWorkChunk = freshFetchWorkChunk(myChunkId);
+ WorkChunk fetchedWorkChunk = getTestManager().freshFetchWorkChunk(myChunkId);
assertEquals(WorkChunkStatusEnum.IN_PROGRESS, fetchedWorkChunk.getStatus());
- verifyWorkChunkMessageHandlerCalled(sendLatch, 1);
+ getTestManager().verifyWorkChunkMessageHandlerCalled(sendLatch, 1);
}
@Test
default void enqueueWorkChunkForProcessing_enqueuesOnlyREADYChunks() throws InterruptedException {
// setup
- disableWorkChunkMessageHandler();
- enableMaintenanceRunner(false);
+ getTestManager().disableWorkChunkMessageHandler();
+ getTestManager().enableMaintenanceRunner(false);
StringBuilder sb = new StringBuilder();
// first step is always complete
@@ -62,20 +84,20 @@ public interface IWorkChunkStateTransitions extends IWorkChunkCommon, WorkChunkT
.append(status.name());
}
String state = sb.toString();
- JobDefinition> jobDef = withJobDefinition(false);
- String instanceId = createAndStoreJobInstance(jobDef);
+ JobDefinition> jobDef = getTestManager().withJobDefinition(false);
+ String instanceId = getTestManager().createAndStoreJobInstance(jobDef);
JobMaintenanceStateInformation stateInformation = new JobMaintenanceStateInformation(
instanceId,
jobDef,
state
);
- createChunksInStates(stateInformation);
+ getTestManager().createChunksInStates(stateInformation);
// test
PointcutLatch latch = new PointcutLatch(new Exception().getStackTrace()[0].getMethodName());
latch.setExpectedCount(stateInformation.getInitialWorkChunks().size());
for (WorkChunk chunk : stateInformation.getInitialWorkChunks()) {
- getSvc().enqueueWorkChunkForProcessing(chunk.getId(), updated -> {
+ getTestManager().getSvc().enqueueWorkChunkForProcessing(chunk.getId(), updated -> {
// should not update non-ready chunks
ourLog.info("Enqueuing chunk with state {}; updated {}", chunk.getStatus().name(), updated);
int expected = chunk.getStatus() == WorkChunkStatusEnum.READY ? 1 : 0;
diff --git a/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/IWorkChunkStorageTests.java b/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/IWorkChunkStorageTests.java
index 80119ffbdf3..f0e45bfbf5d 100644
--- a/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/IWorkChunkStorageTests.java
+++ b/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/IWorkChunkStorageTests.java
@@ -1,5 +1,30 @@
+/*-
+ * #%L
+ * HAPI FHIR JPA Server - Batch2 specification tests
+ * %%
+ * 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.hapi.fhir.batch2.test;
+import ca.uhn.fhir.batch2.model.JobInstance;
+import ca.uhn.fhir.batch2.model.WorkChunk;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertNull;
+
import ca.uhn.fhir.batch2.model.JobDefinition;
import ca.uhn.fhir.batch2.model.JobInstance;
import ca.uhn.fhir.batch2.model.JobWorkNotification;
@@ -31,12 +56,12 @@ public interface IWorkChunkStorageTests extends IWorkChunkCommon, WorkChunkTestC
@Test
default void testStoreAndFetchWorkChunk_NoData() {
JobInstance instance = createInstance();
- String instanceId = getSvc().storeNewInstance(instance);
+ String instanceId = getTestManager().getSvc().storeNewInstance(instance);
- String id = storeWorkChunk(JOB_DEFINITION_ID, TARGET_STEP_ID, instanceId, 0, null);
+ String id = getTestManager().storeWorkChunk(JOB_DEFINITION_ID, TARGET_STEP_ID, instanceId, 0, null);
- runInTransaction(() -> {
- WorkChunk chunk = freshFetchWorkChunk(id);
+ getTestManager().runInTransaction(() -> {
+ WorkChunk chunk = getTestManager().freshFetchWorkChunk(id);
assertNull(chunk.getData());
});
}
@@ -44,50 +69,50 @@ public interface IWorkChunkStorageTests extends IWorkChunkCommon, WorkChunkTestC
@Test
default void testWorkChunkCreate_inReadyState() {
JobInstance instance = createInstance();
- String instanceId = getSvc().storeNewInstance(instance);
+ String instanceId = getTestManager().getSvc().storeNewInstance(instance);
- enableMaintenanceRunner(false);
+ getTestManager().enableMaintenanceRunner(false);
- String id = storeWorkChunk(JOB_DEFINITION_ID, TARGET_STEP_ID, instanceId, 0, CHUNK_DATA);
+ String id = getTestManager().storeWorkChunk(JOB_DEFINITION_ID, TARGET_STEP_ID, instanceId, 0, CHUNK_DATA);
assertNotNull(id);
- runInTransaction(() -> assertEquals(WorkChunkStatusEnum.READY, freshFetchWorkChunk(id).getStatus()));
+ getTestManager().runInTransaction(() -> assertEquals(WorkChunkStatusEnum.READY, freshFetchWorkChunk(id).getStatus()));
}
@Test
default void testNonGatedWorkChunkInReady_IsQueuedDuringMaintenance() throws InterruptedException {
// setup
int expectedCalls = 1;
- enableMaintenanceRunner(false);
- PointcutLatch sendingLatch = disableWorkChunkMessageHandler();
+ getTestManager().enableMaintenanceRunner(false);
+ PointcutLatch sendingLatch = getTestManager().disableWorkChunkMessageHandler();
sendingLatch.setExpectedCount(expectedCalls);
String state = "1|READY,1|QUEUED";
- JobDefinition> jobDefinition = withJobDefinition(false);
- String instanceId = createAndStoreJobInstance(jobDefinition);
+ JobDefinition> jobDefinition = getTestManager().withJobDefinition(false);
+ String instanceId = getTestManager().createAndStoreJobInstance(jobDefinition);
JobMaintenanceStateInformation stateInformation = new JobMaintenanceStateInformation(instanceId, jobDefinition, state);
- createChunksInStates(stateInformation);
+ getTestManager().createChunksInStates(stateInformation);
String id = stateInformation.getInitialWorkChunks().stream().findFirst().orElseThrow().getId();
// verify created in ready
- runInTransaction(() -> assertEquals(WorkChunkStatusEnum.READY, freshFetchWorkChunk(id).getStatus()));
+ getTestManager().runInTransaction(() -> assertEquals(WorkChunkStatusEnum.READY, freshFetchWorkChunk(id).getStatus()));
// test
- runMaintenancePass();
+ getTestManager().runMaintenancePass();
// verify it's in QUEUED now
- stateInformation.verifyFinalStates(getSvc());
- verifyWorkChunkMessageHandlerCalled(sendingLatch, expectedCalls);
+ stateInformation.verifyFinalStates(getTestManager().getSvc());
+ getTestManager().verifyWorkChunkMessageHandlerCalled(sendingLatch, expectedCalls);
}
@Test
default void testStoreAndFetchWorkChunk_WithData() {
// setup
- disableWorkChunkMessageHandler();
- enableMaintenanceRunner(false);
- JobDefinition> jobDefinition = withJobDefinition(false);
+ getTestManager().disableWorkChunkMessageHandler();
+ getTestManager().enableMaintenanceRunner(false);
+ JobDefinition> jobDefinition = getTestManager().withJobDefinition(false);
JobInstance instance = createInstance();
- String instanceId = getSvc().storeNewInstance(instance);
+ String instanceId = getTestManager().getSvc().storeNewInstance(instance);
// we're not transitioning this state; we're just checking storage of data
JobMaintenanceStateInformation info = new JobMaintenanceStateInformation(instanceId, jobDefinition, "1|QUEUED");
@@ -95,11 +120,11 @@ public interface IWorkChunkStorageTests extends IWorkChunkCommon, WorkChunkTestC
chunk.setData(CHUNK_DATA);
});
- createChunksInStates(info);
+ getTestManager().createChunksInStates(info);
String id = info.getInitialWorkChunks().stream().findFirst().orElseThrow().getId();
// verify created in QUEUED
- runInTransaction(() -> assertEquals(WorkChunkStatusEnum.QUEUED, freshFetchWorkChunk(id).getStatus()));
+ getTestManager().runInTransaction(() -> assertEquals(WorkChunkStatusEnum.QUEUED, freshFetchWorkChunk(id).getStatus()));
// test; manually dequeue chunk
WorkChunk chunk = getSvc().onWorkChunkDequeue(id).orElseThrow(IllegalArgumentException::new);
@@ -111,33 +136,33 @@ public interface IWorkChunkStorageTests extends IWorkChunkCommon, WorkChunkTestC
assertEquals(WorkChunkStatusEnum.IN_PROGRESS, chunk.getStatus());
assertEquals(CHUNK_DATA, chunk.getData());
- runInTransaction(() -> assertEquals(WorkChunkStatusEnum.IN_PROGRESS, freshFetchWorkChunk(id).getStatus()));
+ getTestManager().runInTransaction(() -> assertEquals(WorkChunkStatusEnum.IN_PROGRESS, freshFetchWorkChunk(id).getStatus()));
}
@Test
default void testMarkChunkAsCompleted_Success() {
// setup
String state = "2|IN_PROGRESS,2|COMPLETED";
- disableWorkChunkMessageHandler();
- enableMaintenanceRunner(false);
+ getTestManager().disableWorkChunkMessageHandler();
+ getTestManager().enableMaintenanceRunner(false);
- JobDefinition> jobDefinition = withJobDefinition(false);
- String instanceId = createAndStoreJobInstance(jobDefinition);
+ JobDefinition> jobDefinition = getTestManager().withJobDefinition(false);
+ String instanceId = getTestManager().createAndStoreJobInstance(jobDefinition);
JobMaintenanceStateInformation info = new JobMaintenanceStateInformation(instanceId, jobDefinition, state);
info.addWorkChunkModifier(chunk -> {
chunk.setCreateTime(new Date());
chunk.setData(CHUNK_DATA);
});
- createChunksInStates(info);
+ getTestManager().createChunksInStates(info);
String chunkId = info.getInitialWorkChunks().stream().findFirst().orElseThrow().getId();
// run test
- runInTransaction(() -> getSvc().onWorkChunkCompletion(new WorkChunkCompletionEvent(chunkId, 50, 0)));
+ getTestManager().runInTransaction(() -> getTestManager().getSvc().onWorkChunkCompletion(new WorkChunkCompletionEvent(chunkId, 50, 0)));
// verify
- info.verifyFinalStates(getSvc());
- WorkChunk entity = freshFetchWorkChunk(chunkId);
+ info.verifyFinalStates(getTestManager().getSvc());
+ WorkChunk entity = getTestManager().freshFetchWorkChunk(chunkId);
assertEquals(WorkChunkStatusEnum.COMPLETED, entity.getStatus());
assertEquals(50, entity.getRecordsProcessed());
assertNotNull(entity.getCreateTime());
@@ -148,21 +173,21 @@ public interface IWorkChunkStorageTests extends IWorkChunkCommon, WorkChunkTestC
default void testMarkChunkAsCompleted_Error() {
// setup
String state = "1|IN_PROGRESS,1|ERRORED";
- disableWorkChunkMessageHandler();
- enableMaintenanceRunner(false);
- JobDefinition> jobDef = withJobDefinition(false);
- String instanceId = createAndStoreJobInstance(jobDef);
+ getTestManager().disableWorkChunkMessageHandler();
+ getTestManager().enableMaintenanceRunner(false);
+ JobDefinition> jobDef = getTestManager().withJobDefinition(false);
+ String instanceId = getTestManager().createAndStoreJobInstance(jobDef);
JobMaintenanceStateInformation info = new JobMaintenanceStateInformation(
instanceId, jobDef, state
);
- createChunksInStates(info);
+ getTestManager().createChunksInStates(info);
String chunkId = info.getInitialWorkChunks().stream().findFirst().orElseThrow().getId();
// test
WorkChunkErrorEvent request = new WorkChunkErrorEvent(chunkId, ERROR_MESSAGE_A);
- getSvc().onWorkChunkError(request);
- runInTransaction(() -> {
- WorkChunk entity = freshFetchWorkChunk(chunkId);
+ getTestManager().getSvc().onWorkChunkError(request);
+ getTestManager().runInTransaction(() -> {
+ WorkChunk entity = getTestManager().freshFetchWorkChunk(chunkId);
assertEquals(WorkChunkStatusEnum.ERRORED, entity.getStatus());
assertEquals(ERROR_MESSAGE_A, entity.getErrorMessage());
assertEquals(1, entity.getErrorCount());
@@ -171,46 +196,46 @@ public interface IWorkChunkStorageTests extends IWorkChunkCommon, WorkChunkTestC
// Mark errored again
WorkChunkErrorEvent request2 = new WorkChunkErrorEvent(chunkId, "This is an error message 2");
- getSvc().onWorkChunkError(request2);
- runInTransaction(() -> {
- WorkChunk entity = freshFetchWorkChunk(chunkId);
+ getTestManager().getSvc().onWorkChunkError(request2);
+ getTestManager().runInTransaction(() -> {
+ WorkChunk entity = getTestManager().freshFetchWorkChunk(chunkId);
assertEquals(WorkChunkStatusEnum.ERRORED, entity.getStatus());
assertEquals("This is an error message 2", entity.getErrorMessage());
assertEquals(2, entity.getErrorCount());
});
- List chunks = ImmutableList.copyOf(getSvc().fetchAllWorkChunksIterator(instanceId, true));
+ List chunks = ImmutableList.copyOf(getTestManager().getSvc().fetchAllWorkChunksIterator(instanceId, true));
assertEquals(1, chunks.size());
assertEquals(2, chunks.get(0).getErrorCount());
- info.verifyFinalStates(getSvc());
+ info.verifyFinalStates(getTestManager().getSvc());
}
@Test
default void testMarkChunkAsCompleted_Fail() {
// setup
String state = "1|IN_PROGRESS,1|FAILED";
- disableWorkChunkMessageHandler();
- enableMaintenanceRunner(false);
- JobDefinition> jobDef = withJobDefinition(false);
- String instanceId = createAndStoreJobInstance(jobDef);
+ getTestManager().disableWorkChunkMessageHandler();
+ getTestManager().enableMaintenanceRunner(false);
+ JobDefinition> jobDef = getTestManager().withJobDefinition(false);
+ String instanceId = getTestManager().createAndStoreJobInstance(jobDef);
JobMaintenanceStateInformation info = new JobMaintenanceStateInformation(
instanceId, jobDef, state
);
- createChunksInStates(info);
+ getTestManager().createChunksInStates(info);
String chunkId = info.getInitialWorkChunks().stream().findFirst().orElseThrow().getId();
// test
- getSvc().onWorkChunkFailed(chunkId, "This is an error message");
+ getTestManager().getSvc().onWorkChunkFailed(chunkId, "This is an error message");
// verify
- runInTransaction(() -> {
- WorkChunk entity = freshFetchWorkChunk(chunkId);
+ getTestManager().runInTransaction(() -> {
+ WorkChunk entity = getTestManager().freshFetchWorkChunk(chunkId);
assertEquals(WorkChunkStatusEnum.FAILED, entity.getStatus());
assertEquals("This is an error message", entity.getErrorMessage());
});
- info.verifyFinalStates(getSvc());
+ info.verifyFinalStates(getTestManager().getSvc());
}
@Test
@@ -222,20 +247,20 @@ public interface IWorkChunkStorageTests extends IWorkChunkCommon, WorkChunkTestC
1|QUEUED,1|COMPLETED
1|IN_PROGRESS,1|COMPLETED
""";
- disableWorkChunkMessageHandler();
- enableMaintenanceRunner(false);
- JobDefinition> jobDef = withJobDefinition(false);
- String instanceId = createAndStoreJobInstance(jobDef);
+ getTestManager().disableWorkChunkMessageHandler();
+ getTestManager().enableMaintenanceRunner(false);
+ JobDefinition> jobDef = getTestManager().withJobDefinition(false);
+ String instanceId = getTestManager().createAndStoreJobInstance(jobDef);
JobMaintenanceStateInformation info = new JobMaintenanceStateInformation(
instanceId, jobDef, state
);
- createChunksInStates(info);
+ getTestManager().createChunksInStates(info);
List chunkIds = info.getInitialWorkChunks().stream().map(WorkChunk::getId)
.collect(Collectors.toList());
- runInTransaction(() -> getSvc().markWorkChunksWithStatusAndWipeData(instanceId, chunkIds, WorkChunkStatusEnum.COMPLETED, null));
+ getTestManager().runInTransaction(() -> getTestManager().getSvc().markWorkChunksWithStatusAndWipeData(instanceId, chunkIds, WorkChunkStatusEnum.COMPLETED, null));
- Iterator reducedChunks = getSvc().fetchAllWorkChunksIterator(instanceId, true);
+ Iterator reducedChunks = getTestManager().getSvc().fetchAllWorkChunksIterator(instanceId, true);
while (reducedChunks.hasNext()) {
WorkChunk reducedChunk = reducedChunks.next();
diff --git a/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/WorkChunkTestConstants.java b/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/WorkChunkTestConstants.java
index 9f5df3120ff..8ab0157e52b 100644
--- a/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/WorkChunkTestConstants.java
+++ b/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/WorkChunkTestConstants.java
@@ -1,3 +1,22 @@
+/*-
+ * #%L
+ * HAPI FHIR JPA Server - Batch2 specification tests
+ * %%
+ * 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.hapi.fhir.batch2.test;
public interface WorkChunkTestConstants {
diff --git a/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/configs/SpyOverrideConfig.java b/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/configs/SpyOverrideConfig.java
index 46331d1c219..91735cd0414 100644
--- a/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/configs/SpyOverrideConfig.java
+++ b/hapi-fhir-storage-batch2-test-utilities/src/main/java/ca/uhn/hapi/fhir/batch2/test/configs/SpyOverrideConfig.java
@@ -1,3 +1,22 @@
+/*-
+ * #%L
+ * HAPI FHIR JPA Server - Batch2 specification tests
+ * %%
+ * 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.hapi.fhir.batch2.test.configs;
import ca.uhn.fhir.batch2.channel.BatchJobSender;
diff --git a/hapi-fhir-storage-batch2/pom.xml b/hapi-fhir-storage-batch2/pom.xml
index 2d86204e222..7890ad1bfa3 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-storage-batch2/src/main/java/ca/uhn/fhir/batch2/coordinator/ReductionStepExecutorServiceImpl.java b/hapi-fhir-storage-batch2/src/main/java/ca/uhn/fhir/batch2/coordinator/ReductionStepExecutorServiceImpl.java
index c341fb0e48a..fcdfb1ca9f9 100644
--- a/hapi-fhir-storage-batch2/src/main/java/ca/uhn/fhir/batch2/coordinator/ReductionStepExecutorServiceImpl.java
+++ b/hapi-fhir-storage-batch2/src/main/java/ca/uhn/fhir/batch2/coordinator/ReductionStepExecutorServiceImpl.java
@@ -30,6 +30,7 @@ import ca.uhn.fhir.batch2.model.ChunkOutcome;
import ca.uhn.fhir.batch2.model.JobDefinitionStep;
import ca.uhn.fhir.batch2.model.JobInstance;
import ca.uhn.fhir.batch2.model.JobWorkCursor;
+import ca.uhn.fhir.batch2.model.StatusEnum;
import ca.uhn.fhir.batch2.model.WorkChunk;
import ca.uhn.fhir.batch2.model.WorkChunkStatusEnum;
import ca.uhn.fhir.jpa.dao.tx.IHapiTransactionService;
@@ -137,7 +138,6 @@ public class ReductionStepExecutorServiceImpl implements IReductionStepExecutorS
public void reducerPass() {
if (myCurrentlyExecuting.tryAcquire()) {
try {
-
String[] instanceIds = myInstanceIdToJobWorkCursor.keySet().toArray(new String[0]);
if (instanceIds.length > 0) {
String instanceId = instanceIds[0];
@@ -214,6 +214,36 @@ public class ReductionStepExecutorServiceImpl implements IReductionStepExecutorS
boolean defaultSuccessValue = true;
ReductionStepChunkProcessingResponse response = new ReductionStepChunkProcessingResponse(defaultSuccessValue);
+ try {
+ processChunksAndCompleteJob(theJobWorkCursor, step, instance, parameters, reductionStepWorker, response);
+ } catch (Exception ex) {
+ ourLog.error("Job completion failed for Job {}", instance.getInstanceId());
+
+ executeInTransactionWithSynchronization(() -> {
+ myJobPersistence.updateInstance(instance.getInstanceId(), theInstance -> {
+ theInstance.setStatus(StatusEnum.FAILED);
+ return true;
+ });
+ return null;
+ });
+ response.setSuccessful(false);
+ }
+
+ // if no successful chunks, return false
+ if (!response.hasSuccessfulChunksIds()) {
+ response.setSuccessful(false);
+ }
+
+ return response;
+ }
+
+ private void processChunksAndCompleteJob(
+ JobWorkCursor theJobWorkCursor,
+ JobDefinitionStep step,
+ JobInstance instance,
+ PT parameters,
+ IReductionStepWorker reductionStepWorker,
+ ReductionStepChunkProcessingResponse response) {
try {
executeInTransactionWithSynchronization(() -> {
try (Stream chunkIterator =
@@ -277,13 +307,6 @@ public class ReductionStepExecutorServiceImpl implements IReductionStepExecutorS
return null;
});
}
-
- // if no successful chunks, return false
- if (!response.hasSuccessfulChunksIds()) {
- response.setSuccessful(false);
- }
-
- return response;
}
private T executeInTransactionWithSynchronization(Callable runnable) {
diff --git a/hapi-fhir-storage-cr/pom.xml b/hapi-fhir-storage-cr/pom.xml
index deec953b4d9..30a4b7d9731 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-storage-mdm/pom.xml b/hapi-fhir-storage-mdm/pom.xml
index aaaffd4dfe4..21684ec422d 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-storage-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmSubmitterInterceptorLoader.java b/hapi-fhir-storage-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmSubmitterInterceptorLoader.java
index f65d49ab408..58def7ad3cb 100644
--- a/hapi-fhir-storage-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmSubmitterInterceptorLoader.java
+++ b/hapi-fhir-storage-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmSubmitterInterceptorLoader.java
@@ -41,8 +41,8 @@ public class MdmSubmitterInterceptorLoader {
@Autowired
JpaStorageSettings myStorageSettings;
- @Autowired
- private IMdmStorageInterceptor myIMdmStorageInterceptor;
+ @Autowired(required = false)
+ private IMdmStorageInterceptor myMdmStorageInterceptor;
@Autowired
private MdmSearchExpandingInterceptor myMdmSearchExpandingInterceptorInterceptor;
@@ -60,7 +60,9 @@ public class MdmSubmitterInterceptorLoader {
throw new ConfigurationException(
Msg.code(2421) + "MDM requires Message Subscriptions to be enabled in the Storage Settings");
}
- myInterceptorService.registerInterceptor(myIMdmStorageInterceptor);
+ if (myMdmStorageInterceptor != null) {
+ myInterceptorService.registerInterceptor(myMdmStorageInterceptor);
+ }
myInterceptorService.registerInterceptor(myMdmSearchExpandingInterceptorInterceptor);
ourLog.info("MDM interceptors registered");
}
diff --git a/hapi-fhir-storage-test-utilities/pom.xml b/hapi-fhir-storage-test-utilities/pom.xml
index 97697fbeceb..ba4f65c01e5 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-storage/pom.xml b/hapi-fhir-storage/pom.xml
index 96682b6343b..7090925bf5f 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-dstu2.1/pom.xml b/hapi-fhir-structures-dstu2.1/pom.xml
index 541a22ad700..146924739b1 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-dstu2/pom.xml b/hapi-fhir-structures-dstu2/pom.xml
index 0dab5394bcd..76dadd587ec 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/provider/ObservableSupplierSetTest.java b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/provider/ObservableSupplierSetTest.java
new file mode 100644
index 00000000000..d13a161141c
--- /dev/null
+++ b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/provider/ObservableSupplierSetTest.java
@@ -0,0 +1,102 @@
+package ca.uhn.fhir.rest.server.provider;
+
+import ca.uhn.test.util.LogbackCaptureTestExtension;
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import org.jetbrains.annotations.NotNull;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Supplier;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasSize;
+import static org.junit.jupiter.api.Assertions.*;
+
+class ObservableSupplierSetTest {
+
+ private final ObservableSupplierSet myObservableSupplierSet = new ObservableSupplierSet<>();
+ private final TestObserver myObserver = new TestObserver();
+ private final AtomicInteger myCounter = new AtomicInteger();
+
+ @RegisterExtension
+ final LogbackCaptureTestExtension myLogger = new LogbackCaptureTestExtension((ch.qos.logback.classic.Logger) LoggerFactory.getLogger(ObservableSupplierSet.class));
+
+ @BeforeEach
+ public void before() {
+ myObservableSupplierSet.attach(myObserver);
+ myObserver.assertCalls(0, 0);
+ }
+
+ @Test
+ public void observersNotifiedByAddRemove() {
+ Supplier supplier = myCounter::incrementAndGet;
+ myObservableSupplierSet.addSupplier(supplier);
+ myObserver.assertCalls(1, 0);
+ assertEquals(0, myCounter.get());
+ assertThat(myObservableSupplierSet.getSupplierResults(), hasSize(1));
+ assertEquals(1, myCounter.get());
+ myObservableSupplierSet.removeSupplier(supplier);
+ myObserver.assertCalls(1, 1);
+ assertThat(myObservableSupplierSet.getSupplierResults(), hasSize(0));
+ }
+
+ @Test
+ public void testRemoveWrongSupplier() {
+ myObservableSupplierSet.addSupplier(myCounter::incrementAndGet);
+ myObserver.assertCalls(1, 0);
+ assertEquals(0, myCounter.get());
+ assertThat(myObservableSupplierSet.getSupplierResults(), hasSize(1));
+ assertEquals(1, myCounter.get());
+
+ // You might expect this to remove our supplier, but in fact it is a different lambda, so it fails and logs a stack trace
+ myObservableSupplierSet.removeSupplier(myCounter::incrementAndGet);
+ myObserver.assertCalls(1, 0);
+ assertThat(myObservableSupplierSet.getSupplierResults(), hasSize(1));
+ List events = myLogger.filterLoggingEventsWithMessageContaining("Failed to remove supplier");
+ assertThat(events, hasSize(1));
+ assertEquals(Level.WARN, events.get(0).getLevel());
+ }
+
+ @Test
+ public void testDetach() {
+ myObservableSupplierSet.addSupplier(myCounter::incrementAndGet);
+ myObserver.assertCalls(1, 0);
+ assertThat(myObservableSupplierSet.getSupplierResults(), hasSize(1));
+
+ myObservableSupplierSet.addSupplier(myCounter::incrementAndGet);
+ myObserver.assertCalls(2, 0);
+ assertThat(myObservableSupplierSet.getSupplierResults(), hasSize(2));
+
+ myObservableSupplierSet.detach(myObserver);
+
+ // We now have a third supplier but the observer has been detached, so it was not notified of the third supplier
+ myObservableSupplierSet.addSupplier(myCounter::incrementAndGet);
+ myObserver.assertCalls(2, 0);
+ assertThat(myObservableSupplierSet.getSupplierResults(), hasSize(3));
+ }
+
+ private static class TestObserver implements IObservableSupplierSetObserver {
+ int updated = 0;
+ int removed = 0;
+
+ @Override
+ public void update(@NotNull Supplier theSupplier) {
+ ++updated;
+ }
+
+ @Override
+ public void remove(@NotNull Supplier theSupplier) {
+ ++removed;
+ }
+
+ public void assertCalls(int theExpectedUpdated, int theExpectedRemoved) {
+ assertEquals(theExpectedUpdated, updated);
+ assertEquals(theExpectedRemoved, removed);
+ }
+ }
+}
diff --git a/hapi-fhir-structures-dstu3/pom.xml b/hapi-fhir-structures-dstu3/pom.xml
index fc3ad9f5c7f..cfddebcbaae 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-hl7org-dstu2/pom.xml b/hapi-fhir-structures-hl7org-dstu2/pom.xml
index 04e09044793..3ec00da7fc7 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-r4/pom.xml b/hapi-fhir-structures-r4/pom.xml
index b4150ec9c38..55a7aeba956 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-r4b/pom.xml b/hapi-fhir-structures-r4b/pom.xml
index d852ad84473..73801c099d6 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-r5/pom.xml b/hapi-fhir-structures-r5/pom.xml
index 1c88c4f4869..67862c00146 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-test-utilities/pom.xml b/hapi-fhir-test-utilities/pom.xml
index ff040fa535c..eb4c71307da 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-test-utilities/src/main/java/ca/uhn/test/util/LogbackCaptureTestExtension.java b/hapi-fhir-test-utilities/src/main/java/ca/uhn/test/util/LogbackCaptureTestExtension.java
index f5f61161ba4..eb58685aad5 100644
--- a/hapi-fhir-test-utilities/src/main/java/ca/uhn/test/util/LogbackCaptureTestExtension.java
+++ b/hapi-fhir-test-utilities/src/main/java/ca/uhn/test/util/LogbackCaptureTestExtension.java
@@ -86,6 +86,14 @@ public class LogbackCaptureTestExtension implements BeforeEachCallback, AfterEac
this(theClass.getName());
}
+ public LogbackCaptureTestExtension(Class> theClass, Level theLevel) {
+ this(theClass.getName(), theLevel);
+ }
+
+ public LogbackCaptureTestExtension(org.slf4j.Logger theLogger) {
+ this((Logger) theLogger);
+ }
+
/**
* Returns a copy to avoid concurrent modification errors.
* @return A copy of the log events so far.
@@ -154,6 +162,16 @@ public class LogbackCaptureTestExtension implements BeforeEachCallback, AfterEac
.collect(Collectors.toList());
}
+ /**
+ * Extract the log messages from the logging events.
+ * @return a copy of the List of log messages
+ *
+ */
+ @Nonnull
+ public List getLogMessages() {
+ return getLogEvents().stream().map(ILoggingEvent::getMessage).collect(Collectors.toList());
+ }
+
// Hamcrest matcher support
public static Matcher eventWithLevelAndMessageContains(@Nonnull Level theLevel, @Nonnull String thePartialMessage) {
return new LogbackEventMatcher(theLevel, thePartialMessage);
diff --git a/hapi-fhir-test-utilities/src/main/java/ca/uhn/test/util/StaticLogbackCaptureTestExtension.java b/hapi-fhir-test-utilities/src/main/java/ca/uhn/test/util/StaticLogbackCaptureTestExtension.java
new file mode 100644
index 00000000000..9c8dda60674
--- /dev/null
+++ b/hapi-fhir-test-utilities/src/main/java/ca/uhn/test/util/StaticLogbackCaptureTestExtension.java
@@ -0,0 +1,39 @@
+package ca.uhn.test.util;
+
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import org.junit.jupiter.api.extension.AfterAllCallback;
+import org.junit.jupiter.api.extension.BeforeAllCallback;
+import org.junit.jupiter.api.extension.ExtensionContext;
+
+import java.util.List;
+
+/**
+ * This is a static wrapper around LogbackCaptureTestExtension for use in IT tests when you need to assert on App
+ * startup log entries
+ */
+
+public class StaticLogbackCaptureTestExtension implements BeforeAllCallback, AfterAllCallback {
+ private final LogbackCaptureTestExtension myLogbackCaptureTestExtension;
+
+ public StaticLogbackCaptureTestExtension(LogbackCaptureTestExtension theLogbackCaptureTestExtension) {
+ myLogbackCaptureTestExtension = theLogbackCaptureTestExtension;
+ }
+
+ public StaticLogbackCaptureTestExtension() {
+ myLogbackCaptureTestExtension = new LogbackCaptureTestExtension();
+ }
+
+ @Override
+ public void beforeAll(ExtensionContext theExtensionContext) throws Exception {
+ myLogbackCaptureTestExtension.beforeEach(theExtensionContext);
+ }
+
+ @Override
+ public void afterAll(ExtensionContext theExtensionContext) throws Exception {
+ myLogbackCaptureTestExtension.afterEach(theExtensionContext);
+ }
+
+ public List filterLoggingEventsWithMessageEqualTo(String theMessageText) {
+ return myLogbackCaptureTestExtension.filterLoggingEventsWithMessageEqualTo(theMessageText);
+ }
+}
diff --git a/hapi-fhir-testpage-overlay/pom.xml b/hapi-fhir-testpage-overlay/pom.xml
index 0081f27ff59..02489770f91 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../pom.xml
diff --git a/hapi-fhir-validation-resources-dstu2.1/pom.xml b/hapi-fhir-validation-resources-dstu2.1/pom.xml
index be3911ce0ac..22142383e08 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-validation-resources-dstu2/pom.xml b/hapi-fhir-validation-resources-dstu2/pom.xml
index ab34e8d8bcc..27b3b119848 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-validation-resources-dstu3/pom.xml b/hapi-fhir-validation-resources-dstu3/pom.xml
index 522ac2b450c..a33191a05ec 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-validation-resources-r4/pom.xml b/hapi-fhir-validation-resources-r4/pom.xml
index bb7ed613bb1..44b6a5f1805 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-validation-resources-r4b/pom.xml b/hapi-fhir-validation-resources-r4b/pom.xml
index fb7965abff1..d58235a44b1 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-validation-resources-r5/pom.xml b/hapi-fhir-validation-resources-r5/pom.xml
index 11e616c37cd..3bde201665c 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-validation/pom.xml b/hapi-fhir-validation/pom.xml
index bd6a099c68c..b1432477175 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-tinder-plugin/pom.xml b/hapi-tinder-plugin/pom.xml
index 4fb7cf0d88e..368e8aaf6a9 100644
--- a/hapi-tinder-plugin/pom.xml
+++ b/hapi-tinder-plugin/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 7.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../pom.xml
diff --git a/hapi-tinder-plugin/src/main/resources/vm/jpa_resource_provider.vm b/hapi-tinder-plugin/src/main/resources/vm/jpa_resource_provider.vm
index 807fe45c5b0..421c2a663d9 100644
--- a/hapi-tinder-plugin/src/main/resources/vm/jpa_resource_provider.vm
+++ b/hapi-tinder-plugin/src/main/resources/vm/jpa_resource_provider.vm
@@ -73,11 +73,9 @@ public class ${className}ResourceProvider extends
@OptionalParam(name=ca.uhn.fhir.rest.api.Constants.PARAM_LIST)
StringAndListParam theList,
-#if ( $version == 'R5' )
@Description(shortDefinition="The language of the resource")
@OptionalParam(name=ca.uhn.fhir.rest.api.Constants.PARAM_LANGUAGE)
TokenAndListParam theResourceLanguage,
-#end
@Description(shortDefinition="Search for resources which have the given source value (Resource.meta.source)")
@OptionalParam(name=ca.uhn.fhir.rest.api.Constants.PARAM_SOURCE)
@@ -160,9 +158,8 @@ public class ${className}ResourceProvider extends
paramMap.add(ca.uhn.fhir.rest.api.Constants.PARAM_PROFILE, theSearchForProfile);
paramMap.add(ca.uhn.fhir.rest.api.Constants.PARAM_SOURCE, theSearchForSource);
paramMap.add(ca.uhn.fhir.rest.api.Constants.PARAM_LIST, theList);
-#if ( $version == 'R5' )
paramMap.add(ca.uhn.fhir.rest.api.Constants.PARAM_LANGUAGE, theResourceLanguage);
-#end
+
paramMap.add("_has", theHas);
#foreach ( $param in $searchParams )
paramMap.add("${param.name}", the${param.nameCapitalized});
diff --git a/hapi-tinder-test/pom.xml b/hapi-tinder-test/pom.xml
index 5f84df6f169..99a2b4d97a8 100644
--- a/hapi-tinder-test/pom.xml
+++ b/hapi-tinder-test/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 7.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../pom.xml
diff --git a/pom.xml b/pom.xml
index a3004385ff1..2ce4f6d190a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,7 +9,7 @@
ca.uhn.hapi.fhir
hapi-fhir
pom
- 7.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
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 5f119fcd90b..890e8f28ed4 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../../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 4250751cced..83b846622ad 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../../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 0fd0f7c3774..a4d48372ff5 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.1.7-SNAPSHOT
+ 7.1.8-SNAPSHOT
../../pom.xml