Merge pull request #2067 from jamesagnew/ft_2020_09_02_term_multi_version_support

ConceptMap multi version support
This commit is contained in:
IanMMarshall 2020-09-11 12:05:14 -04:00 committed by GitHub
commit b29d5388c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 1403 additions and 62 deletions

View File

@ -125,6 +125,8 @@ ca.uhn.fhir.jpa.dao.dstu3.FhirResourceDaoConceptMapDstu3.matchesFound=Matches fo
ca.uhn.fhir.jpa.dao.dstu3.FhirResourceDaoConceptMapDstu3.noMatchesFound=No matches found!
ca.uhn.fhir.jpa.dao.r4.FhirResourceDaoConceptMapR4.matchesFound=Matches found!
ca.uhn.fhir.jpa.dao.r4.FhirResourceDaoConceptMapR4.noMatchesFound=No matches found!
ca.uhn.fhir.jpa.dao.r5.FhirResourceDaoConceptMapR5.matchesFound=Matches found!
ca.uhn.fhir.jpa.dao.r5.FhirResourceDaoConceptMapR5.noMatchesFound=No matches found!
ca.uhn.fhir.jpa.dao.r4.FhirResourceDaoSearchParameterR4.invalidSearchParamExpression=The expression "{0}" can not be evaluated and may be invalid: {1}
ca.uhn.fhir.jpa.dao.predicate.PredicateBuilderToken.textModifierDisabledForSearchParam=The :text modifier is disabled for this search parameter
@ -142,6 +144,7 @@ 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.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!

View File

@ -23,11 +23,14 @@ package ca.uhn.fhir.jpa.api.model;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.hl7.fhir.r4.model.Coding;
import org.hl7.fhir.r4.model.StringType;
import org.hl7.fhir.r4.model.UriType;
public class TranslationQuery {
private Coding myCoding;
private Long myResourceId;
private UriType myUrl;
private StringType myConceptMapVersion;
private UriType mySource;
private UriType myTarget;
private UriType myTargetSystem;
@ -58,6 +61,32 @@ public class TranslationQuery {
myResourceId = theResourceId;
}
//-- url
public boolean hasUrl() {
return myUrl != null && myUrl.hasValue();
}
public UriType getUrl() {
return myUrl;
}
public void setUrl(UriType theUrl) {
myUrl = theUrl;
}
//-- ConceptMapVersion
public boolean hasConceptMapVersion() {
return myConceptMapVersion != null && myConceptMapVersion.hasValue();
}
public StringType getConceptMapVersion() {
return myConceptMapVersion;
}
public void setConceptMapVersion(StringType theConceptMapVersion) {
myConceptMapVersion = theConceptMapVersion;
}
public boolean hasSource() {
return mySource != null && mySource.hasValue();
}
@ -107,6 +136,8 @@ public class TranslationQuery {
.append(getCoding().getSystem(), that.getCoding().getSystem())
.append(getCoding().getVersion(), that.getCoding().getVersion())
.append(getResourceId(), that.getResourceId())
.append(getUrl(), that.getUrl())
.append(getConceptMapVersion(), that.getConceptMapVersion())
.append(getSource(), that.getSource())
.append(getTarget(), that.getTarget())
.append(getTargetSystem(), that.getTargetSystem())
@ -120,6 +151,8 @@ public class TranslationQuery {
.append(getCoding().getSystem())
.append(getCoding().getVersion())
.append(getResourceId())
.append(getUrl())
.append(getConceptMapVersion())
.append(getSource())
.append(getTarget())
.append(getTargetSystem())

View File

@ -1,5 +1,8 @@
package ca.uhn.fhir.jpa.api.model;
import java.util.ArrayList;
import java.util.List;
/*
* #%L
* HAPI FHIR JPA API
@ -24,15 +27,15 @@ import org.apache.commons.lang3.Validate;
import org.hl7.fhir.r4.model.BooleanType;
import org.hl7.fhir.r4.model.CodeableConcept;
import org.hl7.fhir.r4.model.Coding;
import org.hl7.fhir.r4.model.StringType;
import org.hl7.fhir.r4.model.UriType;
import java.util.ArrayList;
import java.util.List;
public class TranslationRequest {
private CodeableConcept myCodeableConcept;
private Long myResourceId;
private BooleanType myReverse;
private UriType myUrl;
private StringType myConceptMapVersion;
private UriType mySource;
private UriType myTarget;
private UriType myTargetSystem;
@ -90,6 +93,24 @@ public class TranslationRequest {
return false;
}
public UriType getUrl() {
return myUrl;
}
public TranslationRequest setUrl(UriType theUrl) {
myUrl = theUrl;
return this;
}
public StringType getConceptMapVersion() {
return myConceptMapVersion;
}
public TranslationRequest setConceptMapVersion(StringType theConceptMapVersion) {
myConceptMapVersion = theConceptMapVersion;
return this;
}
public UriType getSource() {
return mySource;
}
@ -130,6 +151,14 @@ public class TranslationRequest {
translationQuery.setResourceId(this.getResourceId());
}
if (this.hasUrl()) {
translationQuery.setUrl(this.getUrl());
}
if (this.hasConceptMapVersion()) {
translationQuery.setConceptMapVersion(this.getConceptMapVersion());
}
if (this.hasSource()) {
translationQuery.setSource(this.getSource());
}
@ -156,6 +185,14 @@ public class TranslationRequest {
return myReverse != null;
}
public boolean hasUrl() {
return myUrl != null && myUrl.hasValue();
}
public boolean hasConceptMapVersion() {
return myConceptMapVersion != null && myConceptMapVersion.hasValue();
}
public boolean hasSource() {
return mySource != null && mySource.hasValue();
}

View File

@ -1,12 +1,15 @@
package ca.uhn.fhir.jpa.dao.data;
import ca.uhn.fhir.jpa.entity.TermConceptMap;
import java.util.List;
import java.util.Optional;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.Optional;
import ca.uhn.fhir.jpa.entity.TermConceptMap;
/*
* #%L
@ -36,6 +39,17 @@ public interface ITermConceptMapDao extends JpaRepository<TermConceptMap, Long>
@Query("SELECT cm FROM TermConceptMap cm WHERE cm.myResourcePid = :resource_pid")
Optional<TermConceptMap> findTermConceptMapByResourcePid(@Param("resource_pid") Long theResourcePid);
@Query("SELECT cm FROM TermConceptMap cm WHERE cm.myUrl = :url")
// Keep backwards compatibility, recommend to use findTermConceptMapByUrlAndNullVersion instead
@Deprecated
@Query("SELECT cm FROM TermConceptMap cm WHERE cm.myUrl = :url and cm.myVersion is null")
Optional<TermConceptMap> findTermConceptMapByUrl(@Param("url") String theUrl);
@Query("SELECT cm FROM TermConceptMap cm WHERE cm.myUrl = :url and cm.myVersion is null")
Optional<TermConceptMap> findTermConceptMapByUrlAndNullVersion(@Param("url") String theUrl);
@Query(value="SELECT cm FROM TermConceptMap cm INNER JOIN ResourceTable r ON r.myId = cm.myResourcePid WHERE cm.myUrl = :url ORDER BY r.myUpdated DESC")
List<TermConceptMap> getTermConceptMapEntitiesByUrlOrderByVersion(Pageable thePage, @Param("url") String theUrl);
@Query("SELECT cm FROM TermConceptMap cm WHERE cm.myUrl = :url AND cm.myVersion = :version")
Optional<TermConceptMap> findTermConceptMapByUrlAndVersion(@Param("url") String theUrl, @Param("version") String theVersion);
}

View File

@ -32,6 +32,8 @@ import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
import ca.uhn.fhir.jpa.term.api.ITermReadSvc;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import org.hl7.fhir.convertors.VersionConvertor_40_50;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.BooleanType;
import org.hl7.fhir.r4.model.CodeType;
@ -39,6 +41,7 @@ import org.hl7.fhir.r4.model.Coding;
import org.hl7.fhir.r4.model.ConceptMap;
import org.hl7.fhir.r4.model.StringType;
import org.hl7.fhir.r4.model.UriType;
import org.hl7.fhir.r4.model.Enumerations.ConceptMapEquivalence;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Date;
@ -152,7 +155,11 @@ public class FhirResourceDaoConceptMapR4 extends BaseHapiFhirResourceDao<Concept
translationMatch.setSource(new UriType(element.getConceptMapUrl()));
if (element.getConceptMapGroupElementTargets().size() == 1) {
translationMatch.setEquivalence(new CodeType(element.getConceptMapGroupElementTargets().get(0).getEquivalence().toCode()));
ConceptMapEquivalence eq = element.getConceptMapGroupElementTargets().get(0).getEquivalence();
if (eq != null) {
translationMatch.setEquivalence(new CodeType(eq.toCode()));
}
}
retVal.addMatch(translationMatch);

View File

@ -1,5 +1,21 @@
package ca.uhn.fhir.jpa.dao.r5;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.hl7.fhir.convertors.VersionConvertor_40_50;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.Enumerations.ConceptMapEquivalence;
import org.hl7.fhir.r5.model.BooleanType;
import org.hl7.fhir.r5.model.CodeType;
import org.hl7.fhir.r5.model.Coding;
import org.hl7.fhir.r5.model.ConceptMap;
import org.hl7.fhir.r5.model.StringType;
import org.hl7.fhir.r5.model.UriType;
import org.springframework.beans.factory.annotation.Autowired;
/*
* #%L
* HAPI FHIR JPA Server
@ -29,23 +45,9 @@ import ca.uhn.fhir.jpa.entity.TermConceptMapGroupElement;
import ca.uhn.fhir.jpa.entity.TermConceptMapGroupElementTarget;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
import ca.uhn.fhir.jpa.term.api.ITermReadSvc;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import org.hl7.fhir.convertors.VersionConvertor_40_50;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r5.model.BooleanType;
import org.hl7.fhir.r5.model.CodeType;
import org.hl7.fhir.r5.model.Coding;
import org.hl7.fhir.r5.model.ConceptMap;
import org.hl7.fhir.r5.model.StringType;
import org.hl7.fhir.r5.model.UriType;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
public class FhirResourceDaoConceptMapR5 extends BaseHapiFhirResourceDao<ConceptMap> implements IFhirResourceDaoConceptMap<ConceptMap> {
@Autowired
@ -153,7 +155,11 @@ public class FhirResourceDaoConceptMapR5 extends BaseHapiFhirResourceDao<Concept
translationMatch.setSource(VersionConvertor_40_50.convertUri(new UriType(element.getConceptMapUrl())));
if (element.getConceptMapGroupElementTargets().size() == 1) {
translationMatch.setEquivalence(VersionConvertor_40_50.convertCode(new CodeType(element.getConceptMapGroupElementTargets().get(0).getEquivalence().toCode())));
ConceptMapEquivalence eq = element.getConceptMapGroupElementTargets().get(0).getEquivalence();
if (eq != null) {
translationMatch.setEquivalence(VersionConvertor_40_50.convertCode(new CodeType(eq.toCode())));
}
}
retVal.addMatch(translationMatch);

View File

@ -35,12 +35,13 @@ import static org.apache.commons.lang3.StringUtils.length;
@Entity
@Table(name = "TRM_CONCEPT_MAP", uniqueConstraints = {
@UniqueConstraint(name = "IDX_CONCEPT_MAP_URL", columnNames = {"URL"})
@UniqueConstraint(name = "IDX_CONCEPT_MAP_URL", columnNames = {"URL", "VER"})
})
public class TermConceptMap implements Serializable {
private static final long serialVersionUID = 1L;
static final int MAX_URL_LENGTH = 200;
static final int MAX_VER_LENGTH = 200;
@Id()
@SequenceGenerator(name = "SEQ_CONCEPT_MAP_PID", sequenceName = "SEQ_CONCEPT_MAP_PID")
@ -64,6 +65,9 @@ public class TermConceptMap 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;
@OneToMany(mappedBy = "myConceptMap")
private List<TermConceptMapGroup> myConceptMapGroups;
@ -131,6 +135,17 @@ public class TermConceptMap implements Serializable {
return this;
}
public String getVersion() {
return myVersion;
}
public TermConceptMap setVersion(String theVersion) {
ValidateUtil.isNotTooLongOrThrowIllegalArgument(theVersion, MAX_VER_LENGTH,
"Version exceeds maximum length (" + MAX_VER_LENGTH + "): " + length(theVersion));
myVersion = theVersion;
return this;
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
@ -140,6 +155,7 @@ public class TermConceptMap implements Serializable {
.append("mySource", mySource)
.append("myTarget", myTarget)
.append("myUrl", myUrl)
.append("myVersion", myVersion)
.append(myConceptMapGroups != null ? ("myConceptMapGroups - size=" + myConceptMapGroups.size()) : ("myConceptMapGroups=(null)"))
.toString();
}

View File

@ -54,6 +54,8 @@ public class BaseJpaResourceProviderConceptMapDstu3 extends JpaResourceProviderD
public Parameters translate(
HttpServletRequest theServletRequest,
@IdParam(optional = true) IdType theId,
@OperationParam(name = "url", min = 0, max = 1) UriType theUrl,
@OperationParam(name = "conceptMapVersion", min = 0, max = 1) StringType theConceptMapVersion,
@OperationParam(name = "code", min = 0, max = 1) CodeType theSourceCode,
@OperationParam(name = "system", min = 0, max = 1) UriType theSourceCodeSystem,
@OperationParam(name = "version", min = 0, max = 1) StringType theSourceCodeSystemVersion,
@ -65,6 +67,10 @@ public class BaseJpaResourceProviderConceptMapDstu3 extends JpaResourceProviderD
@OperationParam(name = "reverse", min = 0, max = 1) BooleanType theReverse,
RequestDetails theRequestDetails
) {
boolean haveUrl = theUrl != null
&& theUrl.hasValue();
boolean haveConceptMapVersion = theConceptMapVersion != null
&& theConceptMapVersion.hasValue();
boolean haveSourceCode = theSourceCode != null
&& theSourceCode.hasValue();
boolean haveSourceCodeSystem = theSourceCodeSystem != null
@ -93,6 +99,15 @@ public class BaseJpaResourceProviderConceptMapDstu3 extends JpaResourceProviderD
TranslationRequest translationRequest = new TranslationRequest();
try {
if (haveUrl) {
translationRequest.setUrl(VersionConvertor_30_40.convertUri(theUrl));
}
if (haveConceptMapVersion) {
translationRequest.setConceptMapVersion(VersionConvertor_30_40.convertString(theConceptMapVersion));
}
// Convert from DSTU3 to R4
if (haveSourceCode) {
translationRequest.getCodeableConcept().addCoding().setCodeElement(VersionConvertor_30_40.convertCode(theSourceCode));

View File

@ -49,6 +49,8 @@ public class BaseJpaResourceProviderConceptMapR4 extends JpaResourceProviderR4<C
public Parameters translate(
HttpServletRequest theServletRequest,
@IdParam(optional = true) IdType theId,
@OperationParam(name = "url", min = 0, max = 1) UriType theUrl,
@OperationParam(name = "conceptMapVersion", min = 0, max = 1) StringType theConceptMapVersion,
@OperationParam(name = "code", min = 0, max = 1) CodeType theSourceCode,
@OperationParam(name = "system", min = 0, max = 1) UriType theSourceCodeSystem,
@OperationParam(name = "version", min = 0, max = 1) StringType theSourceCodeSystemVersion,
@ -60,6 +62,10 @@ public class BaseJpaResourceProviderConceptMapR4 extends JpaResourceProviderR4<C
@OperationParam(name = "reverse", min = 0, max = 1) BooleanType theReverse,
RequestDetails theRequestDetails
) {
boolean haveUrl = theUrl != null
&& theUrl.hasValue();
boolean haveConceptMapVersion = theConceptMapVersion != null
&& theConceptMapVersion.hasValue();
boolean haveSourceCode = theSourceCode != null
&& theSourceCode.hasCode();
boolean haveSourceCodeSystem = theSourceCodeSystem != null
@ -88,6 +94,14 @@ public class BaseJpaResourceProviderConceptMapR4 extends JpaResourceProviderR4<C
TranslationRequest translationRequest = new TranslationRequest();
if (haveUrl) {
translationRequest.setUrl(theUrl);
}
if (haveConceptMapVersion) {
translationRequest.setConceptMapVersion(theConceptMapVersion);
}
if (haveSourceCode) {
translationRequest.getCodeableConcept().addCoding().setCodeElement(theSourceCode);

View File

@ -50,6 +50,8 @@ public class BaseJpaResourceProviderConceptMapR5 extends JpaResourceProviderR5<C
public Parameters translate(
HttpServletRequest theServletRequest,
@IdParam(optional = true) IdType theId,
@OperationParam(name = "url", min = 0, max = 1) UriType theUrl,
@OperationParam(name = "conceptMapVersion", min = 0, max = 1) StringType theConceptMapVersion,
@OperationParam(name = "code", min = 0, max = 1) CodeType theSourceCode,
@OperationParam(name = "system", min = 0, max = 1) UriType theSourceCodeSystem,
@OperationParam(name = "version", min = 0, max = 1) StringType theSourceCodeSystemVersion,
@ -61,6 +63,10 @@ public class BaseJpaResourceProviderConceptMapR5 extends JpaResourceProviderR5<C
@OperationParam(name = "reverse", min = 0, max = 1) BooleanType theReverse,
RequestDetails theRequestDetails
) {
boolean haveUrl = theUrl != null
&& theUrl.hasValue();
boolean haveConceptMapVersion = theConceptMapVersion != null
&& theConceptMapVersion.hasValue();
boolean haveSourceCode = theSourceCode != null
&& theSourceCode.hasCode();
boolean haveSourceCodeSystem = theSourceCodeSystem != null
@ -89,6 +95,14 @@ public class BaseJpaResourceProviderConceptMapR5 extends JpaResourceProviderR5<C
TranslationRequest translationRequest = new TranslationRequest();
if (haveUrl) {
translationRequest.setUrl(VersionConvertor_40_50.convertUri(theUrl));
}
if (haveConceptMapVersion) {
translationRequest.setConceptMapVersion(VersionConvertor_40_50.convertString(theConceptMapVersion));
}
if (haveSourceCode) {
translationRequest.getCodeableConcept().addCoding().setCodeElement(VersionConvertor_40_50.convertCode(theSourceCode));

View File

@ -131,6 +131,7 @@ import org.quartz.JobExecutionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
@ -1514,6 +1515,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
TermConceptMap termConceptMap = new TermConceptMap();
termConceptMap.setResource(theResourceTable);
termConceptMap.setUrl(theConceptMap.getUrl());
termConceptMap.setVersion(theConceptMap.getVersion());
String source = theConceptMap.hasSourceUriType() ? theConceptMap.getSourceUriType().getValueAsString() : null;
String target = theConceptMap.hasTargetUriType() ? theConceptMap.getTargetUriType().getValueAsString() : null;
@ -1547,7 +1549,13 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
* Do the upload.
*/
String conceptMapUrl = termConceptMap.getUrl();
Optional<TermConceptMap> optionalExistingTermConceptMapByUrl = myConceptMapDao.findTermConceptMapByUrl(conceptMapUrl);
String conceptMapVersion = termConceptMap.getVersion();
Optional<TermConceptMap> optionalExistingTermConceptMapByUrl = null;
if (isBlank(conceptMapVersion)) {
optionalExistingTermConceptMapByUrl = myConceptMapDao.findTermConceptMapByUrlAndNullVersion(conceptMapUrl);
} else {
optionalExistingTermConceptMapByUrl = myConceptMapDao.findTermConceptMapByUrlAndVersion(conceptMapUrl, conceptMapVersion);
}
if (!optionalExistingTermConceptMapByUrl.isPresent()) {
try {
if (isNotBlank(source)) {
@ -1628,13 +1636,22 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
} else {
TermConceptMap existingTermConceptMap = optionalExistingTermConceptMapByUrl.get();
String msg = myContext.getLocalizer().getMessage(
BaseTermReadSvcImpl.class,
"cannotCreateDuplicateConceptMapUrl",
conceptMapUrl,
existingTermConceptMap.getResource().getIdDt().toUnqualifiedVersionless().getValue());
if (isBlank(conceptMapVersion)) {
String msg = myContext.getLocalizer().getMessage(
BaseTermReadSvcImpl.class,
"cannotCreateDuplicateConceptMapUrl",
conceptMapUrl,
existingTermConceptMap.getResource().getIdDt().toUnqualifiedVersionless().getValue());
throw new UnprocessableEntityException(msg);
throw new UnprocessableEntityException(msg);
} else {
String msg = myContext.getLocalizer().getMessage(
BaseTermReadSvcImpl.class,
"cannotCreateDuplicateConceptMapUrlAndVersion",
conceptMapUrl, conceptMapVersion,
existingTermConceptMap.getResource().getIdDt().toUnqualifiedVersionless().getValue());
throw new UnprocessableEntityException(msg);
}
}
ourLog.info("Done storing TermConceptMap[{}] for {}", termConceptMap.getId(), theConceptMap.getIdElement().toVersionless().getValueAsString());
@ -1920,6 +1937,12 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
List<TermConceptMapGroupElementTarget> cachedTargets;
ArrayList<Predicate> predicates;
Coding coding;
//-- get the latest ConceptMapVersion if theTranslationRequest has url, but ConceptMapVersion
String latestConceptMapVersion = null;
if (theTranslationRequest.hasUrl() && !theTranslationRequest.hasConceptMapVersion())
latestConceptMapVersion = getLatestConceptMapVersion(theTranslationRequest);
for (TranslationQuery translationQuery : translationQueries) {
cachedTargets = myTranslationCache.getIfPresent(translationQuery);
if (cachedTargets == null) {
@ -1946,6 +1969,21 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
predicates.add(criteriaBuilder.equal(groupJoin.get("myTarget"), translationQuery.getTargetSystem().getValueAsString()));
}
if (translationQuery.hasUrl()) {
predicates.add(criteriaBuilder.equal(conceptMapJoin.get("myUrl"), translationQuery.getUrl().getValueAsString()));
if (translationQuery.hasConceptMapVersion()) {
// both url and conceptMapVersion
predicates.add(criteriaBuilder.equal(conceptMapJoin.get("myVersion"), translationQuery.getConceptMapVersion().getValueAsString()));
} else {
if (StringUtils.isNotBlank(latestConceptMapVersion)) {
// only url and use latestConceptMapVersion
predicates.add(criteriaBuilder.equal(conceptMapJoin.get("myVersion"), latestConceptMapVersion));
} else {
predicates.add(criteriaBuilder.isNull(conceptMapJoin.get("myVersion")));
}
}
}
if (translationQuery.hasSource()) {
predicates.add(criteriaBuilder.equal(conceptMapJoin.get("mySource"), translationQuery.getSource().getValueAsString()));
}
@ -2003,6 +2041,12 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
List<TermConceptMapGroupElement> cachedElements;
ArrayList<Predicate> predicates;
Coding coding;
//-- get the latest ConceptMapVersion if theTranslationRequest has url, but ConceptMapVersion
String latestConceptMapVersion = null;
if (theTranslationRequest.hasUrl() && !theTranslationRequest.hasConceptMapVersion())
latestConceptMapVersion = getLatestConceptMapVersion(theTranslationRequest);
for (TranslationQuery translationQuery : translationQueries) {
cachedElements = myTranslationWithReverseCache.getIfPresent(translationQuery);
if (cachedElements == null) {
@ -2029,6 +2073,21 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
predicates.add(criteriaBuilder.equal(groupJoin.get("myTargetVersion"), coding.getVersion()));
}
if (translationQuery.hasUrl()) {
predicates.add(criteriaBuilder.equal(conceptMapJoin.get("myUrl"), translationQuery.getUrl().getValueAsString()));
if (translationQuery.hasConceptMapVersion()) {
// both url and conceptMapVersion
predicates.add(criteriaBuilder.equal(conceptMapJoin.get("myVersion"), translationQuery.getConceptMapVersion().getValueAsString()));
} else {
if (StringUtils.isNotBlank(latestConceptMapVersion)) {
// only url and use latestConceptMapVersion
predicates.add(criteriaBuilder.equal(conceptMapJoin.get("myVersion"), latestConceptMapVersion));
} else {
predicates.add(criteriaBuilder.isNull(conceptMapJoin.get("myVersion")));
}
}
}
if (translationQuery.hasTargetSystem()) {
predicates.add(criteriaBuilder.equal(groupJoin.get("mySource"), translationQuery.getTargetSystem().getValueAsString()));
}
@ -2094,6 +2153,20 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
throw new ResourceNotFoundException("Unknown ValueSet: " + UrlUtil.escapeUrlParam(theValueSet));
}
// Special case for the translate operation with url and without
// conceptMapVersion, find the latest conecptMapVersion
private String getLatestConceptMapVersion(TranslationRequest theTranslationRequest) {
Pageable page = PageRequest.of(0, 1);
List<TermConceptMap> theConceptMapList = myConceptMapDao.getTermConceptMapEntitiesByUrlOrderByVersion(page,
theTranslationRequest.getUrl().asStringValue());
if (!theConceptMapList.isEmpty()) {
return theConceptMapList.get(0).getVersion();
}
return null;
}
@Override
@Transactional
public CodeValidationResult validateCodeInValueSet(ValidationSupportContext theValidationSupportContext, ConceptValidationOptions theOptions, String theCodeSystem, String theCode, String theDisplay, @Nonnull IBaseResource theValueSet) {

View File

@ -1,23 +1,32 @@
package ca.uhn.fhir.jpa.dao.dstu3;
import ca.uhn.fhir.jpa.api.model.TranslationMatch;
import ca.uhn.fhir.jpa.api.model.TranslationRequest;
import ca.uhn.fhir.jpa.api.model.TranslationResult;
import ca.uhn.fhir.util.TestUtil;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.List;
import java.util.Optional;
import org.hl7.fhir.dstu3.model.ConceptMap;
import org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.Coding;
import org.hl7.fhir.r4.model.Enumerations;
import org.hl7.fhir.r4.model.UriType;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import static org.junit.jupiter.api.Assertions.*;
import ca.uhn.fhir.jpa.api.model.TranslationMatch;
import ca.uhn.fhir.jpa.api.model.TranslationRequest;
import ca.uhn.fhir.jpa.api.model.TranslationResult;
import ca.uhn.fhir.jpa.entity.TermConceptMap;
public class FhirResourceDaoDstu3ConceptMapTest extends BaseJpaDstu3Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu3ConceptMapTest.class);
@ -98,4 +107,74 @@ public class FhirResourceDaoDstu3ConceptMapTest extends BaseJpaDstu3Test {
});
}
@Test
public void testConcaptMapFindTermConceptMapByUrl() {
Pageable page = PageRequest.of(0, 1);
List<TermConceptMap> theExpConceptMapList = myTermConceptMapDao.getTermConceptMapEntitiesByUrlOrderByVersion(page, CM_URL);
assertEquals(1, theExpConceptMapList.size());
assertEquals(CM_URL, theExpConceptMapList.get(0).getUrl());
}
@Test
public void testConcaptMapTwoConceptMapWithSameUrlDifferentVersion() {
String theUrl = "http://loinc.org/property/analyte-suffix";
ConceptMap theConceptMap1 = new ConceptMap();
ConceptMap theConceptMap2 = new ConceptMap();
theConceptMap1.setUrl(theUrl).setStatus(PublicationStatus.ACTIVE).setName("name1").setVersion("v1");
theConceptMap2.setUrl(theUrl).setStatus(PublicationStatus.ACTIVE).setName("name2").setVersion("v2");
myConceptMapDao.create(theConceptMap1);
myConceptMapDao.create(theConceptMap2);
Optional<TermConceptMap> theExpConceptMapV1 = myTermConceptMapDao.findTermConceptMapByUrlAndVersion(theUrl, "v1");
Optional<TermConceptMap> theExpConceptMapV2 = myTermConceptMapDao.findTermConceptMapByUrlAndVersion(theUrl, "v2");
assertTrue(theExpConceptMapV1.isPresent());
assertEquals(theUrl, theExpConceptMapV1.get().getUrl());
assertEquals("v1", theExpConceptMapV1.get().getVersion());
assertTrue(theExpConceptMapV2.isPresent());
assertEquals(theUrl, theExpConceptMapV2.get().getUrl());
assertEquals("v2", theExpConceptMapV2.get().getVersion());
// should return the latest one which is v2
Pageable page = PageRequest.of(0, 1);
List<TermConceptMap> theExpSecondOne = myTermConceptMapDao.getTermConceptMapEntitiesByUrlOrderByVersion(page, theUrl);
assertEquals(1, theExpSecondOne.size());
assertEquals(theUrl, theExpSecondOne.get(0).getUrl());
assertEquals("v2", theExpSecondOne.get(0).getVersion());
}
@Test
public void testConcaptMapTwoConceptMapWithSameUrlOneWithoutVersion() {
String theUrl = "http://loinc.org/property/analyte-suffix";
ConceptMap theConceptMap1 = new ConceptMap();
ConceptMap theConceptMap2 = new ConceptMap();
theConceptMap1.setUrl(theUrl).setStatus(PublicationStatus.ACTIVE).setName("name1").setVersion("v1");
theConceptMap2.setUrl(theUrl).setStatus(PublicationStatus.ACTIVE).setName("name2");
myConceptMapDao.create(theConceptMap1);
myConceptMapDao.create(theConceptMap2);
Optional<TermConceptMap> theExpConceptMapV1 = myTermConceptMapDao.findTermConceptMapByUrlAndVersion(theUrl, "v1");
assertTrue(theExpConceptMapV1.isPresent());
assertEquals(theUrl, theExpConceptMapV1.get().getUrl());
assertEquals("v1", theExpConceptMapV1.get().getVersion());
// should return the latest one which in this case is not versioned
Pageable page = PageRequest.of(0, 1);
List<TermConceptMap> theExpSecondOne = myTermConceptMapDao.getTermConceptMapEntitiesByUrlOrderByVersion(page, theUrl);
assertEquals(1, theExpSecondOne.size());
assertEquals(theUrl, theExpSecondOne.get(0).getUrl());
assertNull(theExpSecondOne.get(0).getVersion());
}
}

View File

@ -1,31 +1,37 @@
package ca.uhn.fhir.jpa.dao.r4;
import ca.uhn.fhir.jpa.api.model.TranslationMatch;
import ca.uhn.fhir.jpa.api.model.TranslationRequest;
import ca.uhn.fhir.jpa.api.model.TranslationResult;
import ca.uhn.fhir.util.TestUtil;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
import java.util.List;
import java.util.Optional;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.CanonicalType;
import org.hl7.fhir.r4.model.CodeableConcept;
import org.hl7.fhir.r4.model.Coding;
import org.hl7.fhir.r4.model.ConceptMap;
import org.hl7.fhir.r4.model.Enumerations.ConceptMapEquivalence;
import org.hl7.fhir.r4.model.Enumerations.PublicationStatus;
import org.hl7.fhir.r4.model.UriType;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import java.io.IOException;
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 ca.uhn.fhir.jpa.api.model.TranslationMatch;
import ca.uhn.fhir.jpa.api.model.TranslationRequest;
import ca.uhn.fhir.jpa.api.model.TranslationResult;
import ca.uhn.fhir.jpa.entity.TermConceptMap;
public class FhirResourceDaoR4ConceptMapTest extends BaseJpaR4Test {
private static final Logger ourLog = LoggerFactory.getLogger(FhirResourceDaoR4ConceptMapTest.class);
@ -1148,5 +1154,74 @@ public class FhirResourceDaoR4ConceptMapTest extends BaseJpaR4Test {
assertEquals("S52.209A", outcome.getMatches().get(0).getConcept().getCode());
}
@Test
public void testConcaptMapFindTermConceptMapByUrl() {
Pageable page = PageRequest.of(0, 1);
List<TermConceptMap> theExpConceptMapList = myTermConceptMapDao.getTermConceptMapEntitiesByUrlOrderByVersion(page, CM_URL);
assertEquals(1, theExpConceptMapList.size());
assertEquals(CM_URL, theExpConceptMapList.get(0).getUrl());
}
@Test
public void testConcaptMapTwoConceptMapWithSameUrlDifferentVersion() {
String theUrl = "http://loinc.org/property/analyte-suffix";
ConceptMap theConceptMap1 = new ConceptMap();
ConceptMap theConceptMap2 = new ConceptMap();
theConceptMap1.setUrl(theUrl).setStatus(PublicationStatus.ACTIVE).setName("name1").setVersion("v1");
theConceptMap2.setUrl(theUrl).setStatus(PublicationStatus.ACTIVE).setName("name2").setVersion("v2");
myConceptMapDao.create(theConceptMap1);
myConceptMapDao.create(theConceptMap2);
Optional<TermConceptMap> theExpConceptMapV1 = myTermConceptMapDao.findTermConceptMapByUrlAndVersion(theUrl, "v1");
Optional<TermConceptMap> theExpConceptMapV2 = myTermConceptMapDao.findTermConceptMapByUrlAndVersion(theUrl, "v2");
assertTrue(theExpConceptMapV1.isPresent());
assertEquals(theUrl, theExpConceptMapV1.get().getUrl());
assertEquals("v1", theExpConceptMapV1.get().getVersion());
assertTrue(theExpConceptMapV2.isPresent());
assertEquals(theUrl, theExpConceptMapV2.get().getUrl());
assertEquals("v2", theExpConceptMapV2.get().getVersion());
// should return the latest one which is v2
Pageable page = PageRequest.of(0, 1);
List<TermConceptMap> theExpSecondOne = myTermConceptMapDao.getTermConceptMapEntitiesByUrlOrderByVersion(page, theUrl);
assertEquals(1, theExpSecondOne.size());
assertEquals(theUrl, theExpSecondOne.get(0).getUrl());
assertEquals("v2", theExpSecondOne.get(0).getVersion());
}
@Test
public void testConcaptMapTwoConceptMapWithSameUrlOneWithoutVersion() {
String theUrl = "http://loinc.org/property/analyte-suffix";
ConceptMap theConceptMap1 = new ConceptMap();
ConceptMap theConceptMap2 = new ConceptMap();
theConceptMap1.setUrl(theUrl).setStatus(PublicationStatus.ACTIVE).setName("name1").setVersion("v1");
theConceptMap2.setUrl(theUrl).setStatus(PublicationStatus.ACTIVE).setName("name2");
myConceptMapDao.create(theConceptMap1);
myConceptMapDao.create(theConceptMap2);
Optional<TermConceptMap> theExpConceptMapV1 = myTermConceptMapDao.findTermConceptMapByUrlAndVersion(theUrl, "v1");
assertTrue(theExpConceptMapV1.isPresent());
assertEquals(theUrl, theExpConceptMapV1.get().getUrl());
assertEquals("v1", theExpConceptMapV1.get().getVersion());
// should return the latest one which is v2
Pageable page = PageRequest.of(0, 1);
List<TermConceptMap> theExpSecondOne = myTermConceptMapDao.getTermConceptMapEntitiesByUrlOrderByVersion(page, theUrl);
assertEquals(1, theExpSecondOne.size());
assertEquals(theUrl, theExpSecondOne.get(0).getUrl());
assertNull(theExpSecondOne.get(0).getVersion());
}
}

View File

@ -1,18 +1,30 @@
package ca.uhn.fhir.jpa.provider.dstu3;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.util.TestUtil;
import org.hl7.fhir.dstu3.model.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.hl7.fhir.dstu3.model.BooleanType;
import org.hl7.fhir.dstu3.model.CodeType;
import org.hl7.fhir.dstu3.model.Coding;
import org.hl7.fhir.dstu3.model.ConceptMap;
import org.hl7.fhir.dstu3.model.ConceptMap.ConceptMapGroupComponent;
import org.hl7.fhir.dstu3.model.ConceptMap.SourceElementComponent;
import org.hl7.fhir.dstu3.model.ConceptMap.TargetElementComponent;
import org.hl7.fhir.dstu3.model.Enumerations.ConceptMapEquivalence;
import org.hl7.fhir.dstu3.model.Parameters;
import org.hl7.fhir.dstu3.model.Parameters.ParametersParameterComponent;
import org.hl7.fhir.dstu3.model.StringType;
import org.hl7.fhir.dstu3.model.UriType;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;
import static org.junit.jupiter.api.Assertions.*;
import ca.uhn.fhir.rest.api.MethodOutcome;
public class ResourceProviderDstu3ConceptMapTest extends BaseResourceProviderDstu3Test {
private static final Logger ourLog = LoggerFactory.getLogger(ResourceProviderDstu3ConceptMapTest.class);
@ -114,4 +126,550 @@ public class ResourceProviderDstu3ConceptMapTest extends BaseResourceProviderDst
part = getPartByName(param, "source");
assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
}
@Test
public void testTranslateWithConceptMapUrlAndVersion() {
String url = "http://url";
createConceptMap(url, "v1", "12222", "Target Code 12222");
createConceptMap(url, "v2", "13333", "Target Code 13333");
Parameters inParams = new Parameters();
inParams.addParameter().setName("url").setValue(new UriType(url));
inParams.addParameter().setName("conceptMapVersion").setValue(new StringType("v2"));
inParams.addParameter().setName("system").setValue(new UriType(CS_URL));
inParams.addParameter().setName("targetsystem").setValue(new UriType(CS_URL_2));
inParams.addParameter().setName("code").setValue(new CodeType("11111"));
ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
Parameters respParams = ourClient
.operation()
.onType(ConceptMap.class)
.named("translate")
.withParameters(inParams)
.execute();
ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
ParametersParameterComponent param = getParameterByName(respParams, "result");
assertTrue(((BooleanType) param.getValue()).booleanValue());
param = getParameterByName(respParams, "message");
assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
assertEquals(1, getNumberOfParametersByName(respParams, "match"));
param = getParametersByName(respParams, "match").get(0);
assertEquals(3, param.getPart().size());
ParametersParameterComponent part = getPartByName(param, "equivalence");
assertEquals("equal", ((CodeType) part.getValue()).getValueAsString());
part = getPartByName(param, "concept");
Coding coding = (Coding) part.getValue();
assertEquals("13333", coding.getCode());
assertEquals("Target Code 13333", coding.getDisplay());
assertFalse(coding.getUserSelected());
assertEquals(CS_URL_2, coding.getSystem());
assertEquals("Version 2", coding.getVersion());
part = getPartByName(param, "source");
assertEquals(url, ((UriType) part.getValue()).getValueAsString());
}
@Test
public void testTranslateWithVersionedConcaptMapUrl_v2() {
String url = "http://url";
createConceptMap(url, "v1", "12222", "Target Code 12222");
createConceptMap(url, "v2", "13333", "Target Code 13333");
// Call translate with ConceptMap v2.
Parameters inParams = new Parameters();
inParams.addParameter().setName("url").setValue(new UriType(url));
inParams.addParameter().setName("conceptMapVersion").setValue(new StringType("v2"));
inParams.addParameter().setName("system").setValue(new UriType(CS_URL));
inParams.addParameter().setName("targetsystem").setValue(new UriType(CS_URL_2));
inParams.addParameter().setName("code").setValue(new CodeType("11111"));
ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
Parameters respParams = ourClient
.operation()
.onType(ConceptMap.class)
.named("translate")
.withParameters(inParams)
.execute();
ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
// Should return v2 since v2 specified.
ParametersParameterComponent param = getParameterByName(respParams, "result");
assertTrue(((BooleanType) param.getValue()).booleanValue());
param = getParameterByName(respParams, "message");
assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
assertEquals(1, getNumberOfParametersByName(respParams, "match"));
param = getParametersByName(respParams, "match").get(0);
assertEquals(3, param.getPart().size());
ParametersParameterComponent part = getPartByName(param, "equivalence");
assertEquals("equal", ((CodeType) part.getValue()).getValueAsString());
part = getPartByName(param, "concept");
Coding coding = (Coding) part.getValue();
assertEquals("13333", coding.getCode());
assertEquals("Target Code 13333", coding.getDisplay());
assertFalse(coding.getUserSelected());
assertEquals(CS_URL_2, coding.getSystem());
assertEquals("Version 2", coding.getVersion());
part = getPartByName(param, "source");
assertEquals(url, ((UriType) part.getValue()).getValueAsString());
}
@Test
public void testTranslateWithVersionedConcaptMapUrl_v1() {
String url = "http://url";
createConceptMap(url, "v1", "12222", "Target Code 12222");
createConceptMap(url, "v2", "13333", "Target Code 13333");
// Call translate with ConceptMap v1.
Parameters inParams = new Parameters();
inParams.addParameter().setName("url").setValue(new UriType(url));
inParams.addParameter().setName("conceptMapVersion").setValue(new StringType("v1"));
inParams.addParameter().setName("system").setValue(new UriType(CS_URL));
inParams.addParameter().setName("targetsystem").setValue(new UriType(CS_URL_2));
inParams.addParameter().setName("code").setValue(new CodeType("11111"));
ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
Parameters respParams = ourClient
.operation()
.onType(ConceptMap.class)
.named("translate")
.withParameters(inParams)
.execute();
ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
// Should return v1 since v1 specified.
ParametersParameterComponent param = getParameterByName(respParams, "result");
assertTrue(((BooleanType) param.getValue()).booleanValue());
param = getParameterByName(respParams, "message");
assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
assertEquals(1, getNumberOfParametersByName(respParams, "match"));
param = getParametersByName(respParams, "match").get(0);
assertEquals(3, param.getPart().size());
ParametersParameterComponent part = getPartByName(param, "equivalence");
assertEquals("equal", ((CodeType) part.getValue()).getValueAsString());
part = getPartByName(param, "concept");
Coding coding = (Coding) part.getValue();
assertEquals("12222", coding.getCode());
assertEquals("Target Code 12222", coding.getDisplay());
assertFalse(coding.getUserSelected());
assertEquals(CS_URL_2, coding.getSystem());
assertEquals("Version 2", coding.getVersion());
part = getPartByName(param, "source");
assertEquals(url, ((UriType) part.getValue()).getValueAsString());
}
@Test
public void testTranslateWithVersionedConcaptMapUrl_NoVersion() {
String url = "http://url";
createConceptMap(url, "v1", "12222", "Target Code 12222");
createConceptMap(url, "v2", "13333", "Target Code 13333");
// Call translate with no ConceptMap version.
Parameters inParams = new Parameters();
inParams.addParameter().setName("url").setValue(new UriType(url));
inParams.addParameter().setName("system").setValue(new UriType(CS_URL));
inParams.addParameter().setName("targetsystem").setValue(new UriType(CS_URL_2));
inParams.addParameter().setName("code").setValue(new CodeType("11111"));
ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
Parameters respParams = ourClient
.operation()
.onType(ConceptMap.class)
.named("translate")
.withParameters(inParams)
.execute();
ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
// Should return v2 since v2 is the most recently updated version.
ParametersParameterComponent param = getParameterByName(respParams, "result");
assertTrue(((BooleanType) param.getValue()).booleanValue());
param = getParameterByName(respParams, "message");
assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
assertEquals(1, getNumberOfParametersByName(respParams, "match"));
param = getParametersByName(respParams, "match").get(0);
assertEquals(3, param.getPart().size());
ParametersParameterComponent part = getPartByName(param, "equivalence");
assertEquals("equal", ((CodeType) part.getValue()).getValueAsString());
part = getPartByName(param, "concept");
Coding coding = (Coding) part.getValue();
assertEquals("13333", coding.getCode());
assertEquals("Target Code 13333", coding.getDisplay());
assertFalse(coding.getUserSelected());
assertEquals(CS_URL_2, coding.getSystem());
assertEquals("Version 2", coding.getVersion());
part = getPartByName(param, "source");
assertEquals(url, ((UriType) part.getValue()).getValueAsString());
}
@Test
public void testTranslateWithVersionedConcaptMapUrl_NoVersion_null_v1() {
String url = "http://url";
createConceptMap(url, null, "12222", "Target Code 12222"); // first version is null
createConceptMap(url, "v2", "13333", "Target Code 13333");
// Call translate with no ConceptMap version.
Parameters inParams = new Parameters();
inParams.addParameter().setName("url").setValue(new UriType(url));
inParams.addParameter().setName("system").setValue(new UriType(CS_URL));
inParams.addParameter().setName("targetsystem").setValue(new UriType(CS_URL_2));
inParams.addParameter().setName("code").setValue(new CodeType("11111"));
ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
Parameters respParams = ourClient
.operation()
.onType(ConceptMap.class)
.named("translate")
.withParameters(inParams)
.execute();
ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
// Should return v2 since v2 is the most recently updated version.
ParametersParameterComponent param = getParameterByName(respParams, "result");
assertTrue(((BooleanType) param.getValue()).booleanValue());
param = getParameterByName(respParams, "message");
assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
assertEquals(1, getNumberOfParametersByName(respParams, "match"));
param = getParametersByName(respParams, "match").get(0);
assertEquals(3, param.getPart().size());
ParametersParameterComponent part = getPartByName(param, "equivalence");
assertEquals("equal", ((CodeType) part.getValue()).getValueAsString());
part = getPartByName(param, "concept");
Coding coding = (Coding) part.getValue();
assertEquals("13333", coding.getCode());
assertEquals("Target Code 13333", coding.getDisplay());
assertFalse(coding.getUserSelected());
assertEquals(CS_URL_2, coding.getSystem());
assertEquals("Version 2", coding.getVersion());
part = getPartByName(param, "source");
assertEquals(url, ((UriType) part.getValue()).getValueAsString());
}
@Test
public void testTranslateWithVersionedConcaptMapUrl_NoVersion_null_v2() {
String url = "http://url";
createConceptMap(url, "v1", "12222", "Target Code 12222");
createConceptMap(url, null, "13333", "Target Code 13333"); // second version is null
// Call translate with no ConceptMap version.
Parameters inParams = new Parameters();
inParams.addParameter().setName("url").setValue(new UriType(url));
inParams.addParameter().setName("system").setValue(new UriType(CS_URL));
inParams.addParameter().setName("targetsystem").setValue(new UriType(CS_URL_2));
inParams.addParameter().setName("code").setValue(new CodeType("11111"));
ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
Parameters respParams = ourClient
.operation()
.onType(ConceptMap.class)
.named("translate")
.withParameters(inParams)
.execute();
ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
// Should return v2 since v2 is the most recently updated version.
ParametersParameterComponent param = getParameterByName(respParams, "result");
assertTrue(((BooleanType) param.getValue()).booleanValue());
param = getParameterByName(respParams, "message");
assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
assertEquals(1, getNumberOfParametersByName(respParams, "match"));
param = getParametersByName(respParams, "match").get(0);
assertEquals(3, param.getPart().size());
ParametersParameterComponent part = getPartByName(param, "equivalence");
assertEquals("equal", ((CodeType) part.getValue()).getValueAsString());
part = getPartByName(param, "concept");
Coding coding = (Coding) part.getValue();
assertEquals("13333", coding.getCode());
assertEquals("Target Code 13333", coding.getDisplay());
assertFalse(coding.getUserSelected());
assertEquals(CS_URL_2, coding.getSystem());
assertEquals("Version 2", coding.getVersion());
part = getPartByName(param, "source");
assertEquals(url, ((UriType) part.getValue()).getValueAsString());
}
@Test
public void testTranslateWithConceptMap_WrongUrl_NoVersion() {
String url = "http://url";
createConceptMap(url, "v1", "12222", "Target Code 12222");
createConceptMap(url, "v2", "13333", "Target Code 13333");
Parameters inParams = new Parameters();
inParams.addParameter().setName("url").setValue(new UriType("http://invalid.url.com")); // no exsits url
inParams.addParameter().setName("system").setValue(new UriType(CS_URL));
inParams.addParameter().setName("targetsystem").setValue(new UriType(CS_URL_2));
inParams.addParameter().setName("code").setValue(new CodeType("11111"));
ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
Parameters respParams = ourClient
.operation()
.onType(ConceptMap.class)
.named("translate")
.withParameters(inParams)
.execute();
ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
ParametersParameterComponent param = getParameterByName(respParams, "result");
assertFalse(((BooleanType) param.getValue()).booleanValue());
param = getParameterByName(respParams, "message");
assertEquals("No matches found!", ((StringType) param.getValue()).getValueAsString());
}
@Test
public void testTranslateWithReverseConceptMapUrlAndVersion() {
String url = "http://url";
createReverseConceptMap(url, "v1", "12222", "Source Code 12222");
createReverseConceptMap(url, "v2", "13333", "Source Code 13333");
Parameters inParams = new Parameters();
inParams.addParameter().setName("url").setValue(new UriType(url));
inParams.addParameter().setName("conceptMapVersion").setValue(new StringType("v2"));
inParams.addParameter().setName("code").setValue(new CodeType("11111"));
inParams.addParameter().setName("reverse").setValue(new BooleanType(true));
ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
Parameters respParams = ourClient
.operation()
.onType(ConceptMap.class)
.named("translate")
.withParameters(inParams)
.execute();
ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
ParametersParameterComponent param = getParameterByName(respParams, "result");
assertTrue(((BooleanType) param.getValue()).booleanValue());
param = getParameterByName(respParams, "message");
assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
assertEquals(1, getNumberOfParametersByName(respParams, "match"));
param = getParametersByName(respParams, "match").get(0);
assertEquals(2, param.getPart().size());
ParametersParameterComponent part = getPartByName(param, "concept");
Coding coding = (Coding) part.getValue();
assertEquals("13333", coding.getCode());
assertEquals("Source Code 13333", coding.getDisplay());
assertFalse(coding.getUserSelected());
assertEquals(CS_URL, coding.getSystem());
assertEquals("Version 1", coding.getVersion());
part = getPartByName(param, "source");
assertEquals(url, ((UriType) part.getValue()).getValueAsString());
}
@Test
public void testTranslateWithReverseConceptMapUrl_NoVersion() {
String url = "http://url";
createReverseConceptMap(url, "v1", "12222", "Source Code 12222");
createReverseConceptMap(url, "v2", "13333", "Source Code 13333");
Parameters inParams = new Parameters();
inParams.addParameter().setName("url").setValue(new UriType(url));
inParams.addParameter().setName("code").setValue(new CodeType("11111"));
inParams.addParameter().setName("reverse").setValue(new BooleanType(true));
ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
Parameters respParams = ourClient
.operation()
.onType(ConceptMap.class)
.named("translate")
.withParameters(inParams)
.execute();
ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
ParametersParameterComponent param = getParameterByName(respParams, "result");
assertTrue(((BooleanType) param.getValue()).booleanValue());
param = getParameterByName(respParams, "message");
assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
assertEquals(1, getNumberOfParametersByName(respParams, "match"));
param = getParametersByName(respParams, "match").get(0);
assertEquals(2, param.getPart().size());
ParametersParameterComponent part = getPartByName(param, "concept");
Coding coding = (Coding) part.getValue();
assertEquals("13333", coding.getCode());
assertEquals("Source Code 13333", coding.getDisplay());
assertFalse(coding.getUserSelected());
assertEquals(CS_URL, coding.getSystem());
assertEquals("Version 1", coding.getVersion());
part = getPartByName(param, "source");
assertEquals(url, ((UriType) part.getValue()).getValueAsString());
}
@Test
public void testTranslateWithReverseConceptMapUrl_NoVersion_null_v1() {
String url = "http://url";
createReverseConceptMap(url, null, "12222", "Source Code 12222");
createReverseConceptMap(url, "v2", "13333", "Source Code 13333");
Parameters inParams = new Parameters();
inParams.addParameter().setName("url").setValue(new UriType(url));
inParams.addParameter().setName("code").setValue(new CodeType("11111"));
inParams.addParameter().setName("reverse").setValue(new BooleanType(true));
ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
Parameters respParams = ourClient
.operation()
.onType(ConceptMap.class)
.named("translate")
.withParameters(inParams)
.execute();
ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
ParametersParameterComponent param = getParameterByName(respParams, "result");
assertTrue(((BooleanType) param.getValue()).booleanValue());
param = getParameterByName(respParams, "message");
assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
assertEquals(1, getNumberOfParametersByName(respParams, "match"));
param = getParametersByName(respParams, "match").get(0);
assertEquals(2, param.getPart().size());
ParametersParameterComponent part = getPartByName(param, "concept");
Coding coding = (Coding) part.getValue();
assertEquals("13333", coding.getCode());
assertEquals("Source Code 13333", coding.getDisplay());
assertFalse(coding.getUserSelected());
assertEquals(CS_URL, coding.getSystem());
assertEquals("Version 1", coding.getVersion());
part = getPartByName(param, "source");
assertEquals(url, ((UriType) part.getValue()).getValueAsString());
}
@Test
public void testTranslateWithReverseConceptMapUrl_NoVersion_null_v2() {
String url = "http://url";
createReverseConceptMap(url, "v1", "12222", "Source Code 12222");
createReverseConceptMap(url, null, "13333", "Source Code 13333");
Parameters inParams = new Parameters();
inParams.addParameter().setName("url").setValue(new UriType(url));
inParams.addParameter().setName("code").setValue(new CodeType("11111"));
inParams.addParameter().setName("reverse").setValue(new BooleanType(true));
ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
Parameters respParams = ourClient
.operation()
.onType(ConceptMap.class)
.named("translate")
.withParameters(inParams)
.execute();
ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
ParametersParameterComponent param = getParameterByName(respParams, "result");
assertTrue(((BooleanType) param.getValue()).booleanValue());
param = getParameterByName(respParams, "message");
assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
assertEquals(1, getNumberOfParametersByName(respParams, "match"));
param = getParametersByName(respParams, "match").get(0);
assertEquals(2, param.getPart().size());
ParametersParameterComponent part = getPartByName(param, "concept");
Coding coding = (Coding) part.getValue();
assertEquals("13333", coding.getCode());
assertEquals("Source Code 13333", coding.getDisplay());
assertFalse(coding.getUserSelected());
assertEquals(CS_URL, coding.getSystem());
assertEquals("Version 1", coding.getVersion());
part = getPartByName(param, "source");
assertEquals(url, ((UriType) part.getValue()).getValueAsString());
}
private void createConceptMap(String url, String version, String targetCode, String targetDisplay) {
ConceptMap conceptMap = new ConceptMap();
conceptMap.setUrl(url).setVersion(version).setSource(new UriType(VS_URL)).setTarget(new UriType(VS_URL_2));
ConceptMapGroupComponent group1 = conceptMap.addGroup();
group1.setSource(CS_URL).setSourceVersion("Version 1").setTarget(CS_URL_2).setTargetVersion("Version 2");
SourceElementComponent element1 = group1.addElement();
element1.setCode("11111").setDisplay("Source Code 11111");
TargetElementComponent target1 = element1.addTarget();
target1.setCode(targetCode).setDisplay(targetDisplay).setEquivalence(ConceptMapEquivalence.EQUAL);
IIdType conceptMapId = myConceptMapDao.create(conceptMap, mySrd).getId().toUnqualifiedVersionless();
conceptMap = myConceptMapDao.read(conceptMapId);
ourLog.info("ConceptMap: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
}
private void createReverseConceptMap(String url, String version, String sourceCode, String sourceDisplay) {
//- conceptMap1 v1
ConceptMap conceptMap = new ConceptMap();
conceptMap.setUrl(url).setVersion(version).setSource(new UriType(VS_URL)).setTarget(new UriType(VS_URL_2));
ConceptMapGroupComponent group1 = conceptMap.addGroup();
group1.setSource(CS_URL).setSourceVersion("Version 1").setTarget(CS_URL_2).setTargetVersion("Version 2");
SourceElementComponent element1 = group1.addElement();
element1.setCode(sourceCode).setDisplay(sourceDisplay);
TargetElementComponent target1 = element1.addTarget();
target1.setCode("11111").setDisplay("11111");
IIdType conceptMapId = myConceptMapDao.create(conceptMap, mySrd).getId().toUnqualifiedVersionless();
ConceptMap conceptMap1 = myConceptMapDao.read(conceptMapId);
ourLog.info("ConceptMap : \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap1));
}
}

View File

@ -1,16 +1,31 @@
package ca.uhn.fhir.jpa.provider.r4;
import ca.uhn.fhir.rest.api.MethodOutcome;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.*;
import org.hl7.fhir.r4.model.BooleanType;
import org.hl7.fhir.r4.model.CodeType;
import org.hl7.fhir.r4.model.CodeableConcept;
import org.hl7.fhir.r4.model.Coding;
import org.hl7.fhir.r4.model.ConceptMap;
import org.hl7.fhir.r4.model.ConceptMap.ConceptMapGroupComponent;
import org.hl7.fhir.r4.model.ConceptMap.SourceElementComponent;
import org.hl7.fhir.r4.model.ConceptMap.TargetElementComponent;
import org.hl7.fhir.r4.model.Enumerations.ConceptMapEquivalence;
import org.hl7.fhir.r4.model.Parameters;
import org.hl7.fhir.r4.model.Parameters.ParametersParameterComponent;
import org.hl7.fhir.r4.model.StringType;
import org.hl7.fhir.r4.model.UriType;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;
import static org.junit.jupiter.api.Assertions.*;
import ca.uhn.fhir.rest.api.MethodOutcome;
public class ResourceProviderR4ConceptMapTest extends BaseResourceProviderR4Test {
private static final Logger ourLog = LoggerFactory.getLogger(ResourceProviderR4ConceptMapTest.class);
@ -870,6 +885,90 @@ public class ResourceProviderR4ConceptMapTest extends BaseResourceProviderR4Test
assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
}
@Test
public void testTranslateWithConcaptMapUrlAndVersion() {
//- conceptMap1 v1
ConceptMap conceptMap1 = new ConceptMap();
conceptMap1.setUrl(CM_URL).setVersion("v1").setSource(new UriType(VS_URL)).setTarget(new UriType(VS_URL_2));
ConceptMapGroupComponent group1 = conceptMap1.addGroup();
group1.setSource(CS_URL).setSourceVersion("Version 1").setTarget(CS_URL_2).setTargetVersion("Version 2");
SourceElementComponent element1 = group1.addElement();
element1.setCode("11111").setDisplay("Source Code 11111");
TargetElementComponent target1 = element1.addTarget();
target1.setCode("12222").setDisplay("Target Code 12222").setEquivalence(ConceptMapEquivalence.EQUAL);
IIdType conceptMapId1 = myConceptMapDao.create(conceptMap1, mySrd).getId().toUnqualifiedVersionless();
conceptMap1 = myConceptMapDao.read(conceptMapId1);
ourLog.info("ConceptMap: 2 \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap1));
//- conceptMap1 v2
ConceptMap conceptMap2 = new ConceptMap();
conceptMap2.setUrl(CM_URL).setVersion("v2").setSource(new UriType(VS_URL)).setTarget(new UriType(VS_URL_2));
ConceptMapGroupComponent group2 = conceptMap2.addGroup();
group2.setSource(CS_URL).setSourceVersion("Version 1").setTarget(CS_URL_2).setTargetVersion("Version 2");
SourceElementComponent element2 = group2.addElement();
element2.setCode("11111").setDisplay("Source Code 11111");
TargetElementComponent target2 = element2.addTarget();
target2.setCode("13333").setDisplay("Target Code 13333").setEquivalence(ConceptMapEquivalence.EQUAL);
IIdType conceptMapId2 = myConceptMapDao.create(conceptMap2, mySrd).getId().toUnqualifiedVersionless();
conceptMap2 = myConceptMapDao.read(conceptMapId2);
ourLog.info("ConceptMap: 2 \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap2));
Parameters inParams = new Parameters();
inParams.addParameter().setName("url").setValue(new UriType(CM_URL));
inParams.addParameter().setName("conceptMapVersion").setValue(new StringType("v2"));
inParams.addParameter().setName("system").setValue(new UriType(CS_URL));
inParams.addParameter().setName("targetsystem").setValue(new UriType(CS_URL_2));
inParams.addParameter().setName("code").setValue(new CodeType("11111"));
ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
Parameters respParams = myClient
.operation()
.onType(ConceptMap.class)
.named("translate")
.withParameters(inParams)
.execute();
ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
ParametersParameterComponent param = getParameterByName(respParams, "result");
assertTrue(((BooleanType) param.getValue()).booleanValue());
param = getParameterByName(respParams, "message");
assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
assertEquals(1, getNumberOfParametersByName(respParams, "match"));
param = getParametersByName(respParams, "match").get(0);
assertEquals(3, param.getPart().size());
ParametersParameterComponent part = getPartByName(param, "equivalence");
assertEquals("equal", ((CodeType) part.getValue()).getCode());
part = getPartByName(param, "concept");
Coding coding = (Coding) part.getValue();
assertEquals("13333", coding.getCode());
assertEquals("Target Code 13333", coding.getDisplay());
assertFalse(coding.getUserSelected());
assertEquals(CS_URL_2, coding.getSystem());
assertEquals("Version 2", coding.getVersion());
part = getPartByName(param, "source");
assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
}
@Test
public void testTranslateWithInstance() {
ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
@ -1621,6 +1720,89 @@ public class ResourceProviderR4ConceptMapTest extends BaseResourceProviderR4Test
assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
}
@Test
public void testTranslateWithReverseConcaptMapUrlAndVersion() {
//- conceptMap1 v1
ConceptMap conceptMap1 = new ConceptMap();
conceptMap1.setUrl(CM_URL).setVersion("v1").setSource(new UriType(VS_URL)).setTarget(new UriType(VS_URL_2));
ConceptMapGroupComponent group1 = conceptMap1.addGroup();
group1.setSource(CS_URL).setSourceVersion("Version 1").setTarget(CS_URL_2).setTargetVersion("Version 2");
SourceElementComponent element1 = group1.addElement();
element1.setCode("12222").setDisplay("Source Code 12222");
TargetElementComponent target1 = element1.addTarget();
target1.setCode("11111").setDisplay("11111").setEquivalence(ConceptMapEquivalence.EQUAL);
IIdType conceptMapId1 = myConceptMapDao.create(conceptMap1, mySrd).getId().toUnqualifiedVersionless();
conceptMap1 = myConceptMapDao.read(conceptMapId1);
ourLog.info("ConceptMap: 2 \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap1));
//- conceptMap1 v2
ConceptMap conceptMap2 = new ConceptMap();
conceptMap2.setUrl(CM_URL).setVersion("v2").setSource(new UriType(VS_URL)).setTarget(new UriType(VS_URL_2));
ConceptMapGroupComponent group2 = conceptMap2.addGroup();
group2.setSource(CS_URL).setSourceVersion("Version 1").setTarget(CS_URL_2).setTargetVersion("Version 2");
SourceElementComponent element2 = group2.addElement();
element2.setCode("13333").setDisplay("Source Code 13333");
TargetElementComponent target2 = element2.addTarget();
target2.setCode("11111").setDisplay("Target Code 11111").setEquivalence(ConceptMapEquivalence.EQUAL);
IIdType conceptMapId2 = myConceptMapDao.create(conceptMap2, mySrd).getId().toUnqualifiedVersionless();
conceptMap2 = myConceptMapDao.read(conceptMapId2);
ourLog.info("ConceptMap: 2 \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap2));
Parameters inParams = new Parameters();
inParams.addParameter().setName("url").setValue(new UriType(CM_URL));
inParams.addParameter().setName("conceptMapVersion").setValue(new StringType("v2"));
inParams.addParameter().setName("code").setValue(new CodeType("11111"));
inParams.addParameter().setName("reverse").setValue(new BooleanType(true));
ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
Parameters respParams = myClient
.operation()
.onType(ConceptMap.class)
.named("translate")
.withParameters(inParams)
.execute();
ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
ParametersParameterComponent param = getParameterByName(respParams, "result");
assertTrue(((BooleanType) param.getValue()).booleanValue());
param = getParameterByName(respParams, "message");
assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
assertEquals(1, getNumberOfParametersByName(respParams, "match"));
param = getParametersByName(respParams, "match").get(0);
assertEquals(3, param.getPart().size());
ParametersParameterComponent part = getPartByName(param, "equivalence");
assertEquals("equal", ((CodeType) part.getValue()).getCode());
part = getPartByName(param, "concept");
Coding coding = (Coding) part.getValue();
assertEquals("13333", coding.getCode());
assertEquals("Source Code 13333", coding.getDisplay());
assertFalse(coding.getUserSelected());
assertEquals(CS_URL, coding.getSystem());
assertEquals("Version 1", coding.getVersion());
part = getPartByName(param, "source");
assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
}
@Test
public void testTranslateWithReverseAndInstance() {
ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);

View File

@ -0,0 +1,191 @@
package ca.uhn.fhir.jpa.provider.r5;
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 org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.Enumerations.ConceptMapEquivalence;
import org.hl7.fhir.r5.model.BooleanType;
import org.hl7.fhir.r5.model.CodeType;
import org.hl7.fhir.r5.model.Coding;
import org.hl7.fhir.r5.model.ConceptMap;
import org.hl7.fhir.r5.model.ConceptMap.ConceptMapGroupComponent;
import org.hl7.fhir.r5.model.ConceptMap.SourceElementComponent;
import org.hl7.fhir.r5.model.ConceptMap.TargetElementComponent;
import org.hl7.fhir.r5.model.Enumerations.ConceptMapRelationship;
import org.hl7.fhir.r5.model.Parameters;
import org.hl7.fhir.r5.model.Parameters.ParametersParameterComponent;
import org.hl7.fhir.r5.model.StringType;
import org.hl7.fhir.r5.model.UriType;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ResourceProviderR5ConceptMapTest extends BaseResourceProviderR5Test {
private static final Logger ourLog = LoggerFactory.getLogger(ResourceProviderR5ConceptMapTest.class);
@Test
public void testTranslateWithConcaptMapUrlAndVersion() {
//- conceptMap1 v1
ConceptMap conceptMap1 = new ConceptMap();
conceptMap1.setUrl(CM_URL).setVersion("v1").setSource(new UriType(VS_URL)).setTarget(new UriType(VS_URL_2));
ConceptMapGroupComponent group1 = conceptMap1.addGroup();
group1.setSource(CS_URL).setSourceVersion("Version 1").setTarget(CS_URL_2).setTargetVersion("Version 2");
SourceElementComponent element1 = group1.addElement();
element1.setCode("11111").setDisplay("Source Code 11111");
TargetElementComponent target1 = element1.addTarget();
target1.setCode("12222").setDisplay("Target Code 12222");
IIdType conceptMapId1 = myConceptMapDao.create(conceptMap1, mySrd).getId().toUnqualifiedVersionless();
conceptMap1 = myConceptMapDao.read(conceptMapId1);
ourLog.info("ConceptMap: 2 \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap1));
//- conceptMap1 v2
ConceptMap conceptMap2 = new ConceptMap();
conceptMap2.setUrl(CM_URL).setVersion("v2").setSource(new UriType(VS_URL)).setTarget(new UriType(VS_URL_2));
ConceptMapGroupComponent group2 = conceptMap2.addGroup();
group2.setSource(CS_URL).setSourceVersion("Version 1").setTarget(CS_URL_2).setTargetVersion("Version 2");
SourceElementComponent element2 = group2.addElement();
element2.setCode("11111").setDisplay("Source Code 11111");
TargetElementComponent target2 = element2.addTarget();
target2.setCode("13333").setDisplay("Target Code 13333");
IIdType conceptMapId2 = myConceptMapDao.create(conceptMap2, mySrd).getId().toUnqualifiedVersionless();
conceptMap2 = myConceptMapDao.read(conceptMapId2);
ourLog.info("ConceptMap: 2 \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap2));
Parameters inParams = new Parameters();
inParams.addParameter().setName("url").setValue(new UriType(CM_URL));
inParams.addParameter().setName("conceptMapVersion").setValue(new StringType("v2"));
inParams.addParameter().setName("system").setValue(new UriType(CS_URL));
inParams.addParameter().setName("targetsystem").setValue(new UriType(CS_URL_2));
inParams.addParameter().setName("code").setValue(new CodeType("11111"));
ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
Parameters respParams = myClient
.operation()
.onType(ConceptMap.class)
.named("translate")
.withParameters(inParams)
.execute();
ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
ParametersParameterComponent param = getParameterByName(respParams, "result");
assertTrue(((BooleanType) param.getValue()).booleanValue());
param = getParameterByName(respParams, "message");
assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
assertEquals(1, getNumberOfParametersByName(respParams, "match"));
param = getParametersByName(respParams, "match").get(0);
assertEquals(2, param.getPart().size());
ParametersParameterComponent part = getPartByName(param, "concept");
Coding coding = (Coding) part.getValue();
assertEquals("13333", coding.getCode());
assertEquals("Target Code 13333", coding.getDisplay());
assertFalse(coding.getUserSelected());
assertEquals(CS_URL_2, coding.getSystem());
assertEquals("Version 2", coding.getVersion());
part = getPartByName(param, "source");
assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
}
@Test
public void testTranslateWithReverseConcaptMapUrlAndVersion() {
//- conceptMap1 v1
ConceptMap conceptMap1 = new ConceptMap();
conceptMap1.setUrl(CM_URL).setVersion("v1").setSource(new UriType(VS_URL)).setTarget(new UriType(VS_URL_2));
ConceptMapGroupComponent group1 = conceptMap1.addGroup();
group1.setSource(CS_URL).setSourceVersion("Version 1").setTarget(CS_URL_2).setTargetVersion("Version 2");
SourceElementComponent element1 = group1.addElement();
element1.setCode("12222").setDisplay("Source Code 12222");
TargetElementComponent target1 = element1.addTarget();
target1.setCode("11111").setDisplay("11111").setRelationship(ConceptMapRelationship.EQUIVALENT);
IIdType conceptMapId1 = myConceptMapDao.create(conceptMap1, mySrd).getId().toUnqualifiedVersionless();
conceptMap1 = myConceptMapDao.read(conceptMapId1);
ourLog.info("ConceptMap: 2 \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap1));
//- conceptMap1 v2
ConceptMap conceptMap2 = new ConceptMap();
conceptMap2.setUrl(CM_URL).setVersion("v2").setSource(new UriType(VS_URL)).setTarget(new UriType(VS_URL_2));
ConceptMapGroupComponent group2 = conceptMap2.addGroup();
group2.setSource(CS_URL).setSourceVersion("Version 1").setTarget(CS_URL_2).setTargetVersion("Version 2");
SourceElementComponent element2 = group2.addElement();
element2.setCode("13333").setDisplay("Source Code 13333");
TargetElementComponent target2 = element2.addTarget();
target2.setCode("11111").setDisplay("Target Code 11111").setRelationship(ConceptMapRelationship.EQUIVALENT);
IIdType conceptMapId2 = myConceptMapDao.create(conceptMap2, mySrd).getId().toUnqualifiedVersionless();
conceptMap2 = myConceptMapDao.read(conceptMapId2);
ourLog.info("ConceptMap: 2 \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap2));
Parameters inParams = new Parameters();
inParams.addParameter().setName("url").setValue(new UriType(CM_URL));
inParams.addParameter().setName("conceptMapVersion").setValue(new StringType("v2"));
inParams.addParameter().setName("code").setValue(new CodeType("11111"));
inParams.addParameter().setName("reverse").setValue(new BooleanType(true));
ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
Parameters respParams = myClient
.operation()
.onType(ConceptMap.class)
.named("translate")
.withParameters(inParams)
.execute();
ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
ParametersParameterComponent param = getParameterByName(respParams, "result");
assertTrue(((BooleanType) param.getValue()).booleanValue());
param = getParameterByName(respParams, "message");
assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
assertEquals(1, getNumberOfParametersByName(respParams, "match"));
param = getParametersByName(respParams, "match").get(0);
assertEquals(3, param.getPart().size());
ParametersParameterComponent part = getPartByName(param, "equivalence");
assertEquals("equivalent", ((CodeType) part.getValue()).getCode());
part = getPartByName(param, "concept");
Coding coding = (Coding) part.getValue();
assertEquals("13333", coding.getCode());
assertEquals("Source Code 13333", coding.getDisplay());
assertFalse(coding.getUserSelected());
assertEquals(CS_URL, coding.getSystem());
assertEquals("Version 1", coding.getVersion());
part = getPartByName(param, "source");
assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
}
}

View File

@ -25,6 +25,8 @@ import org.hl7.fhir.utilities.validation.ValidationOptions;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
@ -52,6 +54,13 @@ public class TerminologySvcImplR4Test extends BaseTermR4Test {
persistConceptMap(conceptMap, HttpVerb.POST);
}
private void createAndPersistConceptMap(String version) {
ConceptMap conceptMap = createConceptMap();
conceptMap.setId("ConceptMap/cm");
conceptMap.setVersion(version);
persistConceptMap(conceptMap, HttpVerb.POST);
}
@SuppressWarnings("EnumSwitchStatementWhichMissesCases")
private void persistConceptMap(ConceptMap theConceptMap, HttpVerb theVerb) {
switch (theVerb) {
@ -266,6 +275,19 @@ public class TerminologySvcImplR4Test extends BaseTermR4Test {
}
@Test
public void testDuplicateConceptMapUrlsAndVersions() {
createAndPersistConceptMap("v1");
try {
createAndPersistConceptMap("v1");
fail();
} catch (UnprocessableEntityException e) {
assertEquals("Can not create multiple ConceptMap resources with ConceptMap.url \"http://example.com/my_concept_map\", ConceptMap.version \"v1\", already have one with resource ID: ConceptMap/" + myConceptMapId.getIdPart(), e.getMessage());
}
}
@Test
public void testDuplicateValueSetUrls() throws Exception {
myDaoConfig.setPreExpandValueSets(true);
@ -292,10 +314,11 @@ public class TerminologySvcImplR4Test extends BaseTermR4Test {
new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(@Nonnull TransactionStatus theStatus) {
Optional<TermConceptMap> optionalConceptMap = myTermConceptMapDao.findTermConceptMapByUrl(CM_URL);
assertTrue(optionalConceptMap.isPresent());
Pageable page = PageRequest.of(0, 1);
List<TermConceptMap> optionalConceptMap = myTermConceptMapDao.getTermConceptMapEntitiesByUrlOrderByVersion(page, CM_URL);
assertEquals(1, optionalConceptMap.size());
TermConceptMap conceptMap = optionalConceptMap.get();
TermConceptMap conceptMap = optionalConceptMap.get(0);
ourLog.info("ConceptMap:\n" + conceptMap.toString());
@ -470,10 +493,11 @@ public class TerminologySvcImplR4Test extends BaseTermR4Test {
new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(@Nonnull TransactionStatus theStatus) {
Optional<TermConceptMap> optionalConceptMap = myTermConceptMapDao.findTermConceptMapByUrl(CM_URL);
assertTrue(optionalConceptMap.isPresent());
Pageable page = PageRequest.of(0, 1);
List<TermConceptMap> optionalConceptMap = myTermConceptMapDao.getTermConceptMapEntitiesByUrlOrderByVersion(page, CM_URL);
assertEquals(1, optionalConceptMap.size());
TermConceptMap conceptMap = optionalConceptMap.get();
TermConceptMap conceptMap = optionalConceptMap.get(0);
ourLog.info("ConceptMap:\n" + conceptMap.toString());