diff --git a/hapi-fhir-base/src/main/resources/ca/uhn/fhir/i18n/hapi-messages.properties b/hapi-fhir-base/src/main/resources/ca/uhn/fhir/i18n/hapi-messages.properties index 7b82ec3a81f..61bbafae571 100644 --- a/hapi-fhir-base/src/main/resources/ca/uhn/fhir/i18n/hapi-messages.properties +++ b/hapi-fhir-base/src/main/resources/ca/uhn/fhir/i18n/hapi-messages.properties @@ -144,11 +144,13 @@ ca.uhn.fhir.jpa.binstore.BinaryAccessProvider.unknownType=Content in resource of ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl.cannotCreateDuplicateCodeSystemUrl=Can not create multiple CodeSystem resources with CodeSystem.url "{0}", already have one with resource ID: {1} ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl.cannotCreateDuplicateCodeSystemUrlAndVersion=Can not create multiple CodeSystem resources with CodeSystem.url "{0}" and CodeSystem.version "{1}", already have one with resource ID: {2} -ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl.cannotUpdateVersionForExistingCodeSystemVersion=Updated CodeSystem has wrong version id. Existing CodeSystem resource has CodeSystem.url "{0}" and CodeSystem.version "{1}", already have one with resource ID: {2} +ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl.cannotUpdateUrlOrVersionForCodeSystemResource=Cannot update URL or version for CodeSystem resource. Existing CodeSystem resource with resource ID {0} found with CodeSystem.url "{1}" and CodeSystem.version "{2}" ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl.cannotCreateDuplicateConceptMapUrl=Can not create multiple ConceptMap resources with ConceptMap.url "{0}", already have one with resource ID: {1} ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl.cannotCreateDuplicateConceptMapUrlAndVersion=Can not create multiple ConceptMap resources with ConceptMap.url "{0}", ConceptMap.version "{1}", already have one with resource ID: {2} ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl.cannotCreateDuplicateValueSetUrl=Can not create multiple ValueSet resources with ValueSet.url "{0}", already have one with resource ID: {1} ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl.expansionTooLarge=Expansion of ValueSet produced too many codes (maximum {0}) - Operation aborted! +ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl.cannotCreateDuplicateValueSetUrlAndVersion=Can not create multiple CodeSystem resources with CodeSystem.url "{0}" and CodeSystem.version "{1}", already have one with resource ID: {2} +ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl.cannotUpdateUrlOrVersionForValueSetResource=Cannot update URL or version for ValueSet resource. Existing ValueSet resource with resource ID {0} found with ValueSet.url "{1}" and ValueSet.version "{2}" ca.uhn.fhir.jpa.patch.JsonPatchUtils.failedToApplyPatch=Failed to apply JSON patch to {0}: {1} diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/HapiFhirResourceDaoCodeSystemUtil.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/HapiFhirResourceDaoCodeSystemUtil.java deleted file mode 100644 index 72cf8ac39ab..00000000000 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/HapiFhirResourceDaoCodeSystemUtil.java +++ /dev/null @@ -1,28 +0,0 @@ -package ca.uhn.fhir.jpa.dao; - -import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemDao; -import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemVersionDao; -import ca.uhn.fhir.jpa.entity.TermCodeSystem; -import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion; -import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc; - -import static org.apache.commons.lang3.StringUtils.isNotBlank; - -public class HapiFhirResourceDaoCodeSystemUtil { - - static public void deleteCodeSystemEntities(ITermCodeSystemDao theCsDao, ITermCodeSystemVersionDao theCsvDao, - ITermDeferredStorageSvc theTermDeferredStorageSvc, String theCodeSystemUrl, - String theCodeSystemVersion) { - if (isNotBlank(theCodeSystemUrl)) { - TermCodeSystem persCs = theCsDao.findByCodeSystemUri(theCodeSystemUrl); - if (persCs != null) { - if (theCodeSystemVersion != null) { - TermCodeSystemVersion persCsVersion = theCsvDao.findByCodeSystemPidAndVersion(persCs.getPid(), theCodeSystemVersion); - theTermDeferredStorageSvc.deleteCodeSystemVersion(persCsVersion); - } else { - theTermDeferredStorageSvc.deleteCodeSystem(persCs); - } - } - } - } -} diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermValueSetDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermValueSetDao.java index f3a841f49e6..a7d72f71d6e 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermValueSetDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermValueSetDao.java @@ -28,6 +28,7 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; +import java.util.List; import java.util.Optional; public interface ITermValueSetDao extends JpaRepository { @@ -41,4 +42,14 @@ public interface ITermValueSetDao extends JpaRepository { @Query("SELECT vs FROM TermValueSet vs WHERE vs.myExpansionStatus = :expansion_status") Slice findByExpansionStatus(Pageable pageable, @Param("expansion_status") TermValueSetPreExpansionStatusEnum theExpansionStatus); + @Query(value="SELECT vs FROM TermValueSet vs INNER JOIN ResourceTable r ON r.myId = vs.myResourcePid WHERE vs.myUrl = :url ORDER BY r.myUpdated DESC") + List findTermValueSetByUrl(Pageable thePage, @Param("url") String theUrl); + + @Query("SELECT vs FROM TermValueSet vs WHERE vs.myUrl = :url AND vs.myVersion IS NULL") + Optional findTermValueSetByUrlAndNullVersion(@Param("url") String theUrl); + + @Query("SELECT vs FROM TermValueSet vs WHERE vs.myUrl = :url AND vs.myVersion = :version") + Optional findTermValueSetByUrlAndVersion(@Param("url") String theUrl, @Param("version") String theVersion); + + } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoCodeSystemDstu3.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoCodeSystemDstu3.java index 621d83d5e9a..c42f4125ce1 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoCodeSystemDstu3.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoCodeSystemDstu3.java @@ -25,10 +25,6 @@ import ca.uhn.fhir.context.support.IValidationSupport; import ca.uhn.fhir.context.support.ValidationSupportContext; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoCodeSystem; import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao; -import ca.uhn.fhir.jpa.dao.HapiFhirResourceDaoCodeSystemUtil; -import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemDao; -import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemVersionDao; -import ca.uhn.fhir.jpa.entity.TermCodeSystem; import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource; import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc; import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; @@ -67,10 +63,6 @@ public class FhirResourceDaoCodeSystemDstu3 extends BaseHapiFhirResourceDao implements IFhirResourceDaoValueSet { private static final Logger ourLog = LoggerFactory.getLogger(FhirResourceDaoValueSetDstu3.class); - @Autowired - private ITermReadSvc myHapiTerminologySvc; - @Autowired private DefaultProfileValidationSupport myDefaultProfileValidationSupport; @@ -283,12 +280,12 @@ public class FhirResourceDaoValueSetDstu3 extends BaseHapiFhirResourceDao implements IFhirResourceDaoValueSet { - @Autowired - private ITermReadSvc myHapiTerminologySvc; - @Autowired private DefaultProfileValidationSupport myDefaultProfileValidationSupport; @@ -113,17 +110,14 @@ public class FhirResourceDaoValueSetR4 extends BaseHapiFhirResourceDao ValueSet source = new ValueSet(); source.setUrl(theUri); -// source.getCompose().addInclude().addValueSet(theUri); + source.getCompose().addInclude().addValueSet(theUri); if (isNotBlank(theFilter)) { -// ConceptSetComponent include = source.getCompose().addInclude(); -// ConceptSetFilterComponent filter = include.addFilter(); - ConceptSetFilterComponent filter = source.getCompose().addInclude().addValueSet(theUri).addFilter(); + ConceptSetComponent include = source.getCompose().addInclude(); + ConceptSetFilterComponent filter = include.addFilter(); filter.setProperty("display"); filter.setOp(FilterOperator.EQUAL); filter.setValue(theFilter); - } else { - source.getCompose().addInclude().addValueSet(theUri); } ValueSet retVal = doExpand(source); @@ -151,17 +145,14 @@ public class FhirResourceDaoValueSetR4 extends BaseHapiFhirResourceDao ValueSet source = new ValueSet(); source.setUrl(theUri); -// source.getCompose().addInclude().addValueSet(theUri); + source.getCompose().addInclude().addValueSet(theUri); if (isNotBlank(theFilter)) { -// ConceptSetComponent include = source.getCompose().addInclude(); -// ConceptSetFilterComponent filter = include.addFilter(); - ConceptSetFilterComponent filter = source.getCompose().addInclude().addValueSet(theUri).addFilter(); + ConceptSetComponent include = source.getCompose().addInclude(); + ConceptSetFilterComponent filter = include.addFilter(); filter.setProperty("display"); filter.setOp(FilterOperator.EQUAL); filter.setValue(theFilter); - } else { - source.getCompose().addInclude().addValueSet(theUri); } ValueSet retVal = doExpand(source, theOffset, theCount); @@ -268,9 +259,9 @@ public class FhirResourceDaoValueSetR4 extends BaseHapiFhirResourceDao if (myDaoConfig.isPreExpandValueSets() && !retVal.isUnchangedInCurrentOperation()) { if (retVal.getDeleted() == null) { ValueSet valueSet = (ValueSet) theResource; - myHapiTerminologySvc.storeTermValueSet(retVal, valueSet); + myTerminologySvc.storeTermValueSet(retVal, valueSet); } else { - myHapiTerminologySvc.deleteValueSetAndChildren(retVal); + myTerminologySvc.deleteValueSetAndChildren(retVal); } } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r5/FhirResourceDaoCodeSystemR5.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r5/FhirResourceDaoCodeSystemR5.java index 9b5fe473c96..c9bd9125be4 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r5/FhirResourceDaoCodeSystemR5.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r5/FhirResourceDaoCodeSystemR5.java @@ -25,11 +25,7 @@ import ca.uhn.fhir.context.support.IValidationSupport; import ca.uhn.fhir.context.support.ValidationSupportContext; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoCodeSystem; import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao; -import ca.uhn.fhir.jpa.dao.HapiFhirResourceDaoCodeSystemUtil; -import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemDao; -import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemVersionDao; import ca.uhn.fhir.jpa.dao.index.IdHelperService; -import ca.uhn.fhir.jpa.entity.TermCodeSystem; import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource; import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc; import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; @@ -65,10 +61,6 @@ public class FhirResourceDaoCodeSystemR5 extends BaseHapiFhirResourceDao implements IFhirResourceDaoValueSet { - @Autowired - private ITermReadSvc myHapiTerminologySvc; - @Autowired @Qualifier("myDefaultProfileValidationSupport") private IValidationSupport myDefaultProfileValidationSupport; @@ -267,9 +264,9 @@ public class FhirResourceDaoValueSetR5 extends BaseHapiFhirResourceDao if (myDaoConfig.isPreExpandValueSets() && !retVal.isUnchangedInCurrentOperation()) { if (retVal.getDeleted() == null) { ValueSet valueSet = (ValueSet) theResource; - myHapiTerminologySvc.storeTermValueSet(retVal, org.hl7.fhir.convertors.conv40_50.ValueSet40_50.convertValueSet(valueSet)); + myTerminologySvc.storeTermValueSet(retVal, org.hl7.fhir.convertors.conv40_50.ValueSet40_50.convertValueSet(valueSet)); } else { - myHapiTerminologySvc.deleteValueSetAndChildren(retVal); + myTerminologySvc.deleteValueSetAndChildren(retVal); } } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TermValueSet.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TermValueSet.java index 48811e9256b..4cbe867d6cf 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TermValueSet.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TermValueSet.java @@ -37,7 +37,7 @@ import static org.apache.commons.lang3.StringUtils.left; import static org.apache.commons.lang3.StringUtils.length; @Table(name = "TRM_VALUESET", uniqueConstraints = { - @UniqueConstraint(name = "IDX_VALUESET_URL", columnNames = {"URL"}) + @UniqueConstraint(name = "IDX_VALUESET_URL", columnNames = {"URL", "VER"}) }) @Entity() public class TermValueSet implements Serializable { @@ -46,6 +46,7 @@ public class TermValueSet implements Serializable { public static final int MAX_EXPANSION_STATUS_LENGTH = 50; public static final int MAX_NAME_LENGTH = 200; public static final int MAX_URL_LENGTH = 200; + static final int MAX_VER_LENGTH = 200; @Id() @SequenceGenerator(name = "SEQ_VALUESET_PID", sequenceName = "SEQ_VALUESET_PID") @@ -56,6 +57,9 @@ public class TermValueSet implements Serializable { @Column(name = "URL", nullable = false, length = MAX_URL_LENGTH) private String myUrl; + @Column(name = "VER", nullable = true, length = MAX_VER_LENGTH) + private String myVersion; + @OneToOne() @JoinColumn(name = "RES_ID", referencedColumnName = "RES_ID", nullable = false, updatable = false, foreignKey = @ForeignKey(name = "FK_TRMVALUESET_RES")) private ResourceTable myResource; @@ -183,6 +187,17 @@ public class TermValueSet implements Serializable { myExpansionStatus = theExpansionStatus; } + public String getVersion() { + return myVersion; + } + + public TermValueSet setVersion(String theVersion) { + ValidateUtil.isNotTooLongOrThrowIllegalArgument(theVersion, MAX_VER_LENGTH, + "Version exceeds maximum length (" + MAX_VER_LENGTH + "): " + length(theVersion)); + myVersion = theVersion; + return this; + } + @Override public boolean equals(Object theO) { if (this == theO) return true; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/BaseTermReadSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/BaseTermReadSvcImpl.java index 860d85cd055..9eb75636f6e 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/BaseTermReadSvcImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/BaseTermReadSvcImpl.java @@ -332,7 +332,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc { deleteConceptMap(theResourceTable); } - public void deleteValueSet(ResourceTable theResourceTable) { + public void deleteValueSetForResource(ResourceTable theResourceTable) { // Get existing entity so it can be deleted. Optional optionalExistingTermValueSetById = myValueSetDao.findByResourcePid(theResourceTable.getId()); @@ -350,7 +350,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc { @Override @Transactional public void deleteValueSetAndChildren(ResourceTable theResourceTable) { - deleteValueSet(theResourceTable); + deleteValueSetForResource(theResourceTable); } private ValueSet expandValueSetInMemory(ValueSetExpansionOptions theExpansionOptions, ValueSet theValueSetToExpand, VersionIndependentConcept theWantConceptOrNull) { @@ -392,7 +392,12 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc { Optional optionalTermValueSet; if (theValueSetToExpand.hasUrl()) { - optionalTermValueSet = myValueSetDao.findByUrl(theValueSetToExpand.getUrl()); + if (theValueSetToExpand.hasVersion()) { + optionalTermValueSet = myValueSetDao.findTermValueSetByUrlAndVersion(theValueSetToExpand.getUrl(), theValueSetToExpand.getVersion()); + } else { + List termValueSets = myValueSetDao.findTermValueSetByUrl(PageRequest.of(0, 1), theValueSetToExpand.getUrl()); + optionalTermValueSet = Optional.of(termValueSets.get(0)); + } } else { optionalTermValueSet = Optional.empty(); } @@ -1795,38 +1800,52 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc { ValidateUtil.isTrueOrThrowInvalidRequest(theResourceTable != null, "No resource supplied"); ValidateUtil.isNotBlankOrThrowUnprocessableEntity(theValueSet.getUrl(), "ValueSet has no value for ValueSet.url"); + /* + * Get CodeSystem and validate CodeSystemVersion + */ TermValueSet termValueSet = new TermValueSet(); termValueSet.setResource(theResourceTable); termValueSet.setUrl(theValueSet.getUrl()); + termValueSet.setVersion(theValueSet.getVersion()); termValueSet.setName(theValueSet.hasName() ? theValueSet.getName() : null); - // We delete old versions; we don't support versioned ValueSets. - deleteValueSet(theResourceTable); + // Delete version being replaced + deleteValueSetForResource(theResourceTable); /* * Do the upload. */ String url = termValueSet.getUrl(); - Optional optionalExistingTermValueSetByUrl = myValueSetDao.findByUrl(url); + String version = termValueSet.getVersion(); + Optional optionalExistingTermValueSetByUrl; + if (version != null) { + optionalExistingTermValueSetByUrl = myValueSetDao.findTermValueSetByUrlAndVersion(url, version); + } else { + optionalExistingTermValueSetByUrl = myValueSetDao.findTermValueSetByUrlAndNullVersion(url); + } if (!optionalExistingTermValueSetByUrl.isPresent()) { - termValueSet = myValueSetDao.save(termValueSet); + myValueSetDao.save(termValueSet); } else { TermValueSet existingTermValueSet = optionalExistingTermValueSetByUrl.get(); - - String msg = myContext.getLocalizer().getMessage( - BaseTermReadSvcImpl.class, - "cannotCreateDuplicateValueSetUrl", - url, - existingTermValueSet.getResource().getIdDt().toUnqualifiedVersionless().getValue()); - + String msg; + if (version != null) { + msg = myContext.getLocalizer().getMessage( + BaseTermReadSvcImpl.class, + "cannotCreateDuplicateValueSetUrlAndVersion", + url, version, existingTermValueSet.getResource().getIdDt().toUnqualifiedVersionless().getValue()); + } else { + msg = myContext.getLocalizer().getMessage( + BaseTermReadSvcImpl.class, + "cannotCreateDuplicateValueSetUrl", + url, existingTermValueSet.getResource().getIdDt().toUnqualifiedVersionless().getValue()); + } throw new UnprocessableEntityException(msg); } - - ourLog.info("Done storing TermValueSet[{}] for {}", termValueSet.getId(), theValueSet.getIdElement().toVersionless().getValueAsString()); } + @Override public IFhirResourceDaoCodeSystem.SubsumesResult subsumes(IPrimitiveType theCodeA, IPrimitiveType theCodeB, IPrimitiveType theSystem, IBaseCoding theCodingA, IBaseCoding theCodingB) { diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermCodeSystemStorageSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermCodeSystemStorageSvcImpl.java index b37f98235b9..ac19b652593 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermCodeSystemStorageSvcImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermCodeSystemStorageSvcImpl.java @@ -238,17 +238,6 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc { ourLog.info(" * Deleting code system version {}", theCodeSystemVersion.getCodeSystemVersionId()); deleteCodeSystemVersion(theCodeSystemVersion.getPid()); - // Check if the version deleted is the current version. If so, delete TermCodeSystem as well. - TermCodeSystem termCodeSystem = theCodeSystemVersion.getCodeSystem(); - TransactionTemplate txTemplate = new TransactionTemplate(myTransactionManager); - txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); - txTemplate.executeWithoutResult(t -> { - if (myCodeSystemVersionDao.findByCodeSystemPid(termCodeSystem.getPid()).size() == 0) { - ourLog.info(" * Deleting code system {}", termCodeSystem.getPid()); - deleteCodeSystem(termCodeSystem); - } - }); - } /** @@ -709,27 +698,29 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc { } private void checkForCodeSystemVersionDuplicate(TermCodeSystem theCodeSystem, String theSystemUri, String theSystemVersionId, ResourceTable theCodeSystemResourceTable) { - // Check if CodeSystemVersion entity already exists. TermCodeSystemVersion codeSystemVersionEntity; String msg = null; if (theSystemVersionId == null) { + // Check if a non-versioned TermCodeSystemVersion entity already exists for this TermCodeSystem. codeSystemVersionEntity = myCodeSystemVersionDao.findByCodeSystemPidVersionIsNull(theCodeSystem.getPid()); if (codeSystemVersionEntity != null) { msg = myContext.getLocalizer().getMessage(BaseTermReadSvcImpl.class, "cannotCreateDuplicateCodeSystemUrl", theSystemUri, codeSystemVersionEntity.getResource().getIdDt().toUnqualifiedVersionless().getValue()); } } else { + // Check if a TermCodeSystemVersion entity already exists for this TermCodeSystem and version. codeSystemVersionEntity = myCodeSystemVersionDao.findByCodeSystemPidAndVersion(theCodeSystem.getPid(), theSystemVersionId); if (codeSystemVersionEntity != null) { msg = myContext.getLocalizer().getMessage(BaseTermReadSvcImpl.class, "cannotCreateDuplicateCodeSystemUrlAndVersion", theSystemUri, theSystemVersionId, codeSystemVersionEntity.getResource().getIdDt().toUnqualifiedVersionless().getValue()); } else { + // Check if a TermCodeSystemVersion entity already exists for this CodeSystem resource (i.e. with a different version or URL) codeSystemVersionEntity = myCodeSystemVersionDao.findByCodeSystemResourcePid(theCodeSystemResourceTable.getId()); if (codeSystemVersionEntity != null) { - msg = myContext.getLocalizer().getMessage(BaseTermReadSvcImpl.class, "cannotCreateDuplicateCodeSystemUrlAndVersion", theSystemUri, theSystemVersionId, codeSystemVersionEntity.getResource().getIdDt().toUnqualifiedVersionless().getValue()); + msg = myContext.getLocalizer().getMessage(BaseTermReadSvcImpl.class, "cannotUpdateUrlOrVersionForCodeSystemResource", codeSystemVersionEntity.getResource().getIdDt().toUnqualifiedVersionless().getValue(), theSystemUri, theSystemVersionId); throw new UnprocessableEntityException(msg); } } } - // Throw exception if the CodeSystemVersion is being duplicated. + // Throw exception if the TermCodeSystemVersion is being duplicated. if (codeSystemVersionEntity != null) { if (!ObjectUtil.equals(codeSystemVersionEntity.getResource().getId(), theCodeSystemResourceTable.getId())) { throw new UnprocessableEntityException(msg); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermDeferredStorageSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermDeferredStorageSvcImpl.java index 3a4e3f47139..e27177f3f1a 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermDeferredStorageSvcImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermDeferredStorageSvcImpl.java @@ -29,6 +29,7 @@ import ca.uhn.fhir.jpa.entity.TermCodeSystem; 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.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.sched.HapiJob; import ca.uhn.fhir.jpa.model.sched.ISchedulerService; import ca.uhn.fhir.jpa.model.sched.ScheduledJobDefinition; @@ -119,8 +120,15 @@ public class TermDeferredStorageSvcImpl implements ITermDeferredStorageSvc { @Override @Transactional - public void deleteCodeSystemVersion(TermCodeSystemVersion theCodeSystemVersion) { - myDefferedCodeSystemVersionsDeletions.add(theCodeSystemVersion); + public void deleteCodeSystemForResource(ResourceTable theCodeSystemToDelete) { + TermCodeSystemVersion codeSystemVersionToDelete = myCodeSystemVersionDao.findByCodeSystemResourcePid(theCodeSystemToDelete.getResourceId()); + if (codeSystemVersionToDelete != null) { + myDefferedCodeSystemVersionsDeletions.add(codeSystemVersionToDelete); + } + TermCodeSystem codeSystemToDelete = myCodeSystemDao.findByResourcePid(theCodeSystemToDelete.getResourceId()); + if (codeSystemToDelete != null) { + deleteCodeSystem(codeSystemToDelete); + } } @Override @@ -219,6 +227,7 @@ public class TermDeferredStorageSvcImpl implements ITermDeferredStorageSvc { myDeferredConceptMaps.clear(); myDeferredConcepts.clear(); myDefferedCodeSystemsDeletions.clear(); + myConceptLinksToSaveLater.clear(); } @Transactional(propagation = Propagation.NEVER) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermLoaderSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermLoaderSvcImpl.java index 3fe945458a5..5e452989081 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermLoaderSvcImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermLoaderSvcImpl.java @@ -381,6 +381,7 @@ public class TermLoaderSvcImpl implements ITermLoaderSvc { String codeSystemVersionId = theUploadProperties.getProperty(LOINC_CODESYSTEM_VERSION.getCode()); if (codeSystemVersionId != null) { loincCs.setVersion(codeSystemVersionId); + loincCs.setId(loincCs.getId() + "-" + codeSystemVersionId); } } catch (IOException e) { throw new InternalErrorException("Failed to load loinc.xml", e); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/ValueSetConceptAccumulator.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/ValueSetConceptAccumulator.java index 869d8ba1b72..fda53d03c5e 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/ValueSetConceptAccumulator.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/ValueSetConceptAccumulator.java @@ -42,13 +42,12 @@ public class ValueSetConceptAccumulator implements IValueSetConceptAccumulator { private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ValueSetConceptAccumulator.class); private TermValueSet myTermValueSet; - private ITermValueSetDao myValueSetDao; - private ITermValueSetConceptDao myValueSetConceptDao; - private ITermValueSetConceptDesignationDao myValueSetConceptDesignationDao; + final private ITermValueSetDao myValueSetDao; + final private ITermValueSetConceptDao myValueSetConceptDao; + final private ITermValueSetConceptDesignationDao myValueSetConceptDesignationDao; private int myConceptsSaved; private int myDesignationsSaved; private int myConceptsExcluded; - private int myCount; public ValueSetConceptAccumulator(@Nonnull TermValueSet theTermValueSet, @Nonnull ITermValueSetDao theValueSetDao, @Nonnull ITermValueSetConceptDao theValueSetConceptDao, @Nonnull ITermValueSetConceptDesignationDao theValueSetConceptDesignationDao) { myTermValueSet = theTermValueSet; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/api/ITermDeferredStorageSvc.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/api/ITermDeferredStorageSvc.java index 9fddda117f1..eada0db384b 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/api/ITermDeferredStorageSvc.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/api/ITermDeferredStorageSvc.java @@ -24,6 +24,7 @@ import ca.uhn.fhir.jpa.entity.TermCodeSystem; 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.jpa.model.entity.ResourceTable; import org.hl7.fhir.r4.model.ConceptMap; import org.hl7.fhir.r4.model.ValueSet; @@ -55,7 +56,7 @@ public interface ITermDeferredStorageSvc { void deleteCodeSystem(TermCodeSystem theCodeSystem); - void deleteCodeSystemVersion(TermCodeSystemVersion theCodeSystemVersion); + void deleteCodeSystemForResource(ResourceTable theCodeSystemResourceToDelete); /** * This is mostly here for unit tests - Saves any and all deferred concepts and links diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/BaseJpaDstu3Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/BaseJpaDstu3Test.java index 720a4bd0a3d..7c8a52d6a48 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/BaseJpaDstu3Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/BaseJpaDstu3Test.java @@ -52,7 +52,6 @@ import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.EncodingEnum; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory; -import ca.uhn.fhir.util.TestUtil; import ca.uhn.fhir.util.UrlUtil; import org.apache.commons.io.IOUtils; import org.hibernate.search.jpa.FullTextEntityManager; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3TerminologyTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3TerminologyTest.java index d34393b7b61..7c21676735e 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3TerminologyTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3TerminologyTest.java @@ -80,6 +80,7 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test { private CodeSystem createExternalCs() { CodeSystem codeSystem = new CodeSystem(); codeSystem.setUrl(URL_MY_CODE_SYSTEM); + codeSystem.setVersion("SYSTEM VERSION"); codeSystem.setContent(CodeSystemContentMode.NOTPRESENT); codeSystem.setName("ACME Codes"); IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified(); @@ -124,6 +125,7 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test { private void createExternalCsLarge() { CodeSystem codeSystem = new CodeSystem(); codeSystem.setUrl(URL_MY_CODE_SYSTEM); + codeSystem.setVersion("SYSTEM VERSION"); codeSystem.setContent(CodeSystemContentMode.NOTPRESENT); IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified(); @@ -165,6 +167,7 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test { private CodeSystem createExternalCsDogs() { CodeSystem codeSystem = new CodeSystem(); codeSystem.setUrl(URL_MY_CODE_SYSTEM); + codeSystem.setVersion("SYSTEM VERSION"); codeSystem.setContent(CodeSystemContentMode.NOTPRESENT); IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified(); @@ -698,6 +701,7 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test { public void testLookupSnomed() { CodeSystem codeSystem = new CodeSystem(); codeSystem.setUrl("http://snomed.info/sct"); + codeSystem.setVersion("SYSTEM VERSION"); codeSystem.setContent(CodeSystemContentMode.NOTPRESENT); IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified(); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3ValueSetTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3ValueSetTest.java index eeacca3ea22..9500b926ac7 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3ValueSetTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3ValueSetTest.java @@ -22,6 +22,7 @@ import org.springframework.transaction.annotation.Transactional; import java.io.IOException; +import static org.awaitility.Awaitility.await; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.not; @@ -76,6 +77,7 @@ public class FhirResourceDaoDstu3ValueSetTest extends BaseJpaDstu3Test { validationOutcome = myValueSetDao.validateCode(vsIdentifier, null, code, system, null, null, null, mySrd); assertEquals(false, validationOutcome.isOk()); + await().until(() -> clearDeferredStorageQueue()); myTermSvc.preExpandDeferredValueSetsToTerminologyTables(); runInTransaction(() -> { @@ -95,6 +97,16 @@ public class FhirResourceDaoDstu3ValueSetTest extends BaseJpaDstu3Test { } + private boolean clearDeferredStorageQueue() { + + if(!myTerminologyDeferredStorageSvc.isStorageQueueEmpty()) { + myTerminologyDeferredStorageSvc.saveAllDeferred(); + return false; + } else { + return true; + } + + } @Test @Disabled diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java index 6f82419b86c..12ef9a2206a 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java @@ -64,7 +64,6 @@ import ca.uhn.fhir.jpa.search.IStaleSearchDeletingSvc; import ca.uhn.fhir.jpa.search.reindex.IResourceReindexingSvc; import ca.uhn.fhir.jpa.search.warm.ICacheWarmingSvc; import ca.uhn.fhir.jpa.searchparam.registry.SearchParamRegistryImpl; -import ca.uhn.fhir.jpa.subscription.match.registry.SubscriptionRegistry; import ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl; import ca.uhn.fhir.jpa.term.TermDeferredStorageSvcImpl; import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc; @@ -81,7 +80,6 @@ import ca.uhn.fhir.rest.server.BasePagingProvider; import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor; import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory; import ca.uhn.fhir.test.utilities.ITestDataBuilder; -import ca.uhn.fhir.util.TestUtil; import ca.uhn.fhir.util.UrlUtil; import ca.uhn.fhir.validation.FhirValidator; import ca.uhn.fhir.validation.ValidationResult; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4CodeSystemTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4CodeSystemTest.java index 4328183f249..9d917a7af8a 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4CodeSystemTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4CodeSystemTest.java @@ -136,10 +136,10 @@ public class FhirResourceDaoR4CodeSystemTest extends BaseJpaR4Test { // Attempt to delete second version myCodeSystemDao.delete(id_second, mySrd); - // Only the resource will be deleted initially + // Only the resource will be deleted initially, but the URL for the TermCodeSystem will be cleared and not searchable. runInTransaction(() -> { assertEquals(1, myTermCodeSystemDao.count()); - assertNotNull(myTermCodeSystemDao.findByCodeSystemUri("http://foo")); + assertNull(myTermCodeSystemDao.findByCodeSystemUri("http://foo")); assertEquals(1, myTermCodeSystemVersionDao.count()); assertEquals(222, myTermConceptDao.count()); List resourceList = myResourceTableDao.findAll(); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchWithElasticSearchIT.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchWithElasticSearchIT.java index 2139b93b543..1b614aa7d04 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchWithElasticSearchIT.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchWithElasticSearchIT.java @@ -209,6 +209,7 @@ public class FhirResourceDaoR4SearchWithElasticSearchIT extends BaseJpaTest { private CodeSystem createExternalCs() { CodeSystem codeSystem = new CodeSystem(); codeSystem.setUrl(URL_MY_CODE_SYSTEM); + codeSystem.setVersion("SYSTEM VERSION"); codeSystem.setContent(CodeSystem.CodeSystemContentMode.NOTPRESENT); IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified(); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4TerminologyElasticsearchIT.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4TerminologyElasticsearchIT.java index e5c298a8011..098754e33ea 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4TerminologyElasticsearchIT.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4TerminologyElasticsearchIT.java @@ -85,6 +85,7 @@ public class FhirResourceDaoR4TerminologyElasticsearchIT extends BaseJpaTest { public void testExpandWithIncludeContainingDashesInInclude() { CodeSystem codeSystem = new CodeSystem(); codeSystem.setUrl(URL_MY_CODE_SYSTEM); + codeSystem.setVersion("SYSTEM VERSION"); codeSystem.setContent(CodeSystemContentMode.NOTPRESENT); IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified(); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4TerminologyTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4TerminologyTest.java index 63b88299e1b..29db57d857f 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4TerminologyTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4TerminologyTest.java @@ -80,6 +80,7 @@ public class FhirResourceDaoR4TerminologyTest extends BaseJpaR4Test { private CodeSystem createExternalCs() { CodeSystem codeSystem = new CodeSystem(); codeSystem.setUrl(URL_MY_CODE_SYSTEM); + codeSystem.setVersion("SYSTEM VERSION"); codeSystem.setContent(CodeSystemContentMode.NOTPRESENT); IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified(); @@ -129,6 +130,7 @@ public class FhirResourceDaoR4TerminologyTest extends BaseJpaR4Test { private CodeSystem createExternalCsDogs() { CodeSystem codeSystem = new CodeSystem(); codeSystem.setUrl(URL_MY_CODE_SYSTEM); + codeSystem.setVersion("SYSTEM VERSION"); codeSystem.setContent(CodeSystemContentMode.NOTPRESENT); IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified(); @@ -159,6 +161,7 @@ public class FhirResourceDaoR4TerminologyTest extends BaseJpaR4Test { private void createExternalCsLarge() { CodeSystem codeSystem = new CodeSystem(); codeSystem.setUrl(URL_MY_CODE_SYSTEM); + codeSystem.setVersion("SYSTEM VERSION"); codeSystem.setContent(CodeSystemContentMode.NOTPRESENT); IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified(); @@ -473,6 +476,7 @@ public class FhirResourceDaoR4TerminologyTest extends BaseJpaR4Test { public void testExpandWithIncludeContainingDashesInInclude() { CodeSystem codeSystem = new CodeSystem(); codeSystem.setUrl(URL_MY_CODE_SYSTEM); + codeSystem.setVersion("SYSTEM VERSION"); codeSystem.setContent(CodeSystemContentMode.NOTPRESENT); IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified(); @@ -815,6 +819,7 @@ public class FhirResourceDaoR4TerminologyTest extends BaseJpaR4Test { public void testLookupSnomed() { CodeSystem codeSystem = new CodeSystem(); codeSystem.setUrl("http://snomed.info/sct"); + codeSystem.setVersion("SYSTEM VERSION"); codeSystem.setContent(CodeSystemContentMode.NOTPRESENT); IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified(); @@ -828,7 +833,7 @@ public class FhirResourceDaoR4TerminologyTest extends BaseJpaR4Test { StringType code = new StringType("ParentA"); StringType system = new StringType("http://snomed.info/sct"); - IValidationSupport.LookupCodeResult outcome = myCodeSystemDao.lookupCode(code, system, null,null, mySrd); + IValidationSupport.LookupCodeResult outcome = myCodeSystemDao.lookupCode(code, system, null, mySrd); assertEquals(true, outcome.isFound()); } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ValidateTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ValidateTest.java index 9a6804f4020..57f45050655 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ValidateTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ValidateTest.java @@ -9,8 +9,6 @@ import ca.uhn.fhir.jpa.entity.TermValueSet; import ca.uhn.fhir.jpa.entity.TermValueSetPreExpansionStatusEnum; import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl; -import ca.uhn.fhir.jpa.term.TerminologyLoaderSvcLoincTest; -import ca.uhn.fhir.jpa.term.ZipCollectionBuilder; import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc; import ca.uhn.fhir.jpa.term.api.ITermLoaderSvc; import ca.uhn.fhir.jpa.term.api.ITermReadSvc; @@ -80,7 +78,6 @@ import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.not; 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; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r5/BaseJpaR5Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r5/BaseJpaR5Test.java index da959cba3c6..85784c49eb6 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r5/BaseJpaR5Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r5/BaseJpaR5Test.java @@ -69,7 +69,6 @@ import ca.uhn.fhir.rest.api.EncodingEnum; import ca.uhn.fhir.rest.server.BasePagingProvider; import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor; import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory; -import ca.uhn.fhir.util.TestUtil; import ca.uhn.fhir.util.UrlUtil; import ca.uhn.fhir.validation.FhirValidator; import ca.uhn.fhir.validation.ValidationResult; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderDstu3ValueSetTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderDstu3ValueSetTest.java index 9c85d3f9afb..e293bb59bb7 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderDstu3ValueSetTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderDstu3ValueSetTest.java @@ -13,7 +13,6 @@ import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; -import ca.uhn.fhir.util.TestUtil; import ca.uhn.fhir.util.UrlUtil; import com.google.common.base.Charsets; import org.apache.commons.io.IOUtils; @@ -37,7 +36,6 @@ import org.hl7.fhir.dstu3.model.ValueSet.ConceptSetComponent; import org.hl7.fhir.dstu3.model.ValueSet.FilterOperator; import org.hl7.fhir.instance.model.api.IIdType; import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallbackWithoutResult; @@ -137,6 +135,7 @@ public class ResourceProviderDstu3ValueSetTest extends BaseResourceProviderDstu3 runInTransaction(() -> { CodeSystem codeSystem = new CodeSystem(); codeSystem.setUrl(CS_URL); + codeSystem.setVersion("SYSTEM VERSION"); codeSystem.setContent(CodeSystemContentMode.NOTPRESENT); IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified(); @@ -823,7 +822,7 @@ public class ResourceProviderDstu3ValueSetTest extends BaseResourceProviderDstu3 codeSystem.setUrl(URL_MY_CODE_SYSTEM); codeSystem.setContent(CodeSystemContentMode.NOTPRESENT); codeSystem.setName("ACME Codes"); - codeSystem.setVersion("1.2.3.4"); + codeSystem.setVersion("SYSTEM VERSION"); IIdType id = theCodeSystemDao.create(codeSystem, theRequestDetails).getId().toUnqualified(); ResourceTable table = theResourceTableDao.findById(id.getIdPartAsLong()).orElseThrow(IllegalStateException::new); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4CodeSystemTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4CodeSystemTest.java index 0ed780b76e4..48986d9b46c 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4CodeSystemTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4CodeSystemTest.java @@ -25,9 +25,6 @@ public class ResourceProviderR4CodeSystemTest extends BaseResourceProviderR4Test CodeSystem cs = loadResourceFromClasspath(CodeSystem.class, "/extensional-case-3-cs.xml"); myCodeSystemDao.create(cs, mySrd); - ValueSet upload = loadResourceFromClasspath(ValueSet.class, "/extensional-case-3-vs.xml"); - myValueSetDao.create(upload, mySrd).getId().toUnqualifiedVersionless(); - CodeSystem parentChildCs = new CodeSystem(); parentChildCs.setUrl(SYSTEM_PARENTCHILD); parentChildCs.setStatus(Enumerations.PublicationStatus.ACTIVE); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4CodeSystemVersionedTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4CodeSystemVersionedTest.java index d6cce634524..8853d23a439 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4CodeSystemVersionedTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4CodeSystemVersionedTest.java @@ -37,9 +37,6 @@ public class ResourceProviderR4CodeSystemVersionedTest extends BaseResourceProvi cs = loadResourceFromClasspath(CodeSystem.class, "/extensional-case-3-cs-v2.xml"); myCodeSystemDao.create(cs, mySrd); - ValueSet upload = loadResourceFromClasspath(ValueSet.class, "/extensional-case-3-vs.xml"); - myValueSetDao.create(upload, mySrd).getId().toUnqualifiedVersionless(); - CodeSystem parentChildCs = new CodeSystem(); parentChildCs.setUrl(SYSTEM_PARENTCHILD); parentChildCs.setVersion("1"); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ValueSetTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ValueSetTest.java index 1785024a411..b3cca872d96 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ValueSetTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ValueSetTest.java @@ -16,7 +16,6 @@ import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; -import ca.uhn.fhir.util.ParametersUtil; import ca.uhn.fhir.util.UrlUtil; import com.google.common.base.Charsets; import org.apache.commons.io.IOUtils; @@ -1060,6 +1059,7 @@ public class ResourceProviderR4ValueSetTest extends BaseResourceProviderR4Test { public static CodeSystem createExternalCs(IFhirResourceDao theCodeSystemDao, IResourceTableDao theResourceTableDao, ITermCodeSystemStorageSvc theTermCodeSystemStorageSvc, ServletRequestDetails theRequestDetails) { CodeSystem codeSystem = new CodeSystem(); codeSystem.setUrl(URL_MY_CODE_SYSTEM); + codeSystem.setVersion("SYSTEM VERSION"); codeSystem.setContent(CodeSystemContentMode.NOTPRESENT); IIdType id = theCodeSystemDao.create(codeSystem, theRequestDetails).getId().toUnqualified(); @@ -1093,6 +1093,7 @@ public class ResourceProviderR4ValueSetTest extends BaseResourceProviderR4Test { public static CodeSystem createExternalCs(IFhirResourceDao theCodeSystemDao, IResourceTableDao theResourceTableDao, ITermCodeSystemStorageSvc theTermCodeSystemStorageSvc, ServletRequestDetails theRequestDetails, String theCodeSystemVersion) { CodeSystem codeSystem = new CodeSystem(); codeSystem.setUrl(URL_MY_CODE_SYSTEM); + codeSystem.setVersion("SYSTEM VERSION"); codeSystem.setContent(CodeSystemContentMode.NOTPRESENT); codeSystem.setVersion(theCodeSystemVersion); IIdType id = theCodeSystemDao.create(codeSystem, theRequestDetails).getId().toUnqualified(); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/TerminologyUploaderProviderR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/TerminologyUploaderProviderR4Test.java index 5dc82c5fbc1..f1aa18de3ff 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/TerminologyUploaderProviderR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/TerminologyUploaderProviderR4Test.java @@ -106,7 +106,7 @@ public class TerminologyUploaderProviderR4Test extends BaseResourceProviderR4Tes ourLog.info(resp); assertThat(((IntegerType) respParam.getParameter().get(1).getValue()).getValue(), greaterThan(1)); - assertThat(((Reference) respParam.getParameter().get(2).getValue()).getReference(), matchesPattern("CodeSystem\\/[a-zA-Z0-9]+")); + assertThat(((Reference) respParam.getParameter().get(2).getValue()).getReference(), matchesPattern("CodeSystem\\/[a-zA-Z0-9\\.\\-]+")); /* * Try uploading a second time diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r5/ResourceProviderR5ValueSetTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r5/ResourceProviderR5ValueSetTest.java index 919c3b8e8b9..c26c8bde431 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r5/ResourceProviderR5ValueSetTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r5/ResourceProviderR5ValueSetTest.java @@ -1405,6 +1405,7 @@ public class ResourceProviderR5ValueSetTest extends BaseResourceProviderR5Test { public static CodeSystem createExternalCs(IFhirResourceDao theCodeSystemDao, IResourceTableDao theResourceTableDao, ITermCodeSystemStorageSvc theTermCodeSystemStorageSvc, ServletRequestDetails theRequestDetails) { CodeSystem codeSystem = new CodeSystem(); codeSystem.setUrl(URL_MY_CODE_SYSTEM); + codeSystem.setVersion("SYSTEM VERSION"); codeSystem.setContent(CodeSystemContentMode.NOTPRESENT); IIdType id = theCodeSystemDao.create(codeSystem, theRequestDetails).getId().toUnqualified(); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologyLoaderSvcLoincIntegratedTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologyLoaderSvcLoincIntegratedTest.java index 5543102a7dc..b6703763dbe 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologyLoaderSvcLoincIntegratedTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologyLoaderSvcLoincIntegratedTest.java @@ -41,6 +41,8 @@ public class TerminologyLoaderSvcLoincIntegratedTest extends BaseJpaR4Test { TermCodeSystemVersion myTermCodeSystemVersion = myTermCodeSystemVersionDao.findByCodeSystemPidAndVersion(myTermCodeSystem.getPid(), "2.67"); assertEquals(myTermCodeSystem.getCurrentVersion().getPid(), myTermCodeSystemVersion.getPid()); assertEquals(myTermCodeSystem.getResource().getId(), myTermCodeSystemVersion.getResource().getId()); + + assertEquals(1, myResourceTableDao.count()); }); // Update LOINC marked as version 2.67 @@ -56,6 +58,8 @@ public class TerminologyLoaderSvcLoincIntegratedTest extends BaseJpaR4Test { TermCodeSystemVersion myTermCodeSystemVersion = myTermCodeSystemVersionDao.findByCodeSystemPidAndVersion(myTermCodeSystem.getPid(), "2.67"); assertEquals(myTermCodeSystem.getCurrentVersion().getPid(), myTermCodeSystemVersion.getPid()); assertEquals(myTermCodeSystem.getResource().getId(), myTermCodeSystemVersion.getResource().getId()); + + assertEquals(1, myResourceTableDao.count()); }); @@ -72,6 +76,8 @@ public class TerminologyLoaderSvcLoincIntegratedTest extends BaseJpaR4Test { TermCodeSystemVersion mySecondTermCodeSystemVersion = myTermCodeSystemVersionDao.findByCodeSystemPidAndVersion(myTermCodeSystem.getPid(), "2.68"); assertEquals(myTermCodeSystem.getCurrentVersion().getPid(), mySecondTermCodeSystemVersion.getPid()); assertEquals(myTermCodeSystem.getResource().getId(), mySecondTermCodeSystemVersion.getResource().getId()); + + assertEquals(2, myResourceTableDao.count()); }); } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologySvcDeltaR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologySvcDeltaR4Test.java index db601c7a330..265e2064761 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologySvcDeltaR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologySvcDeltaR4Test.java @@ -184,7 +184,7 @@ public class TerminologySvcDeltaR4Test extends BaseJpaR4Test { assertEquals(2, outcome.getUpdatedConceptCount()); runInTransaction(() -> { - TermConcept concept = myTermSvc.findCode("http://foo/cs", "ChildAA", null).orElseThrow(() -> new IllegalStateException()); + TermConcept concept = myTermSvc.findCode("http://foo/cs", "ChildAA").orElseThrow(() -> new IllegalStateException()); assertEquals(2, concept.getParents().size()); assertThat(concept.getParentPidsAsString(), matchesPattern("^[0-9]+ [0-9]+$")); }); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologySvcImplDstu3Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologySvcImplDstu3Test.java index c3787c589b0..0ffe92d13bb 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologySvcImplDstu3Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologySvcImplDstu3Test.java @@ -63,6 +63,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test { codeSystem.setUrl(CS_URL); codeSystem.setContent(CodeSystemContentMode.NOTPRESENT); codeSystem.setName("SYSTEM NAME"); + codeSystem.setVersion("SYSTEM VERSION"); IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified(); ResourceTable table = myResourceTableDao.findById(id.getIdPartAsLong()).orElseThrow(IllegalArgumentException::new); @@ -116,6 +117,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test { private void createCodeSystem2() { CodeSystem codeSystem = new CodeSystem(); codeSystem.setUrl(CS_URL_2); + codeSystem.setVersion("SYSTEM VERSION"); codeSystem.setContent(CodeSystemContentMode.NOTPRESENT); IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified(); @@ -135,6 +137,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test { runInTransaction(() -> { CodeSystem codeSystem = new CodeSystem(); codeSystem.setUrl(LOINC_URI); + codeSystem.setVersion("SYSTEM VERSION"); codeSystem.setContent(CodeSystemContentMode.NOTPRESENT); IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified(); @@ -204,6 +207,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test { public void testCreateDuplicateCodeSystemUri() { CodeSystem codeSystem = new CodeSystem(); codeSystem.setUrl(CS_URL); + codeSystem.setVersion("SYSTEM VERSION"); codeSystem.setContent(CodeSystemContentMode.NOTPRESENT); IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified(); @@ -226,12 +230,13 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test { // Try to update to a different resource codeSystem = new CodeSystem(); codeSystem.setUrl(CS_URL); + codeSystem.setVersion("SYSTEM VERSION"); codeSystem.setContent(CodeSystemContentMode.NOTPRESENT); try { myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified(); fail(); } catch (UnprocessableEntityException e) { - assertThat(e.getMessage(), containsString("Can not create multiple CodeSystem resources with CodeSystem.url \"http://example.com/my_code_system\", already have one with resource ID: CodeSystem/")); + assertThat(e.getMessage(), containsString("Can not create multiple CodeSystem resources with CodeSystem.url \"http://example.com/my_code_system\" and CodeSystem.version \"SYSTEM VERSION\", already have one with resource ID: CodeSystem/")); } } @@ -1813,6 +1818,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test { public void testStoreCodeSystemInvalidCyclicLoop() { CodeSystem codeSystem = new CodeSystem(); codeSystem.setUrl(CS_URL); + codeSystem.setVersion("SYSTEM VERSION"); codeSystem.setContent(CodeSystemContentMode.NOTPRESENT); IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified(); @@ -1834,7 +1840,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test { child.addChild(parent, RelationshipTypeEnum.ISA); try { - myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(table.getPersistentId(), "http://foo", "SYSTEM NAME", "SYSTEM VERSION", cs, table); + myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(table.getPersistentId(), CS_URL, "SYSTEM NAME", "SYSTEM VERSION", cs, table); fail(); } catch (InvalidRequestException e) { assertEquals("CodeSystem contains circular reference around code parent", e.getMessage()); @@ -1948,6 +1954,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test { CodeSystem cs = new CodeSystem(); cs.setUrl("http://codesystems-r-us"); + cs.setVersion("SYSTEM VERSION"); cs.setContent(CodeSystem.CodeSystemContentMode.NOTPRESENT); IIdType csId = myCodeSystemDao.create(cs).getId().toUnqualifiedVersionless();