Fix transaction scoping (#2799)

* Work on transaction boundaries

* Test fixes

* Test fixes

* Test fix

* Resolve FIXME

* Test fix

* Test fix

* Test fix

* Test fixes

* Test fix

* Adjust changelog

* Remove unneeded changelog

* Test fix

* Test fixes

* Test fixes

* Test fixes

* Test fixes

* Test fix

* Fixes

* Test fix
This commit is contained in:
James Agnew 2021-10-11 16:45:22 -04:00 committed by GitHub
parent aed718bd6f
commit 756b0fdc7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
117 changed files with 989 additions and 783 deletions

View File

@ -0,0 +1,5 @@
---
type: fix
issue: 2799
title: "Certain ValueSet validation/expansion operations failed with a 'no transaction' error on
Postgresql. This has been corrected. Thanks to @tyfoni-systematic for reporting!"

View File

@ -33,6 +33,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.batch.item.ItemWriter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import java.util.List;
@ -51,6 +52,7 @@ public class BulkImportFileWriter implements ItemWriter<ParsedBulkImportRecord>
@SuppressWarnings({"SwitchStatementWithTooFewBranches", "rawtypes", "unchecked"})
@Override
public void write(List<? extends ParsedBulkImportRecord> theItemLists) throws Exception {
assert TransactionSynchronizationManager.isActualTransactionActive();
String offsets = "unknown";
if (theItemLists.size() > 0) {

View File

@ -34,8 +34,11 @@ import org.springframework.batch.core.configuration.annotation.StepBuilderFactor
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.core.partition.PartitionHandler;
import org.springframework.batch.core.partition.support.TaskExecutorPartitionHandler;
import org.springframework.batch.core.step.item.KeyGenerator;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.repeat.CompletionPolicy;
import org.springframework.batch.repeat.RepeatContext;
import org.springframework.batch.repeat.exception.ExceptionHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;

View File

@ -69,10 +69,15 @@ public class BulkImportStepListener implements StepExecutionListener, RetryListe
message.append("Error: ").append(nextErrorMessage).append("\n");
}
theStepExecution.addFailureException(new RuntimeException(message.toString()));
myBulkDataImportSvc.setJobToStatus(jobUuid, BulkImportJobStatusEnum.ERROR, message.toString());
ExitStatus exitStatus = ExitStatus.FAILED.addExitDescription(message.toString());
theStepExecution.setExitStatus(exitStatus);
// Replace the built-in error message with a better one
return ExitStatus.FAILED.addExitDescription(message.toString());
return exitStatus;
}
return theStepExecution.getExitStatus();

View File

@ -34,6 +34,7 @@ import org.hl7.fhir.instance.model.api.IIdType;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Nonnull;
import java.util.ArrayList;
@ -62,6 +63,7 @@ public class ResourceVersionSvcDaoImpl implements IResourceVersionSvc {
@Override
@Nonnull
@Transactional
public ResourceVersionMap getVersionMap(RequestPartitionId theRequestPartitionId, String theResourceName, SearchParameterMap theSearchParamMap) {
IFhirResourceDao<?> dao = myDaoRegistry.getResourceDao(theResourceName);

View File

@ -203,7 +203,7 @@ import java.util.Date;
@Configuration
@EnableJpaRepositories(basePackages = "ca.uhn.fhir.jpa.dao.data")
@EnableJpaRepositories(basePackages = "ca.uhn.fhir.jpa.dao.data", enableDefaultTransactions=true)
@Import({
SearchParamConfig.class, BatchJobsConfig.class
})

View File

@ -271,10 +271,12 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
ResourcePersistentId pid = match.iterator().next();
Supplier<LazyDaoMethodOutcome.EntityAndResource> entitySupplier = () -> {
ResourceTable foundEntity = myEntityManager.find(ResourceTable.class, pid.getId());
IBaseResource resource = toResource(foundEntity, false);
theResource.setId(resource.getIdElement().getValue());
return new LazyDaoMethodOutcome.EntityAndResource(foundEntity, resource);
return myTxTemplate.execute(tx -> {
ResourceTable foundEntity = myEntityManager.find(ResourceTable.class, pid.getId());
IBaseResource resource = toResource(foundEntity, false);
theResource.setId(resource.getIdElement().getValue());
return new LazyDaoMethodOutcome.EntityAndResource(foundEntity, resource);
});
};
Supplier<IIdType> idSupplier = () -> {

View File

@ -35,6 +35,7 @@ import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
import ca.uhn.fhir.rest.param.ReferenceParam;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.support.TransactionTemplate;
import java.util.ArrayList;
import java.util.Date;
@ -77,8 +78,10 @@ public abstract class BaseHapiFhirResourceDaoObservation<T extends IBaseResource
theSearchParameterMap.setLastN(true);
SortSpec effectiveDtm = new SortSpec(getEffectiveParamName()).setOrder(SortOrderEnum.DESC);
SortSpec observationCode = new SortSpec(getCodeParamName()).setOrder(SortOrderEnum.ASC).setChain(effectiveDtm);
if(theSearchParameterMap.containsKey(getSubjectParamName()) || theSearchParameterMap.containsKey(getPatientParamName())) {
fixSubjectParamsOrderForLastn(theSearchParameterMap, theRequestDetails);
if (theSearchParameterMap.containsKey(getSubjectParamName()) || theSearchParameterMap.containsKey(getPatientParamName())) {
new TransactionTemplate(myPlatformTransactionManager).executeWithoutResult(tx -> fixSubjectParamsOrderForLastn(theSearchParameterMap, theRequestDetails));
theSearchParameterMap.setSort(new SortSpec(getSubjectParamName()).setOrder(SortOrderEnum.ASC).setChain(observationCode));
} else {
theSearchParameterMap.setSort(observationCode);
@ -90,7 +93,7 @@ public abstract class BaseHapiFhirResourceDaoObservation<T extends IBaseResource
// the output. The reason for this is that observations are indexed by patient/subject forced ID, but then ordered in the
// final result set by subject/patient resource PID.
TreeMap<Long, IQueryParameterType> orderedSubjectReferenceMap = new TreeMap<>();
if(theSearchParameterMap.containsKey(getSubjectParamName())) {
if (theSearchParameterMap.containsKey(getSubjectParamName())) {
RequestPartitionId requestPartitionId = myRequestPartitionHelperService.determineReadPartitionForRequestForSearchType(theRequestDetails, getResourceName(), theSearchParameterMap, null);
@ -124,8 +127,11 @@ public abstract class BaseHapiFhirResourceDaoObservation<T extends IBaseResource
}
abstract protected String getEffectiveParamName();
abstract protected String getCodeParamName();
abstract protected String getSubjectParamName();
abstract protected String getPatientParamName();
}

View File

@ -54,6 +54,7 @@ import org.springframework.beans.factory.annotation.Qualifier;
import javax.annotation.Nonnull;
import javax.annotation.PostConstruct;
import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -230,12 +231,14 @@ public class FhirResourceDaoValueSetDstu2 extends BaseHapiFhirResourceDao<ValueS
@Nonnull
@Override
@Transactional
public IValidationSupport.LookupCodeResult lookupCode(IPrimitiveType<String> theCode, IPrimitiveType<String> theSystem, CodingDt theCoding, RequestDetails theRequest) {
return lookupCode(theCode, theSystem, theCoding, null, theRequest);
}
@Nonnull
@Override
@Transactional
public IValidationSupport.LookupCodeResult lookupCode(IPrimitiveType<String> theCode, IPrimitiveType<String> theSystem, CodingDt theCoding, IPrimitiveType<String> theDisplayLanguage, RequestDetails theRequest) {
boolean haveCoding = theCoding != null && isNotBlank(theCoding.getSystem()) && isNotBlank(theCoding.getCode());
boolean haveCode = theCode != null && theCode.isEmpty() == false;

View File

@ -28,7 +28,7 @@ import org.springframework.data.repository.query.Param;
import java.util.Optional;
public interface IBinaryStorageEntityDao extends JpaRepository<BinaryStorageEntity, String> {
public interface IBinaryStorageEntityDao extends JpaRepository<BinaryStorageEntity, String>, IHapiFhirJpaRepository {
@Query("SELECT e FROM BinaryStorageEntity e WHERE e.myBlobId = :blob_id AND e.myResourceId = :resource_id")
Optional<BinaryStorageEntity> findByIdAndResourceId(@Param("blob_id") String theBlobId, @Param("resource_id") String theResourceId);

View File

@ -26,7 +26,7 @@ import org.springframework.data.repository.query.Param;
* #L%
*/
public interface IBulkExportCollectionDao extends JpaRepository<BulkExportCollectionEntity, Long> {
public interface IBulkExportCollectionDao extends JpaRepository<BulkExportCollectionEntity, Long>, IHapiFhirJpaRepository {
@Modifying
@Query("DELETE FROM BulkExportCollectionEntity t")

View File

@ -26,7 +26,7 @@ import org.springframework.data.repository.query.Param;
* #L%
*/
public interface IBulkExportCollectionFileDao extends JpaRepository<BulkExportCollectionFileEntity, Long> {
public interface IBulkExportCollectionFileDao extends JpaRepository<BulkExportCollectionFileEntity, Long>, IHapiFhirJpaRepository {
@Modifying
@Query("DELETE FROM BulkExportCollectionFileEntity t")

View File

@ -32,7 +32,7 @@ import java.util.Optional;
* #L%
*/
public interface IBulkExportJobDao extends JpaRepository<BulkExportJobEntity, Long> {
public interface IBulkExportJobDao extends JpaRepository<BulkExportJobEntity, Long>, IHapiFhirJpaRepository {
@Query("SELECT j FROM BulkExportJobEntity j WHERE j.myJobId = :jobid")
Optional<BulkExportJobEntity> findByJobId(@Param("jobid") String theUuid);

View File

@ -30,7 +30,7 @@ import java.util.Optional;
* #L%
*/
public interface IBulkImportJobDao extends JpaRepository<BulkImportJobEntity, Long> {
public interface IBulkImportJobDao extends JpaRepository<BulkImportJobEntity, Long>, IHapiFhirJpaRepository {
@Query("SELECT j FROM BulkImportJobEntity j WHERE j.myJobId = :jobid")
Optional<BulkImportJobEntity> findByJobId(@Param("jobid") String theUuid);

View File

@ -29,7 +29,7 @@ import java.util.Optional;
* #L%
*/
public interface IBulkImportJobFileDao extends JpaRepository<BulkImportJobFileEntity, Long> {
public interface IBulkImportJobFileDao extends JpaRepository<BulkImportJobFileEntity, Long>, IHapiFhirJpaRepository {
@Query("SELECT f FROM BulkImportJobFileEntity f WHERE f.myJob.myJobId = :jobId ORDER BY f.myFileSequence ASC")
List<BulkImportJobFileEntity> findAllForJob(@Param("jobId") String theJobId);

View File

@ -30,26 +30,11 @@ import java.util.Optional;
* #L%
*/
public interface IForcedIdDao extends JpaRepository<ForcedId, Long> {
public interface IForcedIdDao extends JpaRepository<ForcedId, Long>, IHapiFhirJpaRepository {
@Query("SELECT f FROM ForcedId f WHERE myResourcePid IN (:resource_pids)")
List<ForcedId> findAllByResourcePid(@Param("resource_pids") List<Long> theResourcePids);
@Query("SELECT f.myResourcePid FROM ForcedId f WHERE myForcedId IN (:forced_id)")
List<Long> findByForcedId(@Param("forced_id") Collection<String> theForcedId);
@Query("SELECT f.myResourcePid FROM ForcedId f WHERE myResourceType = :resource_type AND myForcedId = :forced_id")
Optional<Long> findByTypeAndForcedId(@Param("resource_type") String theResourceType, @Param("forced_id") String theForcedId);
@Query("SELECT f.myResourcePid FROM ForcedId f WHERE myPartitionId.myPartitionId IS NULL AND myResourceType = :resource_type AND myForcedId = :forced_id")
Optional<Long> findByPartitionIdNullAndTypeAndForcedId(@Param("resource_type") String theResourceType, @Param("forced_id") String theForcedId);
@Query("SELECT f.myResourcePid FROM ForcedId f WHERE myPartitionId.myPartitionId IN :partition_id AND myResourceType = :resource_type AND myForcedId = :forced_id")
Optional<Long> findByPartitionIdAndTypeAndForcedId(@Param("partition_id") Collection<Integer> thePartitionId, @Param("resource_type") String theResourceType, @Param("forced_id") String theForcedId);
@Query("SELECT f.myResourcePid FROM ForcedId f WHERE (myPartitionId.myPartitionId IN :partition_id OR myPartitionId.myPartitionId IS NULL) AND myResourceType = :resource_type AND myForcedId = :forced_id")
Optional<Long> findByPartitionIdOrNullAndTypeAndForcedId(@Param("partition_id") Collection<Integer> thePartitionId, @Param("resource_type") String theResourceType, @Param("forced_id") String theForcedId);
@Query("SELECT f FROM ForcedId f WHERE f.myResourcePid = :resource_pid")
Optional<ForcedId> findByResourcePid(@Param("resource_pid") Long theResourcePid);
@ -57,48 +42,6 @@ public interface IForcedIdDao extends JpaRepository<ForcedId, Long> {
@Query("DELETE FROM ForcedId t WHERE t.myId = :pid")
void deleteByPid(@Param("pid") Long theId);
/**
* This method returns a Collection where each row is an element in the collection. Each element in the collection
* is an object array, where the order matters (the array represents columns returned by the query). Be careful if you change this query in any way.
*/
@Query("SELECT f.myForcedId, f.myResourcePid FROM ForcedId f WHERE myResourceType = :resource_type AND myForcedId IN ( :forced_id )")
Collection<Object[]> findByTypeAndForcedId(@Param("resource_type") String theResourceType, @Param("forced_id") Collection<String> theForcedId);
/**
* This method returns a Collection where each row is an element in the collection. Each element in the collection
* is an object array, where the order matters (the array represents columns returned by the query). Be careful if you change this query in any way.
*/
@Query("SELECT f.myForcedId, f.myResourcePid FROM ForcedId f WHERE myPartitionIdValue IN ( :partition_id ) AND myResourceType = :resource_type AND myForcedId IN ( :forced_id )")
Collection<Object[]> findByTypeAndForcedIdInPartitionIds(@Param("resource_type") String theResourceType, @Param("forced_id") Collection<String> theForcedId, @Param("partition_id") Collection<Integer> thePartitionId);
/**
* This method returns a Collection where each row is an element in the collection. Each element in the collection
* is an object array, where the order matters (the array represents columns returned by the query). Be careful if you change this query in any way.
*/
@Query("SELECT f.myForcedId, f.myResourcePid FROM ForcedId f WHERE (myPartitionIdValue IS NULL OR myPartitionIdValue IN ( :partition_id )) AND myResourceType = :resource_type AND myForcedId IN ( :forced_id )")
Collection<Object[]> findByTypeAndForcedIdInPartitionIdsOrNullPartition(@Param("resource_type") String theResourceType, @Param("forced_id") Collection<String> theForcedId, @Param("partition_id") Collection<Integer> thePartitionId);
/**
* This method returns a Collection where each row is an element in the collection. Each element in the collection
* is an object array, where the order matters (the array represents columns returned by the query). Be careful if you change this query in any way.
*/
@Query("SELECT f.myForcedId, f.myResourcePid FROM ForcedId f WHERE myPartitionIdValue IS NULL AND myResourceType = :resource_type AND myForcedId IN ( :forced_id )")
Collection<Object[]> findByTypeAndForcedIdInPartitionNull(@Param("resource_type") String theResourceType, @Param("forced_id") Collection<String> theForcedId);
/**
* Warning: No DB index exists for this particular query, so it may not perform well
* <p>
* This method returns a Collection where each row is an element in the collection. Each element in the collection
* is an object array, where the order matters (the array represents columns returned by the query). Be careful if you change this query in any way.
*/
@Query("" +
"SELECT " +
" f.myResourceType, f.myResourcePid, f.myForcedId, t.myDeleted " +
"FROM ForcedId f " +
"JOIN ResourceTable t ON t.myId = f.myResourcePid " +
"WHERE f.myForcedId IN ( :forced_id )")
Collection<Object[]> findAndResolveByForcedIdWithNoType(@Param("forced_id") Collection<String> theForcedIds);
/**
* This method returns a Collection where each row is an element in the collection. Each element in the collection
* is an object array, where the order matters (the array represents columns returned by the query). Be careful if you change this query in any way.

View File

@ -0,0 +1,7 @@
package ca.uhn.fhir.jpa.dao.data;
import javax.transaction.Transactional;
@Transactional(Transactional.TxType.MANDATORY)
public interface IHapiFhirJpaRepository {
}

View File

@ -33,7 +33,7 @@ import java.util.Date;
import java.util.List;
@Repository
public interface IMdmLinkDao extends JpaRepository<MdmLink, Long> {
public interface IMdmLinkDao extends JpaRepository<MdmLink, Long>, IHapiFhirJpaRepository {
@Modifying
@Query("DELETE FROM MdmLink f WHERE myGoldenResourcePid = :pid OR mySourcePid = :pid")
int deleteWithAnyReferenceToPid(@Param("pid") Long thePid);

View File

@ -27,7 +27,7 @@ import java.util.Optional;
* #L%
*/
public interface INpmPackageDao extends JpaRepository<NpmPackageEntity, Long> {
public interface INpmPackageDao extends JpaRepository<NpmPackageEntity, Long>, IHapiFhirJpaRepository {
@Query("SELECT p FROM NpmPackageEntity p WHERE p.myPackageId = :id")
Optional<NpmPackageEntity> findByPackageId(@Param("id") String thePackageId);

View File

@ -29,7 +29,7 @@ import java.util.Optional;
* #L%
*/
public interface INpmPackageVersionDao extends JpaRepository<NpmPackageVersionEntity, Long> {
public interface INpmPackageVersionDao extends JpaRepository<NpmPackageVersionEntity, Long>, IHapiFhirJpaRepository {
@Query("SELECT p FROM NpmPackageVersionEntity p WHERE p.myPackageId = :id")
Collection<NpmPackageVersionEntity> findByPackageId(@Param("id") String thePackageId);

View File

@ -28,7 +28,7 @@ import org.springframework.data.repository.query.Param;
* #L%
*/
public interface INpmPackageVersionResourceDao extends JpaRepository<NpmPackageVersionResourceEntity, Long> {
public interface INpmPackageVersionResourceDao extends JpaRepository<NpmPackageVersionResourceEntity, Long>, IHapiFhirJpaRepository {
@Query("SELECT e FROM NpmPackageVersionResourceEntity e WHERE e.myResourceType = :resourceType AND e.myFhirVersion = :fhirVersion AND e.myPackageVersion.myCurrentVersion = true")
Slice<NpmPackageVersionResourceEntity> findCurrentVersionByResourceType(Pageable thePage, @Param("fhirVersion") FhirVersionEnum theFhirVersion, @Param("resourceType") String theResourceType);

View File

@ -28,7 +28,7 @@ import java.util.Optional;
* #L%
*/
public interface IPartitionDao extends JpaRepository<PartitionEntity, Integer> {
public interface IPartitionDao extends JpaRepository<PartitionEntity, Integer>, IHapiFhirJpaRepository {
@Query("SELECT p FROM PartitionEntity p WHERE p.myName = :name")
Optional<PartitionEntity> findForName(@Param("name") String theName);

View File

@ -28,7 +28,7 @@ import org.springframework.data.repository.query.Param;
* #L%
*/
public interface IResourceHistoryTableDao extends JpaRepository<ResourceHistoryTable, Long> {
public interface IResourceHistoryTableDao extends JpaRepository<ResourceHistoryTable, Long>, IHapiFhirJpaRepository {
@Query("SELECT t FROM ResourceHistoryTable t LEFT OUTER JOIN FETCH t.myProvenance WHERE t.myResourceId = :id AND t.myResourceVersion = :version")

View File

@ -28,7 +28,7 @@ import java.util.List;
* #L%
*/
public interface IResourceHistoryTagDao extends JpaRepository<ResourceHistoryTag, Long> {
public interface IResourceHistoryTagDao extends JpaRepository<ResourceHistoryTag, Long>, IHapiFhirJpaRepository {
@Modifying
@Query("DELETE FROM ResourceHistoryTag t WHERE t.myResourceHistoryPid = :historyPid")

View File

@ -27,7 +27,7 @@ import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface IResourceIndexedSearchParamCoordsDao extends JpaRepository<ResourceIndexedSearchParamCoords, Long> {
public interface IResourceIndexedSearchParamCoordsDao extends JpaRepository<ResourceIndexedSearchParamCoords, Long>, IHapiFhirJpaRepository {
@Modifying
@Query("delete from ResourceIndexedSearchParamCoords t WHERE t.myResourcePid = :resid")
void deleteByResourceId(@Param("resid") Long theResourcePid);

View File

@ -28,7 +28,7 @@ import org.springframework.data.repository.query.Param;
import java.util.List;
public interface IResourceIndexedSearchParamDateDao extends JpaRepository<ResourceIndexedSearchParamDate, Long> {
public interface IResourceIndexedSearchParamDateDao extends JpaRepository<ResourceIndexedSearchParamDate, Long>, IHapiFhirJpaRepository {
@Modifying
@Query("delete from ResourceIndexedSearchParamDate t WHERE t.myResourcePid = :resid")
void deleteByResourceId(@Param("resid") Long theResourcePid);

View File

@ -27,7 +27,7 @@ import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface IResourceIndexedSearchParamNumberDao extends JpaRepository<ResourceIndexedSearchParamNumber, Long> {
public interface IResourceIndexedSearchParamNumberDao extends JpaRepository<ResourceIndexedSearchParamNumber, Long>, IHapiFhirJpaRepository {
@Modifying
@Query("delete from ResourceIndexedSearchParamNumber t WHERE t.myResourcePid = :resid")
void deleteByResourceId(@Param("resid") Long theResourcePid);

View File

@ -27,7 +27,7 @@ import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface IResourceIndexedSearchParamQuantityDao extends JpaRepository<ResourceIndexedSearchParamQuantity, Long> {
public interface IResourceIndexedSearchParamQuantityDao extends JpaRepository<ResourceIndexedSearchParamQuantity, Long>, IHapiFhirJpaRepository {
@Modifying
@Query("delete from ResourceIndexedSearchParamQuantity t WHERE t.myResourcePid = :resid")
void deleteByResourceId(@Param("resid") Long theResourcePid);

View File

@ -28,7 +28,7 @@ import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface IResourceIndexedSearchParamQuantityNormalizedDao extends JpaRepository<ResourceIndexedSearchParamQuantityNormalized, Long> {
public interface IResourceIndexedSearchParamQuantityNormalizedDao extends JpaRepository<ResourceIndexedSearchParamQuantityNormalized, Long>, IHapiFhirJpaRepository {
@Modifying
@Query("delete from ResourceIndexedSearchParamQuantityNormalized t WHERE t.myResourcePid = :resid")
void deleteByResourceId(@Param("resid") Long theResourcePid);

View File

@ -28,7 +28,7 @@ import org.springframework.data.repository.query.Param;
import java.util.List;
public interface IResourceIndexedSearchParamStringDao extends JpaRepository<ResourceIndexedSearchParamString, Long> {
public interface IResourceIndexedSearchParamStringDao extends JpaRepository<ResourceIndexedSearchParamString, Long>, IHapiFhirJpaRepository {
@Modifying
@Query("DELETE FROM ResourceIndexedSearchParamString t WHERE t.myResourcePid = :resId")

View File

@ -26,7 +26,7 @@ import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface IResourceIndexedSearchParamTokenDao extends JpaRepository<ResourceIndexedSearchParamToken, Long> {
public interface IResourceIndexedSearchParamTokenDao extends JpaRepository<ResourceIndexedSearchParamToken, Long>, IHapiFhirJpaRepository {
@Query("select count(*) from ResourceIndexedSearchParamToken t WHERE t.myResourcePid = :resid")
int countForResourceId(@Param("resid") Long theResourcePid);

View File

@ -29,7 +29,7 @@ import org.springframework.data.repository.query.Param;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamUri;
public interface IResourceIndexedSearchParamUriDao extends JpaRepository<ResourceIndexedSearchParamUri, Long> {
public interface IResourceIndexedSearchParamUriDao extends JpaRepository<ResourceIndexedSearchParamUri, Long>, IHapiFhirJpaRepository {
@Query("SELECT DISTINCT p.myUri FROM ResourceIndexedSearchParamUri p WHERE p.myResourceType = :resource_type AND p.myParamName = :param_name")
public Collection<String> findAllByResourceTypeAndParamName(@Param("resource_type") String theResourceType, @Param("param_name") String theParamName);

View File

@ -28,7 +28,7 @@ import org.springframework.data.repository.query.Param;
import java.util.List;
public interface IResourceLinkDao extends JpaRepository<ResourceLink, Long> {
public interface IResourceLinkDao extends JpaRepository<ResourceLink, Long>, IHapiFhirJpaRepository {
@Modifying
@Query("DELETE FROM ResourceLink t WHERE t.mySourceResourcePid = :resId")

View File

@ -33,7 +33,7 @@ import java.util.Map;
* #L%
*/
public interface IResourceProvenanceDao extends JpaRepository<ResourceHistoryProvenanceEntity, Long> {
public interface IResourceProvenanceDao extends JpaRepository<ResourceHistoryProvenanceEntity, Long>, IHapiFhirJpaRepository {
@Modifying
@Query("DELETE FROM ResourceHistoryProvenanceEntity t WHERE t.myId = :pid")

View File

@ -28,7 +28,7 @@ import org.springframework.data.repository.query.Param;
import ca.uhn.fhir.jpa.entity.ResourceSearchView;
public interface IResourceSearchViewDao extends JpaRepository<ResourceSearchView, Long> {
public interface IResourceSearchViewDao extends JpaRepository<ResourceSearchView, Long>, IHapiFhirJpaRepository {
@Query("SELECT v FROM ResourceSearchView v WHERE v.myResourceId in (:pids)")
Collection<ResourceSearchView> findByResourceIds(@Param("pids") Collection<Long> pids);

View File

@ -7,6 +7,8 @@ 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.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collection;
import java.util.Date;
@ -34,7 +36,8 @@ import java.util.Optional;
* #L%
*/
public interface IResourceTableDao extends JpaRepository<ResourceTable, Long> {
@Transactional(propagation = Propagation.MANDATORY)
public interface IResourceTableDao extends JpaRepository<ResourceTable, Long>, IHapiFhirJpaRepository {
@Query("SELECT t.myId FROM ResourceTable t WHERE t.myDeleted IS NOT NULL")
Slice<Long> findIdsOfDeletedResources(Pageable thePageable);

View File

@ -29,7 +29,7 @@ import org.springframework.data.repository.query.Param;
import ca.uhn.fhir.jpa.model.entity.ResourceTag;
public interface IResourceTagDao extends JpaRepository<ResourceTag, Long> {
public interface IResourceTagDao extends JpaRepository<ResourceTag, Long>, IHapiFhirJpaRepository {
@Query("" +
"SELECT t FROM ResourceTag t " +
"INNER JOIN FETCH t.myTag td " +

View File

@ -32,7 +32,7 @@ import java.util.Optional;
* #L%
*/
public interface ISearchDao extends JpaRepository<Search, Long> {
public interface ISearchDao extends JpaRepository<Search, Long>, IHapiFhirJpaRepository {
@Query("SELECT s FROM Search s LEFT OUTER JOIN FETCH s.myIncludes WHERE s.myUuid = :uuid")
Optional<Search> findByUuidAndFetchIncludes(@Param("uuid") String theUuid);

View File

@ -26,7 +26,7 @@ import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface ISearchIncludeDao extends JpaRepository<SearchInclude, Long> {
public interface ISearchIncludeDao extends JpaRepository<SearchInclude, Long>, IHapiFhirJpaRepository {
@Modifying
@Query(value="DELETE FROM SearchInclude r WHERE r.mySearchPid = :search")

View File

@ -29,7 +29,7 @@ import java.util.List;
* #L%
*/
public interface ISearchParamPresentDao extends JpaRepository<SearchParamPresent, Long> {
public interface ISearchParamPresentDao extends JpaRepository<SearchParamPresent, Long>, IHapiFhirJpaRepository {
@Query("SELECT s FROM SearchParamPresent s WHERE s.myResource = :res")
List<SearchParamPresent> findAllForResource(@Param("res") ResourceTable theResource);

View File

@ -31,7 +31,7 @@ import java.util.List;
* #L%
*/
public interface ISearchResultDao extends JpaRepository<SearchResult, Long> {
public interface ISearchResultDao extends JpaRepository<SearchResult, Long>, IHapiFhirJpaRepository {
@Query(value="SELECT r.myResourcePid FROM SearchResult r WHERE r.mySearchPid = :search ORDER BY r.myOrder ASC")
Slice<Long> findWithSearchPid(@Param("search") Long theSearchPid, Pageable thePage);

View File

@ -27,7 +27,7 @@ import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface ISubscriptionTableDao extends JpaRepository<SubscriptionTable, Long> {
public interface ISubscriptionTableDao extends JpaRepository<SubscriptionTable, Long>, IHapiFhirJpaRepository {
@Modifying
@Query("DELETE FROM SubscriptionTable t WHERE t.mySubscriptionResource = :subscription ")

View File

@ -24,6 +24,6 @@ import org.springframework.data.jpa.repository.JpaRepository;
import ca.uhn.fhir.jpa.model.entity.TagDefinition;
public interface ITagDefinitionDao extends JpaRepository<TagDefinition, Long> {
public interface ITagDefinitionDao extends JpaRepository<TagDefinition, Long>, IHapiFhirJpaRepository {
// nothing
}

View File

@ -28,7 +28,7 @@ import ca.uhn.fhir.jpa.entity.TermCodeSystem;
import java.util.Optional;
public interface ITermCodeSystemDao extends JpaRepository<TermCodeSystem, Long> {
public interface ITermCodeSystemDao extends JpaRepository<TermCodeSystem, Long>, IHapiFhirJpaRepository {
@Query("SELECT cs FROM TermCodeSystem cs WHERE cs.myCodeSystemUri = :code_system_uri")
TermCodeSystem findByCodeSystemUri(@Param("code_system_uri") String theCodeSystemUri);

View File

@ -29,7 +29,7 @@ import java.util.List;
* #L%
*/
public interface ITermCodeSystemVersionDao extends JpaRepository<TermCodeSystemVersion, Long> {
public interface ITermCodeSystemVersionDao extends JpaRepository<TermCodeSystemVersion, Long>, IHapiFhirJpaRepository {
@Modifying
@Query("DELETE FROM TermCodeSystemVersion csv WHERE csv.myCodeSystem = :cs")

View File

@ -32,7 +32,7 @@ import java.util.Optional;
* #L%
*/
public interface ITermConceptDao extends JpaRepository<TermConcept, Long> {
public interface ITermConceptDao extends JpaRepository<TermConcept, Long>, IHapiFhirJpaRepository {
@Query("SELECT COUNT(t) FROM TermConcept t WHERE t.myCodeSystem.myId = :cs_pid")
Integer countByCodeSystemVersion(@Param("cs_pid") Long thePid);

View File

@ -27,7 +27,7 @@ import org.springframework.data.repository.query.Param;
* #L%
*/
public interface ITermConceptDesignationDao extends JpaRepository<TermConceptDesignation, Long> {
public interface ITermConceptDesignationDao extends JpaRepository<TermConceptDesignation, Long>, IHapiFhirJpaRepository {
@Query("SELECT t.myId FROM TermConceptDesignation t WHERE t.myCodeSystemVersion.myId = :csv_pid")
Slice<Long> findIdsByCodeSystemVersion(Pageable thePage, @Param("csv_pid") Long thePid);

View File

@ -31,7 +31,7 @@ import ca.uhn.fhir.jpa.entity.TermConceptMap;
* #L%
*/
public interface ITermConceptMapDao extends JpaRepository<TermConceptMap, Long> {
public interface ITermConceptMapDao extends JpaRepository<TermConceptMap, Long>, IHapiFhirJpaRepository {
@Query("DELETE FROM TermConceptMap cm WHERE cm.myId = :pid")
@Modifying
void deleteTermConceptMapById(@Param("pid") Long theId);

View File

@ -26,7 +26,7 @@ import org.springframework.data.repository.query.Param;
* #L%
*/
public interface ITermConceptMapGroupDao extends JpaRepository<TermConceptMapGroup, Long> {
public interface ITermConceptMapGroupDao extends JpaRepository<TermConceptMapGroup, Long>, IHapiFhirJpaRepository {
@Query("DELETE FROM TermConceptMapGroup g WHERE g.myId = :pid")
@Modifying
void deleteTermConceptMapGroupById(@Param("pid") Long theId);

View File

@ -26,7 +26,7 @@ import org.springframework.data.repository.query.Param;
* #L%
*/
public interface ITermConceptMapGroupElementDao extends JpaRepository<TermConceptMapGroupElement, Long> {
public interface ITermConceptMapGroupElementDao extends JpaRepository<TermConceptMapGroupElement, Long>, IHapiFhirJpaRepository {
@Query("DELETE FROM TermConceptMapGroupElement e WHERE e.myId = :pid")
@Modifying
void deleteTermConceptMapGroupElementById(@Param("pid") Long theId);

View File

@ -26,7 +26,7 @@ import org.springframework.data.repository.query.Param;
* #L%
*/
public interface ITermConceptMapGroupElementTargetDao extends JpaRepository<TermConceptMapGroupElementTarget, Long> {
public interface ITermConceptMapGroupElementTargetDao extends JpaRepository<TermConceptMapGroupElementTarget, Long>, IHapiFhirJpaRepository {
@Query("DELETE FROM TermConceptMapGroupElementTarget t WHERE t.myId = :pid")
@Modifying
void deleteTermConceptMapGroupElementTargetById(@Param("pid") Long theId);

View File

@ -29,7 +29,7 @@ import java.util.Collection;
* #L%
*/
public interface ITermConceptParentChildLinkDao extends JpaRepository<TermConceptParentChildLink, Long> {
public interface ITermConceptParentChildLinkDao extends JpaRepository<TermConceptParentChildLink, Long>, IHapiFhirJpaRepository {
@Query("SELECT COUNT(t) FROM TermConceptParentChildLink t WHERE t.myCodeSystem.myId = :cs_pid")
Integer countByCodeSystemVersion(@Param("cs_pid") Long thePid);

View File

@ -27,7 +27,7 @@ import org.springframework.data.repository.query.Param;
* #L%
*/
public interface ITermConceptPropertyDao extends JpaRepository<TermConceptProperty, Long> {
public interface ITermConceptPropertyDao extends JpaRepository<TermConceptProperty, Long>, IHapiFhirJpaRepository {
@Query("SELECT t.myId FROM TermConceptProperty t WHERE t.myCodeSystemVersion.myId = :cs_pid")
Slice<Long> findIdsByCodeSystemVersion(Pageable thePage, @Param("cs_pid") Long thePid);

View File

@ -29,7 +29,7 @@ import org.springframework.data.repository.query.Param;
import java.util.List;
import java.util.Optional;
public interface ITermValueSetConceptDao extends JpaRepository<TermValueSetConcept, Long> {
public interface ITermValueSetConceptDao extends JpaRepository<TermValueSetConcept, Long>, IHapiFhirJpaRepository {
@Query("SELECT COUNT(*) FROM TermValueSetConcept vsc WHERE vsc.myValueSetPid = :pid")
Integer countByTermValueSetId(@Param("pid") Long theValueSetId);

View File

@ -26,7 +26,7 @@ import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface ITermValueSetConceptDesignationDao extends JpaRepository<TermValueSetConceptDesignation, Long> {
public interface ITermValueSetConceptDesignationDao extends JpaRepository<TermValueSetConceptDesignation, Long>, IHapiFhirJpaRepository {
@Query("SELECT COUNT(vscd) FROM TermValueSetConceptDesignation vscd WHERE vscd.myValueSetPid = :pid")
Integer countByTermValueSetId(@Param("pid") Long theValueSetId);

View File

@ -29,7 +29,7 @@ import java.util.List;
* #L%
*/
public interface ITermValueSetConceptViewDao extends JpaRepository<TermValueSetConceptView, Long> {
public interface ITermValueSetConceptViewDao extends JpaRepository<TermValueSetConceptView, Long>, IHapiFhirJpaRepository {
@Query("SELECT v FROM TermValueSetConceptView v WHERE v.myConceptValueSetPid = :pid AND v.myConceptOrder >= :from AND v.myConceptOrder < :to ORDER BY v.myConceptOrder")
List<TermValueSetConceptView> findByTermValueSetId(@Param("from") int theFrom, @Param("to") int theTo, @Param("pid") Long theValueSetId);

View File

@ -28,7 +28,7 @@ import org.springframework.data.repository.query.Param;
import java.io.Serializable;
import java.util.List;
public interface ITermValueSetConceptViewOracleDao extends JpaRepository<TermValueSetConceptViewOracle, Long> {
public interface ITermValueSetConceptViewOracleDao extends JpaRepository<TermValueSetConceptViewOracle, Long>, IHapiFhirJpaRepository {
@Query("SELECT v FROM TermValueSetConceptViewOracle v WHERE v.myConceptValueSetPid = :pid AND v.myConceptOrder >= :from AND v.myConceptOrder < :to ORDER BY v.myConceptOrder")
List<TermValueSetConceptViewOracle> findByTermValueSetId(@Param("from") int theFrom, @Param("to") int theTo, @Param("pid") Long theValueSetId);

View File

@ -31,7 +31,7 @@ import org.springframework.data.repository.query.Param;
import java.util.List;
import java.util.Optional;
public interface ITermValueSetDao extends JpaRepository<TermValueSet, Long> {
public interface ITermValueSetDao extends JpaRepository<TermValueSet, Long>, IHapiFhirJpaRepository {
@Query("SELECT vs FROM TermValueSet vs WHERE vs.myResourcePid = :resource_pid")
Optional<TermValueSet> findByResourcePid(@Param("resource_pid") Long theResourcePid);

View File

@ -47,10 +47,9 @@ 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.IdType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@ -97,9 +96,8 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
*/
@Service
public class IdHelperService {
private static final String RESOURCE_PID = "RESOURCE_PID";
private static final Logger ourLog = LoggerFactory.getLogger(IdHelperService.class);
public static final Predicate[] EMPTY_PREDICATE_ARRAY = new Predicate[0];
private static final String RESOURCE_PID = "RESOURCE_PID";
@Autowired
protected IForcedIdDao myForcedIdDao;
@Autowired
@ -110,6 +108,16 @@ public class IdHelperService {
private FhirContext myFhirCtx;
@Autowired
private MemoryCacheService myMemoryCacheService;
@PersistenceContext(type = PersistenceContextType.TRANSACTION)
private EntityManager myEntityManager;
@Autowired
private PartitionSettings myPartitionSettings;
private boolean myDontCheckActiveTransactionForUnitTest;
@VisibleForTesting
void setDontCheckActiveTransactionForUnitTest(boolean theDontCheckActiveTransactionForUnitTest) {
myDontCheckActiveTransactionForUnitTest = theDontCheckActiveTransactionForUnitTest;
}
public void delete(ForcedId forcedId) {
myForcedIdDao.deleteByPid(forcedId.getId());
@ -123,6 +131,8 @@ public class IdHelperService {
*/
@Nonnull
public IResourceLookup resolveResourceIdentity(@Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, String theResourceId) throws ResourceNotFoundException {
assert myDontCheckActiveTransactionForUnitTest || TransactionSynchronizationManager.isSynchronizationActive();
IdDt id = new IdDt(theResourceType, theResourceId);
Map<String, List<IResourceLookup>> matches = translateForcedIdToPids(theRequestPartitionId,
Collections.singletonList(id));
@ -149,16 +159,12 @@ public class IdHelperService {
* Returns a mapping of Id -> ResourcePersistentId.
* If any resource is not found, it will throw ResourceNotFound exception
* (and no map will be returned)
*
* @param theRequestPartitionId
* @param theResourceType
* @param theIds
* @return
*/
@Nonnull
public Map<String, ResourcePersistentId> resolveResourcePersistentIds(@Nonnull RequestPartitionId theRequestPartitionId,
String theResourceType,
List<String> theIds) {
String theResourceType,
List<String> theIds) {
assert myDontCheckActiveTransactionForUnitTest || TransactionSynchronizationManager.isSynchronizationActive();
Validate.notNull(theIds, "theIds cannot be null");
Validate.isTrue(!theIds.isEmpty(), "theIds must not be empty");
@ -170,15 +176,13 @@ public class IdHelperService {
// is already a PID
retVal = new ResourcePersistentId(Long.parseLong(id));
retVals.put(id, retVal);
}
else {
} else {
// is a forced id
// we must resolve!
if (myDaoConfig.isDeleteEnabled()) {
retVal = new ResourcePersistentId(resolveResourceIdentity(theRequestPartitionId, theResourceType, id).getResourceId());
retVals.put(id, retVal);
}
else {
} else {
// fetch from cache... adding to cache if not available
String key = toForcedIdToPidKey(theRequestPartitionId, theResourceType, id);
retVal = myMemoryCacheService.getThenPutAfterCommit(MemoryCacheService.CacheEnum.FORCED_ID_TO_PID, key, t -> {
@ -217,7 +221,7 @@ public class IdHelperService {
* Returns true if the given resource ID should be stored in a forced ID. Under default config
* (meaning client ID strategy is {@link ca.uhn.fhir.jpa.api.config.DaoConfig.ClientIdStrategyEnum#ALPHANUMERIC})
* this will return true if the ID has any non-digit characters.
*
* <p>
* In {@link ca.uhn.fhir.jpa.api.config.DaoConfig.ClientIdStrategyEnum#ANY} mode it will always return true.
*/
public boolean idRequiresForcedId(String theId) {
@ -229,12 +233,6 @@ public class IdHelperService {
return RequestPartitionId.stringifyForKey(theRequestPartitionId) + "/" + theResourceType + "/" + theId;
}
@PersistenceContext(type = PersistenceContextType.TRANSACTION)
private EntityManager myEntityManager;
@Autowired
private PartitionSettings myPartitionSettings;
/**
* Given a collection of resource IDs (resource type + id), resolves the internal persistent IDs.
* <p>
@ -243,6 +241,8 @@ public class IdHelperService {
*/
@Nonnull
public List<ResourcePersistentId> resolveResourcePersistentIdsWithCache(RequestPartitionId theRequestPartitionId, List<IIdType> theIds) {
assert myDontCheckActiveTransactionForUnitTest || TransactionSynchronizationManager.isSynchronizationActive();
for (IIdType id : theIds) {
if (!id.hasIdPart()) {
throw new InvalidRequestException("Parameter value missing in request");
@ -528,6 +528,8 @@ public class IdHelperService {
* @return A Set of strings representing the FHIR IDs of the pids.
*/
public Set<String> translatePidsToFhirResourceIds(Set<Long> thePids) {
assert myDontCheckActiveTransactionForUnitTest || TransactionSynchronizationManager.isSynchronizationActive();
Map<Long, Optional<String>> pidToForcedIdMap = translatePidsToForcedIds(thePids);
//If the result of the translation is an empty optional, it means there is no forced id, and we can use the PID as the resource ID.
@ -540,6 +542,8 @@ public class IdHelperService {
}
public Map<Long, Optional<String>> translatePidsToForcedIds(Set<Long> thePids) {
assert myDontCheckActiveTransactionForUnitTest || TransactionSynchronizationManager.isSynchronizationActive();
Map<Long, Optional<String>> retVal = new HashMap<>(myMemoryCacheService.getAllPresent(MemoryCacheService.CacheEnum.PID_TO_FORCED_ID, thePids));
List<Long> remainingPids = thePids
@ -577,6 +581,8 @@ public class IdHelperService {
@Deprecated
@Nullable
public Long getPidOrNull(IBaseResource theResource) {
assert myDontCheckActiveTransactionForUnitTest || TransactionSynchronizationManager.isSynchronizationActive();
IAnyResource anyResource = (IAnyResource) theResource;
Long retVal = (Long) anyResource.getUserData(RESOURCE_PID);
if (retVal == null) {
@ -597,6 +603,8 @@ public class IdHelperService {
@Deprecated
@Nonnull
public Long getPidOrThrowException(IIdType theId) {
assert myDontCheckActiveTransactionForUnitTest || TransactionSynchronizationManager.isSynchronizationActive();
List<IIdType> ids = Collections.singletonList(theId);
List<ResourcePersistentId> resourcePersistentIds = this.resolveResourcePersistentIdsWithCache(RequestPartitionId.allPartitions(), ids);
return resourcePersistentIds.get(0).getIdAsLong();
@ -609,6 +617,8 @@ public class IdHelperService {
@Deprecated
@Nonnull
public List<Long> getPidsOrThrowException(List<IIdType> theIds) {
assert myDontCheckActiveTransactionForUnitTest || TransactionSynchronizationManager.isSynchronizationActive();
List<ResourcePersistentId> resourcePersistentIds = this.resolveResourcePersistentIdsWithCache(RequestPartitionId.allPartitions(), theIds);
return resourcePersistentIds.stream().map(ResourcePersistentId::getIdAsLong).collect(Collectors.toList());
}

View File

@ -124,6 +124,7 @@ public class JpaPackageCache extends BasePackageCacheManager implements IHapiPac
private PartitionSettings myPartitionSettings;
@Override
@Transactional
public NpmPackage loadPackageFromCacheOnly(String theId, @Nullable String theVersion) {
Optional<NpmPackageVersionEntity> packageVersion = loadPackageVersionEntity(theId, theVersion);
if (!packageVersion.isPresent() && theVersion.endsWith(".x")) {
@ -338,7 +339,7 @@ public class JpaPackageCache extends BasePackageCacheManager implements IHapiPac
requestDetails.setTenantId(JpaConstants.DEFAULT_PARTITION_NAME);
}
return (ResourceTable) getBinaryDao().create(theResourceBinary, requestDetails).getEntity();
} else {
} else {
return (ResourceTable) getBinaryDao().create(theResourceBinary).getEntity();
}
}
@ -388,6 +389,7 @@ public class JpaPackageCache extends BasePackageCacheManager implements IHapiPac
}
@Override
@Transactional
public NpmPackage loadPackage(String thePackageId, String thePackageVersion) throws FHIRException, IOException {
NpmPackage cachedPackage = loadPackageFromCacheOnly(thePackageId, thePackageVersion);
if (cachedPackage != null) {
@ -414,6 +416,7 @@ public class JpaPackageCache extends BasePackageCacheManager implements IHapiPac
}
@Override
@Transactional(Transactional.TxType.NEVER)
public NpmPackage installPackage(PackageInstallationSpec theInstallationSpec) throws IOException {
Validate.notBlank(theInstallationSpec.getName(), "thePackageId must not be blank");
Validate.notBlank(theInstallationSpec.getVersion(), "thePackageVersion must not be blank");
@ -429,7 +432,13 @@ public class JpaPackageCache extends BasePackageCacheManager implements IHapiPac
return addPackageToCache(theInstallationSpec.getName(), theInstallationSpec.getVersion(), new ByteArrayInputStream(theInstallationSpec.getPackageContents()), sourceDescription);
}
return loadPackage(theInstallationSpec.getName(), theInstallationSpec.getVersion());
return newTxTemplate().execute(tx -> {
try {
return loadPackage(theInstallationSpec.getName(), theInstallationSpec.getVersion());
} catch (IOException e) {
throw new InternalErrorException(e);
}
});
}
protected byte[] loadPackageUrlContents(String thePackageUrl) {
@ -660,7 +669,7 @@ public class JpaPackageCache extends BasePackageCacheManager implements IHapiPac
public List<IBaseResource> loadPackageAssetsByType(FhirVersionEnum theFhirVersion, String theResourceType) {
// List<NpmPackageVersionResourceEntity> outcome = myPackageVersionResourceDao.findAll();
Slice<NpmPackageVersionResourceEntity> outcome = myPackageVersionResourceDao.findCurrentVersionByResourceType(PageRequest.of(0, 1000), theFhirVersion, theResourceType);
return outcome.stream().map(t->loadPackageEntity(t)).collect(Collectors.toList());
return outcome.stream().map(t -> loadPackageEntity(t)).collect(Collectors.toList());
}
private void deleteAndExpungeResourceBinary(IIdType theResourceBinaryId, ExpungeOptions theOptions) {

View File

@ -968,10 +968,8 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
// Create an initial search in the DB and give it an ID
saveSearch();
assert !TransactionSynchronizationManager.isActualTransactionActive();
TransactionTemplate txTemplate = new TransactionTemplate(myManagedTxManager);
txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
if (myCustomIsolationSupported) {
txTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);

View File

@ -1443,6 +1443,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
@Override
@Transactional
public boolean isValueSetPreExpandedForCodeValidation(ValueSet theValueSet) {
Optional<TermValueSet> optionalTermValueSet = fetchValueSetEntity(theValueSet);
@ -1471,6 +1472,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
protected IValidationSupport.CodeValidationResult validateCodeIsInPreExpandedValueSet(
ConceptValidationOptions theValidationOptions,
ValueSet theValueSet, String theSystem, String theCode, String theDisplay, Coding theCoding, CodeableConcept theCodeableConcept) {
assert TransactionSynchronizationManager.isSynchronizationActive();
ValidateUtil.isNotNullOrThrowUnprocessableEntity(theValueSet.hasId(), "ValueSet.id is required");
ResourcePersistentId valueSetResourcePid = myConceptStorageSvc.getValueSetResourcePid(theValueSet.getIdElement());
@ -1538,6 +1540,8 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
}
private List<TermValueSetConcept> findByValueSetResourcePidSystemAndCode(ResourcePersistentId theResourcePid, String theSystem, String theCode) {
assert TransactionSynchronizationManager.isSynchronizationActive();
List<TermValueSetConcept> retVal = new ArrayList<>();
Optional<TermValueSetConcept> optionalTermValueSetConcept;
int versionIndex = theSystem.indexOf("|");
@ -1800,6 +1804,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
}
@Override
@Transactional
public CodeValidationResult validateCode(ConceptValidationOptions theOptions, IIdType theValueSetId, String theValueSetIdentifier, String theCodeSystemIdentifierToValidate, String theCodeToValidate, String theDisplayToValidate, IBaseDatatype theCodingToValidate, IBaseDatatype theCodeableConceptToValidate) {
CodeableConcept codeableConcept = toCanonicalCodeableConcept(theCodeableConceptToValidate);

View File

@ -20,6 +20,7 @@ import org.hl7.fhir.r4.model.ValueSet;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.transaction.Transactional;
import java.util.List;
import java.util.Optional;
import java.util.Set;
@ -103,6 +104,7 @@ public interface ITermReadSvc extends IValidationSupport {
/**
* Version independent
*/
@Transactional()
CodeValidationResult validateCodeIsInPreExpandedValueSet(ConceptValidationOptions theOptions, IBaseResource theValueSet, String theSystem, String theCode, String theDisplay, IBaseDatatype theCoding, IBaseDatatype theCodeableConcept);
boolean isValueSetPreExpandedForCodeValidation(ValueSet theValueSet);

View File

@ -1214,7 +1214,7 @@ public class BulkDataExportSvcImplR4Test extends BaseJpaR4Test {
goldenPatient.setId("PAT999");
SystemRequestDetails srd = SystemRequestDetails.newSystemRequestAllPartitions();
DaoMethodOutcome g1Outcome = myPatientDao.update(goldenPatient, srd);
Long goldenPid = myIdHelperService.getPidOrNull(g1Outcome.getResource());
Long goldenPid = runInTransaction(() -> myIdHelperService.getPidOrNull(g1Outcome.getResource()));
//Create our golden records' data.
createObservationWithIndex(999, g1Outcome.getId());
@ -1224,7 +1224,7 @@ public class BulkDataExportSvcImplR4Test extends BaseJpaR4Test {
for (int i = 0; i < 10; i++) {
DaoMethodOutcome patientOutcome = createPatientWithIndex(i);
IIdType patId = patientOutcome.getId().toUnqualifiedVersionless();
Long sourcePid = myIdHelperService.getPidOrNull(patientOutcome.getResource());
Long sourcePid = runInTransaction(() -> myIdHelperService.getPidOrNull(patientOutcome.getResource()));
//Link the patient to the golden resource
linkToGoldenResource(goldenPid, sourcePid);
@ -1246,14 +1246,14 @@ public class BulkDataExportSvcImplR4Test extends BaseJpaR4Test {
Patient goldenPatient2 = new Patient();
goldenPatient2.setId("PAT888");
DaoMethodOutcome g2Outcome = myPatientDao.update(goldenPatient2, new SystemRequestDetails().setRequestPartitionId(RequestPartitionId.defaultPartition()));
Long goldenPid2 = myIdHelperService.getPidOrNull(g2Outcome.getResource());
Long goldenPid2 = runInTransaction(() -> myIdHelperService.getPidOrNull(g2Outcome.getResource()));
//Create some nongroup patients MDM linked to a different golden resource. They shouldnt be included in the query.
for (int i = 0; i < 5; i++) {
int index = 1000 + i;
DaoMethodOutcome patientOutcome = createPatientWithIndex(index);
IIdType patId = patientOutcome.getId().toUnqualifiedVersionless();
Long sourcePid = myIdHelperService.getPidOrNull(patientOutcome.getResource());
Long sourcePid = runInTransaction(() -> myIdHelperService.getPidOrNull(patientOutcome.getResource()));
linkToGoldenResource(goldenPid2, sourcePid);
createObservationWithIndex(index, patId);
createImmunizationWithIndex(index, patId);
@ -1325,6 +1325,6 @@ public class BulkDataExportSvcImplR4Test extends BaseJpaR4Test {
mdmLink.setLinkSource(MdmLinkSourceEnum.MANUAL);
mdmLink.setUpdated(new Date());
mdmLink.setVersion("1");
myMdmLinkDao.save(mdmLink);
runInTransaction(() -> myMdmLinkDao.save(mdmLink));
}
}

View File

@ -34,6 +34,7 @@ import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobInstance;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.configuration.JobRegistry;
import org.springframework.batch.core.explore.JobExplorer;
import org.springframework.batch.core.launch.NoSuchJobException;
@ -42,6 +43,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import static ca.uhn.fhir.jpa.batch.config.BatchConstants.BULK_IMPORT_JOB_NAME;
@ -177,8 +179,14 @@ public class BulkDataImportR4Test extends BaseJpaR4Test implements ITestDataBuil
JobInstance jobInstance = myJobExplorer.getLastJobInstance(BULK_IMPORT_JOB_NAME);
JobExecution jobExecution = myJobExplorer.getLastJobExecution(jobInstance);
String exitDescription = jobExecution.getExitStatus().getExitDescription();
assertThat(exitDescription, containsString("File: File With Description"));
List<StepExecution> failedExecutions = jobExecution
.getStepExecutions()
.stream()
.filter(t -> t.getExitStatus().getExitCode().equals("FAILED"))
.collect(Collectors.toList());
assertEquals(2, failedExecutions.size());
assertThat(failedExecutions.get(1).getStepName(), containsString(":File With Description"));
}

View File

@ -0,0 +1,26 @@
package ca.uhn.fhir.jpa.config;
import net.ttddyy.dsproxy.ExecutionInfo;
import net.ttddyy.dsproxy.QueryInfo;
import net.ttddyy.dsproxy.support.ProxyDataSourceBuilder;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import java.util.List;
import java.util.Locale;
public class MandatoryTransactionListener implements ProxyDataSourceBuilder.SingleQueryExecution {
@Override
public void execute(ExecutionInfo execInfo, List<QueryInfo> queryInfoList) {
if (!TransactionSynchronizationManager.isSynchronizationActive()) {
for (QueryInfo nextQuery : queryInfoList) {
String query = nextQuery.getQuery().toLowerCase(Locale.US);
if (query.contains("hfj_") || query.contains("trm_")) {
if (query.startsWith("select ") || query.startsWith("insert ") || query.startsWith("update ")) {
throw new IllegalStateException("No transaction active executing query: " + nextQuery.getQuery());
}
}
}
}
}
}

View File

@ -127,6 +127,7 @@ public class TestR4Config extends BaseJavaConfigR4 {
// .logQueryBySlf4j(level)
.logSlowQueryBySlf4j(10, TimeUnit.SECONDS, level)
.beforeQuery(new BlockLargeNumbersOfParamsListener())
.beforeQuery(new MandatoryTransactionListener())
.afterQuery(captureQueriesListener())
.afterQuery(new CurrentThreadCaptureQueriesListener())
.countQuery(singleQueryCountHolder())

View File

@ -5,6 +5,7 @@ import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@ -26,16 +27,18 @@ class ResourceTableFKProviderTest extends BaseJpaR4Test {
@Test
public void testWeHaveAllForeignKeys() {
List<Object[]> result = myEntityManager.createNativeQuery("SELECT FKTABLE_NAME, FKCOLUMN_NAME FROM INFORMATION_SCHEMA.CROSS_REFERENCES WHERE PKTABLE_NAME = 'HFJ_RESOURCE'").getResultList();
List<ResourceForeignKey> expected = result.stream().map(a -> new ResourceForeignKey(a[0].toString(), a[1].toString())).collect(Collectors.toList());
runInTransaction(()-> {
List<Object[]> result = myEntityManager.createNativeQuery("SELECT FKTABLE_NAME, FKCOLUMN_NAME FROM INFORMATION_SCHEMA.CROSS_REFERENCES WHERE PKTABLE_NAME = 'HFJ_RESOURCE'").getResultList();
List<ResourceForeignKey> expected = result.stream().map(a -> new ResourceForeignKey(a[0].toString(), a[1].toString())).collect(Collectors.toList());
// Add the extra FKs that are not available in the CROSS_REFERENCES table
expected.add(new ResourceForeignKey("HFJ_HISTORY_TAG", "RES_ID"));
expected.add(new ResourceForeignKey("TRM_CODESYSTEM_VER", "RES_ID"));
expected.add(new ResourceForeignKey("HFJ_RES_VER_PROV", "RES_PID"));
// If this assertion fails, it means hapi-fhir has added a new foreign-key dependency to HFJ_RESOURCE. To fix
// the test, add the missing key to myResourceTableFKProvider.getResourceForeignKeys()
assertThat(myResourceTableFKProvider.getResourceForeignKeys(), containsInAnyOrder(expected.toArray()));
// Add the extra FKs that are not available in the CROSS_REFERENCES table
expected.add(new ResourceForeignKey("HFJ_HISTORY_TAG", "RES_ID"));
expected.add(new ResourceForeignKey("TRM_CODESYSTEM_VER", "RES_ID"));
expected.add(new ResourceForeignKey("HFJ_RES_VER_PROV", "RES_PID"));
// If this assertion fails, it means hapi-fhir has added a new foreign-key dependency to HFJ_RESOURCE. To fix
// the test, add the missing key to myResourceTableFKProvider.getResourceForeignKeys()
assertThat(myResourceTableFKProvider.getResourceForeignKeys(), containsInAnyOrder(expected.toArray()));
});
}
}

View File

@ -8,6 +8,7 @@ import ca.uhn.fhir.jpa.util.MemoryCacheService;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import org.hl7.fhir.r4.model.Patient;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
@ -40,6 +41,11 @@ public class IdHelperServiceTest {
@InjectMocks
private IdHelperService myHelperService;
@BeforeEach
public void beforeEach() {
myHelperService.setDontCheckActiveTransactionForUnitTest(true);
}
@Test
public void resolveResourcePersistentIds_withValidPids_returnsMap() {
RequestPartitionId partitionId = RequestPartitionId.allPartitions();

View File

@ -557,7 +557,9 @@ public abstract class BaseJpaR4Test extends BaseJpaTest implements ITestDataBuil
@AfterEach
public void afterPurgeDatabase() {
myMdmLinkDao.deleteAll();
runInTransaction(()->{
myMdmLinkDao.deleteAll();
});
purgeDatabase(myDaoConfig, mySystemDao, myResourceReindexingSvc, mySearchCoordinatorSvc, mySearchParamRegistry, myBulkDataExportSvc);
}

View File

@ -18,8 +18,22 @@ import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.util.HapiExtensions;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.*;
import org.hl7.fhir.r4.model.BooleanType;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Coverage;
import org.hl7.fhir.r4.model.DateTimeType;
import org.hl7.fhir.r4.model.DateType;
import org.hl7.fhir.r4.model.Encounter;
import org.hl7.fhir.r4.model.Enumerations;
import org.hl7.fhir.r4.model.Enumerations.PublicationStatus;
import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r4.model.Observation;
import org.hl7.fhir.r4.model.Organization;
import org.hl7.fhir.r4.model.Patient;
import org.hl7.fhir.r4.model.Practitioner;
import org.hl7.fhir.r4.model.Reference;
import org.hl7.fhir.r4.model.SearchParameter;
import org.hl7.fhir.r4.model.ServiceRequest;
import org.junit.jupiter.api.Test;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
@ -43,8 +57,6 @@ import static org.hamcrest.Matchers.stringContainsInOrder;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test {
@ -334,7 +346,7 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test
sp.setType(Enumerations.SearchParamType.COMPOSITE);
sp.setStatus(PublicationStatus.ACTIVE);
sp.addBase("Patient");
sp.addComponent() .setExpression("Patient");
sp.addComponent().setExpression("Patient");
sp.addExtension()
.setUrl(HapiExtensions.EXT_SP_UNIQUE)
.setValue(new BooleanType(true));
@ -1103,9 +1115,11 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test
public void testUniqueValuesAreIndexed_RefAndDateAndToken() {
createUniqueObservationSubjectDateCode();
List<ResourceIndexedComboStringUnique> uniques;
uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(0, uniques.size(), uniques.toString());
runInTransaction(() -> {
List<ResourceIndexedComboStringUnique> uniques;
uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(0, uniques.size(), uniques.toString());
});
Patient pt1 = new Patient();
pt1.setActive(true);
@ -1123,16 +1137,17 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test
ourLog.info("ID1: {} - ID2: {} - ID3: {}", id1, id2, id3);
uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(1, uniques.size(), uniques.toString());
assertEquals("Observation/" + id2.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue());
assertEquals("Observation?code=foo%7Cbar&date=2011-01-01&subject=Patient%2F" + id1.getIdPart(), uniques.get(0).getIndexString());
runInTransaction(() -> {
List<ResourceIndexedComboStringUnique> uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(1, uniques.size(), uniques.toString());
assertEquals("Observation/" + id2.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue());
assertEquals("Observation?code=foo%7Cbar&date=2011-01-01&subject=Patient%2F" + id1.getIdPart(), uniques.get(0).getIndexString());
});
}
@Test
public void testUniqueValuesAreIndexed_Reference_UsingModifierSyntax() {
createUniqueNameAndManagingOrganizationSps();
List<ResourceIndexedComboStringUnique> uniques;
Organization org = new Organization();
org.setId("Organization/ORG");
@ -1149,10 +1164,12 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test
assertThat(myMessages.toString(), containsString("Using UNIQUE index for query for search: Patient?name=FAMILY1&organization=Organization%2FORG"));
myMessages.clear();
uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(1, uniques.size());
assertEquals("Patient/" + id1.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue());
assertEquals("Patient?name=FAMILY1&organization=Organization%2FORG", uniques.get(0).getIndexString());
runInTransaction(() -> {
List<ResourceIndexedComboStringUnique> uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(1, uniques.size());
assertEquals("Patient/" + id1.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue());
assertEquals("Patient?name=FAMILY1&organization=Organization%2FORG", uniques.get(0).getIndexString());
});
// Again with a change
pt1 = new Patient();
@ -1160,16 +1177,17 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test
pt1.addName().setFamily("FAMILY1");
pt1.setManagingOrganization(new Reference("Organization/ORG"));
id1 = myPatientDao.update(pt1, "Patient?name=FAMILY1&organization:Organization=ORG", mySrd).getId().toUnqualifiedVersionless();
IIdType id2 = myPatientDao.update(pt1, "Patient?name=FAMILY1&organization:Organization=ORG", mySrd).getId().toUnqualifiedVersionless();
logCapturedMessages();
assertThat(myMessages.toString(), containsString("Using UNIQUE index for query for search: Patient?name=FAMILY1&organization=Organization%2FORG"));
myMessages.clear();
uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(1, uniques.size());
assertEquals("Patient/" + id1.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue());
assertEquals("Patient?name=FAMILY1&organization=Organization%2FORG", uniques.get(0).getIndexString());
runInTransaction(() -> {
List<ResourceIndexedComboStringUnique> uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(1, uniques.size());
assertEquals("Patient/" + id2.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue());
assertEquals("Patient?name=FAMILY1&organization=Organization%2FORG", uniques.get(0).getIndexString());
});
}
@ -1208,7 +1226,6 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test
@Test
public void testUniqueValuesAreIndexed_StringAndReference_UsingConditional() {
createUniqueNameAndManagingOrganizationSps();
List<ResourceIndexedComboStringUnique> uniques;
Organization org = new Organization();
org.setId("Organization/ORG");
@ -1220,28 +1237,31 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test
pt1.setManagingOrganization(new Reference("Organization/ORG"));
IIdType id1 = myPatientDao.update(pt1, "Patient?name=FAMILY1&organization.name=ORG").getId().toUnqualifiedVersionless();
uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(1, uniques.size());
assertEquals("Patient/" + id1.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue());
assertEquals("Patient?name=FAMILY1&organization=Organization%2FORG", uniques.get(0).getIndexString());
runInTransaction(() -> {
List<ResourceIndexedComboStringUnique> uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(1, uniques.size());
assertEquals("Patient/" + id1.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue());
assertEquals("Patient?name=FAMILY1&organization=Organization%2FORG", uniques.get(0).getIndexString());
});
// Again
pt1 = new Patient();
pt1.addName().setFamily("FAMILY1");
pt1.setManagingOrganization(new Reference("Organization/ORG"));
id1 = myPatientDao.update(pt1, "Patient?name=FAMILY1&organization.name=ORG").getId().toUnqualifiedVersionless();
myPatientDao.update(pt1, "Patient?name=FAMILY1&organization.name=ORG").getId().toUnqualifiedVersionless();
uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(1, uniques.size());
assertEquals("Patient/" + id1.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue());
assertEquals("Patient?name=FAMILY1&organization=Organization%2FORG", uniques.get(0).getIndexString());
runInTransaction(()->{
List<ResourceIndexedComboStringUnique> uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(1, uniques.size());
assertEquals("Patient/" + id1.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue());
assertEquals("Patient?name=FAMILY1&organization=Organization%2FORG", uniques.get(0).getIndexString());
});
}
@Test
public void testUniqueValuesAreIndexed_StringAndReference_UsingConditionalInTransaction() {
createUniqueNameAndManagingOrganizationSps();
List<ResourceIndexedComboStringUnique> uniques;
Organization org = new Organization();
org.setId("Organization/ORG");
@ -1251,7 +1271,7 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test
Bundle bundle = new Bundle();
bundle.setType(Bundle.BundleType.TRANSACTION);
String orgId = "urn:uuid:" + UUID.randomUUID().toString();
String orgId = "urn:uuid:" + UUID.randomUUID();
org = new Organization();
org.setName("ORG");
bundle
@ -1276,10 +1296,12 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test
IIdType id1 = new IdType(resp.getEntry().get(1).getResponse().getLocation());
uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(1, uniques.size());
assertEquals("Patient/" + id1.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue());
assertEquals("Patient?name=FAMILY1&organization=Organization%2FORG", uniques.get(0).getIndexString());
runInTransaction(() -> {
List<ResourceIndexedComboStringUnique> uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(1, uniques.size());
assertEquals("Patient/" + id1.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue());
assertEquals("Patient?name=FAMILY1&organization=Organization%2FORG", uniques.get(0).getIndexString());
});
// Again
@ -1309,13 +1331,14 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test
resp = mySystemDao.transaction(mySrd, bundle);
id1 = new IdType(resp.getEntry().get(1).getResponse().getLocation());
uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(1, uniques.size());
assertEquals("Patient/" + id1.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue());
assertEquals("Patient?name=FAMILY1&organization=Organization%2FORG", uniques.get(0).getIndexString());
IdType id2 = new IdType(resp.getEntry().get(1).getResponse().getLocation());
runInTransaction(() -> {
List<ResourceIndexedComboStringUnique> uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(1, uniques.size());
assertEquals("Patient/" + id2.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue());
assertEquals("Patient?name=FAMILY1&organization=Organization%2FORG", uniques.get(0).getIndexString());
});
}
@Test
@ -1323,26 +1346,31 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test
createUniqueBirthdateAndGenderSps();
Patient pt;
List<ResourceIndexedComboStringUnique> uniques;
pt = new Patient();
pt.setGender(Enumerations.AdministrativeGender.MALE);
myPatientDao.create(pt).getId().toUnqualifiedVersionless();
uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(0, uniques.size(), uniques.toString());
runInTransaction(() -> {
List<ResourceIndexedComboStringUnique> uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(0, uniques.size(), uniques.toString());
});
pt = new Patient();
myPatientDao.create(pt).getId().toUnqualifiedVersionless();
uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(0, uniques.size(), uniques.toString());
runInTransaction(() -> {
List<ResourceIndexedComboStringUnique> uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(0, uniques.size(), uniques.toString());
});
pt = new Patient();
pt.setBirthDateElement(new DateType());
pt.setGender(Enumerations.AdministrativeGender.MALE);
myPatientDao.create(pt).getId().toUnqualifiedVersionless();
uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(0, uniques.size(), uniques.toString());
runInTransaction(() -> {
List<ResourceIndexedComboStringUnique> uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(0, uniques.size(), uniques.toString());
});
}
@Test
@ -1354,14 +1382,15 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test
org.setName("ORG");
myOrganizationDao.update(org);
List<ResourceIndexedComboStringUnique> uniques;
Patient pt;
pt = new Patient();
pt.setManagingOrganization(new Reference("Organization/ORG"));
myPatientDao.create(pt).getId().toUnqualifiedVersionless();
uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(0, uniques.size(), uniques.toString());
runInTransaction(() -> {
List<ResourceIndexedComboStringUnique> uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(0, uniques.size(), uniques.toString());
});
pt = new Patient();
pt.addName()
@ -1370,14 +1399,18 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test
.addGiven("GIVEN2")
.addGiven("GIVEN2"); // GIVEN2 happens twice
myPatientDao.create(pt).getId().toUnqualifiedVersionless();
uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(0, uniques.size(), uniques.toString());
runInTransaction(() -> {
List<ResourceIndexedComboStringUnique> uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(0, uniques.size(), uniques.toString());
});
pt = new Patient();
pt.setActive(true);
myPatientDao.create(pt).getId().toUnqualifiedVersionless();
uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(0, uniques.size(), uniques.toString());
runInTransaction(() -> {
List<ResourceIndexedComboStringUnique> uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(0, uniques.size(), uniques.toString());
});
}
@Test
@ -1402,22 +1435,27 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test
myResourceReindexingSvc.forceReindexingPass();
myResourceReindexingSvc.forceReindexingPass();
List<ResourceIndexedComboStringUnique> uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(1, uniques.size(), uniques.toString());
assertEquals("Observation/" + id2.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue());
assertEquals("Observation?code=foo%7Cbar&date=2011-01-01&subject=Patient%2F" + id1.getIdPart(), uniques.get(0).getIndexString());
runInTransaction(() -> {
List<ResourceIndexedComboStringUnique> uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(1, uniques.size(), uniques.toString());
assertEquals("Observation/" + id2.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue());
assertEquals("Observation?code=foo%7Cbar&date=2011-01-01&subject=Patient%2F" + id1.getIdPart(), uniques.get(0).getIndexString());
});
myResourceIndexedCompositeStringUniqueDao.deleteAll();
runInTransaction(() -> {
myResourceIndexedCompositeStringUniqueDao.deleteAll();
});
myResourceReindexingSvc.markAllResourcesForReindexing();
myResourceReindexingSvc.forceReindexingPass();
myResourceReindexingSvc.forceReindexingPass();
uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(1, uniques.size(), uniques.toString());
assertEquals("Observation/" + id2.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue());
assertEquals("Observation?code=foo%7Cbar&date=2011-01-01&subject=Patient%2F" + id1.getIdPart(), uniques.get(0).getIndexString());
runInTransaction(() -> {
List<ResourceIndexedComboStringUnique> uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(1, uniques.size(), uniques.toString());
assertEquals("Observation/" + id2.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue());
assertEquals("Observation?code=foo%7Cbar&date=2011-01-01&subject=Patient%2F" + id1.getIdPart(), uniques.get(0).getIndexString());
});
}
@ -1509,5 +1547,4 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test
}
}

View File

@ -1212,12 +1212,12 @@ public class FhirResourceDaoR4ConceptMapTest extends BaseJpaR4Test {
@Test
public void testConceptMapFindTermConceptMapByUrl() {
Pageable page = PageRequest.of(0, 1);
List<TermConceptMap> theExpConceptMapList = myTermConceptMapDao.getTermConceptMapEntitiesByUrlOrderByMostRecentUpdate(page, CM_URL);
assertEquals(1, theExpConceptMapList.size());
assertEquals(CM_URL, theExpConceptMapList.get(0).getUrl());
runInTransaction(()-> {
Pageable page = PageRequest.of(0, 1);
List<TermConceptMap> theExpConceptMapList = myTermConceptMapDao.getTermConceptMapEntitiesByUrlOrderByMostRecentUpdate(page, CM_URL);
assertEquals(1, theExpConceptMapList.size());
assertEquals(CM_URL, theExpConceptMapList.get(0).getUrl());
});
}
@Test
@ -1233,24 +1233,26 @@ public class FhirResourceDaoR4ConceptMapTest extends BaseJpaR4Test {
myConceptMapDao.create(theConceptMap1);
myConceptMapDao.create(theConceptMap2);
Optional<TermConceptMap> theExpConceptMapV1 = myTermConceptMapDao.findTermConceptMapByUrlAndVersion(theUrl, "v1");
Optional<TermConceptMap> theExpConceptMapV2 = myTermConceptMapDao.findTermConceptMapByUrlAndVersion(theUrl, "v2");
runInTransaction(()-> {
Optional<TermConceptMap> theExpConceptMapV1 = myTermConceptMapDao.findTermConceptMapByUrlAndVersion(theUrl, "v1");
Optional<TermConceptMap> theExpConceptMapV2 = myTermConceptMapDao.findTermConceptMapByUrlAndVersion(theUrl, "v2");
assertTrue(theExpConceptMapV1.isPresent());
assertEquals(theUrl, theExpConceptMapV1.get().getUrl());
assertEquals("v1", theExpConceptMapV1.get().getVersion());
assertTrue(theExpConceptMapV1.isPresent());
assertEquals(theUrl, theExpConceptMapV1.get().getUrl());
assertEquals("v1", theExpConceptMapV1.get().getVersion());
assertTrue(theExpConceptMapV2.isPresent());
assertEquals(theUrl, theExpConceptMapV2.get().getUrl());
assertEquals("v2", theExpConceptMapV2.get().getVersion());
assertTrue(theExpConceptMapV2.isPresent());
assertEquals(theUrl, theExpConceptMapV2.get().getUrl());
assertEquals("v2", theExpConceptMapV2.get().getVersion());
// should return the latest one which is v2
Pageable page = PageRequest.of(0, 1);
List<TermConceptMap> theExpSecondOne = myTermConceptMapDao.getTermConceptMapEntitiesByUrlOrderByMostRecentUpdate(page, theUrl);
// should return the latest one which is v2
Pageable page = PageRequest.of(0, 1);
List<TermConceptMap> theExpSecondOne = myTermConceptMapDao.getTermConceptMapEntitiesByUrlOrderByMostRecentUpdate(page, theUrl);
assertEquals(1, theExpSecondOne.size());
assertEquals(theUrl, theExpSecondOne.get(0).getUrl());
assertEquals("v2", theExpSecondOne.get(0).getVersion());
assertEquals(1, theExpSecondOne.size());
assertEquals(theUrl, theExpSecondOne.get(0).getUrl());
assertEquals("v2", theExpSecondOne.get(0).getVersion());
});
}
@Test
@ -1266,18 +1268,20 @@ public class FhirResourceDaoR4ConceptMapTest extends BaseJpaR4Test {
myConceptMapDao.create(theConceptMap1);
myConceptMapDao.create(theConceptMap2);
Optional<TermConceptMap> theExpConceptMapV1 = myTermConceptMapDao.findTermConceptMapByUrlAndVersion(theUrl, "v1");
runInTransaction(()-> {
Optional<TermConceptMap> theExpConceptMapV1 = myTermConceptMapDao.findTermConceptMapByUrlAndVersion(theUrl, "v1");
assertTrue(theExpConceptMapV1.isPresent());
assertEquals(theUrl, theExpConceptMapV1.get().getUrl());
assertEquals("v1", theExpConceptMapV1.get().getVersion());
assertTrue(theExpConceptMapV1.isPresent());
assertEquals(theUrl, theExpConceptMapV1.get().getUrl());
assertEquals("v1", theExpConceptMapV1.get().getVersion());
// should return the latest one which is v2
Pageable page = PageRequest.of(0, 1);
List<TermConceptMap> theExpSecondOne = myTermConceptMapDao.getTermConceptMapEntitiesByUrlOrderByMostRecentUpdate(page, theUrl);
// should return the latest one which is v2
Pageable page = PageRequest.of(0, 1);
List<TermConceptMap> theExpSecondOne = myTermConceptMapDao.getTermConceptMapEntitiesByUrlOrderByMostRecentUpdate(page, theUrl);
assertEquals(1, theExpSecondOne.size());
assertEquals(theUrl, theExpSecondOne.get(0).getUrl());
assertNull(theExpSecondOne.get(0).getVersion());
assertEquals(1, theExpSecondOne.size());
assertEquals(theUrl, theExpSecondOne.get(0).getUrl());
assertNull(theExpSecondOne.get(0).getVersion());
});
}
}

View File

@ -759,7 +759,6 @@ public class FhirResourceDaoR4LegacySearchBuilderTest extends BaseJpaR4Test {
}
@Test
public void testEmptyChain() {
@ -4923,7 +4922,9 @@ public class FhirResourceDaoR4LegacySearchBuilderTest extends BaseJpaR4Test {
p.addName().setFamily("A1");
myPatientDao.create(p);
assertEquals(0, mySearchEntityDao.count());
runInTransaction(() -> {
assertEquals(0, mySearchEntityDao.count());
});
SearchParameterMap map = new SearchParameterMap();
StringOrListParam or = new StringOrListParam();
@ -4934,7 +4935,9 @@ public class FhirResourceDaoR4LegacySearchBuilderTest extends BaseJpaR4Test {
map.add(Patient.SP_NAME, or);
IBundleProvider results = myPatientDao.search(map);
assertEquals(1, results.getResources(0, 10).size());
assertEquals(1, mySearchEntityDao.count());
runInTransaction(() -> {
assertEquals(1, mySearchEntityDao.count());
});
map = new SearchParameterMap();
or = new StringOrListParam();
@ -4947,7 +4950,9 @@ public class FhirResourceDaoR4LegacySearchBuilderTest extends BaseJpaR4Test {
results = myPatientDao.search(map);
assertEquals(1, results.getResources(0, 10).size());
// We expect a new one because we don't cache the search URL for very long search URLs
assertEquals(2, mySearchEntityDao.count());
runInTransaction(() -> {
assertEquals(2, mySearchEntityDao.count());
});
}
@Test
@ -5141,7 +5146,9 @@ public class FhirResourceDaoR4LegacySearchBuilderTest extends BaseJpaR4Test {
p.addName().setFamily("A1");
myPatientDao.create(p);
assertEquals(0, mySearchEntityDao.count());
runInTransaction(() -> {
assertEquals(0, mySearchEntityDao.count());
});
SearchParameterMap map = new SearchParameterMap();
StringOrListParam or = new StringOrListParam();
@ -5152,8 +5159,9 @@ public class FhirResourceDaoR4LegacySearchBuilderTest extends BaseJpaR4Test {
map.add(Patient.SP_NAME, or);
IBundleProvider results = myPatientDao.search(map);
assertEquals(1, results.getResources(0, 10).size());
assertEquals(1, mySearchEntityDao.count());
runInTransaction(() -> {
assertEquals(1, mySearchEntityDao.count());
});
map = new SearchParameterMap();
or = new StringOrListParam();
or.addOr(new StringParam("A1"));
@ -5163,8 +5171,9 @@ public class FhirResourceDaoR4LegacySearchBuilderTest extends BaseJpaR4Test {
map.add(Patient.SP_NAME, or);
results = myPatientDao.search(map);
assertEquals(1, results.getResources(0, 10).size());
assertEquals(1, mySearchEntityDao.count());
runInTransaction(() -> {
assertEquals(1, mySearchEntityDao.count());
});
}
/**

View File

@ -89,8 +89,8 @@ public class FhirResourceDaoR4SearchCustomSearchParamTest extends BaseJpaR4Test
@AfterEach
public void after() {
myDaoConfig.setValidateSearchParameterExpressionsOnSave(new DaoConfig().isValidateSearchParameterExpressionsOnSave());
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED);
}
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED);
}
@BeforeEach
public void beforeDisableResultReuse() {
@ -101,7 +101,7 @@ public class FhirResourceDaoR4SearchCustomSearchParamTest extends BaseJpaR4Test
@Test
public void testStoreSearchParamWithBracketsInExpression() {
myDaoConfig.setMarkResourcesForReindexingUponSearchParameterChange(true);
SearchParameter fooSp = new SearchParameter();
@ -138,7 +138,7 @@ public class FhirResourceDaoR4SearchCustomSearchParamTest extends BaseJpaR4Test
mySearchParamRegistry.forceRefresh();
}
@Test
public void testStoreSearchParamWithBracketsInExpressionNormalizedQuantityStorageSupported() {
@ -158,7 +158,7 @@ public class FhirResourceDaoR4SearchCustomSearchParamTest extends BaseJpaR4Test
mySearchParameterDao.create(fooSp, mySrd);
mySearchParamRegistry.forceRefresh();
}
/**
* See #2023
*/
@ -182,7 +182,7 @@ public class FhirResourceDaoR4SearchCustomSearchParamTest extends BaseJpaR4Test
Patient patient = new Patient();
patient.setId("future-appointment-count-pt");
patient.setActive(true);
patient.addExtension( "http://integer", new IntegerType(1));
patient.addExtension("http://integer", new IntegerType(1));
myPatientDao.update(patient);
IBundleProvider search;
@ -546,7 +546,6 @@ public class FhirResourceDaoR4SearchCustomSearchParamTest extends BaseJpaR4Test
}
@Test
public void testOverrideAndDisableBuiltInSearchParametersWithOverridingDisabled() {
myModelConfig.setDefaultSearchParamsCanBeOverridden(false);
@ -596,13 +595,15 @@ public class FhirResourceDaoR4SearchCustomSearchParamTest extends BaseJpaR4Test
g.addMember().getEntity().setReferenceElement(pid);
myGroupDao.create(g);
assertThat(myResourceLinkDao.findAll(), empty());
assertThat(ListUtil.filter(myResourceIndexedSearchParamTokenDao.findAll(), new ListUtil.Filter<ResourceIndexedSearchParamToken>() {
@Override
public boolean isOut(ResourceIndexedSearchParamToken object) {
return !object.getResourceType().equals("Group") || object.isMissing();
}
}), empty());
runInTransaction(() -> {
assertThat(myResourceLinkDao.findAll(), empty());
assertThat(ListUtil.filter(myResourceIndexedSearchParamTokenDao.findAll(), new ListUtil.Filter<ResourceIndexedSearchParamToken>() {
@Override
public boolean isOut(ResourceIndexedSearchParamToken object) {
return !object.getResourceType().equals("Group") || object.isMissing();
}
}), empty());
});
}
/**
@ -1676,7 +1677,4 @@ public class FhirResourceDaoR4SearchCustomSearchParamTest extends BaseJpaR4Test
}
}

View File

@ -84,11 +84,13 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
org.setActive(true);
myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
assertThat(mySearchParamPresentDao.findAll(), empty());
assertThat(myResourceIndexedSearchParamStringDao.findAll(), empty());
assertThat(myResourceIndexedSearchParamDateDao.findAll(), empty());
assertThat(myResourceIndexedSearchParamTokenDao.findAll(), hasSize(1));
assertThat(myResourceIndexedSearchParamQuantityDao.findAll(), empty());
runInTransaction(() -> {
assertThat(mySearchParamPresentDao.findAll(), empty());
assertThat(myResourceIndexedSearchParamStringDao.findAll(), empty());
assertThat(myResourceIndexedSearchParamDateDao.findAll(), empty());
assertThat(myResourceIndexedSearchParamTokenDao.findAll(), hasSize(1));
assertThat(myResourceIndexedSearchParamQuantityDao.findAll(), empty());
});
}
@ -101,11 +103,13 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
org.setActive(true);
myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
assertThat(mySearchParamPresentDao.findAll(), empty());
assertThat(myResourceIndexedSearchParamStringDao.findAll(), empty());
assertThat(myResourceIndexedSearchParamDateDao.findAll(), empty());
assertThat(myResourceIndexedSearchParamTokenDao.findAll(), hasSize(1));
assertThat(myResourceIndexedSearchParamQuantityDao.findAll(), empty());
runInTransaction(() -> {
assertThat(mySearchParamPresentDao.findAll(), empty());
assertThat(myResourceIndexedSearchParamStringDao.findAll(), empty());
assertThat(myResourceIndexedSearchParamDateDao.findAll(), empty());
assertThat(myResourceIndexedSearchParamTokenDao.findAll(), hasSize(1));
assertThat(myResourceIndexedSearchParamQuantityDao.findAll(), empty());
});
}
@ -118,11 +122,13 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
org.setActive(true);
myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
assertThat(mySearchParamPresentDao.findAll(), empty());
assertThat(myResourceIndexedSearchParamStringDao.findAll(), empty());
assertThat(myResourceIndexedSearchParamDateDao.findAll(), empty());
assertThat(myResourceIndexedSearchParamTokenDao.findAll(), hasSize(1));
assertThat(myResourceIndexedSearchParamQuantityDao.findAll(), empty());
runInTransaction(() -> {
assertThat(mySearchParamPresentDao.findAll(), empty());
assertThat(myResourceIndexedSearchParamStringDao.findAll(), empty());
assertThat(myResourceIndexedSearchParamDateDao.findAll(), empty());
assertThat(myResourceIndexedSearchParamTokenDao.findAll(), hasSize(1));
assertThat(myResourceIndexedSearchParamQuantityDao.findAll(), empty());
});
}

View File

@ -200,6 +200,28 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
myDaoConfig.setReuseCachedSearchResultsForMillis(null);
}
@Test
public void testSearchInExistingTransaction() {
createPatient(withBirthdate("2021-01-01"));
// Search in a new transaction
IBundleProvider outcome = runInTransaction(() -> {
return myPatientDao.search(new SearchParameterMap().add(Patient.SP_BIRTHDATE, new DateParam("lt2022")));
});
assertEquals(1, outcome.sizeOrThrowNpe());
assertEquals(1, outcome.getResources(0, 999).size());
// Search and fetch in a new transaction
runInTransaction(() -> {
IBundleProvider outcome2 = myPatientDao.search(new SearchParameterMap().add(Patient.SP_BIRTHDATE, new DateParam("lt2022")));
assertEquals(1, outcome2.sizeOrThrowNpe());
assertEquals(1, outcome2.getResources(0, 999).size());
});
}
@Test
public void testCanonicalReference() {
StructureDefinition sd = new StructureDefinition();
@ -5079,7 +5101,7 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
p.addName().setFamily("A1");
myPatientDao.create(p);
assertEquals(0, mySearchEntityDao.count());
runInTransaction(()->assertEquals(0, mySearchEntityDao.count()));
SearchParameterMap map = new SearchParameterMap();
StringOrListParam or = new StringOrListParam();
@ -5090,7 +5112,7 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
map.add(Patient.SP_NAME, or);
IBundleProvider results = myPatientDao.search(map);
assertEquals(1, results.getResources(0, 10).size());
assertEquals(1, mySearchEntityDao.count());
runInTransaction(()->assertEquals(1, mySearchEntityDao.count()));
map = new SearchParameterMap();
or = new StringOrListParam();
@ -5103,7 +5125,7 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
results = myPatientDao.search(map);
assertEquals(1, results.getResources(0, 10).size());
// We expect a new one because we don't cache the search URL for very long search URLs
assertEquals(2, mySearchEntityDao.count());
runInTransaction(()->assertEquals(2, mySearchEntityDao.count()));
}
@Test
@ -5296,7 +5318,7 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
p.addName().setFamily("A1");
myPatientDao.create(p);
assertEquals(0, mySearchEntityDao.count());
runInTransaction(()->assertEquals(0, mySearchEntityDao.count()));
SearchParameterMap map = new SearchParameterMap();
StringOrListParam or = new StringOrListParam();
@ -5307,7 +5329,7 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
map.add(Patient.SP_NAME, or);
IBundleProvider results = myPatientDao.search(map);
assertEquals(1, results.getResources(0, 10).size());
assertEquals(1, mySearchEntityDao.count());
assertEquals(1, runInTransaction(()->mySearchEntityDao.count()));
map = new SearchParameterMap();
or = new StringOrListParam();
@ -5318,7 +5340,7 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
map.add(Patient.SP_NAME, or);
results = myPatientDao.search(map);
assertEquals(1, results.getResources(0, 10).size());
assertEquals(1, mySearchEntityDao.count());
assertEquals(1, runInTransaction(()->mySearchEntityDao.count()));
}

View File

@ -2,6 +2,7 @@ package ca.uhn.fhir.jpa.dao.r4;
import ca.uhn.fhir.jpa.api.config.DaoConfig;
import ca.uhn.fhir.jpa.dao.data.ISearchDao;
import ca.uhn.fhir.jpa.entity.TermValueSet;
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamDate;
@ -3288,7 +3289,7 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test {
p.addName().setFamily("A1");
myPatientDao.create(p);
assertEquals(0, mySearchEntityDao.count());
runInTransaction(()->assertEquals(0, mySearchEntityDao.count()));
SearchParameterMap map = new SearchParameterMap();
StringOrListParam or = new StringOrListParam();
@ -3299,7 +3300,7 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test {
map.add(Patient.SP_NAME, or);
IBundleProvider results = myPatientDao.search(map);
assertEquals(1, results.getResources(0, 10).size());
assertEquals(1, mySearchEntityDao.count());
runInTransaction(()->assertEquals(1, mySearchEntityDao.count()));
map = new SearchParameterMap();
or = new StringOrListParam();
@ -3312,7 +3313,7 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test {
results = myPatientDao.search(map);
assertEquals(1, results.getResources(0, 10).size());
// We expect a new one because we don't cache the search URL for very long search URLs
assertEquals(2, mySearchEntityDao.count());
runInTransaction(()->assertEquals(2, mySearchEntityDao.count()));
}
@ -3400,7 +3401,7 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test {
p.addName().setFamily("A1");
myPatientDao.create(p);
assertEquals(0, mySearchEntityDao.count());
runInTransaction(()->assertEquals(0, mySearchEntityDao.count()));
SearchParameterMap map = new SearchParameterMap();
StringOrListParam or = new StringOrListParam();
@ -3411,7 +3412,7 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test {
map.add(Patient.SP_NAME, or);
IBundleProvider results = myPatientDao.search(map);
assertEquals(1, results.getResources(0, 10).size());
assertEquals(1, mySearchEntityDao.count());
runInTransaction(()->assertEquals(1, mySearchEntityDao.count()));
map = new SearchParameterMap();
or = new StringOrListParam();
@ -3422,7 +3423,7 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test {
map.add(Patient.SP_NAME, or);
results = myPatientDao.search(map);
assertEquals(1, results.getResources(0, 10).size());
assertEquals(1, mySearchEntityDao.count());
runInTransaction(()->assertEquals(1, mySearchEntityDao.count()));
}

View File

@ -6,11 +6,11 @@ import ca.uhn.fhir.jpa.api.config.DaoConfig;
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink.RelationshipTypeEnum;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.term.TermReindexingSvcImpl;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.param.TokenParam;
import ca.uhn.fhir.rest.param.TokenParamModifier;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
@ -18,7 +18,6 @@ import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.util.TestUtil;
import ca.uhn.fhir.validation.FhirValidator;
import ca.uhn.fhir.validation.ValidationResult;
import org.hl7.fhir.instance.model.api.IIdType;
@ -37,11 +36,10 @@ import org.hl7.fhir.r4.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.r4.model.ValueSet.FilterOperator;
import org.hl7.fhir.r4.model.ValueSet.ValueSetComposeComponent;
import org.hl7.fhir.r4.model.ValueSet.ValueSetExpansionContainsComponent;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.AfterAll;
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 java.util.ArrayList;
import java.util.Date;
@ -85,41 +83,43 @@ public class FhirResourceDaoR4TerminologyTest extends BaseJpaR4Test {
codeSystem.setContent(CodeSystemContentMode.NOTPRESENT);
IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified();
ResourceTable table = myResourceTableDao.findById(id.getIdPartAsLong()).orElseThrow(IllegalStateException::new);
return runInTransaction(() -> {
ResourceTable table = myResourceTableDao.findById(id.getIdPartAsLong()).orElseThrow(IllegalStateException::new);
TermCodeSystemVersion cs = new TermCodeSystemVersion();
cs.setResource(table);
TermCodeSystemVersion cs = new TermCodeSystemVersion();
cs.setResource(table);
TermConcept parentA = new TermConcept(cs, "ParentA").setDisplay("Parent A");
cs.getConcepts().add(parentA);
TermConcept parentA = new TermConcept(cs, "ParentA").setDisplay("Parent A");
cs.getConcepts().add(parentA);
TermConcept childAA = new TermConcept(cs, "childAA").setDisplay("Child AA");
parentA.addChild(childAA, RelationshipTypeEnum.ISA);
TermConcept childAA = new TermConcept(cs, "childAA").setDisplay("Child AA");
parentA.addChild(childAA, RelationshipTypeEnum.ISA);
TermConcept childAAA = new TermConcept(cs, "childAAA").setDisplay("Child AAA");
childAA.addChild(childAAA, RelationshipTypeEnum.ISA);
TermConcept childAAA = new TermConcept(cs, "childAAA").setDisplay("Child AAA");
childAA.addChild(childAAA, RelationshipTypeEnum.ISA);
TermConcept childAAB = new TermConcept(cs, "childAAB").setDisplay("Child AAB");
childAA.addChild(childAAB, RelationshipTypeEnum.ISA);
TermConcept childAAB = new TermConcept(cs, "childAAB").setDisplay("Child AAB");
childAA.addChild(childAAB, RelationshipTypeEnum.ISA);
TermConcept childAB = new TermConcept(cs, "childAB").setDisplay("Child AB");
parentA.addChild(childAB, RelationshipTypeEnum.ISA);
TermConcept childAB = new TermConcept(cs, "childAB").setDisplay("Child AB");
parentA.addChild(childAB, RelationshipTypeEnum.ISA);
TermConcept parentB = new TermConcept(cs, "ParentB").setDisplay("Parent B");
cs.getConcepts().add(parentB);
TermConcept parentB = new TermConcept(cs, "ParentB").setDisplay("Parent B");
cs.getConcepts().add(parentB);
TermConcept childBA = new TermConcept(cs, "childBA").setDisplay("Child BA");
childBA.addChild(childAAB, RelationshipTypeEnum.ISA);
parentB.addChild(childBA, RelationshipTypeEnum.ISA);
TermConcept childBA = new TermConcept(cs, "childBA").setDisplay("Child BA");
childBA.addChild(childAAB, RelationshipTypeEnum.ISA);
parentB.addChild(childBA, RelationshipTypeEnum.ISA);
TermConcept parentC = new TermConcept(cs, "ParentC").setDisplay("Parent C");
cs.getConcepts().add(parentC);
TermConcept parentC = new TermConcept(cs, "ParentC").setDisplay("Parent C");
cs.getConcepts().add(parentC);
TermConcept childCA = new TermConcept(cs, "childCA").setDisplay("Child CA");
parentC.addChild(childCA, RelationshipTypeEnum.ISA);
TermConcept childCA = new TermConcept(cs, "childCA").setDisplay("Child CA");
parentC.addChild(childCA, RelationshipTypeEnum.ISA);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
return codeSystem;
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
return codeSystem;
});
}
private void createExternalCsAndLocalVs() {
@ -135,28 +135,30 @@ public class FhirResourceDaoR4TerminologyTest extends BaseJpaR4Test {
codeSystem.setContent(CodeSystemContentMode.NOTPRESENT);
IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified();
ResourceTable table = myResourceTableDao.findById(id.getIdPartAsLong()).orElseThrow(IllegalStateException::new);
return runInTransaction(() -> {
ResourceTable table = myResourceTableDao.findById(id.getIdPartAsLong()).orElseThrow(IllegalStateException::new);
TermCodeSystemVersion cs = new TermCodeSystemVersion();
cs.setResource(table);
TermCodeSystemVersion cs = new TermCodeSystemVersion();
cs.setResource(table);
TermConcept hello = new TermConcept(cs, "hello").setDisplay("Hello");
cs.getConcepts().add(hello);
TermConcept hello = new TermConcept(cs, "hello").setDisplay("Hello");
cs.getConcepts().add(hello);
TermConcept goodbye = new TermConcept(cs, "goodbye").setDisplay("Goodbye");
cs.getConcepts().add(goodbye);
TermConcept goodbye = new TermConcept(cs, "goodbye").setDisplay("Goodbye");
cs.getConcepts().add(goodbye);
TermConcept dogs = new TermConcept(cs, "dogs").setDisplay("Dogs");
cs.getConcepts().add(dogs);
TermConcept dogs = new TermConcept(cs, "dogs").setDisplay("Dogs");
cs.getConcepts().add(dogs);
TermConcept labrador = new TermConcept(cs, "labrador").setDisplay("Labrador");
dogs.addChild(labrador, RelationshipTypeEnum.ISA);
TermConcept labrador = new TermConcept(cs, "labrador").setDisplay("Labrador");
dogs.addChild(labrador, RelationshipTypeEnum.ISA);
TermConcept beagle = new TermConcept(cs, "beagle").setDisplay("Beagle");
dogs.addChild(beagle, RelationshipTypeEnum.ISA);
TermConcept beagle = new TermConcept(cs, "beagle").setDisplay("Beagle");
dogs.addChild(beagle, RelationshipTypeEnum.ISA);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
return codeSystem;
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
return codeSystem;
});
}
private void createExternalCsLarge() {
@ -166,7 +168,7 @@ public class FhirResourceDaoR4TerminologyTest extends BaseJpaR4Test {
codeSystem.setContent(CodeSystemContentMode.NOTPRESENT);
IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified();
ResourceTable table = myResourceTableDao.findById(id.getIdPartAsLong()).orElseThrow(IllegalStateException::new);
ResourceTable table = runInTransaction(()->myResourceTableDao.findById(id.getIdPartAsLong()).orElseThrow(IllegalStateException::new));
TermCodeSystemVersion cs = new TermCodeSystemVersion();
cs.setResource(table);
@ -331,6 +333,7 @@ public class FhirResourceDaoR4TerminologyTest extends BaseJpaR4Test {
assertEquals("Invalid filter, must have fields populated: property op value", e.getMessage());
}
}
@Test
public void testExpandWithIncludeConceptHaveCodeAndDisplay() {
CodeSystem codeSystem = createExternalCsDogs();
@ -351,7 +354,7 @@ public class FhirResourceDaoR4TerminologyTest extends BaseJpaR4Test {
assertEquals(2, result.getExpansion().getTotal());
ArrayList<String> codes = toCodesContains(result.getExpansion().getContains());
assertThat(codes, containsInAnyOrder("hello", "goodbye"));
for (ValueSetExpansionContainsComponent vsConcept : result.getExpansion().getContains()){
for (ValueSetExpansionContainsComponent vsConcept : result.getExpansion().getContains()) {
assertTrue(vsConcept.getDisplay().contains("VS"));
}
@ -528,7 +531,7 @@ public class FhirResourceDaoR4TerminologyTest extends BaseJpaR4Test {
codeSystem.setContent(CodeSystemContentMode.NOTPRESENT);
IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified();
ResourceTable table = myResourceTableDao.findById(id.getIdPartAsLong()).orElseThrow(IllegalStateException::new);
ResourceTable table = runInTransaction(()->myResourceTableDao.findById(id.getIdPartAsLong()).orElseThrow(IllegalStateException::new));
TermCodeSystemVersion cs = new TermCodeSystemVersion();
cs.setResource(table);
@ -549,7 +552,7 @@ public class FhirResourceDaoR4TerminologyTest extends BaseJpaR4Test {
concept = new TermConcept(cs, "LA9999-7");
cs.getConcepts().add(concept);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION" , cs, table);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
ValueSet valueSet = new ValueSet();
valueSet.setUrl(URL_MY_VALUE_SET);
@ -854,13 +857,13 @@ public class FhirResourceDaoR4TerminologyTest extends BaseJpaR4Test {
codeSystem.setContent(CodeSystemContentMode.NOTPRESENT);
IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified();
ResourceTable table = myResourceTableDao.findById(id.getIdPartAsLong()).orElseThrow(IllegalStateException::new);
ResourceTable table = runInTransaction(()->myResourceTableDao.findById(id.getIdPartAsLong()).orElseThrow(IllegalStateException::new));
TermCodeSystemVersion cs = new TermCodeSystemVersion();
cs.setResource(table);
TermConcept parentA = new TermConcept(cs, "ParentA").setDisplay("Parent A");
cs.getConcepts().add(parentA);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), "http://snomed.info/sct", "Snomed CT", "SYSTEM VERSION" , cs, table);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), "http://snomed.info/sct", "Snomed CT", "SYSTEM VERSION", cs, table);
StringType code = new StringType("ParentA");
StringType system = new StringType("http://snomed.info/sct");

View File

@ -29,9 +29,6 @@ public class FhirResourceDaoR4ValueSetMultiVersionTest extends BaseJpaR4Test {
public static final String URL_MY_VALUE_SET = "http://example.com/my_value_set";
public static final String URL_MY_CODE_SYSTEM = "http://example.com/my_code_system";
private enum ValueSetVersions { NULL, V1, V2 }
@Autowired
protected ITermValueSetConceptDao myTermValueSetConceptDao;
@ -56,7 +53,7 @@ public class FhirResourceDaoR4ValueSetMultiVersionTest extends BaseJpaR4Test {
if (theVersion == null) {
valueSet.setName("ValueSet_noVersion");
} else {
valueSet.setName("ValueSet_"+theVersion);
valueSet.setName("ValueSet_" + theVersion);
}
valueSet.getCompose().addInclude().setSystem(theCodeSystem.getUrl());
return myValueSetDao.create(valueSet, mySrd);
@ -86,31 +83,33 @@ public class FhirResourceDaoR4ValueSetMultiVersionTest extends BaseJpaR4Test {
public void testCreateVersionedValueSets() {
Map<ValueSetVersions, DaoMethodOutcome> myValueSets = createVersionedValueSets();
assertEquals(3, myTermValueSetDao.findTermValueSetByUrl(PageRequest.of(0, 10), URL_MY_VALUE_SET).size());
runInTransaction(() -> {
assertEquals(3, myTermValueSetDao.findTermValueSetByUrl(PageRequest.of(0, 10), URL_MY_VALUE_SET).size());
Optional<TermValueSet> optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndNullVersion(URL_MY_VALUE_SET);
assertTrue(optionalTermValueSet.isPresent());
Long nullVersion_resid = ((ResourceTable)myValueSets.get(ValueSetVersions.NULL).getEntity()).getId();
assertNotNull(nullVersion_resid);
assertNotNull(optionalTermValueSet.get().getResource());
assertEquals(nullVersion_resid, optionalTermValueSet.get().getResource().getId());
assertEquals("ValueSet_noVersion", optionalTermValueSet.get().getName());
Optional<TermValueSet> optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndNullVersion(URL_MY_VALUE_SET);
assertTrue(optionalTermValueSet.isPresent());
Long nullVersion_resid = ((ResourceTable) myValueSets.get(ValueSetVersions.NULL).getEntity()).getId();
assertNotNull(nullVersion_resid);
assertNotNull(optionalTermValueSet.get().getResource());
assertEquals(nullVersion_resid, optionalTermValueSet.get().getResource().getId());
assertEquals("ValueSet_noVersion", optionalTermValueSet.get().getName());
optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v1");
assertTrue(optionalTermValueSet.isPresent());
Long v1Version_resid = ((ResourceTable)myValueSets.get(ValueSetVersions.V1).getEntity()).getId();
assertNotNull(v1Version_resid);
assertNotNull(optionalTermValueSet.get().getResource());
assertEquals(v1Version_resid, optionalTermValueSet.get().getResource().getId());
assertEquals("ValueSet_v1", optionalTermValueSet.get().getName());
optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v1");
assertTrue(optionalTermValueSet.isPresent());
Long v1Version_resid = ((ResourceTable) myValueSets.get(ValueSetVersions.V1).getEntity()).getId();
assertNotNull(v1Version_resid);
assertNotNull(optionalTermValueSet.get().getResource());
assertEquals(v1Version_resid, optionalTermValueSet.get().getResource().getId());
assertEquals("ValueSet_v1", optionalTermValueSet.get().getName());
optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v2");
assertTrue(optionalTermValueSet.isPresent());
Long v2Version_resid = ((ResourceTable)myValueSets.get(ValueSetVersions.V2).getEntity()).getId();
assertNotNull(v2Version_resid);
assertNotNull(optionalTermValueSet.get().getResource());
assertEquals(v2Version_resid, optionalTermValueSet.get().getResource().getId());
assertEquals("ValueSet_v2", optionalTermValueSet.get().getName());
optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v2");
assertTrue(optionalTermValueSet.isPresent());
Long v2Version_resid = ((ResourceTable) myValueSets.get(ValueSetVersions.V2).getEntity()).getId();
assertNotNull(v2Version_resid);
assertNotNull(optionalTermValueSet.get().getResource());
assertEquals(v2Version_resid, optionalTermValueSet.get().getResource().getId());
assertEquals("ValueSet_v2", optionalTermValueSet.get().getName());
});
}
@ -118,108 +117,119 @@ public class FhirResourceDaoR4ValueSetMultiVersionTest extends BaseJpaR4Test {
public void testUpdateVersionedValueSets() {
Map<ValueSetVersions, DaoMethodOutcome> myValueSets = createVersionedValueSets();
assertEquals(3, myTermValueSetDao.findTermValueSetByUrl(PageRequest.of(0, 10), URL_MY_VALUE_SET).size());
runInTransaction(() -> {
assertEquals(3, myTermValueSetDao.findTermValueSetByUrl(PageRequest.of(0, 10), URL_MY_VALUE_SET).size());
TermValueSet termValueSet = myTermValueSetDao.findTermValueSetByUrlAndNullVersion(URL_MY_VALUE_SET).orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " with null version"));
assertEquals("ValueSet_noVersion", termValueSet.getName());
TermValueSet vs = myTermValueSetDao.findTermValueSetByUrlAndNullVersion(URL_MY_VALUE_SET).orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " with null version"));
assertEquals("ValueSet_noVersion", vs.getName());
termValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v1").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v1"));
assertEquals("ValueSet_v1", termValueSet.getName());
vs = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v1").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v1"));
assertEquals("ValueSet_v1", vs.getName());
termValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v2").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v2"));
assertEquals("ValueSet_v2", termValueSet.getName());
vs = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v2").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v2"));
assertEquals("ValueSet_v2", vs.getName());
});
// Update ValueSets
ValueSet updated = (ValueSet)myValueSets.get(ValueSetVersions.NULL).getResource();
ValueSet updated = (ValueSet) myValueSets.get(ValueSetVersions.NULL).getResource();
updated.setName("ValueSet_noVersion_updated");
DaoMethodOutcome nullVersion_update_outcome = myValueSetDao.update(updated);
Long nullVersion_resid = ((ResourceTable)nullVersion_update_outcome.getEntity()).getId();
Long nullVersion_resid = ((ResourceTable) nullVersion_update_outcome.getEntity()).getId();
updated = (ValueSet)myValueSets.get(ValueSetVersions.V1).getResource();
updated = (ValueSet) myValueSets.get(ValueSetVersions.V1).getResource();
updated.setName("ValueSet_v1_updated");
DaoMethodOutcome v1Version_update_outcome = myValueSetDao.update(updated);
Long v1Version_resid = ((ResourceTable)v1Version_update_outcome.getEntity()).getId();
Long v1Version_resid = ((ResourceTable) v1Version_update_outcome.getEntity()).getId();
updated = (ValueSet)myValueSets.get(ValueSetVersions.V2).getResource();
updated = (ValueSet) myValueSets.get(ValueSetVersions.V2).getResource();
updated.setName("ValueSet_v2_updated");
DaoMethodOutcome v2Version_update_outcome = myValueSetDao.update(updated);
Long v2Version_resid = ((ResourceTable)v2Version_update_outcome.getEntity()).getId();
Long v2Version_resid = ((ResourceTable) v2Version_update_outcome.getEntity()).getId();
// Verify that ValueSets were updated.
assertEquals(3, myTermValueSetDao.findTermValueSetByUrl(PageRequest.of(0, 10), URL_MY_VALUE_SET).size());
runInTransaction(() -> assertEquals(3, myTermValueSetDao.findTermValueSetByUrl(PageRequest.of(0, 10), URL_MY_VALUE_SET).size()));
termValueSet = myTermValueSetDao.findTermValueSetByUrlAndNullVersion(URL_MY_VALUE_SET).orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " with null version"));
assertNotNull(nullVersion_resid);
assertNotNull(termValueSet.getResource());
assertEquals(nullVersion_resid, termValueSet.getResource().getId());
assertEquals("ValueSet_noVersion_updated", termValueSet.getName());
runInTransaction(() -> {
TermValueSet termValueSet = myTermValueSetDao.findTermValueSetByUrlAndNullVersion(URL_MY_VALUE_SET).orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " with null version"));
assertNotNull(nullVersion_resid);
assertNotNull(termValueSet.getResource());
assertEquals(nullVersion_resid, termValueSet.getResource().getId());
assertEquals("ValueSet_noVersion_updated", termValueSet.getName());
termValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v1").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v1"));
assertNotNull(v1Version_resid);
assertNotNull(termValueSet.getResource());
assertEquals(v1Version_resid, termValueSet.getResource().getId());
assertEquals("ValueSet_v1_updated", termValueSet.getName());
termValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v2").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v2"));
assertNotNull(v2Version_resid);
assertNotNull(termValueSet.getResource());
assertEquals(v2Version_resid, termValueSet.getResource().getId());
assertEquals("ValueSet_v2_updated", termValueSet.getName());
termValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v1").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v1"));
assertNotNull(v1Version_resid);
assertNotNull(termValueSet.getResource());
assertEquals(v1Version_resid, termValueSet.getResource().getId());
assertEquals("ValueSet_v1_updated", termValueSet.getName());
termValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v2").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v2"));
assertNotNull(v2Version_resid);
assertNotNull(termValueSet.getResource());
assertEquals(v2Version_resid, termValueSet.getResource().getId());
assertEquals("ValueSet_v2_updated", termValueSet.getName());
});
}
@Test
public void testDeleteVersionedValueSets() {
Map<ValueSetVersions, DaoMethodOutcome> myValueSets = createVersionedValueSets();
assertEquals(3, myTermValueSetDao.findTermValueSetByUrl(PageRequest.of(0, 10), URL_MY_VALUE_SET).size());
runInTransaction(() -> {
assertEquals(3, myTermValueSetDao.findTermValueSetByUrl(PageRequest.of(0, 10), URL_MY_VALUE_SET).size());
TermValueSet termValueSet = myTermValueSetDao.findTermValueSetByUrlAndNullVersion(URL_MY_VALUE_SET).orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " with null version"));
assertEquals("ValueSet_noVersion", termValueSet.getName());
TermValueSet termValueSet = myTermValueSetDao.findTermValueSetByUrlAndNullVersion(URL_MY_VALUE_SET).orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " with null version"));
assertEquals("ValueSet_noVersion", termValueSet.getName());
termValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v1").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v1"));
assertEquals("ValueSet_v1", termValueSet.getName());
termValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v1").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v1"));
assertEquals("ValueSet_v1", termValueSet.getName());
termValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v2").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v2"));
assertEquals("ValueSet_v2", termValueSet.getName());
termValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v2").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v2"));
assertEquals("ValueSet_v2", termValueSet.getName());
});
// Delete ValueSets
myValueSetDao.delete(myValueSets.get(ValueSetVersions.NULL).getResource().getIdElement());
assertEquals(2, myTermValueSetDao.findTermValueSetByUrl(PageRequest.of(0, 10), URL_MY_VALUE_SET).size());
Optional<TermValueSet> optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndNullVersion(URL_MY_VALUE_SET);
if (optionalTermValueSet.isPresent()) {
fail();
}
assertNotNull(myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v1").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v1")));
assertNotNull(myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v2").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v2")));
runInTransaction(() -> {
assertEquals(2, myTermValueSetDao.findTermValueSetByUrl(PageRequest.of(0, 10), URL_MY_VALUE_SET).size());
Optional<TermValueSet> optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndNullVersion(URL_MY_VALUE_SET);
if (optionalTermValueSet.isPresent()) {
fail();
}
assertNotNull(myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v1").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v1")));
assertNotNull(myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v2").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v2")));
});
myValueSetDao.delete(myValueSets.get(ValueSetVersions.V1).getResource().getIdElement());
assertEquals(1, myTermValueSetDao.findTermValueSetByUrl(PageRequest.of(0, 10), URL_MY_VALUE_SET).size());
optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndNullVersion(URL_MY_VALUE_SET);
if (optionalTermValueSet.isPresent()) {
fail();
}
optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v1");
if (optionalTermValueSet.isPresent()) {
fail();
}
assertNotNull(myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v2").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v2")));
runInTransaction(() -> {
assertEquals(1, myTermValueSetDao.findTermValueSetByUrl(PageRequest.of(0, 10), URL_MY_VALUE_SET).size());
Optional<TermValueSet> optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndNullVersion(URL_MY_VALUE_SET);
if (optionalTermValueSet.isPresent()) {
fail();
}
optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v1");
if (optionalTermValueSet.isPresent()) {
fail();
}
assertNotNull(myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v2").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v2")));
});
myValueSetDao.delete(myValueSets.get(ValueSetVersions.V2).getResource().getIdElement());
assertEquals(0, myTermValueSetDao.findTermValueSetByUrl(PageRequest.of(0, 10), URL_MY_VALUE_SET).size());
optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndNullVersion(URL_MY_VALUE_SET);
if (optionalTermValueSet.isPresent()) {
fail();
}
optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v1");
if (optionalTermValueSet.isPresent()) {
fail();
}
optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v2");
if (optionalTermValueSet.isPresent()) {
fail();
}
runInTransaction(() -> {
assertEquals(0, myTermValueSetDao.findTermValueSetByUrl(PageRequest.of(0, 10), URL_MY_VALUE_SET).size());
Optional<TermValueSet> optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndNullVersion(URL_MY_VALUE_SET);
if (optionalTermValueSet.isPresent()) {
fail();
}
optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v1");
if (optionalTermValueSet.isPresent()) {
fail();
}
optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v2");
if (optionalTermValueSet.isPresent()) {
fail();
}
});
}
@Test
@ -241,6 +251,7 @@ public class FhirResourceDaoR4ValueSetMultiVersionTest extends BaseJpaR4Test {
}
private enum ValueSetVersions {NULL, V1, V2}
}

View File

@ -1,30 +1,42 @@
package ca.uhn.fhir.jpa.dao.r4;
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.param.StringAndListParam;
import ca.uhn.fhir.rest.param.StringOrListParam;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.util.TestUtil;
import org.hl7.fhir.r4.model.Organization;
import org.hl7.fhir.r4.model.Patient;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import java.util.List;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.MatcherAssert.assertThat;
public class FhirSearchDaoR4Test extends BaseJpaR4Test {
@Autowired
private IFulltextSearchSvc mySearchDao;
@Test
public void testDaoCallRequiresTransaction() {
try {
myResourceTableDao.count();
} catch (InvalidDataAccessApiUsageException e) {
// good
}
assert !TransactionSynchronizationManager.isActualTransactionActive();
}
@Test
public void testContentSearch() {
Long id1;
@ -59,7 +71,7 @@ public class FhirSearchDaoR4Test extends BaseJpaR4Test {
{
StringAndListParam content = new StringAndListParam();
content.addAnd(new StringOrListParam().addOr(new StringParam("AAAS")));
map.add(Constants.PARAM_CONTENT, content);
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1));
@ -68,17 +80,17 @@ public class FhirSearchDaoR4Test extends BaseJpaR4Test {
{
StringAndListParam content = new StringAndListParam();
content.addAnd(new StringOrListParam().addOr(new StringParam("AAAS")).addOr(new StringParam("AAAB")));
map.add(Constants.PARAM_CONTENT, content);
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1, id2));
}
}
// AND
{
StringAndListParam content = new StringAndListParam();
content.addAnd(new StringOrListParam().addOr(new StringParam("AAAS")));
content.addAnd(new StringOrListParam().addOr(new StringParam("CCC")));
map.add(Constants.PARAM_CONTENT, content);
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1));
@ -88,7 +100,7 @@ public class FhirSearchDaoR4Test extends BaseJpaR4Test {
StringAndListParam content = new StringAndListParam();
content.addAnd(new StringOrListParam().addOr(new StringParam("AAAB")).addOr(new StringParam("AAAS")));
content.addAnd(new StringOrListParam().addOr(new StringParam("CCC")));
map.add(Constants.PARAM_CONTENT, content);
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1, id2));
@ -97,14 +109,14 @@ public class FhirSearchDaoR4Test extends BaseJpaR4Test {
{
StringAndListParam content = new StringAndListParam();
content.addAnd(new StringOrListParam().addOr(new StringParam("CCC")).addOr(new StringParam("DDD")));
map.add(Constants.PARAM_CONTENT, content);
List<ResourcePersistentId> found = mySearchDao.search(null, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1, id2, id3));
}
}
@Test
public void testNarrativeSearch() {
Long id1;
@ -132,7 +144,7 @@ public class FhirSearchDaoR4Test extends BaseJpaR4Test {
{
StringAndListParam content = new StringAndListParam();
content.addAnd(new StringOrListParam().addOr(new StringParam("AAAS")));
map.add(Constants.PARAM_TEXT, content);
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1));
@ -141,17 +153,17 @@ public class FhirSearchDaoR4Test extends BaseJpaR4Test {
{
StringAndListParam content = new StringAndListParam();
content.addAnd(new StringOrListParam().addOr(new StringParam("AAAS")).addOr(new StringParam("AAAB")));
map.add(Constants.PARAM_TEXT, content);
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1, id2));
}
}
// AND
{
StringAndListParam content = new StringAndListParam();
content.addAnd(new StringOrListParam().addOr(new StringParam("AAAS")));
content.addAnd(new StringOrListParam().addOr(new StringParam("CCC")));
map.add(Constants.PARAM_TEXT, content);
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1));
@ -161,7 +173,7 @@ public class FhirSearchDaoR4Test extends BaseJpaR4Test {
StringAndListParam content = new StringAndListParam();
content.addAnd(new StringOrListParam().addOr(new StringParam("AAAB")).addOr(new StringParam("AAAS")));
content.addAnd(new StringOrListParam().addOr(new StringParam("CCC")));
map.add(Constants.PARAM_TEXT, content);
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1, id2));
@ -170,7 +182,7 @@ public class FhirSearchDaoR4Test extends BaseJpaR4Test {
{
StringAndListParam content = new StringAndListParam();
content.addAnd(new StringOrListParam().addOr(new StringParam("div")));
map.add(Constants.PARAM_TEXT, content);
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), empty());

View File

@ -3288,8 +3288,8 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
assertThat(e.getMessage(), containsString("Resource type 'Practicioner' is not valid for this path"));
}
assertThat(myResourceTableDao.findAll(), empty());
assertThat(myResourceIndexedSearchParamStringDao.findAll(), empty());
runInTransaction(()->assertThat(myResourceTableDao.findAll(), empty()));
runInTransaction(()->assertThat(myResourceIndexedSearchParamStringDao.findAll(), empty()));
}

View File

@ -1780,7 +1780,9 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
// Date param
ourLog.info("Date indexes:\n * {}", myResourceIndexedSearchParamDateDao.findAll().stream().map(t -> t.toString()).collect(Collectors.joining("\n * ")));
runInTransaction(() -> {
ourLog.info("Date indexes:\n * {}", myResourceIndexedSearchParamDateDao.findAll().stream().map(t -> t.toString()).collect(Collectors.joining("\n * ")));
});
addReadPartition(1);
myCaptureQueriesListener.clear();
SearchParameterMap map = new SearchParameterMap();

View File

@ -66,23 +66,27 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class PersistObservationIndexedSearchParamLastNR4IT {
@Autowired
private ElasticsearchSvcImpl elasticsearchSvc;
@Autowired
private IFhirSystemDao<Bundle, Meta> myDao;
private final String SINGLE_SUBJECT_ID = "4567";
private final String SINGLE_OBSERVATION_PID = "123";
private final Date SINGLE_EFFECTIVEDTM = new Date();
private final String SINGLE_OBSERVATION_CODE_TEXT = "Test Codeable Concept Field for Code";
private final String CATEGORYFIRSTCODINGSYSTEM = "http://mycodes.org/fhir/observation-category";
private final String FIRSTCATEGORYFIRSTCODINGCODE = "test-heart-rate";
private final String CODEFIRSTCODINGSYSTEM = "http://mycodes.org/fhir/observation-code";
private final String CODEFIRSTCODINGCODE = "test-code";
@PersistenceContext(type = PersistenceContextType.TRANSACTION)
protected EntityManager myEntityManager;
@Autowired
ObservationLastNIndexPersistSvc testObservationPersist;
@Autowired
protected FhirContext myFhirCtx;
@Autowired
ObservationLastNIndexPersistSvc testObservationPersist;
@Autowired
private ElasticsearchSvcImpl elasticsearchSvc;
@Autowired
private IFhirSystemDao<Bundle, Meta> myDao;
@Autowired
private DaoConfig myDaoConfig;
private ReferenceAndListParam multiSubjectParams = null;
@BeforeEach
public void before() throws IOException {
@ -100,20 +104,6 @@ public class PersistObservationIndexedSearchParamLastNR4IT {
myDaoConfig.setLastNEnabled(new DaoConfig().isLastNEnabled());
}
private final String SINGLE_SUBJECT_ID = "4567";
private final String SINGLE_OBSERVATION_PID = "123";
private final Date SINGLE_EFFECTIVEDTM = new Date();
private final String SINGLE_OBSERVATION_CODE_TEXT = "Test Codeable Concept Field for Code";
private final String CATEGORYFIRSTCODINGSYSTEM = "http://mycodes.org/fhir/observation-category";
private final String FIRSTCATEGORYFIRSTCODINGCODE = "test-heart-rate";
private final String CODEFIRSTCODINGSYSTEM = "http://mycodes.org/fhir/observation-code";
private final String CODEFIRSTCODINGCODE = "test-code";
private ReferenceAndListParam multiSubjectParams = null;
@Order(3)
@Test
public void testIndexObservationSingle() throws IOException {
@ -467,7 +457,7 @@ public class PersistObservationIndexedSearchParamLastNR4IT {
// execute Observation ID search - Composite Aggregation
searchParameterMap.setLastNMax(1);
List<String> observationIdsOnly = elasticsearchSvc.executeLastN(searchParameterMap,myFhirCtx, 200);
List<String> observationIdsOnly = elasticsearchSvc.executeLastN(searchParameterMap, myFhirCtx, 200);
assertEquals(20, observationIdsOnly.size());

View File

@ -150,9 +150,10 @@ public class JpaPackageCacheTest extends BaseJpaR4Test {
pkg = myPackageCacheManager.loadPackage("hl7.fhir.us.davinci-cdex", null);
assertEquals("0.2.0", pkg.version());
assertEquals("This IG provides detailed guidance that helps implementers use FHIR-based interactions and resources relevant to support specific exchanges of clinical information between provider and payers (or ...", myPackageDao.findByPackageId("hl7.fhir.us.davinci-cdex").get().getDescription());
assertEquals("This IG provides detailed guidance that helps implementers use FHIR-based interactions and resources relevant to support specific exchanges of clinical information between provider and payers (or ...", myPackageVersionDao.findByPackageIdAndVersion("hl7.fhir.us.davinci-cdex", "0.2.0").get().getDescription());
runInTransaction(()-> {
assertEquals("This IG provides detailed guidance that helps implementers use FHIR-based interactions and resources relevant to support specific exchanges of clinical information between provider and payers (or ...", myPackageDao.findByPackageId("hl7.fhir.us.davinci-cdex").get().getDescription());
assertEquals("This IG provides detailed guidance that helps implementers use FHIR-based interactions and resources relevant to support specific exchanges of clinical information between provider and payers (or ...", myPackageVersionDao.findByPackageIdAndVersion("hl7.fhir.us.davinci-cdex", "0.2.0").get().getDescription());
});
}
@Test

View File

@ -24,7 +24,6 @@ import ca.uhn.fhir.util.BundleUtil;
import ca.uhn.fhir.util.StopWatch;
import ca.uhn.fhir.util.UrlUtil;
import com.google.common.base.Charsets;
import com.google.common.base.Stopwatch;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.io.IOUtils;
@ -556,7 +555,7 @@ public class ConsentInterceptorResourceProviderR4Test extends BaseResourceProvid
myClient.create().resource(new Patient().setGender(Enumerations.AdministrativeGender.MALE).addName(new HumanName().setFamily("2"))).execute();
myClient.create().resource(new Patient().setGender(Enumerations.AdministrativeGender.FEMALE).addName(new HumanName().setFamily("3"))).execute();
runInTransaction(()->{
runInTransaction(() -> {
assertEquals(3, myResourceTableDao.count());
});
@ -568,7 +567,7 @@ public class ConsentInterceptorResourceProviderR4Test extends BaseResourceProvid
assertNull(response.getTotalElement().getValue());
StopWatch sw = new StopWatch();
while(true) {
while (true) {
SearchStatusEnum status = runInTransaction(() -> {
Search search = mySearchEntityDao.findByUuidAndFetchIncludes(searchId).orElseThrow(() -> new IllegalStateException());
return search.getStatus();
@ -631,7 +630,7 @@ public class ConsentInterceptorResourceProviderR4Test extends BaseResourceProvid
await()
.until(
()->mySearchEntityDao.findByUuidAndFetchIncludes(searchId).orElseThrow(() -> new IllegalStateException()).getStatus(),
() -> runInTransaction(() -> mySearchEntityDao.findByUuidAndFetchIncludes(searchId).orElseThrow(() -> new IllegalStateException()).getStatus()),
equalTo(SearchStatusEnum.FINISHED)
);

View File

@ -110,8 +110,11 @@ public class HookInterceptorR4Test extends BaseResourceProviderR4Test {
pid.set(resourcePid);
});
IIdType savedPatientId = myClient.create().resource(new Patient()).execute().getId();
Long savedPatientPid = myIdHelperService.resolveResourcePersistentIdsWithCache(null, Collections.singletonList(savedPatientId)).get(0).getIdAsLong();
assertEquals(savedPatientPid.longValue(), pid.get());
runInTransaction(()-> {
Long savedPatientPid = myIdHelperService.resolveResourcePersistentIdsWithCache(null, Collections.singletonList(savedPatientId)).get(0).getIdAsLong();
assertEquals(savedPatientPid.longValue(), pid.get());
});
}
@Test
@ -124,7 +127,7 @@ public class HookInterceptorR4Test extends BaseResourceProviderR4Test {
pid.set(resourcePid);
});
IIdType savedPatientId = myClient.create().resource(new Patient()).execute().getId();
Long savedPatientPid = myIdHelperService.resolveResourcePersistentIdsWithCache(null, Collections.singletonList(savedPatientId)).get(0).getIdAsLong();
Long savedPatientPid = runInTransaction(()->myIdHelperService.resolveResourcePersistentIdsWithCache(null, Collections.singletonList(savedPatientId)).get(0).getIdAsLong());
myClient.delete().resourceById(savedPatientId).execute();
Parameters parameters = new Parameters();
@ -160,9 +163,11 @@ public class HookInterceptorR4Test extends BaseResourceProviderR4Test {
});
patient.setActive(true);
myClient.update().resource(patient).execute();
Long savedPatientPid = myIdHelperService.resolveResourcePersistentIdsWithCache(null, Collections.singletonList(savedPatientId)).get(0).getIdAsLong();
assertEquals(savedPatientPid.longValue(), pidOld.get());
assertEquals(savedPatientPid.longValue(), pidNew.get());
runInTransaction(()-> {
Long savedPatientPid = myIdHelperService.resolveResourcePersistentIdsWithCache(null, Collections.singletonList(savedPatientId)).get(0).getIdAsLong();
assertEquals(savedPatientPid.longValue(), pidOld.get());
assertEquals(savedPatientPid.longValue(), pidNew.get());
});
}
@Test

View File

@ -13,11 +13,9 @@ import ca.uhn.fhir.jpa.model.search.SearchStatusEnum;
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.DateClientParam;
import ca.uhn.fhir.rest.gclient.ReferenceClientParam;
import ca.uhn.fhir.rest.gclient.StringClientParam;
import ca.uhn.fhir.rest.gclient.TokenClientParam;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.util.BundleUtil;
import org.apache.commons.io.IOUtils;
@ -222,10 +220,12 @@ public class ResourceProviderCustomSearchParamR4Test extends BaseResourceProvide
obs2.setStatus(ObservationStatus.FINAL);
IIdType obsId = myObservationDao.create(obs2, mySrd).getId().toUnqualifiedVersionless();
ResourceTable res = myResourceTableDao.findById(patId.getIdPartAsLong()).orElseThrow(IllegalStateException::new);
assertEquals(BaseHapiFhirDao.INDEX_STATUS_INDEXED, res.getIndexStatus().longValue());
res = myResourceTableDao.findById(obsId.getIdPartAsLong()).orElseThrow(IllegalStateException::new);
assertEquals(BaseHapiFhirDao.INDEX_STATUS_INDEXED, res.getIndexStatus().longValue());
runInTransaction(() -> {
ResourceTable res = myResourceTableDao.findById(patId.getIdPartAsLong()).orElseThrow(IllegalStateException::new);
assertEquals(BaseHapiFhirDao.INDEX_STATUS_INDEXED, res.getIndexStatus().longValue());
res = myResourceTableDao.findById(obsId.getIdPartAsLong()).orElseThrow(IllegalStateException::new);
assertEquals(BaseHapiFhirDao.INDEX_STATUS_INDEXED, res.getIndexStatus().longValue());
});
SearchParameter fooSp = new SearchParameter();
fooSp.addBase("Patient");
@ -459,7 +459,7 @@ public class ResourceProviderCustomSearchParamR4Test extends BaseResourceProvide
.returnBundle(Bundle.class)
.execute();
} catch (Exception e) {
} catch (Exception e) {
assertThat(e.getMessage(), is(equalTo("HTTP 400 Bad Request: Invalid date/time format: \"01-01-2020\"")));
}
@ -472,7 +472,7 @@ public class ResourceProviderCustomSearchParamR4Test extends BaseResourceProvide
.returnBundle(Bundle.class)
.execute();
} catch (Exception e) {
} catch (Exception e) {
assertThat(e.getMessage(), is(equalTo("HTTP 400 Bad Request: Invalid date/time format: \"01-01-2020\"")));
}
}
@ -586,5 +586,4 @@ public class ResourceProviderCustomSearchParamR4Test extends BaseResourceProvide
}
}

View File

@ -21,6 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import java.util.Date;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.blankOrNullString;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.greaterThan;
@ -74,7 +75,7 @@ public class ResourceProviderR4CacheTest extends BaseResourceProviderR4Test {
.cacheControl(new CacheControlDirective().setNoStore(true))
.execute();
assertEquals(1, results.getEntry().size());
assertEquals(0, mySearchEntityDao.count());
runInTransaction(()->assertEquals(0, mySearchEntityDao.count()));
assertThat(myCapturingInterceptor.getLastResponse().getHeaders(Constants.HEADER_X_CACHE), empty());
Patient pt2 = new Patient();
@ -89,7 +90,7 @@ public class ResourceProviderR4CacheTest extends BaseResourceProviderR4Test {
.cacheControl(new CacheControlDirective().setNoStore(true))
.execute();
assertEquals(2, results.getEntry().size());
assertEquals(0, mySearchEntityDao.count());
runInTransaction(()->assertEquals(0, mySearchEntityDao.count()));
assertThat(myCapturingInterceptor.getLastResponse().getHeaders(Constants.HEADER_X_CACHE), empty());
}
@ -111,7 +112,7 @@ public class ResourceProviderR4CacheTest extends BaseResourceProviderR4Test {
.cacheControl(new CacheControlDirective().setNoStore(true).setMaxResults(5))
.execute();
assertEquals(5, results.getEntry().size());
assertEquals(0, mySearchEntityDao.count());
runInTransaction(()->assertEquals(0, mySearchEntityDao.count()));
assertThat(myCapturingInterceptor.getLastResponse().getHeaders(Constants.HEADER_X_CACHE), empty());
}
@ -142,7 +143,7 @@ public class ResourceProviderR4CacheTest extends BaseResourceProviderR4Test {
Bundle results = myClient.search().forResource("Patient").where(Patient.FAMILY.matches().value("FAM")).returnBundle(Bundle.class).execute();
assertEquals(1, results.getEntry().size());
assertEquals(1, mySearchEntityDao.count());
runInTransaction(() -> assertEquals(1, mySearchEntityDao.count()));
assertThat(myCapturingInterceptor.getLastResponse().getHeaders(Constants.HEADER_X_CACHE), empty());
Patient pt2 = new Patient();
@ -157,7 +158,7 @@ public class ResourceProviderR4CacheTest extends BaseResourceProviderR4Test {
.cacheControl(new CacheControlDirective().setNoCache(true))
.execute();
assertEquals(2, results.getEntry().size());
assertEquals(2, mySearchEntityDao.count());
runInTransaction(() -> assertEquals(2, mySearchEntityDao.count()));
assertThat(myCapturingInterceptor.getLastResponse().getHeaders(Constants.HEADER_X_CACHE), empty());
}
@ -178,7 +179,7 @@ public class ResourceProviderR4CacheTest extends BaseResourceProviderR4Test {
TestUtil.sleepOneClick();
assertEquals(1, results1.getEntry().size());
assertEquals(1, mySearchEntityDao.count());
runInTransaction(() -> assertEquals(1, mySearchEntityDao.count()));
assertThat(myCapturingInterceptor.getLastResponse().getHeaders(Constants.HEADER_X_CACHE), empty());
Date results1Date = TestUtil.getTimestamp(results1).getValue();
assertThat(results1Date, greaterThan(beforeFirst));
@ -191,7 +192,7 @@ public class ResourceProviderR4CacheTest extends BaseResourceProviderR4Test {
Bundle results2 = myClient.search().forResource("Patient").where(Patient.FAMILY.matches().value("FAM")).returnBundle(Bundle.class).execute();
assertEquals(1, results2.getEntry().size());
assertEquals(1, mySearchEntityDao.count());
runInTransaction(() -> assertEquals(1, mySearchEntityDao.count()));
assertEquals("HIT from " + ourServerBase, myCapturingInterceptor.getLastResponse().getHeaders(Constants.HEADER_X_CACHE).get(0));
assertEquals(results1.getMeta().getLastUpdated(), results2.getMeta().getLastUpdated());
assertEquals(results1.getId(), results2.getId());
@ -205,7 +206,7 @@ public class ResourceProviderR4CacheTest extends BaseResourceProviderR4Test {
p = new Patient();
p.addName().setFamily("Foo");
String p2Id = myPatientDao.create(p).getId().toUnqualifiedVersionless().getValue();
myPatientDao.create(p).getId().toUnqualifiedVersionless().getValue();
Bundle resp1 = myClient
.search()

View File

@ -12,7 +12,15 @@ import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.*;
import org.hl7.fhir.r4.model.BooleanType;
import org.hl7.fhir.r4.model.CodeSystem;
import org.hl7.fhir.r4.model.CodeType;
import org.hl7.fhir.r4.model.CodeableConcept;
import org.hl7.fhir.r4.model.Coding;
import org.hl7.fhir.r4.model.Enumerations;
import org.hl7.fhir.r4.model.Parameters;
import org.hl7.fhir.r4.model.StringType;
import org.hl7.fhir.r4.model.UriType;
import org.hl7.fhir.r4.model.codesystems.ConceptSubsumptionOutcome;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@ -20,16 +28,18 @@ import org.springframework.transaction.annotation.Transactional;
import java.io.IOException;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
public class ResourceProviderR4CodeSystemTest extends BaseResourceProviderR4Test {
private static final String SYSTEM_PARENTCHILD = "http://parentchild";
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceProviderR4CodeSystemTest.class);
private Long parentChildCsId;
private IIdType myCsId;
private static final String CS_ACME_URL = "http://acme.org";
private Long parentChildCsId;
private IIdType myCsId;
@BeforeEach
@Transactional
@ -49,14 +59,14 @@ public class ResourceProviderR4CodeSystemTest extends BaseResourceProviderR4Test
parentChildCs.addConcept().setCode("ParentB").setDisplay("Parent B");
DaoMethodOutcome parentChildCsOutcome = myCodeSystemDao.create(parentChildCs);
parentChildCsId = ((ResourceTable)parentChildCsOutcome.getEntity()).getId();
parentChildCsId = ((ResourceTable) parentChildCsOutcome.getEntity()).getId();
}
@Test
public void testLookupOnExternalCode() {
myCaptureQueriesListener.clear();
ResourceProviderR4ValueSetNoVerCSNoVerTest.createExternalCs(myCodeSystemDao, myResourceTableDao, myTermCodeSystemStorageSvc, mySrd);
runInTransaction(() -> ResourceProviderR4ValueSetNoVerCSNoVerTest.createExternalCs(myCodeSystemDao, myResourceTableDao, myTermCodeSystemStorageSvc, mySrd));
myCaptureQueriesListener.logAllQueriesForCurrentThread();
Parameters respParam = myClient
@ -531,7 +541,7 @@ public class ResourceProviderR4CodeSystemTest extends BaseResourceProviderR4Test
myClient.operation().onType(CodeSystem.class).named("validate-code").withParameters(inParams).execute();
fail();
} catch (InvalidRequestException e) {
assertEquals("HTTP 400 Bad Request: Either CodeSystem ID or CodeSystem identifier must be provided. Unable to validate.",e.getMessage());
assertEquals("HTTP 400 Bad Request: Either CodeSystem ID or CodeSystem identifier must be provided. Unable to validate.", e.getMessage());
}
}
@ -561,7 +571,7 @@ public class ResourceProviderR4CodeSystemTest extends BaseResourceProviderR4Test
myClient.operation().onType(CodeSystem.class).named("validate-code").withParameters(inParams).execute();
fail();
} catch (InvalidRequestException e) {
assertEquals("HTTP 400 Bad Request: No code, coding, or codeableConcept provided to validate.",e.getMessage());
assertEquals("HTTP 400 Bad Request: No code, coding, or codeableConcept provided to validate.", e.getMessage());
}
}
@ -577,7 +587,7 @@ public class ResourceProviderR4CodeSystemTest extends BaseResourceProviderR4Test
myClient.operation().onType(CodeSystem.class).named("validate-code").withParameters(inParams).execute();
fail();
} catch (InvalidRequestException e) {
assertEquals("HTTP 400 Bad Request: $validate-code can only validate (code) OR (coding) OR (codeableConcept)",e.getMessage());
assertEquals("HTTP 400 Bad Request: $validate-code can only validate (code) OR (coding) OR (codeableConcept)", e.getMessage());
}
}
@ -592,7 +602,7 @@ public class ResourceProviderR4CodeSystemTest extends BaseResourceProviderR4Test
myClient.operation().onType(CodeSystem.class).named("validate-code").withParameters(inParams).execute();
fail();
} catch (InvalidRequestException e) {
assertEquals("HTTP 400 Bad Request: Coding.system 'http://url2' does not equal with CodeSystem.url 'http://acme.org'. Unable to validate.",e.getMessage());
assertEquals("HTTP 400 Bad Request: Coding.system 'http://url2' does not equal with CodeSystem.url 'http://acme.org'. Unable to validate.", e.getMessage());
}
}
@ -641,7 +651,7 @@ public class ResourceProviderR4CodeSystemTest extends BaseResourceProviderR4Test
myClient.operation().onType(CodeSystem.class).named("validate-code").withParameters(inParams).execute();
fail();
} catch (InvalidRequestException e) {
assertEquals("HTTP 400 Bad Request: Coding.system 'http://url2' does not equal with CodeSystem.url 'http://acme.org'. Unable to validate.",e.getMessage());
assertEquals("HTTP 400 Bad Request: Coding.system 'http://url2' does not equal with CodeSystem.url 'http://acme.org'. Unable to validate.", e.getMessage());
}
}
@ -772,7 +782,7 @@ public class ResourceProviderR4CodeSystemTest extends BaseResourceProviderR4Test
myClient.operation().onType(CodeSystem.class).named("validate-code").withParameters(inParams).execute();
fail();
} catch (InvalidRequestException e) {
assertEquals("HTTP 400 Bad Request: Coding.system 'http://url2' does not equal with CodeSystem.url 'http://acme.org'. Unable to validate.",e.getMessage());
assertEquals("HTTP 400 Bad Request: Coding.system 'http://url2' does not equal with CodeSystem.url 'http://acme.org'. Unable to validate.", e.getMessage());
}
}

View File

@ -89,8 +89,10 @@ public class ResourceProviderR4CodeSystemVersionedTest extends BaseResourceProvi
@Test
public void testLookupOnExternalCodeMultiVersion() {
ResourceProviderR4ValueSetVerCSVerTest.createExternalCs(myCodeSystemDao, myResourceTableDao, myTermCodeSystemStorageSvc, mySrd, "1");
ResourceProviderR4ValueSetVerCSVerTest.createExternalCs(myCodeSystemDao, myResourceTableDao, myTermCodeSystemStorageSvc, mySrd, "2");
runInTransaction(()->{
ResourceProviderR4ValueSetVerCSVerTest.createExternalCs(myCodeSystemDao, myResourceTableDao, myTermCodeSystemStorageSvc, mySrd, "1");
ResourceProviderR4ValueSetVerCSVerTest.createExternalCs(myCodeSystemDao, myResourceTableDao, myTermCodeSystemStorageSvc, mySrd, "2");
});
// First test with no version specified (should return from last version created)
Parameters respParam = myClient

View File

@ -156,15 +156,17 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv
}
private void createExternalCsAndLocalVs() {
CodeSystem codeSystem = createExternalCs();
createLocalVs(codeSystem);
runInTransaction(() -> {
CodeSystem codeSystem = createExternalCs();
createLocalVs(codeSystem);
});
}
private void createExternalCsAndLocalVsWithUnknownCode() {
CodeSystem codeSystem = createExternalCs();
createLocalVsWithUnknownCode(codeSystem);
runInTransaction(() -> {
CodeSystem codeSystem = createExternalCs();
createLocalVsWithUnknownCode(codeSystem);
});
}
private void createLocalCs() {
@ -257,8 +259,10 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv
loadAndPersistCodeSystemAndValueSet();
await().until(() -> clearDeferredStorageQueue());
myTermSvc.preExpandDeferredValueSetsToTerminologyTables();
Slice<TermValueSet> page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED);
assertEquals(1, page.getContent().size());
runInTransaction(()->{
Slice<TermValueSet> page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED);
assertEquals(1, page.getContent().size());
});
Parameters respParam = myClient
.operation()
@ -312,8 +316,10 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv
loadAndPersistCodeSystemAndValueSet();
await().until(() -> clearDeferredStorageQueue());
myTermSvc.preExpandDeferredValueSetsToTerminologyTables();
Slice<TermValueSet> page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED);
assertEquals(1, page.getContent().size());
runInTransaction(() -> {
Slice<TermValueSet> page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED);
assertEquals(1, page.getContent().size());
});
Parameters respParam = myClient
.operation()
@ -321,7 +327,7 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv
.named("expand")
.withParameter(Parameters.class, "filter", new StringType("blood"))
.execute();
ValueSet expanded = (ValueSet) respParam.getParameter().get(0).getResource();
String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded);
@ -338,8 +344,10 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv
loadAndPersistCodeSystemAndValueSet();
await().until(() -> clearDeferredStorageQueue());
myTermSvc.preExpandDeferredValueSetsToTerminologyTables();
Slice<TermValueSet> page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED);
assertEquals(1, page.getContent().size());
runInTransaction(() -> {
Slice<TermValueSet> page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED);
assertEquals(1, page.getContent().size());
});
Parameters respParam = myClient
.operation()
@ -347,7 +355,7 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv
.named("expand")
.withParameter(Parameters.class, "filter", new StringType("blo"))
.execute();
ValueSet expanded = (ValueSet) respParam.getParameter().get(0).getResource();
String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded);
@ -355,7 +363,7 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv
assertThat(resp, containsString("<display value=\"Systolic blood pressure at First encounter\"/>"));
assertThat(resp, not(containsString("\"Foo Code\"")));
}
@Test
public void testExpandByIdWithFilterWithPreExpansionWithoutPrefixValue() throws Exception {
myDaoConfig.setPreExpandValueSets(true);
@ -363,7 +371,7 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv
loadAndPersistCodeSystemAndValueSet();
await().until(() -> clearDeferredStorageQueue());
myTermSvc.preExpandDeferredValueSetsToTerminologyTables();
Slice<TermValueSet> page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED);
Slice<TermValueSet> page = runInTransaction(() -> myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED));
assertEquals(1, page.getContent().size());
Parameters respParam = myClient
@ -372,7 +380,7 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv
.named("expand")
.withParameter(Parameters.class, "filter", new StringType("lood"))
.execute();
ValueSet expanded = (ValueSet) respParam.getParameter().get(0).getResource();
String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded);
@ -380,8 +388,8 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv
assertThat(resp, not(containsString("<display value=\"Systolic blood pressure at First encounter\"/>")));
assertThat(resp, not(containsString("\"Foo Code\"")));
}
@Test
public void testExpandByUrl() throws Exception {
loadAndPersistCodeSystemAndValueSet();
@ -446,9 +454,11 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv
loadAndPersistCodeSystemAndValueSet();
await().until(() -> clearDeferredStorageQueue());
myTermSvc.preExpandDeferredValueSetsToTerminologyTables();
Slice<TermValueSet> page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED);
assertEquals(1, page.getContent().size());
runInTransaction(()->{
myTermSvc.preExpandDeferredValueSetsToTerminologyTables();
Slice<TermValueSet> page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED);
assertEquals(1, page.getContent().size());
});
Parameters respParam = myClient
.operation()
@ -799,7 +809,7 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv
*/
@Test
public void testInvalidFilter() throws Exception {
String string = IOUtils.toString(getClass().getResourceAsStream("/bug_516_invalid_expansion.json"), StandardCharsets.UTF_8);
String string = loadResource("/bug_516_invalid_expansion.json");
HttpPost post = new HttpPost(ourServerBase + "/ValueSet/%24expand");
post.setEntity(new StringEntity(string, ContentType.parse(ca.uhn.fhir.rest.api.Constants.CT_FHIR_JSON_NEW)));
@ -1080,7 +1090,7 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(expansion));
assertThat(toDirectCodes(expansion.getExpansion().getContains()), containsInAnyOrder("A"));
assertThat(toDirectCodes(expansion.getExpansion().getContains().get(0).getContains()), containsInAnyOrder("AA", "AB"));
assertThat(toDirectCodes(expansion.getExpansion().getContains().get(0).getContains().stream().filter(t->t.getCode().equals("AA")).findFirst().orElseThrow(()->new IllegalArgumentException()).getContains()), containsInAnyOrder("AAA"));
assertThat(toDirectCodes(expansion.getExpansion().getContains().get(0).getContains().stream().filter(t -> t.getCode().equals("AA")).findFirst().orElseThrow(() -> new IllegalArgumentException()).getContains()), containsInAnyOrder("AAA"));
assertEquals(16, myCaptureQueriesListener.getSelectQueries().size());
}
@ -1120,7 +1130,7 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(expansion));
assertThat(toDirectCodes(expansion.getExpansion().getContains()), containsInAnyOrder("A"));
assertThat(toDirectCodes(expansion.getExpansion().getContains().get(0).getContains()), containsInAnyOrder("AA", "AB"));
assertThat(toDirectCodes(expansion.getExpansion().getContains().get(0).getContains().stream().filter(t->t.getCode().equals("AA")).findFirst().orElseThrow(()->new IllegalArgumentException()).getContains()), containsInAnyOrder("AAA"));
assertThat(toDirectCodes(expansion.getExpansion().getContains().get(0).getContains().stream().filter(t -> t.getCode().equals("AA")).findFirst().orElseThrow(() -> new IllegalArgumentException()).getContains()), containsInAnyOrder("AAA"));
assertEquals(14, myCaptureQueriesListener.getSelectQueries().size());
}
@ -1172,7 +1182,7 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(expansion));
assertThat(toDirectCodes(expansion.getExpansion().getContains()), containsInAnyOrder("A"));
assertThat(toDirectCodes(expansion.getExpansion().getContains().get(0).getContains()), containsInAnyOrder("AA", "AB"));
assertThat(toDirectCodes(expansion.getExpansion().getContains().get(0).getContains().stream().filter(t->t.getCode().equals("AA")).findFirst().orElseThrow(()->new IllegalArgumentException()).getContains()), containsInAnyOrder("AAA"));
assertThat(toDirectCodes(expansion.getExpansion().getContains().get(0).getContains().stream().filter(t -> t.getCode().equals("AA")).findFirst().orElseThrow(() -> new IllegalArgumentException()).getContains()), containsInAnyOrder("AAA"));
assertEquals(3, myCaptureQueriesListener.getSelectQueries().size());
}
@ -1435,7 +1445,7 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv
ourLog.info(resp);
assertThat(resp, stringContainsInOrder("<code value=\"11378-7\"/>", "<display value=\"Systolic blood pressure at First encounter\"/>"));
}
@Test
public void testExpandByValueSetWithFilterContainsNoPrefixValue() throws IOException {
loadAndPersistCodeSystem();
@ -1453,10 +1463,10 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv
String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded);
ourLog.info(resp);
assertThat(resp, not(stringContainsInOrder("<code value=\"11378-7\"/>","<display value=\"Systolic blood pressure at First encounter\"/>")));
assertThat(resp, not(stringContainsInOrder("<code value=\"11378-7\"/>", "<display value=\"Systolic blood pressure at First encounter\"/>")));
}
@Test
public void testExpandByValueSetWithFilterNotContainsAnyValue() throws IOException {
loadAndPersistCodeSystem();
@ -1474,10 +1484,10 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv
String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded);
ourLog.info(resp);
assertThat(resp, not(stringContainsInOrder("<code value=\"11378-7\"/>","<display value=\"Systolic blood pressure at First encounter\"/>")));
assertThat(resp, not(stringContainsInOrder("<code value=\"11378-7\"/>", "<display value=\"Systolic blood pressure at First encounter\"/>")));
}
@Test
public void testExpandByUrlWithFilter() throws Exception {
loadAndPersistCodeSystemAndValueSet();
@ -1520,7 +1530,7 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv
private boolean clearDeferredStorageQueue() {
if(!myTerminologyDeferredStorageSvc.isStorageQueueEmpty()) {
if (!myTerminologyDeferredStorageSvc.isStorageQueueEmpty()) {
myTerminologyDeferredStorageSvc.saveAllDeferred();
return false;
} else {

View File

@ -149,15 +149,17 @@ public class ResourceProviderR4ValueSetVerCSNoVerTest extends BaseResourceProvid
}
private void createExternalCsAndLocalVs() {
CodeSystem codeSystem = createExternalCs();
createLocalVs(codeSystem);
runInTransaction(()-> {
CodeSystem codeSystem = createExternalCs();
createLocalVs(codeSystem);
});
}
private void createExternalCsAndLocalVsWithUnknownCode() {
CodeSystem codeSystem = createExternalCs();
createLocalVsWithUnknownCode(codeSystem);
runInTransaction(()-> {
CodeSystem codeSystem = createExternalCs();
createLocalVsWithUnknownCode(codeSystem);
});
}
private void createLocalVs(CodeSystem codeSystem) {
@ -223,8 +225,10 @@ public class ResourceProviderR4ValueSetVerCSNoVerTest extends BaseResourceProvid
loadAndPersistCodeSystemAndValueSet();
await().until(() -> clearDeferredStorageQueue());
myTermSvc.preExpandDeferredValueSetsToTerminologyTables();
Slice<TermValueSet> page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED);
assertEquals(1, page.getContent().size());
runInTransaction(()->{
Slice<TermValueSet> page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED);
assertEquals(1, page.getContent().size());
});
Parameters respParam = myClient
.operation()
@ -278,8 +282,10 @@ public class ResourceProviderR4ValueSetVerCSNoVerTest extends BaseResourceProvid
loadAndPersistCodeSystemAndValueSet();
await().until(() -> clearDeferredStorageQueue());
myTermSvc.preExpandDeferredValueSetsToTerminologyTables();
Slice<TermValueSet> page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED);
assertEquals(1, page.getContent().size());
runInTransaction(()->{
Slice<TermValueSet> page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED);
assertEquals(1, page.getContent().size());
});
Parameters respParam = myClient
.operation()
@ -361,8 +367,10 @@ public class ResourceProviderR4ValueSetVerCSNoVerTest extends BaseResourceProvid
loadAndPersistCodeSystemAndValueSet();
await().until(() -> clearDeferredStorageQueue());
myTermSvc.preExpandDeferredValueSetsToTerminologyTables();
Slice<TermValueSet> page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED);
assertEquals(1, page.getContent().size());
runInTransaction(()->{
Slice<TermValueSet> page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED);
assertEquals(1, page.getContent().size());
});
Parameters respParam = myClient
.operation()

View File

@ -179,14 +179,15 @@ public class ResourceProviderR4ValueSetVerCSVerTest extends BaseResourceProvider
}
private void createExternalCsAndLocalVs() {
String codeSystemUrl = createExternalCs("1");
myLocalVs_v1 = createLocalVs(codeSystemUrl, "1");
myLocalValueSetId_v1 = persistLocalVs(myLocalVs_v1);
codeSystemUrl = createExternalCs("2");
myLocalVs_v2 = createLocalVs(codeSystemUrl, "2");
myLocalValueSetId_v2 = persistLocalVs(myLocalVs_v2);
runInTransaction(()-> {
String codeSystemUrl = createExternalCs("1");
myLocalVs_v1 = createLocalVs(codeSystemUrl, "1");
myLocalValueSetId_v1 = persistLocalVs(myLocalVs_v1);
codeSystemUrl = createExternalCs("2");
myLocalVs_v2 = createLocalVs(codeSystemUrl, "2");
myLocalValueSetId_v2 = persistLocalVs(myLocalVs_v2);
});
}
private ValueSet createLocalVs(String theCodeSystemUrl, String theValueSetVersion) {
@ -268,8 +269,10 @@ public class ResourceProviderR4ValueSetVerCSVerTest extends BaseResourceProvider
loadAndPersistCodeSystemAndValueSet();
await().until(() -> clearDeferredStorageQueue());
myTermSvc.preExpandDeferredValueSetsToTerminologyTables();
Slice<TermValueSet> page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED);
assertEquals(2, page.getContent().size());
runInTransaction(()->{
Slice<TermValueSet> page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED);
assertEquals(2, page.getContent().size());
});
// Verify v1 ValueSet
Parameters respParam = myClient
@ -365,8 +368,10 @@ public class ResourceProviderR4ValueSetVerCSVerTest extends BaseResourceProvider
await().until(() -> clearDeferredStorageQueue());
myTermSvc.preExpandDeferredValueSetsToTerminologyTables();
Slice<TermValueSet> page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED);
assertEquals(2, page.getContent().size());
runInTransaction(()->{
Slice<TermValueSet> page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED);
assertEquals(2, page.getContent().size());
});
// Validate ValueSet v1
Parameters respParam = myClient
@ -532,8 +537,10 @@ public class ResourceProviderR4ValueSetVerCSVerTest extends BaseResourceProvider
await().until(() -> clearDeferredStorageQueue());
myTermSvc.preExpandDeferredValueSetsToTerminologyTables();
Slice<TermValueSet> page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED);
assertEquals(2, page.getContent().size());
runInTransaction(()->{
Slice<TermValueSet> page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED);
assertEquals(2, page.getContent().size());
});
// Check expansion of multi-versioned ValueSet with version 1
Parameters respParam = myClient

View File

@ -143,11 +143,11 @@ public class StaleSearchDeletingSvcR4Test extends BaseResourceProviderR4Test {
});
// It should take two passes to delete the search fully
assertEquals(1, mySearchEntityDao.count());
runInTransaction(()->assertEquals(1, mySearchEntityDao.count()));
myStaleSearchDeletingSvc.pollForStaleSearchesAndDeleteThem();
assertEquals(1, mySearchEntityDao.count());
runInTransaction(()->assertEquals(1, mySearchEntityDao.count()));
myStaleSearchDeletingSvc.pollForStaleSearchesAndDeleteThem();
assertEquals(0, mySearchEntityDao.count());
runInTransaction(()->assertEquals(0, mySearchEntityDao.count()));
}
@ -166,10 +166,15 @@ public class StaleSearchDeletingSvcR4Test extends BaseResourceProviderR4Test {
});
// It should take one pass to delete the search fully
assertEquals(1, mySearchEntityDao.count());
myStaleSearchDeletingSvc.pollForStaleSearchesAndDeleteThem();
assertEquals(0, mySearchEntityDao.count());
runInTransaction(()-> {
assertEquals(1, mySearchEntityDao.count());
});
myStaleSearchDeletingSvc.pollForStaleSearchesAndDeleteThem();
runInTransaction(()-> {
assertEquals(0, mySearchEntityDao.count());
});
}
@Test
@ -193,15 +198,15 @@ public class StaleSearchDeletingSvcR4Test extends BaseResourceProviderR4Test {
});
// Should not delete right now
assertEquals(1, mySearchEntityDao.count());
runInTransaction(()->assertEquals(1, mySearchEntityDao.count()));
myStaleSearchDeletingSvc.pollForStaleSearchesAndDeleteThem();
assertEquals(1, mySearchEntityDao.count());
runInTransaction(()->assertEquals(1, mySearchEntityDao.count()));
sleepAtLeast(1100);
// Now it's time to delete
myStaleSearchDeletingSvc.pollForStaleSearchesAndDeleteThem();
assertEquals(0, mySearchEntityDao.count());
runInTransaction(()->assertEquals(0, mySearchEntityDao.count()));
}

View File

@ -5,8 +5,8 @@ import ca.uhn.fhir.jpa.dao.r4.BaseJpaR4Test;
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.CodeSystem;
import org.hl7.fhir.r4.model.ValueSet;
@ -47,49 +47,51 @@ public abstract class BaseTermR4Test extends BaseJpaR4Test {
codeSystem.setVersion("SYSTEM VERSION");
IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified();
ResourceTable table = myResourceTableDao.findById(id.getIdPartAsLong()).orElseThrow(IllegalArgumentException::new);
return runInTransaction(() -> {
ResourceTable table = myResourceTableDao.findById(id.getIdPartAsLong()).orElseThrow(IllegalArgumentException::new);
TermCodeSystemVersion cs = new TermCodeSystemVersion();
cs.setResource(table);
TermCodeSystemVersion cs = new TermCodeSystemVersion();
cs.setResource(table);
TermConcept parent;
parent = new TermConcept(cs, "ParentWithNoChildrenA");
cs.getConcepts().add(parent);
parent = new TermConcept(cs, "ParentWithNoChildrenB");
cs.getConcepts().add(parent);
parent = new TermConcept(cs, "ParentWithNoChildrenC");
cs.getConcepts().add(parent);
TermConcept parent;
parent = new TermConcept(cs, "ParentWithNoChildrenA");
cs.getConcepts().add(parent);
parent = new TermConcept(cs, "ParentWithNoChildrenB");
cs.getConcepts().add(parent);
parent = new TermConcept(cs, "ParentWithNoChildrenC");
cs.getConcepts().add(parent);
TermConcept parentA = new TermConcept(cs, "ParentA");
cs.getConcepts().add(parentA);
TermConcept parentA = new TermConcept(cs, "ParentA");
cs.getConcepts().add(parentA);
TermConcept childAA = new TermConcept(cs, "childAA");
parentA.addChild(childAA, TermConceptParentChildLink.RelationshipTypeEnum.ISA);
TermConcept childAA = new TermConcept(cs, "childAA");
parentA.addChild(childAA, TermConceptParentChildLink.RelationshipTypeEnum.ISA);
TermConcept childAAA = new TermConcept(cs, "childAAA");
childAAA.addPropertyString("propA", "valueAAA");
childAAA.addPropertyString("propB", "foo");
childAA.addChild(childAAA, TermConceptParentChildLink.RelationshipTypeEnum.ISA);
TermConcept childAAA = new TermConcept(cs, "childAAA");
childAAA.addPropertyString("propA", "valueAAA");
childAAA.addPropertyString("propB", "foo");
childAA.addChild(childAAA, TermConceptParentChildLink.RelationshipTypeEnum.ISA);
TermConcept childAAB = new TermConcept(cs, "childAAB");
childAAB.addPropertyString("propA", "valueAAB");
childAAB.addPropertyString("propB", "foo");
childAAB.addDesignation()
.setUseSystem("D1S")
.setUseCode("D1C")
.setUseDisplay("D1D")
.setValue("D1V");
childAA.addChild(childAAB, TermConceptParentChildLink.RelationshipTypeEnum.ISA);
TermConcept childAAB = new TermConcept(cs, "childAAB");
childAAB.addPropertyString("propA", "valueAAB");
childAAB.addPropertyString("propB", "foo");
childAAB.addDesignation()
.setUseSystem("D1S")
.setUseCode("D1C")
.setUseDisplay("D1D")
.setValue("D1V");
childAA.addChild(childAAB, TermConceptParentChildLink.RelationshipTypeEnum.ISA);
TermConcept childAB = new TermConcept(cs, "childAB");
parentA.addChild(childAB, TermConceptParentChildLink.RelationshipTypeEnum.ISA);
TermConcept childAB = new TermConcept(cs, "childAB");
parentA.addChild(childAB, TermConceptParentChildLink.RelationshipTypeEnum.ISA);
TermConcept parentB = new TermConcept(cs, "ParentB");
cs.getConcepts().add(parentB);
TermConcept parentB = new TermConcept(cs, "ParentB");
cs.getConcepts().add(parentB);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), CS_URL, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), CS_URL, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
return id;
return id;
});
}
void loadAndPersistCodeSystemAndValueSet() throws IOException {

View File

@ -11,8 +11,8 @@ import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
public class TermCodeSystemStorageSvcTest extends BaseJpaR4Test {
@ -30,7 +30,7 @@ public class TermCodeSystemStorageSvcTest extends BaseJpaR4Test {
assertEquals(1, myTermCodeSystemVersionDao.count());
TermCodeSystem myTermCodeSystem = myTermCodeSystemDao.findByCodeSystemUri(URL_MY_CODE_SYSTEM);
TermCodeSystemVersion myTermCodeSystemVersion = myTermCodeSystemVersionDao.findByCodeSystemPidVersionIsNull( myTermCodeSystem.getPid());
TermCodeSystemVersion myTermCodeSystemVersion = myTermCodeSystemVersionDao.findByCodeSystemPidVersionIsNull(myTermCodeSystem.getPid());
assertEquals(myTermCodeSystem.getCurrentVersion().getPid(), myTermCodeSystemVersion.getPid());
assertEquals(myTermCodeSystem.getResource().getId(), myTermCodeSystemVersion.getResource().getId());
});
@ -45,14 +45,14 @@ public class TermCodeSystemStorageSvcTest extends BaseJpaR4Test {
CodeSystem duplicateUpload = createCodeSystemWithMoreThan100Concepts();
duplicateUpload.setVersion("1");
testCreatingAndUpdatingCodeSystemEntity(firstUpload, duplicateUpload, 125,"Can not create multiple CodeSystem resources with CodeSystem.url \"http://example.com/my_code_system\" and CodeSystem.version \"1\", already have one with resource ID: CodeSystem/");
testCreatingAndUpdatingCodeSystemEntity(firstUpload, duplicateUpload, 125, "Can not create multiple CodeSystem resources with CodeSystem.url \"http://example.com/my_code_system\" and CodeSystem.version \"1\", already have one with resource ID: CodeSystem/");
runInTransaction(() -> {
assertEquals(1, myTermCodeSystemDao.count());
assertEquals(1, myTermCodeSystemVersionDao.count());
TermCodeSystem myTermCodeSystem = myTermCodeSystemDao.findByCodeSystemUri(URL_MY_CODE_SYSTEM);
TermCodeSystemVersion myTermCodeSystemVersion = myTermCodeSystemVersionDao.findByCodeSystemPidAndVersion( myTermCodeSystem.getPid(), "1");
TermCodeSystemVersion myTermCodeSystemVersion = myTermCodeSystemVersionDao.findByCodeSystemPidAndVersion(myTermCodeSystem.getPid(), "1");
assertEquals(myTermCodeSystem.getCurrentVersion().getPid(), myTermCodeSystemVersion.getPid());
assertEquals(myTermCodeSystem.getResource().getId(), myTermCodeSystemVersion.getResource().getId());
});
@ -64,7 +64,7 @@ public class TermCodeSystemStorageSvcTest extends BaseJpaR4Test {
duplicateUpload = createCodeSystemWithMoreThan100Concepts();
duplicateUpload.setVersion("2");
testCreatingAndUpdatingCodeSystemEntity(firstUpload, duplicateUpload, 251,"Can not create multiple CodeSystem resources with CodeSystem.url \"http://example.com/my_code_system\" and CodeSystem.version \"2\", already have one with resource ID: CodeSystem/");
testCreatingAndUpdatingCodeSystemEntity(firstUpload, duplicateUpload, 251, "Can not create multiple CodeSystem resources with CodeSystem.url \"http://example.com/my_code_system\" and CodeSystem.version \"2\", already have one with resource ID: CodeSystem/");
runInTransaction(() -> {
assertEquals(1, myTermCodeSystemDao.count());
@ -103,7 +103,7 @@ public class TermCodeSystemStorageSvcTest extends BaseJpaR4Test {
theUpload.addConcept(new CodeSystem.ConceptDefinitionComponent(new CodeType("codeB")));
// Update the CodeSystem and CodeSystemVersion entities
runInTransaction(() -> myTermCodeSystemStorageSvc.storeNewCodeSystemVersionIfNeeded(theUpload, codeSystemResourceEntity));
validateCodeSystemUpdates(expectedCnt+1);
validateCodeSystemUpdates(expectedCnt + 1);
// Try duplicating the CodeSystem
Long originalResId = codeSystemResourceEntity.getId();
@ -118,7 +118,7 @@ public class TermCodeSystemStorageSvcTest extends BaseJpaR4Test {
theUpload.setConcept(new ArrayList<>());
theUpload.setContent((CodeSystem.CodeSystemContentMode.NOTPRESENT));
runInTransaction(() -> myTermCodeSystemStorageSvc.storeNewCodeSystemVersionIfNeeded(theUpload, codeSystemResourceEntity));
validateCodeSystemUpdates(expectedCnt+1);
validateCodeSystemUpdates(expectedCnt + 1);
}
@ -126,7 +126,7 @@ public class TermCodeSystemStorageSvcTest extends BaseJpaR4Test {
myTerminologyDeferredStorageSvc.setProcessDeferred(true);
myTerminologyDeferredStorageSvc.saveDeferred();
myTerminologyDeferredStorageSvc.setProcessDeferred(false);
assertEquals(theExpectedConceptCount, myTermConceptDao.count());
assertEquals(theExpectedConceptCount, runInTransaction(() -> myTermConceptDao.count()));
}

View File

@ -267,6 +267,7 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
private void validateExpandedTermConcepts(String theCurrentVersion, Collection<String> theAllVersions) {
runInTransaction(() -> {
TermConcept termConceptNoVerCsvNoVer = (TermConcept) myEntityManager.createQuery(
"select tc from TermConcept tc join fetch tc.myCodeSystem tcsv where tc.myCode = '" +
VS_NO_VERSIONED_ON_UPLOAD_FIRST_CODE + "' and tcsv.myCodeSystemVersionId is null").getSingleResult();
@ -297,8 +298,9 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
assertEquals(prefixWithVersion(theCurrentVersion, VS_VERSIONED_ON_UPLOAD_FIRST_DISPLAY), termConceptVerCsvVer.getDisplay());
}
theAllVersions.forEach(this::validateExpandedTermConceptsForVersion);
});
}
@ -474,17 +476,21 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
assertNull(vs.getVersion());
// current TermVSs with no upload version have null version
Optional<TermValueSet> noUploadCurrentVsOpt = myITermReadSvc.findCurrentTermValueSet(VS_NO_VERSIONED_ON_UPLOAD);
Optional<TermValueSet> noUploadCurrentVsOpt = getCurrentTermValueSet(VS_NO_VERSIONED_ON_UPLOAD);
assertTrue(noUploadCurrentVsOpt.isPresent());
assertNull(noUploadCurrentVsOpt.get().getVersion());
// current VSs with upload version have upload-version with no version append
Optional<TermValueSet> uploadCurrentVsOpt = myITermReadSvc.findCurrentTermValueSet(VS_VERSIONED_ON_UPLOAD);
Optional<TermValueSet> uploadCurrentVsOpt = getCurrentTermValueSet(VS_VERSIONED_ON_UPLOAD);
assertTrue(uploadCurrentVsOpt.isPresent());
assertEquals(VS_ANSWER_LIST_VERSION, uploadCurrentVsOpt.get().getVersion());
}
private Optional<TermValueSet> getCurrentTermValueSet(String theTheVsNoVersionedOnUpload) {
return runInTransaction(() -> myITermReadSvc.findCurrentTermValueSet(theTheVsNoVersionedOnUpload));
}
@Test()
public void uploadCurrentNoVersion() throws Exception {
@ -515,7 +521,6 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
}
@Test
public void uploadNoVersionThenNoCurrent() throws Exception {
uploadLoincCodeSystem(null, true);
@ -649,38 +654,12 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
}
/**
* Validates TermConcepts were created in the sequence indicated by the parameters
* and their displays match the expected versions
*/
private void validateTermConceptsLoincAllVs(ArrayList<String> theExpectedVersions) {
@SuppressWarnings("unchecked")
List<TermConcept> termConceptNoVerList = (List<TermConcept>) myEntityManager.createQuery(
"from TermConcept where myCode = '" + VS_NO_VERSIONED_ON_UPLOAD_FIRST_CODE + "' order by myId").getResultList();
assertEquals(theExpectedVersions.size(), termConceptNoVerList.size());
for (int i = 0; i < theExpectedVersions.size(); i++) {
assertEquals( prefixWithVersion(theExpectedVersions.get(i), VS_NO_VERSIONED_ON_UPLOAD_FIRST_DISPLAY),
termConceptNoVerList.get(i).getDisplay(), "TermCode with id: " + i + " display");
}
@SuppressWarnings("unchecked")
List<TermConcept> termConceptWithVerList = (List<TermConcept>) myEntityManager.createQuery(
"from TermConcept where myCode = '" + VS_VERSIONED_ON_UPLOAD_FIRST_CODE + "' order by myId").getResultList();
assertEquals(theExpectedVersions.size(), termConceptWithVerList.size());
for (int i = 0; i < theExpectedVersions.size(); i++) {
assertEquals( prefixWithVersion(theExpectedVersions.get(i), VS_VERSIONED_ON_UPLOAD_FIRST_DISPLAY),
termConceptWithVerList.get(i).getDisplay(), "TermCode with id: " + i + " display");
}
}
/**
* Validates TermConcepts were created in the sequence indicated by the parameters
* and their displays match the expected versions
*/
private void validateTermConcepts(ArrayList<String> theExpectedVersions) {
runInTransaction(() -> {
@SuppressWarnings("unchecked")
List<TermConcept> termConceptNoVerList = (List<TermConcept>) myEntityManager.createQuery(
"from TermConcept where myCode = '" + VS_NO_VERSIONED_ON_UPLOAD_FIRST_CODE + "' order by myId").getResultList();
@ -698,6 +677,7 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
assertEquals( prefixWithVersion(theExpectedVersions.get(i), VS_VERSIONED_ON_UPLOAD_FIRST_DISPLAY),
termConceptWithVerList.get(i).getDisplay(), "TermCode with id: " + i + " display");
}
});
}
@ -742,8 +722,6 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
}
private IIdType uploadLoincCodeSystem(String theVersion, boolean theMakeItCurrent) throws Exception {
myFiles = new ZipCollectionBuilder();
@ -784,15 +762,23 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
if (StringUtils.isBlank(theVersion)) return theClassPathPrefix;
switch(theVersion) {
case "2.67": return "/loinc-ver/v267/";
case "2.68": return "/loinc-ver/v268/";
case "2.69": return "/loinc-ver/v269/";
case "2.67":
return "/loinc-ver/v267/";
case "2.68":
return "/loinc-ver/v268/";
case "2.69":
return "/loinc-ver/v269/";
}
fail("Setup failed. Unexpected version: " + theVersion);
return null;
}
private TermCodeSystemVersion fetchCurrentCodeSystemVersion() {
return runInTransaction(() -> (TermCodeSystemVersion) myEntityManager.createQuery(
"select tcsv from TermCodeSystemVersion tcsv join fetch tcsv.myCodeSystem tcs " +
"where tcs.myCurrentVersion = tcsv").getSingleResult());
}
private static void addBaseLoincMandatoryFilesToZip(
ZipCollectionBuilder theFiles, Boolean theIncludeTop2000, String theClassPathPrefix) throws IOException {
@ -820,11 +806,5 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
}
}
private TermCodeSystemVersion fetchCurrentCodeSystemVersion() {
return (TermCodeSystemVersion) myEntityManager.createQuery(
"select tcsv from TermCodeSystemVersion tcsv join fetch tcsv.myCodeSystem tcs " +
"where tcs.myCurrentVersion = tcsv" ).getSingleResult();
}
}

View File

@ -130,12 +130,16 @@ public class TerminologySvcImplR4Test extends BaseTermR4Test {
ValueSet expandedValueSet = myTermSvc.expandValueSet(null, valueSet);
ourLog.info("Expanded ValueSet:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(expandedValueSet));
TermValueSet termValueSet = myTermValueSetDao.findByResourcePid(myExtensionalVsIdOnResourceTable).get();
TermValueSet termValueSet = runInTransaction(()-> {
TermValueSet vs = myTermValueSetDao.findByResourcePid(myExtensionalVsIdOnResourceTable).get();
Long termValueSetId = vs.getId();
assertEquals(3, myTermValueSetConceptDesignationDao.countByTermValueSetId(termValueSetId).intValue());
assertEquals(3, vs.getTotalConceptDesignations().intValue());
assertEquals(24, myTermValueSetConceptDao.countByTermValueSetId(termValueSetId).intValue());
assertEquals(24, vs.getTotalConcepts().intValue());
return vs;
});
Long termValueSetId = termValueSet.getId();
assertEquals(3, myTermValueSetConceptDesignationDao.countByTermValueSetId(termValueSetId).intValue());
assertEquals(3, termValueSet.getTotalConceptDesignations().intValue());
assertEquals(24, myTermValueSetConceptDao.countByTermValueSetId(termValueSetId).intValue());
assertEquals(24, termValueSet.getTotalConcepts().intValue());
new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
@Override
@ -167,12 +171,15 @@ public class TerminologySvcImplR4Test extends BaseTermR4Test {
ValueSet expandedValueSet = myTermSvc.expandValueSet(null, valueSet);
ourLog.info("Expanded ValueSet:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(expandedValueSet));
TermValueSet termValueSet = myTermValueSetDao.findByResourcePid(myExtensionalVsIdOnResourceTable).get();
Long termValueSetId = termValueSet.getId();
assertEquals(3, myTermValueSetConceptDesignationDao.countByTermValueSetId(termValueSetId).intValue());
assertEquals(3, termValueSet.getTotalConceptDesignations().intValue());
assertEquals(24, myTermValueSetConceptDao.countByTermValueSetId(termValueSetId).intValue());
assertEquals(24, termValueSet.getTotalConcepts().intValue());
Long termValueSetId = runInTransaction(()-> {
TermValueSet termValueSet = myTermValueSetDao.findByResourcePid(myExtensionalVsIdOnResourceTable).get();
Long id = termValueSet.getId();
assertEquals(3, myTermValueSetConceptDesignationDao.countByTermValueSetId(id).intValue());
assertEquals(3, termValueSet.getTotalConceptDesignations().intValue());
assertEquals(24, myTermValueSetConceptDao.countByTermValueSetId(id).intValue());
assertEquals(24, termValueSet.getTotalConcepts().intValue());
return id;
});
new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
@Override

View File

@ -129,6 +129,7 @@ public class MdmLinkDaoSvc {
* @param theSourcePid The Pid of the source you wish to find the matching link for.
* @return the {@link MdmLink} that contains the Match information for the source.
*/
@Transactional
public Optional<MdmLink> getMatchedLinkForSourcePid(Long theSourcePid) {
MdmLink exampleLink = myMdmLinkFactory.newMdmLink();
exampleLink.setSourcePid(theSourcePid);
@ -187,6 +188,7 @@ public class MdmLinkDaoSvc {
return myMdmLinkDao.findAll(example);
}
@Transactional
public Optional<MdmLink> findMdmLinkBySource(IBaseResource theSourceResource) {
@Nullable Long pid = myIdHelperService.getPidOrNull(theSourceResource);
if (pid == null) {
@ -214,6 +216,7 @@ public class MdmLinkDaoSvc {
* @param theGoldenResource The {@link IBaseResource} Golden Resource who's links you would like to retrieve.
* @return A list of all {@link MdmLink} entities in which theGoldenResource is the source Golden Resource
*/
@Transactional
public List<MdmLink> findMdmLinksByGoldenResource(IBaseResource theGoldenResource) {
Long pid = myIdHelperService.getPidOrNull(theGoldenResource);
if (pid == null) {
@ -256,6 +259,7 @@ public class MdmLinkDaoSvc {
* @param theSourceResource the source resource to find links for.
* @return all links for the source.
*/
@Transactional
public List<MdmLink> findMdmLinksBySourceResource(IBaseResource theSourceResource) {
Long pid = myIdHelperService.getPidOrNull(theSourceResource);
if (pid == null) {

View File

@ -35,6 +35,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.transaction.annotation.Transactional;
public class MdmLinkQuerySvcImplSvc implements IMdmLinkQuerySvc {
@ -50,6 +51,7 @@ public class MdmLinkQuerySvcImplSvc implements IMdmLinkQuerySvc {
IMdmModelConverterSvc myMdmModelConverterSvc;
@Override
@Transactional
public Page<MdmLinkJson> queryLinks(IIdType theGoldenResourceId, IIdType theSourceResourceId, MdmMatchResultEnum theMatchResult, MdmLinkSourceEnum theLinkSource, MdmTransactionContext theMdmContext, MdmPageRequest thePageRequest) {
Example<MdmLink> exampleLink = exampleLinkFromParameters(theGoldenResourceId, theSourceResourceId, theMatchResult, theLinkSource);
Page<MdmLink> mdmLinkByExample = myMdmLinkDaoSvc.findMdmLinkByExample(exampleLink, thePageRequest);
@ -58,6 +60,7 @@ public class MdmLinkQuerySvcImplSvc implements IMdmLinkQuerySvc {
}
@Override
@Transactional
public Page<MdmLinkJson> getDuplicateGoldenResources(MdmTransactionContext theMdmContext, MdmPageRequest thePageRequest) {
Example<MdmLink> exampleLink = exampleLinkFromParameters(null, null, MdmMatchResultEnum.POSSIBLE_DUPLICATE, null);
Page<MdmLink> mdmLinkPage = myMdmLinkDaoSvc.findMdmLinkByExample(exampleLink, thePageRequest);

Some files were not shown because too many files have changed in this diff Show More