From ceb5ec63847c2bee832027ea93edd902a5356270 Mon Sep 17 00:00:00 2001 From: ianmarshall Date: Wed, 23 Sep 2020 16:42:29 -0400 Subject: [PATCH] Use canonical identifiers for code systems rather than specifying version separately. --- .../context/support/IValidationSupport.java | 13 -- .../api/dao/IFhirResourceDaoCodeSystem.java | 5 - .../jpa/api/dao/IFhirResourceDaoValueSet.java | 4 - .../jpa/dao/FhirResourceDaoValueSetDstu2.java | 20 -- .../dstu3/FhirResourceDaoCodeSystemDstu3.java | 27 +-- .../dstu3/FhirResourceDaoValueSetDstu3.java | 52 ++--- .../dao/r4/FhirResourceDaoCodeSystemR4.java | 27 +-- .../jpa/dao/r4/FhirResourceDaoValueSetR4.java | 49 ++--- .../dao/r5/FhirResourceDaoCodeSystemR5.java | 29 +-- .../jpa/dao/r5/FhirResourceDaoValueSetR5.java | 50 ++--- ...aseJpaResourceProviderCodeSystemDstu3.java | 15 +- .../BaseJpaResourceProviderValueSetDstu3.java | 4 +- .../BaseJpaResourceProviderCodeSystemR4.java | 18 +- .../r4/BaseJpaResourceProviderValueSetR4.java | 4 +- .../BaseJpaResourceProviderCodeSystemR5.java | 15 +- .../r5/BaseJpaResourceProviderValueSetR5.java | 4 +- .../fhir/jpa/term/BaseTermReadSvcImpl.java | 182 +++++++++++------- .../jpa/term/IValueSetConceptAccumulator.java | 4 +- .../uhn/fhir/jpa/term/TermReadSvcDstu3.java | 7 +- .../ca/uhn/fhir/jpa/term/TermReadSvcR4.java | 7 +- .../jpa/term/ValueSetConceptAccumulator.java | 12 +- ...ansionComponentWithConceptAccumulator.java | 63 +++--- .../uhn/fhir/jpa/term/api/ITermReadSvc.java | 4 - .../FhirResourceDaoValueSetDstu2Test.java | 22 --- .../FhirResourceDaoDstu3TerminologyTest.java | 4 +- .../r4/ResourceProviderR4ValueSetTest.java | 17 ++ ...sourceProviderR4ValueSetVersionedTest.java | 33 +++- .../jpa/term/TerminologySvcImplDstu3Test.java | 3 +- .../ValueSetExpansionR4ElasticsearchIT.java | 2 +- .../jpa/term/ValueSetExpansionR4Test.java | 2 +- .../support/BaseValidationSupportWrapper.java | 5 - .../support/CachingValidationSupport.java | 6 - .../CommonCodeSystemsTerminologyService.java | 6 - ...oryTerminologyServerValidationSupport.java | 38 ---- .../support/ValidationSupportChain.java | 10 - .../FhirInstanceValidatorR4Test.java | 2 +- 36 files changed, 300 insertions(+), 465 deletions(-) diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/support/IValidationSupport.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/support/IValidationSupport.java index 047ed241729..49739e62b1e 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/support/IValidationSupport.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/support/IValidationSupport.java @@ -212,19 +212,6 @@ public interface IValidationSupport { return null; } - /** - * Look up a code using the system, system version and code value - * - * @param theValidationSupportContext The validation support module will be passed in to this method. This is convenient in cases where the operation needs to make calls to - * other method in the support chain, so that they can be passed through the entire chain. Implementations of this interface may always safely ignore this parameter. - * @param theSystem The CodeSystem URL - * @param theCode The code - * @param theSystemVersion The CodeSystem version - */ - default LookupCodeResult lookupCode(ValidationSupportContext theValidationSupportContext, String theSystem, String theCode, String theSystemVersion) { - return null; - } - /** * Returns true if the given valueset can be validated by the given * validation support module diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoCodeSystem.java b/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoCodeSystem.java index 2c00c792b49..ba957e00542 100644 --- a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoCodeSystem.java +++ b/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoCodeSystem.java @@ -42,11 +42,6 @@ public interface IFhirResourceDaoCodeSystem ext SubsumesResult subsumes(IPrimitiveType theCodeA, IPrimitiveType theCodeB, IPrimitiveType theSystem, CD theCodingA, CD theCodingB, RequestDetails theRequestDetails); - @Nonnull - IValidationSupport.LookupCodeResult lookupCode(IPrimitiveType theCode, IPrimitiveType theSystem, CD theCoding, IPrimitiveType theVersion, RequestDetails theRequestDetails); - - SubsumesResult subsumes(IPrimitiveType theCodeA, IPrimitiveType theCodeB, IPrimitiveType theSystem, CD theCodingA, CD theCodingB, IPrimitiveType theVersion, RequestDetails theRequestDetails); - class SubsumesResult { private final ConceptSubsumptionOutcome myOutcome; diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoValueSet.java b/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoValueSet.java index def9ad33fc5..a044e2e262b 100644 --- a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoValueSet.java +++ b/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoValueSet.java @@ -38,12 +38,8 @@ public interface IFhirResourceDaoValueSet exten T expandByIdentifier(String theUri, String theFilter); - T expandByIdentifier(String theUri, String theValueSetVersion, String theFilter); - T expandByIdentifier(String theUri, String theFilter, int theOffset, int theCount); - T expandByIdentifier(String theUri, String theValueSetVersion, String theFilter, int theOffset, int theCount); - void purgeCaches(); IValidationSupport.CodeValidationResult validateCode(IPrimitiveType theValueSetIdentifier, IIdType theId, IPrimitiveType theCode, IPrimitiveType theSystem, IPrimitiveType theDisplay, CD theCoding, CC theCodeableConcept, RequestDetails theRequestDetails); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoValueSetDstu2.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoValueSetDstu2.java index 6069ebcd335..77525d07b26 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoValueSetDstu2.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoValueSetDstu2.java @@ -174,21 +174,11 @@ public class FhirResourceDaoValueSetDstu2 extends BaseHapiFhirResourceDao findCodeSystemIdsContainingSystemAndCode(String theCode, String theSystem, RequestDetails theRequest) { if (theSystem != null && theSystem.startsWith("http://hl7.org/fhir/")) { @@ -244,11 +234,6 @@ public class FhirResourceDaoValueSetDstu2 extends BaseHapiFhirResourceDao theCode, IPrimitiveType theSystem, CodingDt theCoding, IPrimitiveType theVersion, RequestDetails theRequestDetails) { - throw new UnsupportedOperationException(); - } - @Override public IValidationSupport.LookupCodeResult lookupCode(IPrimitiveType theCode, IPrimitiveType theSystem, CodingDt theCoding, RequestDetails theRequest) { boolean haveCoding = theCoding != null && isNotBlank(theCoding.getSystem()) && isNotBlank(theCoding.getCode()); @@ -294,11 +279,6 @@ public class FhirResourceDaoValueSetDstu2 extends BaseHapiFhirResourceDao theCodeA, IPrimitiveType theCodeB, IPrimitiveType theSystem, CodingDt theCodingA, CodingDt theCodingB, IPrimitiveType theVersion, RequestDetails theRequestDetails) { - throw new UnsupportedOperationException(); - } - @Override @PostConstruct public void postConstruct() { 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 31873e04da2..3df67dd6bea 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 @@ -85,12 +85,6 @@ public class FhirResourceDaoCodeSystemDstu3 extends BaseHapiFhirResourceDao theCode, IPrimitiveType theSystem, Coding theCoding, RequestDetails theRequestDetails) { - return lookupCode(theCode, theSystem, theCoding, null, theRequestDetails); - } - - @Nonnull - @Override - public IValidationSupport.LookupCodeResult lookupCode(IPrimitiveType theCode, IPrimitiveType theSystem, Coding theCoding, IPrimitiveType theVersion, RequestDetails theRequestDetails) { boolean haveCoding = theCoding != null && isNotBlank(theCoding.getSystem()) && isNotBlank(theCoding.getCode()); boolean haveCode = theCode != null && theCode.isEmpty() == false; boolean haveSystem = theSystem != null && theSystem.isEmpty() == false; @@ -104,29 +98,19 @@ public class FhirResourceDaoCodeSystemDstu3 extends BaseHapiFhirResourceDao theCodeA, IPrimitiveType theCodeB, IPrimitiveType theSystem, Coding theCodingA, Coding theCodingB, IPrimitiveType theVersion, RequestDetails theRequestDetails) { - String codingBVersion = theCodingB != null ? theCodingB.getVersion() : null; - String codingAVersion = theCodingA != null ? theCodingA.getVersion() : null; - return myTerminologySvc.subsumes(theCodeA, theCodeB, theSystem, theCodingA, theCodingB, theVersion, codingAVersion, codingBVersion); - } - @Override public SubsumesResult subsumes(IPrimitiveType theCodeA, IPrimitiveType theCodeB, IPrimitiveType theSystem, Coding theCodingA, Coding theCodingB, RequestDetails theRequestDetails) { return myTerminologySvc.subsumes(theCodeA, theCodeB, theSystem, theCodingA, theCodingB); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoValueSetDstu3.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoValueSetDstu3.java index 0ebb0a93764..637d19630b6 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoValueSetDstu3.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoValueSetDstu3.java @@ -113,7 +113,21 @@ public class FhirResourceDaoValueSetDstu3 extends BaseHapiFhirResourceDao theCode, IPrimitiveType theSystem, Coding theCoding, RequestDetails theRequestDetails) { - return lookupCode(theCode, theSystem, theCoding, null, theRequestDetails); - } - - @Nonnull - @Override - public IValidationSupport.LookupCodeResult lookupCode(IPrimitiveType theCode, IPrimitiveType theSystem, Coding theCoding, IPrimitiveType theVersion, RequestDetails theRequestDetails) { boolean haveCoding = theCoding != null && isNotBlank(theCoding.getSystem()) && isNotBlank(theCoding.getCode()); boolean haveCode = theCode != null && theCode.isEmpty() == false; boolean haveSystem = theSystem != null && theSystem.isEmpty() == false; @@ -99,30 +93,20 @@ public class FhirResourceDaoCodeSystemR4 extends BaseHapiFhirResourceDao theCodeA, IPrimitiveType theCodeB, IPrimitiveType theSystem, Coding theCodingA, Coding theCodingB, IPrimitiveType theVersion, RequestDetails theRequestDetails) { - String codingBVersion = theCodingB != null ? theCodingB.getVersion() : null; - String codingAVersion = theCodingA != null ? theCodingA.getVersion() : null; - return myTerminologySvc.subsumes(theCodeA, theCodeB, theSystem, theCodingA, theCodingB, theVersion, codingAVersion, codingBVersion); - } - @Override public SubsumesResult subsumes(IPrimitiveType theCodeA, IPrimitiveType theCodeB, IPrimitiveType theSystem, Coding theCodingA, Coding theCodingB, RequestDetails theRequestDetails) { return myTerminologySvc.subsumes(theCodeA, theCodeB, theSystem, theCodingA, theCodingB); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoValueSetR4.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoValueSetR4.java index aa0a17ec883..fd6d02f5c56 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoValueSetR4.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoValueSetR4.java @@ -95,7 +95,20 @@ public class FhirResourceDaoValueSetR4 extends BaseHapiFhirResourceDao throw new InvalidRequestException("URI must not be blank or missing"); } - return doExpand(createSourceValueSet(theUri, null, theFilter)); + ValueSet source = new ValueSet(); + source.setUrl(theUri); + + source.getCompose().addInclude().addValueSet(theUri); + + if (isNotBlank(theFilter)) { + ConceptSetComponent include = source.getCompose().addInclude(); + ValueSet.ConceptSetFilterComponent filter = include.addFilter(); + filter.setProperty("display"); + filter.setOp(FilterOperator.EQUAL); + filter.setValue(theFilter); + } + + return doExpand(source); // if (defaultValueSet != null) { // source = getContext().newJsonParser().parseResource(ValueSet.class, getContext().newJsonParser().encodeResourceToString(defaultValueSet)); @@ -111,26 +124,15 @@ public class FhirResourceDaoValueSetR4 extends BaseHapiFhirResourceDao } @Override - public ValueSet expandByIdentifier(String theUri, String theValueSetVersion, String theFilter) { + public ValueSet expandByIdentifier(String theUri, String theFilter, int theOffset, int theCount) { if (isBlank(theUri)) { throw new InvalidRequestException("URI must not be blank or missing"); } - return doExpand(createSourceValueSet(theUri, theValueSetVersion, theFilter)); - } - - private ValueSet createSourceValueSet(String theUri, String theValueSetVersion, String theFilter) { ValueSet source = new ValueSet(); source.setUrl(theUri); - if (theValueSetVersion != null) { - source.setVersion(theValueSetVersion); - } - if (theValueSetVersion != null) { - source.getCompose().addInclude().addValueSet(theUri + "|" +theValueSetVersion); - } else { - source.getCompose().addInclude().addValueSet(theUri); - } + source.getCompose().addInclude().addValueSet(theUri); if (isNotBlank(theFilter)) { ValueSet.ConceptSetComponent include = source.getCompose().addInclude(); @@ -139,25 +141,8 @@ public class FhirResourceDaoValueSetR4 extends BaseHapiFhirResourceDao filter.setOp(ValueSet.FilterOperator.EQUAL); filter.setValue(theFilter); } - return source; - } - @Override - public ValueSet expandByIdentifier(String theUri, String theFilter, int theOffset, int theCount) { - if (isBlank(theUri)) { - throw new InvalidRequestException("URI must not be blank or missing"); - } - - return doExpand(createSourceValueSet(theUri,null,theFilter), theOffset, theCount); - } - - @Override - public ValueSet expandByIdentifier(String theUri, String theValueSetVersion, String theFilter, int theOffset, int theCount) { - if (isBlank(theUri)) { - throw new InvalidRequestException("URI must not be blank or missing"); - } - - return doExpand(createSourceValueSet(theUri,theValueSetVersion,theFilter), theOffset, theCount); + return doExpand(source, theOffset, theCount); } @Override 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 f6ebf2cbb66..d18ab4ac9bf 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 @@ -82,12 +82,6 @@ public class FhirResourceDaoCodeSystemR5 extends BaseHapiFhirResourceDao theCode, IPrimitiveType theSystem, Coding theCoding, RequestDetails theRequestDetails) { - return lookupCode(theCode, theSystem, theCoding, null, theRequestDetails); - } - - @Nonnull - @Override - public IValidationSupport.LookupCodeResult lookupCode(IPrimitiveType theCode, IPrimitiveType theSystem, Coding theCoding, IPrimitiveType theVersion, RequestDetails theRequestDetails) { boolean haveCoding = theCoding != null && isNotBlank(theCoding.getSystem()) && isNotBlank(theCoding.getCode()); boolean haveCode = theCode != null && theCode.isEmpty() == false; boolean haveSystem = theSystem != null && theSystem.isEmpty() == false; @@ -101,30 +95,20 @@ public class FhirResourceDaoCodeSystemR5 extends BaseHapiFhirResourceDao theCodeA, IPrimitiveType theCodeB, IPrimitiveType theSystem, Coding theCodingA, Coding theCodingB, IPrimitiveType theVersion, RequestDetails theRequestDetails) { - String codingBVersion = theCodingB != null ? theCodingB.getVersion() : null; - String codingAVersion = theCodingA != null ? theCodingA.getVersion() : null; - return myTerminologySvc.subsumes(theCodeA, theCodeB, theSystem, theCodingA, theCodingB, theVersion, codingAVersion, codingBVersion); - } - @Override public SubsumesResult subsumes(IPrimitiveType theCodeA, IPrimitiveType theCodeB, IPrimitiveType theSystem, Coding theCodingA, Coding theCodingB, RequestDetails theRequestDetails) { return myTerminologySvc.subsumes(theCodeA, theCodeB, theSystem, theCodingA, theCodingB); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r5/FhirResourceDaoValueSetR5.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r5/FhirResourceDaoValueSetR5.java index 7f6002d31ad..6036e99ef2b 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r5/FhirResourceDaoValueSetR5.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r5/FhirResourceDaoValueSetR5.java @@ -95,7 +95,20 @@ public class FhirResourceDaoValueSetR5 extends BaseHapiFhirResourceDao throw new InvalidRequestException("URI must not be blank or missing"); } - return doExpand(createSourceValueSet(theUri, null, theFilter)); + ValueSet source = new ValueSet(); + source.setUrl(theUri); + + source.getCompose().addInclude().addValueSet(theUri); + + if (isNotBlank(theFilter)) { + ConceptSetComponent include = source.getCompose().addInclude(); + ValueSet.ConceptSetFilterComponent filter = include.addFilter(); + filter.setProperty("display"); + filter.setOp(Enumerations.FilterOperator.EQUAL); + filter.setValue(theFilter); + } + + return doExpand(source); // if (defaultValueSet != null) { // source = getContext().newJsonParser().parseResource(ValueSet.class, getContext().newJsonParser().encodeResourceToString(defaultValueSet)); @@ -111,27 +124,15 @@ public class FhirResourceDaoValueSetR5 extends BaseHapiFhirResourceDao } @Override - public ValueSet expandByIdentifier(String theUri, String theValueSetUri, String theFilter) { + public ValueSet expandByIdentifier(String theUri, String theFilter, int theOffset, int theCount) { if (isBlank(theUri)) { throw new InvalidRequestException("URI must not be blank or missing"); } - return doExpand(createSourceValueSet(theUri, theValueSetUri, theFilter)); - - } - - private ValueSet createSourceValueSet(String theUri, String theValueSetVersion, String theFilter) { ValueSet source = new ValueSet(); source.setUrl(theUri); - if (theValueSetVersion != null) { - source.setVersion(theValueSetVersion); - } - if (theValueSetVersion != null) { - source.getCompose().addInclude().addValueSet(theUri + "|" +theValueSetVersion); - } else { - source.getCompose().addInclude().addValueSet(theUri); - } + source.getCompose().addInclude().addValueSet(theUri); if (isNotBlank(theFilter)) { ValueSet.ConceptSetComponent include = source.getCompose().addInclude(); @@ -140,25 +141,8 @@ public class FhirResourceDaoValueSetR5 extends BaseHapiFhirResourceDao filter.setOp(Enumerations.FilterOperator.EQUAL); filter.setValue(theFilter); } - return source; - } - @Override - public ValueSet expandByIdentifier(String theUri, String theFilter, int theOffset, int theCount) { - if (isBlank(theUri)) { - throw new InvalidRequestException("URI must not be blank or missing"); - } - - return doExpand(createSourceValueSet(theUri, null, theFilter), theOffset, theCount); - } - - @Override - public ValueSet expandByIdentifier(String theUri, String theValueSetVersion, String theFilter, int theOffset, int theCount) { - if (isBlank(theUri)) { - throw new InvalidRequestException("URI must not be blank or missing"); - } - - return doExpand(createSourceValueSet(theUri, theValueSetVersion, theFilter), theOffset, theCount); + return doExpand(source, theOffset, theCount); } @Override diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/BaseJpaResourceProviderCodeSystemDstu3.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/BaseJpaResourceProviderCodeSystemDstu3.java index 49a1a2b9fd8..9c54199e262 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/BaseJpaResourceProviderCodeSystemDstu3.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/BaseJpaResourceProviderCodeSystemDstu3.java @@ -63,7 +63,7 @@ public class BaseJpaResourceProviderCodeSystemDstu3 extends JpaResourceProviderD IFhirResourceDaoCodeSystem dao = (IFhirResourceDaoCodeSystem) getDao(); IValidationSupport.LookupCodeResult result; if (theVersion != null) { - result = dao.lookupCode(theCode, theSystem, theCoding, theVersion, theRequestDetails); + result = dao.lookupCode(theCode, new UriType(theSystem.getValue() + "|" + theVersion), theCoding, theRequestDetails); } else { result = dao.lookupCode(theCode, theSystem, theCoding, theRequestDetails); } @@ -98,11 +98,16 @@ public class BaseJpaResourceProviderCodeSystemDstu3 extends JpaResourceProviderD try { IFhirResourceDaoCodeSystem dao = (IFhirResourceDaoCodeSystem) getDao(); IFhirResourceDaoCodeSystem.SubsumesResult result; - if (theVersion != null || (theCodingA != null && theCodingA.hasVersion()) || (theCodingB != null &&theCodingB.hasVersion())) { - result = dao.subsumes(theCodeA, theCodeB, theSystem, theCodingA, theCodingB, theVersion, theRequestDetails); - } else { - result = dao.subsumes(theCodeA, theCodeB, theSystem, theCodingA, theCodingB, theRequestDetails); + if (theVersion != null) { + theSystem = new UriType(theSystem.asStringValue() + "|" + theVersion.toString()); } + if (theCodingA != null && theCodingA.hasVersion()) { + theCodingA.setSystem(theCodingA.getSystemElement().asStringValue() + "|" + theCodingA.getVersion()); + } + if (theCodingB != null && theCodingB.hasVersion()) { + theCodingB.setSystem(theCodingB.getSystemElement().asStringValue() + "|" + theCodingB.getVersion()); + } + result = dao.subsumes(theCodeA, theCodeB, theSystem, theCodingA, theCodingB, theRequestDetails); return (Parameters) result.toParameters(theRequestDetails.getFhirContext()); } finally { endRequest(theServletRequest); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/BaseJpaResourceProviderValueSetDstu3.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/BaseJpaResourceProviderValueSetDstu3.java index 2bfb61dc0ef..cc865b70c7d 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/BaseJpaResourceProviderValueSetDstu3.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/BaseJpaResourceProviderValueSetDstu3.java @@ -102,7 +102,7 @@ public class BaseJpaResourceProviderValueSetDstu3 extends JpaResourceProviderDst return dao.expand(theId, toFilterString(theFilter), offset, count, theRequestDetails); } else if (haveIdentifier) { if (haveValueSetVersion) { - return dao.expandByIdentifier(url.getValue(), theValueSetVersion.getValue(), toFilterString(theFilter), offset, count); + return dao.expandByIdentifier(url.getValue() + "|" + theValueSetVersion.getValue(), toFilterString(theFilter), offset, count); } else { return dao.expandByIdentifier(url.getValue(), toFilterString(theFilter), offset, count); } @@ -114,7 +114,7 @@ public class BaseJpaResourceProviderValueSetDstu3 extends JpaResourceProviderDst return dao.expand(theId, toFilterString(theFilter), theRequestDetails); } else if (haveIdentifier) { if (haveValueSetVersion) { - return dao.expandByIdentifier(url.getValue(), theValueSetVersion.getValue(), toFilterString(theFilter)); + return dao.expandByIdentifier(url.getValue() + "|" + theValueSetVersion.getValue(), toFilterString(theFilter)); } else { return dao.expandByIdentifier(url.getValue(), toFilterString(theFilter)); } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r4/BaseJpaResourceProviderCodeSystemR4.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r4/BaseJpaResourceProviderCodeSystemR4.java index 43320798757..a54a645ec59 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r4/BaseJpaResourceProviderCodeSystemR4.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r4/BaseJpaResourceProviderCodeSystemR4.java @@ -65,7 +65,10 @@ public class BaseJpaResourceProviderCodeSystemR4 extends JpaResourceProviderR4 dao = (IFhirResourceDaoCodeSystem) getDao(); IValidationSupport.LookupCodeResult result; if (theVersion != null) { - result = dao.lookupCode(theCode, theSystem, theCoding, theVersion, theRequestDetails); + result = dao.lookupCode(theCode, new UriType(theSystem.getValue() + "|" + theVersion), theCoding, theRequestDetails); + } else if (theCoding != null && theCoding.hasVersion()) { + Coding codingWithVersion = new Coding(theCoding.getSystem() + "|" + theCoding.getVersion(), theCoding.getCode(), theCoding.getDisplay()); + result = dao.lookupCode(theCode, theSystem, codingWithVersion, theRequestDetails); } else { result = dao.lookupCode(theCode, theSystem, theCoding, theRequestDetails); } @@ -98,11 +101,16 @@ public class BaseJpaResourceProviderCodeSystemR4 extends JpaResourceProviderR4 dao = (IFhirResourceDaoCodeSystem) getDao(); IFhirResourceDaoCodeSystem.SubsumesResult result; - if (theVersion != null || (theCodingA != null && theCodingA.hasVersion()) || (theCodingB != null &&theCodingB.hasVersion())) { - result = dao.subsumes(theCodeA, theCodeB, theSystem, theCodingA, theCodingB, theVersion, theRequestDetails); - } else { - result = dao.subsumes(theCodeA, theCodeB, theSystem, theCodingA, theCodingB, theRequestDetails); + if (theVersion != null) { + theSystem = new UriType(theSystem.asStringValue() + "|" + theVersion.toString()); } + if (theCodingA != null && theCodingA.hasVersion()) { + theCodingA.setSystem(theCodingA.getSystemElement().asStringValue() + "|" + theCodingA.getVersion()); + } + if (theCodingB != null && theCodingB.hasVersion()) { + theCodingB.setSystem(theCodingB.getSystemElement().asStringValue() + "|" + theCodingB.getVersion()); + } + result = dao.subsumes(theCodeA, theCodeB, theSystem, theCodingA, theCodingB, theRequestDetails); return (Parameters) result.toParameters(theRequestDetails.getFhirContext()); } finally { endRequest(theServletRequest); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r4/BaseJpaResourceProviderValueSetR4.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r4/BaseJpaResourceProviderValueSetR4.java index 6c32c0def2f..b8b6637fcf7 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r4/BaseJpaResourceProviderValueSetR4.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r4/BaseJpaResourceProviderValueSetR4.java @@ -94,7 +94,7 @@ public class BaseJpaResourceProviderValueSetR4 extends JpaResourceProviderR4 dao = (IFhirResourceDaoCodeSystem) getDao(); IValidationSupport.LookupCodeResult result; if (theVersion != null) { - result = dao.lookupCode(theCode, theSystem, theCoding, theVersion, theRequestDetails); + result = dao.lookupCode(theCode, new UriType(theSystem.getValue() + "|" + theVersion), theCoding, theRequestDetails); } else { result = dao.lookupCode(theCode, theSystem, theCoding, theRequestDetails); } @@ -98,11 +98,16 @@ public class BaseJpaResourceProviderCodeSystemR5 extends JpaResourceProviderR5 dao = (IFhirResourceDaoCodeSystem) getDao(); IFhirResourceDaoCodeSystem.SubsumesResult result; - if (theVersion != null || (theCodingA != null && theCodingA.hasVersion()) || (theCodingB != null &&theCodingB.hasVersion())) { - result = dao.subsumes(theCodeA, theCodeB, theSystem, theCodingA, theCodingB, theVersion, theRequestDetails); - } else { - result = dao.subsumes(theCodeA, theCodeB, theSystem, theCodingA, theCodingB, theRequestDetails); + if (theVersion != null) { + theSystem = new UriType(theSystem.asStringValue() + "|" + theVersion.toString()); } + if (theCodingA != null && theCodingA.hasVersion()) { + theCodingA.setSystem(theCodingA.getSystemElement().asStringValue() + "|" + theCodingA.getVersion()); + } + if (theCodingB != null && theCodingB.hasVersion()) { + theCodingB.setSystem(theCodingB.getSystemElement().asStringValue() + "|" + theCodingB.getVersion()); + } + result = dao.subsumes(theCodeA, theCodeB, theSystem, theCodingA, theCodingB, theRequestDetails); return (Parameters) result.toParameters(theRequestDetails.getFhirContext()); } finally { endRequest(theServletRequest); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r5/BaseJpaResourceProviderValueSetR5.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r5/BaseJpaResourceProviderValueSetR5.java index b5d2e93f8f4..79fb1f7d922 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r5/BaseJpaResourceProviderValueSetR5.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r5/BaseJpaResourceProviderValueSetR5.java @@ -94,7 +94,7 @@ public class BaseJpaResourceProviderValueSetR5 extends JpaResourceProviderR5 designations = theConcept.getDesignations(); if (StringUtils.isNotEmpty(codeSystemVersion)) { - addCodeIfNotAlreadyAdded(theValueSetCodeAccumulator, theAddedCodes, designations, theAdd, theCodeCounter, codeSystem, codeSystemVersion, code, display); + addCodeIfNotAlreadyAdded(theValueSetCodeAccumulator, theAddedCodes, designations, theAdd, theCodeCounter, codeSystem + "|" + codeSystemVersion, code, display); } else { addCodeIfNotAlreadyAdded(theValueSetCodeAccumulator, theAddedCodes, designations, theAdd, theCodeCounter, codeSystem, code, display); } } private void addCodeIfNotAlreadyAdded(IValueSetConceptAccumulator theValueSetCodeAccumulator, Set theAddedCodes, Collection theDesignations, boolean theAdd, AtomicInteger theCodeCounter, String theCodeSystem, String theCodeSystemVersion, String theCode, String theDisplay) { - if (isNoneBlank(theCodeSystem, theCode)) { - if (theAdd && theAddedCodes.add(theCodeSystem + "|" + theCode + "|" + theCodeSystemVersion)) { - theValueSetCodeAccumulator.includeConceptWithDesignations(theCodeSystem, theCodeSystemVersion, theCode, theDisplay, theDesignations); + if (StringUtils.isNotEmpty(theCodeSystemVersion)) { + if (isNoneBlank(theCodeSystem, theCode)) { + if (theAdd && theAddedCodes.add(theCodeSystem + "|" + theCode + "|" + theCodeSystemVersion)) { + theValueSetCodeAccumulator.includeConceptWithDesignations(theCodeSystem + "|" + theCodeSystemVersion, theCode, theDisplay, theDesignations); + theCodeCounter.incrementAndGet(); + } + + if (!theAdd && theAddedCodes.remove(theCodeSystem + "|" + theCode + "|" + theCodeSystemVersion)) { + theValueSetCodeAccumulator.excludeConcept(theCodeSystem + "|" + theCodeSystemVersion, theCode); + theCodeCounter.decrementAndGet(); + } + } + } else { + if (theAdd && theAddedCodes.add(theCodeSystem + "|" + theCode)) { + theValueSetCodeAccumulator.includeConceptWithDesignations(theCodeSystem, theCode, theDisplay, theDesignations); theCodeCounter.incrementAndGet(); } - if (!theAdd && theAddedCodes.remove(theCodeSystem + "|" + theCode + "|" + theCodeSystemVersion)) { - theValueSetCodeAccumulator.excludeConcept(theCodeSystem, theCodeSystemVersion, theCode); + if (!theAdd && theAddedCodes.remove(theCodeSystem + "|" + theCode)) { + theValueSetCodeAccumulator.excludeConcept(theCodeSystem, theCode); theCodeCounter.decrementAndGet(); } } @@ -829,7 +841,13 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc { /* * Filters */ - handleFilters(bool, theSystem, codeSystemVersion, qb, theIncludeOrExclude); + String canonicalSystem; + if (codeSystemVersion != null) { + canonicalSystem = theSystem + "|" + codeSystemVersion; + } else { + canonicalSystem = theSystem; + } + handleFilters(bool, canonicalSystem, qb, theIncludeOrExclude); Query luceneQuery = bool.createQuery(); @@ -938,15 +956,15 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc { } } - private void handleFilters(BooleanJunction theBool, String theSystem, String theSystemVersion, QueryBuilder theQb, ValueSet.ConceptSetComponent theIncludeOrExclude) { + private void handleFilters(BooleanJunction theBool, String theCanonicalSystem, QueryBuilder theQb, ValueSet.ConceptSetComponent theIncludeOrExclude) { if (theIncludeOrExclude.getFilter().size() > 0) { for (ValueSet.ConceptSetFilterComponent nextFilter : theIncludeOrExclude.getFilter()) { - handleFilter(theSystem, theSystemVersion, theQb, theBool, nextFilter); + handleFilter(theCanonicalSystem, theQb, theBool, nextFilter); } } } - private void handleFilter(String theSystem, String theSystemVersion, QueryBuilder theQb, BooleanJunction theBool, ValueSet.ConceptSetFilterComponent theFilter) { + private void handleFilter(String theSystem, QueryBuilder theQb, BooleanJunction theBool, ValueSet.ConceptSetFilterComponent theFilter) { if (isBlank(theFilter.getValue()) && theFilter.getOp() == null && isBlank(theFilter.getProperty())) { return; } @@ -962,7 +980,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc { break; case "concept": case "code": - handleFilterConceptAndCode(theSystem, theSystemVersion, theQb, theBool, theFilter); + handleFilterConceptAndCode(theSystem, theQb, theBool, theFilter); break; case "parent": case "child": @@ -971,11 +989,11 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc { break; case "ancestor": isCodeSystemLoingOrThrowInvalidRequestException(theSystem, theFilter.getProperty()); - handleFilterLoincAncestor(theSystem, theSystemVersion, theBool, theFilter); + handleFilterLoincAncestor(theSystem, theBool, theFilter); break; case "descendant": isCodeSystemLoingOrThrowInvalidRequestException(theSystem, theFilter.getProperty()); - handleFilterLoincDescendant(theSystem, theSystemVersion, theBool, theFilter); + handleFilterLoincDescendant(theSystem, theBool, theFilter); break; case "copyright": isCodeSystemLoingOrThrowInvalidRequestException(theSystem, theFilter.getProperty()); @@ -988,8 +1006,9 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc { } private void isCodeSystemLoingOrThrowInvalidRequestException(String theSystem, String theProperty) { - if (!isCodeSystemLoinc(theSystem)) { - throw new InvalidRequestException("Invalid filter, property " + theProperty + " is LOINC-specific and cannot be used with system: " + theSystem); + String systemUrl = getSystemFromCanonicalUrl(theSystem); + if (!isCodeSystemLoinc(systemUrl)) { + throw new InvalidRequestException("Invalid filter, property " + theProperty + " is LOINC-specific and cannot be used with system: " + systemUrl); } } @@ -1025,8 +1044,8 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc { bool.must(textQuery); } - private void handleFilterConceptAndCode(String theSystem, String theSystemVersion, QueryBuilder theQb, BooleanJunction theBool, ValueSet.ConceptSetFilterComponent theFilter) { - TermConcept code = findCode(theSystem, theFilter.getValue(), theSystemVersion) + private void handleFilterConceptAndCode(String theSystem, QueryBuilder theQb, BooleanJunction theBool, ValueSet.ConceptSetFilterComponent theFilter) { + TermConcept code = findCode(theSystem, theFilter.getValue()) .orElseThrow(() -> new InvalidRequestException("Invalid filter criteria - code does not exist: {" + Constants.codeSystemWithDefaultDescription(theSystem) + "}" + theFilter.getValue())); if (theFilter.getOp() == ValueSet.FilterOperator.ISA) { @@ -1071,41 +1090,41 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc { } @SuppressWarnings("EnumSwitchStatementWhichMissesCases") - private void handleFilterLoincAncestor(String theSystem, String theSystemVersion, BooleanJunction theBool, ValueSet.ConceptSetFilterComponent theFilter) { + private void handleFilterLoincAncestor(String theSystem, BooleanJunction theBool, ValueSet.ConceptSetFilterComponent theFilter) { switch (theFilter.getOp()) { case EQUAL: - addLoincFilterAncestorEqual(theSystem, theSystemVersion, theBool, theFilter); + addLoincFilterAncestorEqual(theSystem, theBool, theFilter); break; case IN: - addLoincFilterAncestorIn(theSystem, theSystemVersion, theBool, theFilter); + addLoincFilterAncestorIn(theSystem, theBool, theFilter); break; default: throw new InvalidRequestException("Don't know how to handle op=" + theFilter.getOp() + " on property " + theFilter.getProperty()); } } - private void addLoincFilterAncestorEqual(String theSystem, String theSystemVersion, BooleanJunction theBool, ValueSet.ConceptSetFilterComponent theFilter) { - addLoincFilterAncestorEqual(theSystem, theSystemVersion, theBool, theFilter.getProperty(), theFilter.getValue()); + private void addLoincFilterAncestorEqual(String theSystem, BooleanJunction theBool, ValueSet.ConceptSetFilterComponent theFilter) { + addLoincFilterAncestorEqual(theSystem, theBool, theFilter.getProperty(), theFilter.getValue()); } - private void addLoincFilterAncestorEqual(String theSystem, String theSystemVersion, BooleanJunction theBool, String theProperty, String theValue) { - List terms = getAncestorTerms(theSystem, theSystemVersion, theProperty, theValue); + private void addLoincFilterAncestorEqual(String theSystem, BooleanJunction theBool, String theProperty, String theValue) { + List terms = getAncestorTerms(theSystem, theProperty, theValue); theBool.must(new TermsQuery(terms)); } - private void addLoincFilterAncestorIn(String theSystem, String theSystemVersion, BooleanJunction theBool, ValueSet.ConceptSetFilterComponent theFilter) { + private void addLoincFilterAncestorIn(String theSystem, BooleanJunction theBool, ValueSet.ConceptSetFilterComponent theFilter) { String[] values = theFilter.getValue().split(","); List terms = new ArrayList<>(); for (String value : values) { - terms.addAll(getAncestorTerms(theSystem, theSystemVersion, theFilter.getProperty(), value)); + terms.addAll(getAncestorTerms(theSystem, theFilter.getProperty(), value)); } theBool.must(new TermsQuery(terms)); } - private List getAncestorTerms(String theSystem, String theSystemVersion, String theProperty, String theValue) { + private List getAncestorTerms(String theSystem, String theProperty, String theValue) { List retVal = new ArrayList<>(); - TermConcept code = findCode(theSystem, theValue, theSystemVersion) + TermConcept code = findCode(theSystem, theValue) .orElseThrow(() -> new InvalidRequestException("Invalid filter criteria - code does not exist: {" + Constants.codeSystemWithDefaultDescription(theSystem) + "}" + theValue)); retVal.add(new Term("myParentPids", "" + code.getId())); @@ -1115,41 +1134,41 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc { } @SuppressWarnings("EnumSwitchStatementWhichMissesCases") - private void handleFilterLoincDescendant(String theSystem, String theSystemVersion, BooleanJunction theBool, ValueSet.ConceptSetFilterComponent theFilter) { + private void handleFilterLoincDescendant(String theSystem, BooleanJunction theBool, ValueSet.ConceptSetFilterComponent theFilter) { switch (theFilter.getOp()) { case EQUAL: - addLoincFilterDescendantEqual(theSystem, theSystemVersion, theBool, theFilter); + addLoincFilterDescendantEqual(theSystem, theBool, theFilter); break; case IN: - addLoincFilterDescendantIn(theSystem, theSystemVersion, theBool, theFilter); + addLoincFilterDescendantIn(theSystem, theBool, theFilter); break; default: throw new InvalidRequestException("Don't know how to handle op=" + theFilter.getOp() + " on property " + theFilter.getProperty()); } } - private void addLoincFilterDescendantEqual(String theSystem, String theSystemVersion, BooleanJunction theBool, ValueSet.ConceptSetFilterComponent theFilter) { - addLoincFilterDescendantEqual(theSystem, theSystemVersion, theBool, theFilter.getProperty(), theFilter.getValue()); + private void addLoincFilterDescendantEqual(String theSystem, BooleanJunction theBool, ValueSet.ConceptSetFilterComponent theFilter) { + addLoincFilterDescendantEqual(theSystem, theBool, theFilter.getProperty(), theFilter.getValue()); } - private void addLoincFilterDescendantEqual(String theSystem, String theSystemVersion, BooleanJunction theBool, String theProperty, String theValue) { - List terms = getDescendantTerms(theSystem, theSystemVersion, theProperty, theValue); + private void addLoincFilterDescendantEqual(String theSystem, BooleanJunction theBool, String theProperty, String theValue) { + List terms = getDescendantTerms(theSystem, theProperty, theValue); theBool.must(new TermsQuery(terms)); } - private void addLoincFilterDescendantIn(String theSystem, String theSystemVersion, BooleanJunction theBool, ValueSet.ConceptSetFilterComponent theFilter) { + private void addLoincFilterDescendantIn(String theSystem, BooleanJunction theBool, ValueSet.ConceptSetFilterComponent theFilter) { String[] values = theFilter.getValue().split(","); List terms = new ArrayList<>(); for (String value : values) { - terms.addAll(getDescendantTerms(theSystem, theSystemVersion, theFilter.getProperty(), value)); + terms.addAll(getDescendantTerms(theSystem, theFilter.getProperty(), value)); } theBool.must(new TermsQuery(terms)); } - private List getDescendantTerms(String theSystem, String theSystemVersion, String theProperty, String theValue) { + private List getDescendantTerms(String theSystem, String theProperty, String theValue) { List retVal = new ArrayList<>(); - TermConcept code = findCode(theSystem, theValue, theSystemVersion) + TermConcept code = findCode(theSystem, theValue) .orElseThrow(() -> new InvalidRequestException("Invalid filter criteria - code does not exist: {" + Constants.codeSystemWithDefaultDescription(theSystem) + "}" + theValue)); String[] parentPids = code.getParentPidsAsString().split(" "); @@ -1398,11 +1417,6 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc { @Override public Optional findCode(String theCodeSystem, String theCode) { - return findCode(theCodeSystem, theCode, null); - } - - @Override - public Optional findCode(String theCodeSystem, String theCode, String theVersion) { /* * Loading concepts without a transaction causes issues later on some * platforms (e.g. PSQL) so this transactiontemplate is here to make @@ -1410,8 +1424,9 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc { */ TransactionTemplate txTemplate = new TransactionTemplate(myTransactionManager); txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_MANDATORY); + return txTemplate.execute(t -> { - TermCodeSystemVersion csv = getCurrentCodeSystemVersion(theCodeSystem, theVersion); + TermCodeSystemVersion csv = getCurrentCodeSystemVersion(theCodeSystem); if (csv == null) { return Optional.empty(); } @@ -1420,17 +1435,15 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc { } @Nullable - private TermCodeSystemVersion getCurrentCodeSystemVersion(String theUri, String theVersion) { - StringBuilder key = new StringBuilder(theUri); - if (theVersion != null) { - key.append("|").append(theVersion); - } + private TermCodeSystemVersion getCurrentCodeSystemVersion(String theUri) { + String myVersion = getVersionFromCanonicalUrl(theUri); + String key = theUri; TermCodeSystemVersion retVal = myCodeSystemCurrentVersionCache.get(key.toString(), t -> myTxTemplate.execute(tx -> { TermCodeSystemVersion csv = null; - TermCodeSystem cs = myCodeSystemDao.findByCodeSystemUri(theUri); + TermCodeSystem cs = myCodeSystemDao.findByCodeSystemUri(getSystemFromCanonicalUrl(theUri)); if (cs != null) { - if (theVersion != null) { - csv = myCodeSystemVersionDao.findByCodeSystemPidAndVersion(cs.getPid(), theVersion); + if (myVersion != null) { + csv = myCodeSystemVersionDao.findByCodeSystemPidAndVersion(cs.getPid(), myVersion); } else if (cs.getCurrentVersion() != null) { csv = cs.getCurrentVersion(); } @@ -1447,6 +1460,27 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc { return retVal; } + private String getVersionFromCanonicalUrl(String theUri) { + String retVal = null; + if (StringUtils.isNotEmpty((theUri))) { + int versionSeparator = theUri.lastIndexOf('|'); + if (versionSeparator != -1) { + retVal = theUri.substring(versionSeparator + 1); + } + } + return retVal; + } + + private String getSystemFromCanonicalUrl(String theUri) { + String retVal = theUri; + if (StringUtils.isNotEmpty((theUri))){ + int versionSeparator = theUri.lastIndexOf('|'); + if (versionSeparator != -1) { + retVal = theUri.substring(0, versionSeparator); + } + } + return retVal; + } @Transactional(propagation = Propagation.REQUIRED) @Override @@ -1869,14 +1903,8 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc { @Transactional public IFhirResourceDaoCodeSystem.SubsumesResult subsumes(IPrimitiveType theCodeA, IPrimitiveType theCodeB, IPrimitiveType theSystem, IBaseCoding theCodingA, IBaseCoding theCodingB) { - return subsumes(theCodeA, theCodeB, theSystem, theCodingA, theCodingB, null, null, null); - } - - @Override - @Transactional - public IFhirResourceDaoCodeSystem.SubsumesResult subsumes(IPrimitiveType theCodeA, IPrimitiveType theCodeB, IPrimitiveType theSystem, IBaseCoding theCodingA, IBaseCoding theCodingB, IPrimitiveType theSystemVersion, String theCodingAVersion, String theCodingBVersion) { - VersionIndependentConcept conceptA = toConcept(theCodeA, theSystem, theCodingA, theSystemVersion, theCodingAVersion); - VersionIndependentConcept conceptB = toConcept(theCodeB, theSystem, theCodingB, theSystemVersion, theCodingBVersion); + VersionIndependentConcept conceptA = toConcept(theCodeA, theSystem, theCodingA); + VersionIndependentConcept conceptB = toConcept(theCodeB, theSystem, theCodingB); if (!StringUtils.equals(conceptA.getSystem(), conceptB.getSystem())) { throw new InvalidRequestException("Unable to test subsumption across different code systems"); @@ -1886,10 +1914,22 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc { throw new InvalidRequestException("Unable to test subsumption across different code system versions"); } - TermConcept codeA = findCode(conceptA.getSystem(), conceptA.getCode(), conceptA.getSystemVersion()) + String codeACanonicalUrl; + if (StringUtils.isNotEmpty(conceptA.getSystemVersion())) { + codeACanonicalUrl = conceptA.getSystem() + "|" + conceptA.getSystemVersion(); + } else { + codeACanonicalUrl = conceptA.getSystem(); + } + TermConcept codeA = findCode(codeACanonicalUrl, conceptA.getCode()) .orElseThrow(() -> new InvalidRequestException("Unknown code: " + conceptA)); - TermConcept codeB = findCode(conceptB.getSystem(), conceptB.getCode(), conceptB.getSystemVersion()) + String codeBCanonicalUrl; + if (StringUtils.isNotEmpty(conceptB.getSystemVersion())) { + codeBCanonicalUrl = conceptB.getSystem() + "|" + conceptB.getSystemVersion(); + } else { + codeBCanonicalUrl = conceptB.getSystem(); + } + TermConcept codeB = findCode(codeBCanonicalUrl, conceptB.getCode()) .orElseThrow(() -> new InvalidRequestException("Unknown code: " + conceptB)); FullTextEntityManager em = org.hibernate.search.jpa.Search.getFullTextEntityManager(myEntityManager); @@ -1908,10 +1948,10 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc { protected abstract ValueSet toCanonicalValueSet(IBaseResource theValueSet); - protected IValidationSupport.LookupCodeResult lookupCode(String theSystem, String theCode, String theVersion) { + protected IValidationSupport.LookupCodeResult lookupCode(String theSystem, String theCode) { TransactionTemplate txTemplate = new TransactionTemplate(myTransactionManager); return txTemplate.execute(t -> { - Optional codeOpt = findCode(theSystem, theCode, theVersion); + Optional codeOpt = findCode(theSystem, theCode); if (codeOpt.isPresent()) { TermConcept code = codeOpt.get(); @@ -2456,14 +2496,14 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc { } @NotNull - private VersionIndependentConcept toConcept(IPrimitiveType theCodeType, IPrimitiveType theSystemType, IBaseCoding theCodingType, IPrimitiveType theSystemVersionType, String theCodingVersionType) { + private VersionIndependentConcept toConcept(IPrimitiveType theCodeType, IPrimitiveType theSystemType, IBaseCoding theCodingType) { String code = theCodeType != null ? theCodeType.getValueAsString() : null; - String system = theSystemType != null ? theSystemType.getValueAsString() : null; - String systemVersion = theSystemVersionType != null ? theSystemVersionType.getValueAsString() : null; + String system = theSystemType != null ? getSystemFromCanonicalUrl(theSystemType.getValueAsString()): null; + String systemVersion = theSystemType != null ? getVersionFromCanonicalUrl(theSystemType.getValueAsString()): null; if (theCodingType != null) { code = theCodingType.getCode(); - system = theCodingType.getSystem(); - systemVersion = theCodingVersionType; + system = getSystemFromCanonicalUrl(theCodingType.getSystem()); + systemVersion = getVersionFromCanonicalUrl(theCodingType.getSystem()); } return new VersionIndependentConcept(system, code, null, systemVersion); } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/IValueSetConceptAccumulator.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/IValueSetConceptAccumulator.java index f3b7dd24c5d..34bca1b9d4a 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/IValueSetConceptAccumulator.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/IValueSetConceptAccumulator.java @@ -33,11 +33,11 @@ public interface IValueSetConceptAccumulator { void includeConceptWithDesignations(String theSystem, String theCode, String theDisplay, @Nullable Collection theDesignations); - void includeConceptWithDesignations(String theSystem, String theSystemVersion, String theCode, String theDisplay, @Nullable Collection theDesignations); +// void includeConceptWithDesignations(String theSystem, String theSystemVersion, String theCode, String theDisplay, @Nullable Collection theDesignations); void excludeConcept(String theSystem, String theCode); - void excludeConcept(String theSystem, String theSystemVersion, String theCode); +// void excludeConcept(String theSystem, String theSystemVersion, String theCode); @Nullable default Integer getCapacityRemaining() { diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermReadSvcDstu3.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermReadSvcDstu3.java index 0056824d586..6b266ae52f3 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermReadSvcDstu3.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermReadSvcDstu3.java @@ -149,12 +149,7 @@ public class TermReadSvcDstu3 extends BaseTermReadSvcImpl implements IValidation @Override public LookupCodeResult lookupCode(ValidationSupportContext theValidationSupportContext, String theSystem, String theCode) { - return super.lookupCode(theSystem, theCode, null); - } - - @Override - public LookupCodeResult lookupCode(ValidationSupportContext theValidationSupportContext, String theSystem, String theCode, String theVersion) { - return super.lookupCode(theSystem, theCode, theVersion); + return super.lookupCode(theSystem, theCode); } @Override diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermReadSvcR4.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermReadSvcR4.java index 96243af965a..2075725dc2f 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermReadSvcR4.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermReadSvcR4.java @@ -89,14 +89,9 @@ public class TermReadSvcR4 extends BaseTermReadSvcImpl implements ITermReadSvcR4 return (CodeSystem) theCodeSystem; } - @Override - public LookupCodeResult lookupCode(ValidationSupportContext theValidationSupportContext, String theSystem, String theCode, String theVersion) { - return super.lookupCode(theSystem, theCode, theVersion); - } - @Override public LookupCodeResult lookupCode(ValidationSupportContext theValidationSupportContext, String theSystem, String theCode) { - return super.lookupCode(theSystem, theCode, null); + return super.lookupCode(theSystem, theCode); } @Override 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 30345a91def..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 @@ -71,7 +71,7 @@ public class ValueSetConceptAccumulator implements IValueSetConceptAccumulator { } @Override - public void includeConceptWithDesignations(String theSystem, String theSystemVersion, String theCode, String theDisplay, Collection theDesignations) { + public void includeConceptWithDesignations(String theSystem, String theCode, String theDisplay, Collection theDesignations) { TermValueSetConcept concept = saveConcept(theSystem, theCode, theDisplay); if (theDesignations != null) { for (TermConceptDesignation designation : theDesignations) { @@ -80,18 +80,8 @@ public class ValueSetConceptAccumulator implements IValueSetConceptAccumulator { } } - @Override - public void includeConceptWithDesignations(String theSystem, String theCode, String theDisplay, Collection theDesignations) { - includeConceptWithDesignations(theSystem, null, theCode, theDisplay, theDesignations); - } - @Override public void excludeConcept(String theSystem, String theCode) { - excludeConcept(theSystem, null, theCode); - } - - @Override - public void excludeConcept(String theSystem, String theSystemVersion, String theCode) { if (isAnyBlank(theSystem, theCode)) { return; } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/ValueSetExpansionComponentWithConceptAccumulator.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/ValueSetExpansionComponentWithConceptAccumulator.java index b3af6a3ca15..6005d871f3a 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/ValueSetExpansionComponentWithConceptAccumulator.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/ValueSetExpansionComponentWithConceptAccumulator.java @@ -26,6 +26,7 @@ import ca.uhn.fhir.jpa.term.ex.ExpansionTooCostlyException; import ca.uhn.fhir.model.api.annotation.Block; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.util.HapiExtensions; +import org.apache.commons.lang3.StringUtils; import org.hl7.fhir.r4.model.StringType; import org.hl7.fhir.r4.model.ValueSet; @@ -67,21 +68,18 @@ public class ValueSetExpansionComponentWithConceptAccumulator extends ValueSet.V public void includeConcept(String theSystem, String theCode, String theDisplay) { incrementConceptsCount(); ValueSet.ValueSetExpansionContainsComponent contains = this.addContains(); - contains.setSystem(theSystem); + setSystemAndVersion(theSystem, contains); contains.setCode(theCode); contains.setDisplay(theDisplay); } @Override - public void includeConceptWithDesignations(String theSystem, String theSystemVersion, String theCode, String theDisplay, Collection theDesignations) { + public void includeConceptWithDesignations(String theSystem, String theCode, String theDisplay, Collection theDesignations) { incrementConceptsCount(); ValueSet.ValueSetExpansionContainsComponent contains = this.addContains(); - contains.setSystem(theSystem); + setSystemAndVersion(theSystem, contains); contains.setCode(theCode); contains.setDisplay(theDisplay); - if (theSystemVersion != null) { - contains.setVersion(theSystemVersion); - } if (theDesignations != null) { for (TermConceptDesignation termConceptDesignation : theDesignations) { contains @@ -96,28 +94,28 @@ public class ValueSetExpansionComponentWithConceptAccumulator extends ValueSet.V } } - @Override - public void includeConceptWithDesignations(String theSystem, String theCode, String theDisplay, Collection theDesignations) { - this.includeConceptWithDesignations(theSystem, null, theCode, theDisplay, theDesignations); - } - - @Override - public void excludeConcept(String theSystem, String theSystemVersion, String theCode) { - this - .getContains() - .removeIf(t -> - theSystem.equals(t.getSystem()) && - theCode.equals(t.getCode()) && - theSystemVersion.equals(t.getVersion())); - } - @Override public void excludeConcept(String theSystem, String theCode) { - this - .getContains() - .removeIf(t -> - theSystem.equals(t.getSystem()) && - theCode.equals(t.getCode())); + String excludeSystem; + String excludeSystemVersion; + int versionSeparator = theSystem.indexOf("|"); + if(versionSeparator > -1) { + excludeSystemVersion = theSystem.substring(versionSeparator + 1); + excludeSystem = theSystem.substring(0, versionSeparator); + } else { + excludeSystem = theSystem; + excludeSystemVersion = null; + } + if (excludeSystemVersion != null) { + this.getContains().removeIf(t -> + excludeSystem.equals(t.getSystem()) && + theCode.equals(t.getCode()) && + excludeSystemVersion.equals(t.getVersion())); + } else { + this.getContains().removeIf(t -> + theSystem.equals(t.getSystem()) && + theCode.equals(t.getCode())); + } } private void incrementConceptsCount() { @@ -126,4 +124,17 @@ public class ValueSetExpansionComponentWithConceptAccumulator extends ValueSet.V throw new ExpansionTooCostlyException(msg); } } + + private void setSystemAndVersion(String theSystemAndVersion, ValueSet.ValueSetExpansionContainsComponent myComponent) { + if (StringUtils.isNotEmpty((theSystemAndVersion))) { + int versionSeparator = theSystemAndVersion.lastIndexOf('|'); + if (versionSeparator != -1) { + myComponent.setVersion(theSystemAndVersion.substring(versionSeparator + 1)); + myComponent.setSystem(theSystemAndVersion.substring(0,versionSeparator)); + } else { + myComponent.setSystem(theSystemAndVersion); + } + } + } + } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/api/ITermReadSvc.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/api/ITermReadSvc.java index 124cf2d6450..bfac6ae33d9 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/api/ITermReadSvc.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/api/ITermReadSvc.java @@ -73,8 +73,6 @@ public interface ITermReadSvc extends IValidationSupport { List expandValueSet(ValueSetExpansionOptions theExpansionOptions, String theValueSet); - Optional findCode(String theCodeSystem, String theCode, String theVersion); - Optional findCode(String theCodeSystem, String theCode); Set findCodesAbove(Long theCodeSystemResourcePid, Long theCodeSystemResourceVersionPid, String theCode); @@ -105,8 +103,6 @@ public interface ITermReadSvc extends IValidationSupport { IFhirResourceDaoCodeSystem.SubsumesResult subsumes(IPrimitiveType theCodeA, IPrimitiveType theCodeB, IPrimitiveType theSystem, IBaseCoding theCodingA, IBaseCoding theCodingB); - IFhirResourceDaoCodeSystem.SubsumesResult subsumes(IPrimitiveType theCodeA, IPrimitiveType theCodeB, IPrimitiveType theSystem, IBaseCoding theCodingA, IBaseCoding theCodingB, IPrimitiveType theSystemVersion, String theCodingAVersion, String theCodingBVersion); - void preExpandDeferredValueSetsToTerminologyTables(); /** diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoValueSetDstu2Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoValueSetDstu2Test.java index 32d705e43aa..79a19c89a8a 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoValueSetDstu2Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoValueSetDstu2Test.java @@ -233,26 +233,4 @@ public class FhirResourceDaoValueSetDstu2Test extends BaseJpaDstu2Test { assertThat(resp, not(containsString(""))); } - @Test - public void unsupportedMethodsThrowException() { - IFhirResourceDaoCodeSystem testFhirResourceDaoValueSet = new FhirResourceDaoValueSetDstu2(); - // Multi-version lookupCode method - try { - testFhirResourceDaoValueSet.lookupCode(null, null, null, null, null); - fail(); - } catch (UnsupportedOperationException theE) { - // Success - } - - // Multi-version subsumes method - try { - testFhirResourceDaoValueSet.subsumes(null, null, null, null, null, null, null); - fail(); - } catch (UnsupportedOperationException theE) { - // Success - } - - - } - } 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 7c21676735e..6c7f36b8ea6 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 @@ -524,7 +524,7 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test { myTerminologyDeferredStorageSvc.saveDeferred(); myTerminologyDeferredStorageSvc.saveDeferred(); - IValidationSupport.LookupCodeResult lookupResults = myCodeSystemDao.lookupCode(new StringType("childAA"), new StringType(URL_MY_CODE_SYSTEM), null,null, mySrd); + IValidationSupport.LookupCodeResult lookupResults = myCodeSystemDao.lookupCode(new StringType("childAA"), new StringType(URL_MY_CODE_SYSTEM), null, mySrd); assertEquals(true, lookupResults.isFound()); ValueSet vs = new ValueSet(); @@ -715,7 +715,7 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test { 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/provider/r4/ResourceProviderR4ValueSetTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ValueSetTest.java index 358cd5eb2eb..e49548c259d 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 @@ -56,6 +56,7 @@ import java.util.Optional; import static ca.uhn.fhir.jpa.dao.r4.FhirResourceDaoR4TerminologyTest.URL_MY_CODE_SYSTEM; import static ca.uhn.fhir.jpa.dao.r4.FhirResourceDaoR4TerminologyTest.URL_MY_VALUE_SET; +import static org.awaitility.Awaitility.await; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsStringIgnoringCase; @@ -246,6 +247,7 @@ public class ResourceProviderR4ValueSetTest extends BaseResourceProviderR4Test { myDaoConfig.setPreExpandValueSets(true); loadAndPersistCodeSystemAndValueSet(); + await().until(() -> clearDeferredStorageQueue()); myTermSvc.preExpandDeferredValueSetsToTerminologyTables(); Slice page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED); assertEquals(1, page.getContent().size()); @@ -300,6 +302,7 @@ public class ResourceProviderR4ValueSetTest extends BaseResourceProviderR4Test { myDaoConfig.setPreExpandValueSets(true); loadAndPersistCodeSystemAndValueSet(); + await().until(() -> clearDeferredStorageQueue()); myTermSvc.preExpandDeferredValueSetsToTerminologyTables(); Slice page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED); assertEquals(1, page.getContent().size()); @@ -361,6 +364,7 @@ public class ResourceProviderR4ValueSetTest extends BaseResourceProviderR4Test { myDaoConfig.setPreExpandValueSets(true); loadAndPersistCodeSystemAndValueSet(); + await().until(() -> clearDeferredStorageQueue()); myTermSvc.preExpandDeferredValueSetsToTerminologyTables(); Slice page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED); assertEquals(1, page.getContent().size()); @@ -745,6 +749,7 @@ public class ResourceProviderR4ValueSetTest extends BaseResourceProviderR4Test { String initialValueSetName = valueSet.getName(); validateTermValueSetNotExpanded(initialValueSetName); + await().until(() -> clearDeferredStorageQueue()); myTermSvc.preExpandDeferredValueSetsToTerminologyTables(); validateTermValueSetExpandedAndChildren(initialValueSetName, codeSystem); @@ -774,6 +779,7 @@ public class ResourceProviderR4ValueSetTest extends BaseResourceProviderR4Test { String initialValueSetName = valueSet.getName(); validateTermValueSetNotExpanded(initialValueSetName); + await().until(() -> clearDeferredStorageQueue()); myTermSvc.preExpandDeferredValueSetsToTerminologyTables(); validateTermValueSetExpandedAndChildren(initialValueSetName, codeSystem); @@ -1059,6 +1065,17 @@ public class ResourceProviderR4ValueSetTest extends BaseResourceProviderR4Test { } + private boolean clearDeferredStorageQueue() { + + if(!myTerminologyDeferredStorageSvc.isStorageQueueEmpty()) { + myTerminologyDeferredStorageSvc.saveAllDeferred(); + return false; + } else { + return true; + } + + } + @AfterEach public void afterResetPreExpansionDefault() { myDaoConfig.setPreExpandValueSets(new DaoConfig().isPreExpandValueSets()); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ValueSetVersionedTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ValueSetVersionedTest.java index a57291d387e..88381769748 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ValueSetVersionedTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ValueSetVersionedTest.java @@ -52,6 +52,7 @@ import java.util.Optional; import static ca.uhn.fhir.jpa.dao.r4.FhirResourceDaoR4TerminologyTest.URL_MY_CODE_SYSTEM; import static ca.uhn.fhir.jpa.dao.r4.FhirResourceDaoR4TerminologyTest.URL_MY_VALUE_SET; +import static org.awaitility.Awaitility.await; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsStringIgnoringCase; @@ -331,6 +332,7 @@ public class ResourceProviderR4ValueSetVersionedTest extends BaseResourceProvide myDaoConfig.setPreExpandValueSets(true); loadAndPersistCodeSystemAndValueSet(); + await().until(() -> clearDeferredStorageQueue()); myTermSvc.preExpandDeferredValueSetsToTerminologyTables(); Slice page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED); assertEquals(2, page.getContent().size()); @@ -426,6 +428,7 @@ public class ResourceProviderR4ValueSetVersionedTest extends BaseResourceProvide myDaoConfig.setPreExpandValueSets(true); loadAndPersistCodeSystemAndValueSet(); + await().until(() -> clearDeferredStorageQueue()); myTermSvc.preExpandDeferredValueSetsToTerminologyTables(); Slice page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED); @@ -538,6 +541,7 @@ public class ResourceProviderR4ValueSetVersionedTest extends BaseResourceProvide myDaoConfig.setPreExpandValueSets(true); loadAndPersistCodeSystemAndValueSet(); + await().until(() -> clearDeferredStorageQueue()); myTermSvc.preExpandDeferredValueSetsToTerminologyTables(); Slice page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED); @@ -930,6 +934,7 @@ public class ResourceProviderR4ValueSetVersionedTest extends BaseResourceProvide validateTermValueSetNotExpanded(initialValueSetName_v1, "1", myExtensionalVsIdOnResourceTable_v1); String initialValueSetName_v2 = valueSet_v2.getName(); validateTermValueSetNotExpanded(initialValueSetName_v2, "2", myExtensionalVsIdOnResourceTable_v2); + await().until(() -> clearDeferredStorageQueue()); myTermSvc.preExpandDeferredValueSetsToTerminologyTables(); validateTermValueSetExpandedAndChildrenV1(initialValueSetName_v1, codeSystem_v1); validateTermValueSetExpandedAndChildrenV2(initialValueSetName_v2, codeSystem_v2); @@ -979,6 +984,7 @@ public class ResourceProviderR4ValueSetVersionedTest extends BaseResourceProvide String initialValueSetName_v2 = valueSet_v2.getName(); validateTermValueSetNotExpanded(initialValueSetName_v2, "2", myExtensionalVsIdOnResourceTable_v2); myTermSvc.preExpandDeferredValueSetsToTerminologyTables(); + await().until(() -> clearDeferredStorageQueue()); validateTermValueSetExpandedAndChildrenV1(initialValueSetName_v1, codeSystem_v1); validateTermValueSetExpandedAndChildrenV2(initialValueSetName_v2, codeSystem_v2); @@ -1068,7 +1074,7 @@ public class ResourceProviderR4ValueSetVersionedTest extends BaseResourceProvide TermValueSetConcept concept = termValueSet.getConcepts().get(0); ourLog.info("Concept:\n" + concept.toString()); - assertEquals("http://acme.org", concept.getSystem()); + assertEquals("http://acme.org|1", concept.getSystem()); assertEquals("8450-9", concept.getCode()); assertEquals("Systolic blood pressure--expiration", concept.getDisplay()); assertEquals(2, concept.getDesignations().size()); @@ -1090,7 +1096,7 @@ public class ResourceProviderR4ValueSetVersionedTest extends BaseResourceProvide concept = termValueSet.getConcepts().get(1); ourLog.info("Concept:\n" + concept.toString()); - assertEquals("http://acme.org", concept.getSystem()); + assertEquals("http://acme.org|1", concept.getSystem()); assertEquals("11378-7", concept.getCode()); assertEquals("Systolic blood pressure at First encounter", concept.getDisplay()); assertEquals(0, concept.getDesignations().size()); @@ -1100,7 +1106,7 @@ public class ResourceProviderR4ValueSetVersionedTest extends BaseResourceProvide concept = termValueSet.getConcepts().get(22); ourLog.info("Concept:\n" + concept.toString()); - assertEquals("http://acme.org", concept.getSystem()); + assertEquals("http://acme.org|1", concept.getSystem()); assertEquals("8491-3", concept.getCode()); assertEquals("Systolic blood pressure 1 hour minimum", concept.getDisplay()); assertEquals(1, concept.getDesignations().size()); @@ -1115,7 +1121,7 @@ public class ResourceProviderR4ValueSetVersionedTest extends BaseResourceProvide concept = termValueSet.getConcepts().get(23); ourLog.info("Concept:\n" + concept.toString()); - assertEquals("http://acme.org", concept.getSystem()); + assertEquals("http://acme.org|1", concept.getSystem()); assertEquals("8492-1", concept.getCode()); assertEquals("Systolic blood pressure 8 hour minimum", concept.getDisplay()); assertEquals(0, concept.getDesignations().size()); @@ -1141,7 +1147,7 @@ public class ResourceProviderR4ValueSetVersionedTest extends BaseResourceProvide TermValueSetConcept concept = termValueSet.getConcepts().get(0); ourLog.info("Concept:\n" + concept.toString()); - assertEquals("http://acme.org", concept.getSystem()); + assertEquals("http://acme.org|2", concept.getSystem()); assertEquals("8450-9", concept.getCode()); assertEquals("Systolic blood pressure--expiration v2", concept.getDisplay()); assertEquals(2, concept.getDesignations().size()); @@ -1163,7 +1169,7 @@ public class ResourceProviderR4ValueSetVersionedTest extends BaseResourceProvide concept = termValueSet.getConcepts().get(1); ourLog.info("Concept:\n" + concept.toString()); - assertEquals("http://acme.org", concept.getSystem()); + assertEquals("http://acme.org|2", concept.getSystem()); assertEquals("11378-7", concept.getCode()); assertEquals("Systolic blood pressure at First encounter v2", concept.getDisplay()); assertEquals(0, concept.getDesignations().size()); @@ -1173,7 +1179,7 @@ public class ResourceProviderR4ValueSetVersionedTest extends BaseResourceProvide concept = termValueSet.getConcepts().get(22); ourLog.info("Concept:\n" + concept.toString()); - assertEquals("http://acme.org", concept.getSystem()); + assertEquals("http://acme.org|2", concept.getSystem()); assertEquals("8491-3", concept.getCode()); assertEquals("Systolic blood pressure 1 hour minimum v2", concept.getDisplay()); assertEquals(1, concept.getDesignations().size()); @@ -1188,7 +1194,7 @@ public class ResourceProviderR4ValueSetVersionedTest extends BaseResourceProvide concept = termValueSet.getConcepts().get(23); ourLog.info("Concept:\n" + concept.toString()); - assertEquals("http://acme.org", concept.getSystem()); + assertEquals("http://acme.org|2", concept.getSystem()); assertEquals("8492-1", concept.getCode()); assertEquals("Systolic blood pressure 8 hour minimum v2", concept.getDisplay()); assertEquals(0, concept.getDesignations().size()); @@ -1341,6 +1347,17 @@ public class ResourceProviderR4ValueSetVersionedTest extends BaseResourceProvide } */ + private boolean clearDeferredStorageQueue() { + + if(!myTerminologyDeferredStorageSvc.isStorageQueueEmpty()) { + myTerminologyDeferredStorageSvc.saveAllDeferred(); + return false; + } else { + return true; + } + + } + @Test public void testCreateDuplicatValueSetVersion() { createExternalCsAndLocalVs(); 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 0ffe92d13bb..ba515681dc3 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,7 +63,6 @@ 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); @@ -107,7 +106,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test { 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", null, cs, table); myTerminologyDeferredStorageSvc.saveAllDeferred(); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/ValueSetExpansionR4ElasticsearchIT.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/ValueSetExpansionR4ElasticsearchIT.java index e0d35c85fc1..84f0f663b9c 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/ValueSetExpansionR4ElasticsearchIT.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/ValueSetExpansionR4ElasticsearchIT.java @@ -195,7 +195,7 @@ public class ValueSetExpansionR4ElasticsearchIT extends BaseJpaTest { include.setSystem(CS_URL); myTermSvc.expandValueSet(null, vs, myValueSetCodeAccumulator); - verify(myValueSetCodeAccumulator, times(9)).includeConceptWithDesignations(anyString(), anyString(), anyString(), nullable(String.class), anyCollection()); + verify(myValueSetCodeAccumulator, times(9)).includeConceptWithDesignations(anyString(), anyString(), nullable(String.class), anyCollection()); } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/ValueSetExpansionR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/ValueSetExpansionR4Test.java index c99339b1243..40850b23eaf 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/ValueSetExpansionR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/ValueSetExpansionR4Test.java @@ -904,7 +904,7 @@ public class ValueSetExpansionR4Test extends BaseTermR4Test { include.setSystem(CS_URL); myTermSvc.expandValueSet(null, vs, myValueSetCodeAccumulator); - verify(myValueSetCodeAccumulator, times(9)).includeConceptWithDesignations(anyString(), anyString(), anyString(), nullable(String.class), anyCollection()); + verify(myValueSetCodeAccumulator, times(9)).includeConceptWithDesignations(anyString(), anyString(), nullable(String.class), anyCollection()); } @Test diff --git a/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/support/BaseValidationSupportWrapper.java b/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/support/BaseValidationSupportWrapper.java index 3c6c10f9fb3..cc04a447d10 100644 --- a/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/support/BaseValidationSupportWrapper.java +++ b/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/support/BaseValidationSupportWrapper.java @@ -58,11 +58,6 @@ public class BaseValidationSupportWrapper extends BaseValidationSupport { return myWrap.validateCode(theValidationSupportContext, theOptions, theCodeSystem, theCode, theDisplay, theValueSetUrl); } - @Override - public LookupCodeResult lookupCode(ValidationSupportContext theValidationSupportContext, String theSystem, String theCode, String theVersion) { - return myWrap.lookupCode(theValidationSupportContext, theSystem, theCode, theVersion); - } - @Override public LookupCodeResult lookupCode(ValidationSupportContext theValidationSupportContext, String theSystem, String theCode) { return myWrap.lookupCode(theValidationSupportContext, theSystem, theCode); diff --git a/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/support/CachingValidationSupport.java b/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/support/CachingValidationSupport.java index 53c15009f11..829b9977ad7 100644 --- a/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/support/CachingValidationSupport.java +++ b/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/support/CachingValidationSupport.java @@ -83,12 +83,6 @@ public class CachingValidationSupport extends BaseValidationSupportWrapper imple return loadFromCache(myValidateCodeCache, key, t -> super.validateCode(theValidationSupportContext, theOptions, theCodeSystem, theCode, theDisplay, theValueSetUrl)); } - @Override - public LookupCodeResult lookupCode(ValidationSupportContext theValidationSupportContext, String theSystem, String theCode, String theVersion) { - String key = "lookupCode " + theSystem + " " + theCode + " " + theVersion; - return loadFromCache(myLookupCodeCache, key, t -> super.lookupCode(theValidationSupportContext, theSystem, theCode, theVersion)); - } - @Override public LookupCodeResult lookupCode(ValidationSupportContext theValidationSupportContext, String theSystem, String theCode) { String key = "lookupCode " + theSystem + " " + theCode; diff --git a/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/support/CommonCodeSystemsTerminologyService.java b/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/support/CommonCodeSystemsTerminologyService.java index 51dfe5dd86b..b447c39e160 100644 --- a/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/support/CommonCodeSystemsTerminologyService.java +++ b/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/support/CommonCodeSystemsTerminologyService.java @@ -145,12 +145,6 @@ public class CommonCodeSystemsTerminologyService implements IValidationSupport { } - @Override - public LookupCodeResult lookupCode(ValidationSupportContext theValidationSupportContext, String theSystem, String theCode, String theVersion) { - // For now Common Code Systems will not be versioned. - return lookupCode(theValidationSupportContext, theSystem, theCode); - } - @Override public LookupCodeResult lookupCode(ValidationSupportContext theValidationSupportContext, String theSystem, String theCode) { diff --git a/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/support/InMemoryTerminologyServerValidationSupport.java b/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/support/InMemoryTerminologyServerValidationSupport.java index 6b3d3dd135e..3fca6d034ac 100644 --- a/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/support/InMemoryTerminologyServerValidationSupport.java +++ b/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/support/InMemoryTerminologyServerValidationSupport.java @@ -308,44 +308,6 @@ public class InMemoryTerminologyServerValidationSupport implements IValidationSu .setMessage(message); } - @Override - public LookupCodeResult lookupCode(ValidationSupportContext theValidationSupportContext, String theSystem, String theCode, String theVersion) { - // The following code mostly duplicates the validateCode method, differing in that it includes the code system version in the generated ValueSet resource. - IBaseResource vs; - switch (myCtx.getVersion().getVersion()) { - case DSTU3: - vs = new org.hl7.fhir.dstu3.model.ValueSet() - .setCompose(new org.hl7.fhir.dstu3.model.ValueSet.ValueSetComposeComponent() - .addInclude(new org.hl7.fhir.dstu3.model.ValueSet.ConceptSetComponent().setSystem(theSystem).setVersion(theVersion))); - break; - case R4: - vs = new org.hl7.fhir.r4.model.ValueSet() - .setCompose(new org.hl7.fhir.r4.model.ValueSet.ValueSetComposeComponent() - .addInclude(new org.hl7.fhir.r4.model.ValueSet.ConceptSetComponent().setSystem(theSystem).setVersion(theVersion))); - break; - case R5: - vs = new org.hl7.fhir.r5.model.ValueSet() - .setCompose(new org.hl7.fhir.r5.model.ValueSet.ValueSetComposeComponent() - .addInclude(new org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent().setSystem(theSystem).setVersion(theVersion))); - break; - case DSTU2_HL7ORG: - case DSTU2: - case DSTU2_1: - default: - throw new IllegalArgumentException("Can not handle version: " + myCtx.getVersion().getVersion()); - } - - ValueSetExpansionOutcome valueSetExpansionOutcome = expandValueSet(theValidationSupportContext, null, vs); - if (valueSetExpansionOutcome == null) { - return null; - } - - IBaseResource expansion = valueSetExpansionOutcome.getValueSet(); - - return validateCodeInExpandedValueSet(theValidationSupportContext, new ConceptValidationOptions(), theSystem, theCode, null, expansion).asLookupCodeResult(theSystem, theCode); - - } - @Override public LookupCodeResult lookupCode(ValidationSupportContext theValidationSupportContext, String theSystem, String theCode) { return validateCode(theValidationSupportContext, new ConceptValidationOptions(), theSystem, theCode, null, null).asLookupCodeResult(theSystem, theCode); diff --git a/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/support/ValidationSupportChain.java b/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/support/ValidationSupportChain.java index ac7da03cd07..841038fd4b7 100644 --- a/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/support/ValidationSupportChain.java +++ b/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/support/ValidationSupportChain.java @@ -257,16 +257,6 @@ public class ValidationSupportChain implements IValidationSupport { return null; } - @Override - public LookupCodeResult lookupCode(ValidationSupportContext theValidationSupportContext, String theSystem, String theCode, String theVersion) { - for (IValidationSupport next : myChain) { - if (next.isCodeSystemSupported(theValidationSupportContext, theSystem)) { - return next.lookupCode(theValidationSupportContext, theSystem, theCode, theVersion); - } - } - return null; - } - @Override public LookupCodeResult lookupCode(ValidationSupportContext theValidationSupportContext, String theSystem, String theCode) { for (IValidationSupport next : myChain) { diff --git a/hapi-fhir-validation/src/test/java/org/hl7/fhir/r4/validation/FhirInstanceValidatorR4Test.java b/hapi-fhir-validation/src/test/java/org/hl7/fhir/r4/validation/FhirInstanceValidatorR4Test.java index d5055423b05..48d5cb31eb7 100644 --- a/hapi-fhir-validation/src/test/java/org/hl7/fhir/r4/validation/FhirInstanceValidatorR4Test.java +++ b/hapi-fhir-validation/src/test/java/org/hl7/fhir/r4/validation/FhirInstanceValidatorR4Test.java @@ -254,7 +254,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { return retVal; } }); - when(mockSupport.lookupCode(any(), any(), any(), any())).thenAnswer(t -> { + when(mockSupport.lookupCode(any(), any(), any())).thenAnswer(t -> { String system = t.getArgument(1, String.class); String code = t.getArgument(2, String.class); if (myValidConcepts.contains(system + "___" + code)) {