Pass properties through to Remote Terminology Service on CodeSystem lookup (#5477)

* Pass properties through to Remote Terminology Service on CodeSystem  operation

* Propagate list of property names throughout. Introduce a parameter object for the lookupCode method. Mark other lookupCode methods as deprecated. Add unit tests.

* Update remote terminology service tests

* Address code review comments

* Fix unit tests

* Address latest code review comments to update default methods

* Address latest code review comments to update default methods - update fallback condition

* Address latest code review comments to update default methods - update fallback condition
This commit is contained in:
Martha Mitran 2023-11-28 13:12:05 -08:00 committed by GitHub
parent 63eed3936b
commit ee414b73d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 890 additions and 492 deletions

View File

@ -329,14 +329,16 @@ public interface IValidationSupport {
}
/**
* Look up a code using the system and code value
* Look up a code using the system and code value.
* @deprecated This method has been deprecated in HAPI FHIR 7.0.0. Use {@link IValidationSupport#lookupCode(ValidationSupportContext, LookupCodeRequest)} instead.
*
* @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 theDisplayLanguage to filter out the designation by the display language. To return all designation, set this value to <code>null</code>.
* @param theDisplayLanguage Used to filter out the designation by the display language. To return all designation, set this value to <code>null</code>.
*/
@Deprecated
@Nullable
default LookupCodeResult lookupCode(
ValidationSupportContext theValidationSupportContext,
@ -348,12 +350,14 @@ public interface IValidationSupport {
/**
* Look up a code using the system and code value
* @deprecated This method has been deprecated in HAPI FHIR 7.0.0. Use {@link IValidationSupport#lookupCode(ValidationSupportContext, LookupCodeRequest)} instead.
*
* @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
*/
@Deprecated
@Nullable
default LookupCodeResult lookupCode(
ValidationSupportContext theValidationSupportContext, String theSystem, String theCode) {
@ -361,7 +365,26 @@ public interface IValidationSupport {
}
/**
* Returns <code>true</code> if the given valueset can be validated by the given
* Look up a code using the system, code and other parameters captured in {@link LookupCodeRequest}.
* @since 7.0.0
*
* @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 theLookupCodeRequest The parameters used to perform the lookup, including system and code.
*/
@Nullable
default LookupCodeResult lookupCode(
ValidationSupportContext theValidationSupportContext, @Nonnull LookupCodeRequest theLookupCodeRequest) {
// TODO: can change to return null once the deprecated methods are removed
return lookupCode(
theValidationSupportContext,
theLookupCodeRequest.getSystem(),
theLookupCodeRequest.getCode(),
theLookupCodeRequest.getDisplayLanguage());
}
/**
* Returns <code>true</code> if the given ValueSet can be validated by the given
* validation support module
*
* @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
@ -554,6 +577,11 @@ public interface IValidationSupport {
}
class CodeValidationResult {
public static final String SOURCE_DETAILS = "sourceDetails";
public static final String RESULT = "result";
public static final String MESSAGE = "message";
public static final String DISPLAY = "display";
private String myCode;
private String myMessage;
private IssueSeverity mySeverity;
@ -682,6 +710,23 @@ public interface IValidationSupport {
setSeverity(IssueSeverity.valueOf(theIssueSeverity.toUpperCase()));
return this;
}
public IBaseParameters toParameters(FhirContext theContext) {
IBaseParameters retVal = ParametersUtil.newInstance(theContext);
ParametersUtil.addParameterToParametersBoolean(theContext, retVal, RESULT, isOk());
if (isNotBlank(getMessage())) {
ParametersUtil.addParameterToParametersString(theContext, retVal, MESSAGE, getMessage());
}
if (isNotBlank(getDisplay())) {
ParametersUtil.addParameterToParametersString(theContext, retVal, DISPLAY, getDisplay());
}
if (isNotBlank(getSourceDetails())) {
ParametersUtil.addParameterToParametersString(theContext, retVal, SOURCE_DETAILS, getSourceDetails());
}
return retVal;
}
}
class ValueSetExpansionOutcome {
@ -814,7 +859,7 @@ public interface IValidationSupport {
}
public IBaseParameters toParameters(
FhirContext theContext, List<? extends IPrimitiveType<String>> theProperties) {
FhirContext theContext, List<? extends IPrimitiveType<String>> thePropertyNames) {
IBaseParameters retVal = ParametersUtil.newInstance(theContext);
if (isNotBlank(getCodeSystemDisplayName())) {
@ -829,8 +874,8 @@ public interface IValidationSupport {
if (myProperties != null) {
Set<String> properties = Collections.emptySet();
if (theProperties != null) {
properties = theProperties.stream()
if (thePropertyNames != null) {
properties = thePropertyNames.stream()
.map(IPrimitiveType::getValueAsString)
.collect(Collectors.toSet());
}

View File

@ -0,0 +1,56 @@
package ca.uhn.fhir.context.support;
import java.util.Collection;
import java.util.Collections;
/**
* Represents parameters which can be passed to the $lookup operation for codes.
* @since 7.0.0
*/
public class LookupCodeRequest {
private final String mySystem;
private final String myCode;
private String myDisplayLanguage;
private Collection<String> myPropertyNames;
/**
* @param theSystem The CodeSystem URL
* @param theCode The code
*/
public LookupCodeRequest(String theSystem, String theCode) {
mySystem = theSystem;
myCode = theCode;
}
/**
* @param theSystem The CodeSystem URL
* @param theCode The code
* @param theDisplayLanguage Used to filter out the designation by the display language. To return all designation, set this value to <code>null</code>.
* @param thePropertyNames The collection of properties to be returned in the output. If no properties are specified, the implementor chooses what to return.
*/
public LookupCodeRequest(
String theSystem, String theCode, String theDisplayLanguage, Collection<String> thePropertyNames) {
this(theSystem, theCode);
myDisplayLanguage = theDisplayLanguage;
myPropertyNames = thePropertyNames;
}
public String getSystem() {
return mySystem;
}
public String getCode() {
return myCode;
}
public String getDisplayLanguage() {
return myDisplayLanguage;
}
public Collection<String> getPropertyNames() {
if (myPropertyNames == null) {
return Collections.emptyList();
}
return myPropertyNames;
}
}

View File

@ -23,6 +23,7 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.support.ConceptValidationOptions;
import ca.uhn.fhir.context.support.DefaultProfileValidationSupport;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.context.support.LookupCodeRequest;
import ca.uhn.fhir.context.support.ValidationSupportContext;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.parser.IParser;
@ -308,9 +309,7 @@ public class ValidatorExamples {
@Override
public LookupCodeResult lookupCode(
ValidationSupportContext theValidationSupportContext,
String theSystem,
String theCode,
String theDisplayLanguage) {
@Nonnull LookupCodeRequest validationSupportParameterObject) {
// TODO: implement (or return null if your implementation does not support this function)
return null;
}

View File

@ -0,0 +1,5 @@
---
type: add
issue: 5476
title: "A new method on the IValidationSupport interface called lookupCode(LookupCodeRequest) has been added.
This method will replace the existing lookupCode methods, which are now deprecated."

View File

@ -24,6 +24,7 @@ import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.support.ConceptValidationOptions;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.context.support.IValidationSupport.CodeValidationResult;
import ca.uhn.fhir.context.support.LookupCodeRequest;
import ca.uhn.fhir.context.support.ValidationSupportContext;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoCodeSystem;
@ -41,6 +42,7 @@ import ca.uhn.fhir.rest.param.TokenParam;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.util.FhirTerser;
import ca.uhn.hapi.converters.canonical.VersionCanonicalizer;
import org.apache.commons.collections4.CollectionUtils;
import org.hl7.fhir.common.hapi.validation.support.CommonCodeSystemsTerminologyService;
import org.hl7.fhir.instance.model.api.IBaseCoding;
import org.hl7.fhir.instance.model.api.IBaseDatatype;
@ -52,8 +54,10 @@ import org.hl7.fhir.r4.model.Coding;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import javax.annotation.PostConstruct;
@ -125,8 +129,33 @@ public class JpaResourceDaoCodeSystem<T extends IBaseResource> extends BaseHapiF
IBaseCoding theCoding,
IPrimitiveType<String> theDisplayLanguage,
RequestDetails theRequestDetails) {
return lookupCode(
theCode,
theSystem,
theCoding,
theDisplayLanguage,
CollectionUtils.emptyCollection(),
theRequestDetails);
}
@Nonnull
@Override
public IValidationSupport.LookupCodeResult lookupCode(
IPrimitiveType<String> theCode,
IPrimitiveType<String> theSystem,
IBaseCoding theCoding,
IPrimitiveType<String> theDisplayLanguage,
Collection<IPrimitiveType<String>> thePropertyNames,
RequestDetails theRequestDetails) {
return doLookupCode(
myFhirContext, myTerser, myValidationSupport, theCode, theSystem, theCoding, theDisplayLanguage);
myFhirContext,
myTerser,
myValidationSupport,
theCode,
theSystem,
theCoding,
theDisplayLanguage,
thePropertyNames);
}
@Override
@ -285,7 +314,8 @@ public class JpaResourceDaoCodeSystem<T extends IBaseResource> extends BaseHapiF
IPrimitiveType<String> theCode,
IPrimitiveType<String> theSystem,
IBaseCoding theCoding,
IPrimitiveType<String> theDisplayLanguage) {
IPrimitiveType<String> theDisplayLanguage,
Collection<IPrimitiveType<String>> thePropertyNames) {
boolean haveCoding = theCoding != null
&& isNotBlank(extractCodingSystem(theCoding))
&& isNotBlank(extractCodingCode(theCoding));
@ -323,11 +353,16 @@ public class JpaResourceDaoCodeSystem<T extends IBaseResource> extends BaseHapiF
ourLog.info("Looking up {} / {}", system, code);
Collection<String> propertyNames = CollectionUtils.emptyIfNull(thePropertyNames).stream()
.map(IPrimitiveType::getValueAsString)
.collect(Collectors.toSet());
if (theValidationSupport.isCodeSystemSupported(new ValidationSupportContext(theValidationSupport), system)) {
ourLog.info("Code system {} is supported", system);
IValidationSupport.LookupCodeResult retVal = theValidationSupport.lookupCode(
new ValidationSupportContext(theValidationSupport), system, code, displayLanguage);
new ValidationSupportContext(theValidationSupport),
new LookupCodeRequest(system, code, displayLanguage, propertyNames));
if (retVal != null) {
return retVal;
}

View File

@ -45,7 +45,6 @@ import java.util.Optional;
import java.util.function.Supplier;
import javax.servlet.http.HttpServletRequest;
import static ca.uhn.fhir.jpa.provider.ValueSetOperationProvider.toValidateCodeResult;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public abstract class BaseJpaResourceProviderCodeSystem<T extends IBaseResource> extends BaseJpaResourceProvider<T> {
@ -65,6 +64,7 @@ public abstract class BaseJpaResourceProviderCodeSystem<T extends IBaseResource>
@OperationParam(name = "version", typeName = "string", min = 0),
@OperationParam(name = "display", typeName = "string", min = 1),
@OperationParam(name = "abstract", typeName = "boolean", min = 1),
@OperationParam(name = "property", min = 0, max = OperationParam.MAX_UNLIMITED, typeName = "code")
})
public IBaseParameters lookup(
HttpServletRequest theServletRequest,
@ -75,7 +75,7 @@ public abstract class BaseJpaResourceProviderCodeSystem<T extends IBaseResource>
@OperationParam(name = "displayLanguage", min = 0, max = 1, typeName = "code")
IPrimitiveType<String> theDisplayLanguage,
@OperationParam(name = "property", min = 0, max = OperationParam.MAX_UNLIMITED, typeName = "code")
List<IPrimitiveType<String>> theProperties,
List<IPrimitiveType<String>> thePropertyNames,
RequestDetails theRequestDetails) {
startRequest(theServletRequest);
@ -83,9 +83,10 @@ public abstract class BaseJpaResourceProviderCodeSystem<T extends IBaseResource>
IFhirResourceDaoCodeSystem dao = (IFhirResourceDaoCodeSystem) getDao();
IValidationSupport.LookupCodeResult result;
applyVersionToSystem(theSystem, theVersion);
result = dao.lookupCode(theCode, theSystem, theCoding, theDisplayLanguage, theRequestDetails);
result = dao.lookupCode(
theCode, theSystem, theCoding, theDisplayLanguage, thePropertyNames, theRequestDetails);
result.throwNotFoundIfAppropriate();
return result.toParameters(theRequestDetails.getFhirContext(), theProperties);
return result.toParameters(theRequestDetails.getFhirContext(), thePropertyNames);
} finally {
endRequest(theServletRequest);
}
@ -191,7 +192,7 @@ public abstract class BaseJpaResourceProviderCodeSystem<T extends IBaseResource>
theCodeableConcept,
theRequestDetails);
}
return toValidateCodeResult(getContext(), result);
return result.toParameters(getContext());
} finally {
endRequest(theServletRequest);
}

View File

@ -19,7 +19,6 @@
*/
package ca.uhn.fhir.jpa.provider;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.support.ConceptValidationOptions;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.context.support.IValidationSupport.CodeValidationResult;
@ -61,10 +60,6 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
public class ValueSetOperationProvider extends BaseJpaProvider {
private static final Logger ourLog = LoggerFactory.getLogger(ValueSetOperationProvider.class);
public static final String SOURCE_DETAILS = "sourceDetails";
public static final String RESULT = "result";
public static final String MESSAGE = "message";
public static final String DISPLAY = "display";
@Autowired
protected IValidationSupport myValidationSupport;
@ -149,10 +144,10 @@ public class ValueSetOperationProvider extends BaseJpaProvider {
idempotent = true,
typeName = "ValueSet",
returnParameters = {
@OperationParam(name = RESULT, typeName = "boolean", min = 1),
@OperationParam(name = MESSAGE, typeName = "string"),
@OperationParam(name = DISPLAY, typeName = "string"),
@OperationParam(name = SOURCE_DETAILS, typeName = "string")
@OperationParam(name = CodeValidationResult.RESULT, typeName = "boolean", min = 1),
@OperationParam(name = CodeValidationResult.MESSAGE, typeName = "string"),
@OperationParam(name = CodeValidationResult.DISPLAY, typeName = "string"),
@OperationParam(name = CodeValidationResult.SOURCE_DETAILS, typeName = "string")
})
public IBaseParameters validateCode(
HttpServletRequest theServletRequest,
@ -164,7 +159,8 @@ public class ValueSetOperationProvider extends BaseJpaProvider {
@OperationParam(name = "system", min = 0, max = 1, typeName = "uri") IPrimitiveType<String> theSystem,
@OperationParam(name = "systemVersion", min = 0, max = 1, typeName = "string")
IPrimitiveType<String> theSystemVersion,
@OperationParam(name = DISPLAY, min = 0, max = 1, typeName = "string") IPrimitiveType<String> theDisplay,
@OperationParam(name = CodeValidationResult.DISPLAY, min = 0, max = 1, typeName = "string")
IPrimitiveType<String> theDisplay,
@OperationParam(name = "coding", min = 0, max = 1, typeName = "Coding") IBaseCoding theCoding,
@OperationParam(name = "codeableConcept", min = 0, max = 1, typeName = "CodeableConcept")
ICompositeType theCodeableConcept,
@ -228,7 +224,7 @@ public class ValueSetOperationProvider extends BaseJpaProvider {
theCodeableConcept,
theRequestDetails);
}
return toValidateCodeResult(getContext(), result);
return result.toParameters(getContext());
} finally {
endRequest(theServletRequest);
}
@ -256,7 +252,9 @@ public class ValueSetOperationProvider extends BaseJpaProvider {
name = ProviderConstants.OPERATION_INVALIDATE_EXPANSION,
idempotent = false,
typeName = "ValueSet",
returnParameters = {@OperationParam(name = MESSAGE, typeName = "string", min = 1, max = 1)})
returnParameters = {
@OperationParam(name = CodeValidationResult.MESSAGE, typeName = "string", min = 1, max = 1)
})
public IBaseParameters invalidateValueSetExpansion(
@IdParam IIdType theValueSetId, RequestDetails theRequestDetails, HttpServletRequest theServletRequest) {
startRequest(theServletRequest);
@ -265,7 +263,7 @@ public class ValueSetOperationProvider extends BaseJpaProvider {
String outcome = myTermReadSvc.invalidatePreCalculatedExpansion(theValueSetId, theRequestDetails);
IBaseParameters retVal = ParametersUtil.newInstance(getContext());
ParametersUtil.addParameterToParametersString(getContext(), retVal, MESSAGE, outcome);
ParametersUtil.addParameterToParametersString(getContext(), retVal, CodeValidationResult.MESSAGE, outcome);
return retVal;
} finally {
@ -326,22 +324,4 @@ public class ValueSetOperationProvider extends BaseJpaProvider {
return options;
}
public static IBaseParameters toValidateCodeResult(FhirContext theContext, CodeValidationResult theResult) {
IBaseParameters retVal = ParametersUtil.newInstance(theContext);
ParametersUtil.addParameterToParametersBoolean(theContext, retVal, RESULT, theResult.isOk());
if (isNotBlank(theResult.getMessage())) {
ParametersUtil.addParameterToParametersString(theContext, retVal, MESSAGE, theResult.getMessage());
}
if (isNotBlank(theResult.getDisplay())) {
ParametersUtil.addParameterToParametersString(theContext, retVal, DISPLAY, theResult.getDisplay());
}
if (isNotBlank(theResult.getSourceDetails())) {
ParametersUtil.addParameterToParametersString(
theContext, retVal, SOURCE_DETAILS, theResult.getSourceDetails());
}
return retVal;
}
}

View File

@ -127,7 +127,7 @@ public class ValueSetOperationProviderDstu2 extends ValueSetOperationProvider {
@OperationParam(name = "displayLanguage", min = 0, max = 1, typeName = "code")
IPrimitiveType<String> theDisplayLanguage,
@OperationParam(name = "property", min = 0, max = OperationParam.MAX_UNLIMITED, typeName = "code")
List<IPrimitiveType<String>> theProperties,
List<IPrimitiveType<String>> thePropertyNames,
RequestDetails theRequestDetails) {
startRequest(theServletRequest);
@ -137,9 +137,16 @@ public class ValueSetOperationProviderDstu2 extends ValueSetOperationProvider {
FhirTerser terser = getContext().newTerser();
result = JpaResourceDaoCodeSystem.doLookupCode(
getContext(), terser, myValidationSupport, theCode, theSystem, theCoding, theDisplayLanguage);
getContext(),
terser,
myValidationSupport,
theCode,
theSystem,
theCoding,
theDisplayLanguage,
thePropertyNames);
result.throwNotFoundIfAppropriate();
return result.toParameters(theRequestDetails.getFhirContext(), theProperties);
return result.toParameters(theRequestDetails.getFhirContext(), thePropertyNames);
} finally {
endRequest(theServletRequest);
}

View File

@ -23,6 +23,7 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.support.ConceptValidationOptions;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.context.support.LookupCodeRequest;
import ca.uhn.fhir.context.support.ValidationSupportContext;
import ca.uhn.fhir.context.support.ValueSetExpansionOptions;
import ca.uhn.fhir.i18n.Msg;
@ -90,6 +91,7 @@ import ca.uhn.hapi.converters.canonical.VersionCanonicalizer;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Stopwatch;
import com.google.common.collect.ArrayListMultimap;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
@ -147,7 +149,6 @@ import org.springframework.transaction.interceptor.NoRollbackRuleAttribute;
import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.util.comparator.Comparators;
import java.util.ArrayList;
@ -2575,10 +2576,13 @@ public class TermReadSvcImpl implements ITermReadSvc, IHasScheduledJobs {
return new IFhirResourceDaoCodeSystem.SubsumesResult(subsumes);
}
protected IValidationSupport.LookupCodeResult lookupCode(
String theSystem, String theCode, String theDisplayLanguage) {
@Override
public IValidationSupport.LookupCodeResult lookupCode(
ValidationSupportContext theValidationSupportContext, @Nonnull LookupCodeRequest theLookupCodeRequest) {
TransactionTemplate txTemplate = new TransactionTemplate(myTransactionManager);
return txTemplate.execute(t -> {
final String theSystem = theLookupCodeRequest.getSystem();
final String theCode = theLookupCodeRequest.getCode();
Optional<TermConcept> codeOpt = findCode(theSystem, theCode);
if (codeOpt.isPresent()) {
TermConcept code = codeOpt.get();
@ -2593,7 +2597,7 @@ public class TermReadSvcImpl implements ITermReadSvc, IHasScheduledJobs {
for (TermConceptDesignation next : code.getDesignations()) {
// filter out the designation based on displayLanguage if any
if (isDisplayLanguageMatch(theDisplayLanguage, next.getLanguage())) {
if (isDisplayLanguageMatch(theLookupCodeRequest.getDisplayLanguage(), next.getLanguage())) {
IValidationSupport.ConceptDesignation designation = new IValidationSupport.ConceptDesignation();
designation.setLanguage(next.getLanguage());
designation.setUseSystem(next.getUseSystem());
@ -2604,7 +2608,11 @@ public class TermReadSvcImpl implements ITermReadSvc, IHasScheduledJobs {
}
}
final Collection<String> propertyNames = theLookupCodeRequest.getPropertyNames();
for (TermConceptProperty next : code.getProperties()) {
if (ObjectUtils.isNotEmpty(propertyNames) && !propertyNames.contains(next.getKey())) {
continue;
}
if (next.getType() == TermConceptPropertyTypeEnum.CODING) {
IValidationSupport.CodingConceptProperty property =
new IValidationSupport.CodingConceptProperty(
@ -3117,15 +3125,6 @@ public class TermReadSvcImpl implements ITermReadSvc, IHasScheduledJobs {
return isValueSetPreExpandedForCodeValidation(valueSetR4);
}
@Override
public LookupCodeResult lookupCode(
ValidationSupportContext theValidationSupportContext,
String theSystem,
String theCode,
String theDisplayLanguage) {
return lookupCode(theSystem, theCode, theDisplayLanguage);
}
private static class TermCodeSystemVersionDetails {
private final long myPid;

View File

@ -0,0 +1,101 @@
package ca.uhn.fhir.jpa.provider.dstu3;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.provider.CodeSystemLookupWithPropertiesUtil;
import ca.uhn.fhir.rest.gclient.IOperationUntypedWithInputAndPartialOutput;
import org.hl7.fhir.dstu3.model.CodeSystem;
import org.hl7.fhir.dstu3.model.CodeType;
import org.hl7.fhir.dstu3.model.Parameters;
import org.hl7.fhir.dstu3.model.StringType;
import org.hl7.fhir.dstu3.model.UriType;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Stream;
import static ca.uhn.fhir.jpa.provider.CodeSystemLookupWithPropertiesUtil.ourCode;
import static ca.uhn.fhir.jpa.provider.CodeSystemLookupWithPropertiesUtil.ourCodeSystemId;
import static ca.uhn.fhir.jpa.provider.CodeSystemLookupWithPropertiesUtil.ourCodeSystemUrl;
import static ca.uhn.fhir.jpa.provider.CodeSystemLookupWithPropertiesUtil.ourPropertyA;
import static ca.uhn.fhir.jpa.provider.CodeSystemLookupWithPropertiesUtil.ourPropertyB;
import static ca.uhn.fhir.jpa.provider.CodeSystemLookupWithPropertiesUtil.ourPropertyValueA;
import static ca.uhn.fhir.jpa.provider.CodeSystemLookupWithPropertiesUtil.ourPropertyValueB;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class ResourceProviderDstu3CodeSystemPropertiesTest extends BaseResourceProviderDstu3Test {
public static Stream<Arguments> parametersLookup() {
return CodeSystemLookupWithPropertiesUtil.parametersLookupWithProperties();
}
@ParameterizedTest
@MethodSource(value = "parametersLookup")
public void testLookup_withProperties_returnsCorrectParameters(List<String> theLookupProperties, List<String> theExpectedReturnedProperties) {
// setup
CodeSystem codeSystem = new CodeSystem();
codeSystem.setId(ourCodeSystemId);
codeSystem.setUrl(ourCodeSystemUrl);
CodeSystem.ConceptDefinitionComponent concept = codeSystem.addConcept().setCode(ourCode);
CodeSystem.ConceptPropertyComponent propertyComponent = new CodeSystem.ConceptPropertyComponent()
.setCode(ourPropertyA).setValue(new StringType(ourPropertyValueA));
concept.addProperty(propertyComponent);
propertyComponent = new CodeSystem.ConceptPropertyComponent()
.setCode(ourPropertyB).setValue(new StringType(ourPropertyValueB));
concept.addProperty(propertyComponent);
myCodeSystemDao.create(codeSystem, mySrd);
// test
IOperationUntypedWithInputAndPartialOutput<Parameters> respParam = myClient
.operation()
.onType(CodeSystem.class)
.named(JpaConstants.OPERATION_LOOKUP)
.withParameter(Parameters.class, "code", new CodeType(ourCode))
.andParameter("system", new UriType(ourCodeSystemUrl));
theLookupProperties.forEach(p -> respParam.andParameter("property", new CodeType(p)));
Parameters parameters = respParam.execute();
Iterator<Parameters.ParametersParameterComponent> paramIterator = parameters.getParameter().iterator();
Parameters.ParametersParameterComponent parameter = null;
while (paramIterator.hasNext()) {
Parameters.ParametersParameterComponent currentParameter = paramIterator.next();
if (currentParameter.getName().equals("property")) {
parameter = currentParameter;
break;
}
}
if (theExpectedReturnedProperties.isEmpty()) {
assertNull(parameter);
return;
}
Iterator<CodeSystem.ConceptPropertyComponent> propertyIterator = concept.getProperty().stream()
.filter(property -> theExpectedReturnedProperties.contains(property.getCode())).iterator();
while (propertyIterator.hasNext()) {
CodeSystem.ConceptPropertyComponent property = propertyIterator.next();
assertNotNull(parameter);
Iterator<Parameters.ParametersParameterComponent> parameterPartIterator = parameter.getPart().iterator();
parameter = parameterPartIterator.next();
assertEquals("code", parameter.getName());
assertEquals(property.getCode(), ((CodeType)parameter.getValue()).getValue());
parameter = parameterPartIterator.next();
assertEquals("value", parameter.getName());
assertTrue(property.getValue().equalsShallow(parameter.getValue()));
if (paramIterator.hasNext()) {
parameter = paramIterator.next();
}
}
}
}

View File

@ -1,5 +1,6 @@
package ca.uhn.fhir.jpa.provider.dstu3;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
@ -9,7 +10,6 @@ import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink.RelationshipTypeEnum;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.provider.ValueSetOperationProvider;
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc;
import ca.uhn.fhir.jpa.util.CircularQueueCaptureQueriesListener;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
@ -790,13 +790,13 @@ public class ResourceProviderDstu3ValueSetTest extends BaseResourceProviderDstu3
String resp = myFhirContext.newXmlParser().setPrettyPrint(true).encodeResourceToString(respParam);
ourLog.info(resp);
assertEquals(ValueSetOperationProvider.RESULT, respParam.getParameter().get(0).getName());
assertEquals(IValidationSupport.CodeValidationResult.RESULT, respParam.getParameter().get(0).getName());
assertEquals(true, ((BooleanType) respParam.getParameter().get(0).getValue()).getValue());
assertEquals(ValueSetOperationProvider.DISPLAY, respParam.getParameter().get(1).getName());
assertEquals(IValidationSupport.CodeValidationResult.DISPLAY, respParam.getParameter().get(1).getName());
assertEquals("Male", ((StringType) respParam.getParameter().get(1).getValue()).getValue());
assertEquals(ValueSetOperationProvider.SOURCE_DETAILS, respParam.getParameter().get(2).getName());
assertEquals(IValidationSupport.CodeValidationResult.SOURCE_DETAILS, respParam.getParameter().get(2).getName());
assertEquals("Code was validated against in-memory expansion of ValueSet: http://hl7.org/fhir/ValueSet/administrative-gender", ((StringType) respParam.getParameter().get(2).getValue()).getValue());
}
@ -820,13 +820,13 @@ public class ResourceProviderDstu3ValueSetTest extends BaseResourceProviderDstu3
String resp = myFhirContext.newXmlParser().setPrettyPrint(true).encodeResourceToString(respParam);
ourLog.info(resp);
assertEquals(ValueSetOperationProvider.RESULT, respParam.getParameter().get(0).getName());
assertEquals(IValidationSupport.CodeValidationResult.RESULT, respParam.getParameter().get(0).getName());
assertEquals(true, ((BooleanType) respParam.getParameter().get(0).getValue()).getValue());
assertEquals(ValueSetOperationProvider.DISPLAY, respParam.getParameter().get(1).getName());
assertEquals(IValidationSupport.CodeValidationResult.DISPLAY, respParam.getParameter().get(1).getName());
assertEquals("Male", ((StringType) respParam.getParameter().get(1).getValue()).getValue());
assertEquals(ValueSetOperationProvider.SOURCE_DETAILS, respParam.getParameter().get(2).getName());
assertEquals(IValidationSupport.CodeValidationResult.SOURCE_DETAILS, respParam.getParameter().get(2).getName());
assertEquals("Code was validated against in-memory expansion of ValueSet: http://hl7.org/fhir/ValueSet/administrative-gender", ((StringType) respParam.getParameter().get(2).getValue()).getValue());
}

View File

@ -0,0 +1,91 @@
package ca.uhn.fhir.jpa.provider.r4;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.provider.BaseResourceProviderR4Test;
import ca.uhn.fhir.jpa.provider.CodeSystemLookupWithPropertiesUtil;
import ca.uhn.fhir.rest.gclient.IOperationUntypedWithInputAndPartialOutput;
import org.hl7.fhir.r4.model.CodeSystem;
import org.hl7.fhir.r4.model.CodeType;
import org.hl7.fhir.r4.model.Parameters;
import org.hl7.fhir.r4.model.StringType;
import org.hl7.fhir.r4.model.UriType;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Stream;
import static ca.uhn.fhir.jpa.provider.CodeSystemLookupWithPropertiesUtil.ourCode;
import static ca.uhn.fhir.jpa.provider.CodeSystemLookupWithPropertiesUtil.ourCodeSystemId;
import static ca.uhn.fhir.jpa.provider.CodeSystemLookupWithPropertiesUtil.ourCodeSystemUrl;
import static ca.uhn.fhir.jpa.provider.CodeSystemLookupWithPropertiesUtil.ourPropertyA;
import static ca.uhn.fhir.jpa.provider.CodeSystemLookupWithPropertiesUtil.ourPropertyB;
import static ca.uhn.fhir.jpa.provider.CodeSystemLookupWithPropertiesUtil.ourPropertyValueA;
import static ca.uhn.fhir.jpa.provider.CodeSystemLookupWithPropertiesUtil.ourPropertyValueB;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class ResourceProviderR4CodeSystemPropertiesTest extends BaseResourceProviderR4Test {
public static Stream<Arguments> parametersLookup() {
return CodeSystemLookupWithPropertiesUtil.parametersLookupWithProperties();
}
@ParameterizedTest
@MethodSource(value = "parametersLookup")
public void testLookup_withProperties_returnsCorrectParameters(List<String> theLookupProperties, List<String> theExpectedReturnedProperties) {
// setup
CodeSystem codeSystem = new CodeSystem();
codeSystem.setId(ourCodeSystemId);
codeSystem.setUrl(ourCodeSystemUrl);
CodeSystem.ConceptDefinitionComponent concept = codeSystem.addConcept().setCode(ourCode);
CodeSystem.ConceptPropertyComponent propertyComponent = new CodeSystem.ConceptPropertyComponent()
.setCode(ourPropertyA).setValue(new StringType(ourPropertyValueA));
concept.addProperty(propertyComponent);
propertyComponent = new CodeSystem.ConceptPropertyComponent()
.setCode(ourPropertyB).setValue(new StringType(ourPropertyValueB));
concept.addProperty(propertyComponent);
myCodeSystemDao.create(codeSystem, mySrd);
// test
IOperationUntypedWithInputAndPartialOutput<Parameters> respParam = myClient
.operation()
.onType(CodeSystem.class)
.named(JpaConstants.OPERATION_LOOKUP)
.withParameter(Parameters.class, "code", new CodeType(ourCode))
.andParameter("system", new UriType(ourCodeSystemUrl));
theLookupProperties.forEach(p -> respParam.andParameter("property", new CodeType(p)));
Parameters parameters = respParam.execute();
if (theExpectedReturnedProperties.isEmpty()) {
assertFalse(parameters.hasParameter("property"));
return;
}
assertTrue(parameters.hasParameter("property"));
Iterator<Parameters.ParametersParameterComponent> parameterPropertyIterator = parameters.getParameters("property").iterator();
Iterator<CodeSystem.ConceptPropertyComponent> propertyIterator = concept.getProperty().stream()
.filter(property -> theExpectedReturnedProperties.contains(property.getCode())).iterator();
while (propertyIterator.hasNext()) {
CodeSystem.ConceptPropertyComponent property = propertyIterator.next();
assertTrue(parameterPropertyIterator.hasNext());
Parameters.ParametersParameterComponent parameter = parameterPropertyIterator.next();
Iterator<Parameters.ParametersParameterComponent> parameterPartIterator = parameter.getPart().iterator();
parameter = parameterPartIterator.next();
assertEquals("code", parameter.getName());
assertEquals(property.getCode(), ((CodeType)parameter.getValue()).getCode());
parameter = parameterPartIterator.next();
assertEquals("value", parameter.getName());
assertTrue(property.getValue().equalsShallow(parameter.getValue()));
}
}
}

View File

@ -138,6 +138,29 @@ public class ResourceProviderR4CodeSystemTest extends BaseResourceProviderR4Test
assertEquals(false, ((BooleanType) respParam.getParameter().get(3).getValue()).getValue());
}
@Test
public void testLookupOperationByCodeAndSystemWithPropertiesBuiltInCode() {
Parameters respParam = myClient
.operation()
.onType(CodeSystem.class)
.named("lookup")
.withParameter(Parameters.class, "code", new CodeType("ACSN"))
.andParameter("system", new UriType("http://terminology.hl7.org/CodeSystem/v2-0203"))
.execute();
String resp = myFhirContext.newXmlParser().setPrettyPrint(true).encodeResourceToString(respParam);
ourLog.info(resp);
assertEquals("name", respParam.getParameter().get(0).getName());
assertEquals("v2.0203", ((StringType) respParam.getParameter().get(0).getValue()).getValue());
assertEquals("version", respParam.getParameter().get(1).getName());
assertEquals("2.9", ((StringType) respParam.getParameter().get(1).getValue()).getValue());
assertEquals("display", respParam.getParameter().get(2).getName());
assertEquals("Accession ID", ((StringType) respParam.getParameter().get(2).getValue()).getValue());
assertEquals("abstract", respParam.getParameter().get(3).getName());
assertEquals(false, ((BooleanType) respParam.getParameter().get(3).getValue()).getValue());
}
@Test
public void testLookupOperationByCodeAndSystemBuiltInNonexistantCode() {
try {

View File

@ -1,5 +1,6 @@
package ca.uhn.fhir.jpa.provider.r4;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
@ -14,7 +15,6 @@ import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.provider.BaseResourceProviderR4Test;
import ca.uhn.fhir.jpa.provider.ValueSetOperationProvider;
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
@ -1295,13 +1295,13 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv
String resp = myFhirContext.newXmlParser().setPrettyPrint(true).encodeResourceToString(respParam);
ourLog.info(resp);
assertEquals(ValueSetOperationProvider.RESULT, respParam.getParameter().get(0).getName());
assertEquals(IValidationSupport.CodeValidationResult.RESULT, respParam.getParameter().get(0).getName());
assertEquals(true, ((BooleanType) respParam.getParameter().get(0).getValue()).getValue());
assertEquals(ValueSetOperationProvider.DISPLAY, respParam.getParameter().get(1).getName());
assertEquals(IValidationSupport.CodeValidationResult.DISPLAY, respParam.getParameter().get(1).getName());
assertEquals("Male", ((StringType) respParam.getParameter().get(1).getValue()).getValue());
assertEquals(ValueSetOperationProvider.SOURCE_DETAILS, respParam.getParameter().get(2).getName());
assertEquals(IValidationSupport.CodeValidationResult.SOURCE_DETAILS, respParam.getParameter().get(2).getName());
assertEquals("Code was validated against in-memory expansion of ValueSet: http://hl7.org/fhir/ValueSet/administrative-gender", ((StringType) respParam.getParameter().get(2).getValue()).getValue());
}

View File

@ -2,6 +2,7 @@ package ca.uhn.fhir.jpa.term;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.context.support.ValidationSupportContext;
import ca.uhn.fhir.context.support.LookupCodeRequest;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
import ca.uhn.fhir.jpa.entity.TermConcept;
@ -369,7 +370,7 @@ public class TerminologySvcDeltaR4Test extends BaseJpaR4Test {
assertEquals("http://foo", outcome.getUrl());
assertEquals(CodeSystem.CodeSystemContentMode.NOTPRESENT, outcome.getContent());
IValidationSupport.LookupCodeResult lookup = myTermSvc.lookupCode(new ValidationSupportContext(myValidationSupport), "http://foo", "CBC", null);
IValidationSupport.LookupCodeResult lookup = myTermSvc.lookupCode(new ValidationSupportContext(myValidationSupport), new LookupCodeRequest("http://foo", "CBC"));
assertEquals("Complete Blood Count", lookup.getCodeDisplay());
}
@ -433,7 +434,8 @@ public class TerminologySvcDeltaR4Test extends BaseJpaR4Test {
UploadStatistics outcome = myTermCodeSystemStorageSvc.applyDeltaCodeSystemsAdd("http://foo", delta);
assertEquals(2, outcome.getUpdatedConceptCount());
assertEquals("CODEA0", myTermSvc.lookupCode(new ValidationSupportContext(myValidationSupport), "http://foo", "codea", null).getCodeDisplay());
assertEquals("CODEA0", myTermSvc.lookupCode(new ValidationSupportContext(myValidationSupport),
new LookupCodeRequest("http://foo", "codea")).getCodeDisplay());
// Add codes again with different display
delta = new CustomTerminologySet();
@ -441,12 +443,14 @@ public class TerminologySvcDeltaR4Test extends BaseJpaR4Test {
delta.addRootConcept("codeb", "CODEB1");
outcome = myTermCodeSystemStorageSvc.applyDeltaCodeSystemsAdd("http://foo", delta);
assertEquals(2, outcome.getUpdatedConceptCount());
assertEquals("CODEA1", myTermSvc.lookupCode(new ValidationSupportContext(myValidationSupport), "http://foo", "codea", null).getCodeDisplay());
assertEquals("CODEA1", myTermSvc.lookupCode(new ValidationSupportContext(myValidationSupport),
new LookupCodeRequest("http://foo", "codea")).getCodeDisplay());
// Add codes again with no changes
outcome = myTermCodeSystemStorageSvc.applyDeltaCodeSystemsAdd("http://foo", delta);
assertEquals(2, outcome.getUpdatedConceptCount());
assertEquals("CODEA1", myTermSvc.lookupCode(new ValidationSupportContext(myValidationSupport), "http://foo", "codea", null).getCodeDisplay());
assertEquals("CODEA1", myTermSvc.lookupCode(new ValidationSupportContext(myValidationSupport),
new LookupCodeRequest("http://foo", "codea")).getCodeDisplay());
}
@Test
@ -481,7 +485,8 @@ public class TerminologySvcDeltaR4Test extends BaseJpaR4Test {
.setValue(new Coding("http://snomed.info", "1234567", "Choked on large meal (finding)"));
myCodeSystemDao.create(cs, mySrd);
IValidationSupport.LookupCodeResult result = myTermSvc.lookupCode(new ValidationSupportContext(myValidationSupport), "http://foo/cs", "lunch", null);
IValidationSupport.LookupCodeResult result = myTermSvc.lookupCode(new ValidationSupportContext(myValidationSupport),
new LookupCodeRequest("http://foo/cs", "lunch"));
assertEquals(true, result.isFound());
assertEquals("lunch", result.getSearchedForCode());
assertEquals("http://foo/cs", result.getSearchedForSystem());

View File

@ -2,6 +2,7 @@ package ca.uhn.fhir.jpa.term;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.context.support.ValidationSupportContext;
import ca.uhn.fhir.context.support.LookupCodeRequest;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.config.JpaConfig;
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
@ -214,13 +215,13 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
private void validateValueLookup(String theCurrentVersion, Collection<String> allVersions) {
IValidationSupport.LookupCodeResult resultNoVer = myValidationSupport.lookupCode(
new ValidationSupportContext(myValidationSupport), BASE_LOINC_URL, VS_NO_VERSIONED_ON_UPLOAD_FIRST_CODE, null);
new ValidationSupportContext(myValidationSupport), new LookupCodeRequest(BASE_LOINC_URL, VS_NO_VERSIONED_ON_UPLOAD_FIRST_CODE));
assertNotNull(resultNoVer);
String expectedNoVer = prefixWithVersion(theCurrentVersion, VS_NO_VERSIONED_ON_UPLOAD_FIRST_DISPLAY);
assertEquals(expectedNoVer, resultNoVer.getCodeDisplay());
IValidationSupport.LookupCodeResult resultWithVer = myValidationSupport.lookupCode(
new ValidationSupportContext(myValidationSupport), BASE_LOINC_URL, VS_VERSIONED_ON_UPLOAD_FIRST_CODE, null);
new ValidationSupportContext(myValidationSupport), new LookupCodeRequest(BASE_LOINC_URL, VS_VERSIONED_ON_UPLOAD_FIRST_CODE));
assertNotNull(resultWithVer);
String expectedWithVer = prefixWithVersion(theCurrentVersion, VS_VERSIONED_ON_UPLOAD_FIRST_DISPLAY);
assertEquals(expectedWithVer, resultWithVer.getCodeDisplay());
@ -231,15 +232,15 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
private void lookupForVersion(String theVersion) {
IValidationSupport.LookupCodeResult resultNoVer = myValidationSupport.lookupCode(
new ValidationSupportContext(myValidationSupport), BASE_LOINC_URL + "|" + theVersion,
VS_NO_VERSIONED_ON_UPLOAD_FIRST_CODE, null);
new ValidationSupportContext(myValidationSupport),
new LookupCodeRequest(BASE_LOINC_URL + "|" + theVersion, VS_NO_VERSIONED_ON_UPLOAD_FIRST_CODE));
assertNotNull(resultNoVer);
String expectedNoVer = prefixWithVersion(theVersion, VS_NO_VERSIONED_ON_UPLOAD_FIRST_DISPLAY);
assertEquals(expectedNoVer, resultNoVer.getCodeDisplay());
IValidationSupport.LookupCodeResult resultWithVer = myValidationSupport.lookupCode(
new ValidationSupportContext(myValidationSupport), BASE_LOINC_URL + "|" + theVersion,
VS_VERSIONED_ON_UPLOAD_FIRST_CODE, null);
new ValidationSupportContext(myValidationSupport),
new LookupCodeRequest(BASE_LOINC_URL + "|" + theVersion, VS_VERSIONED_ON_UPLOAD_FIRST_CODE));
assertNotNull(resultWithVer);
String expectedWithVer = prefixWithVersion(theVersion, VS_VERSIONED_ON_UPLOAD_FIRST_DISPLAY);
assertEquals(expectedWithVer, resultWithVer.getCodeDisplay());

View File

@ -0,0 +1,89 @@
package ca.uhn.fhir.jpa.provider.r5;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.provider.CodeSystemLookupWithPropertiesUtil;
import ca.uhn.fhir.rest.gclient.IOperationUntypedWithInputAndPartialOutput;
import org.hl7.fhir.r5.model.CodeSystem;
import org.hl7.fhir.r5.model.CodeType;
import org.hl7.fhir.r5.model.Parameters;
import org.hl7.fhir.r5.model.StringType;
import org.hl7.fhir.r5.model.UriType;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Stream;
import static ca.uhn.fhir.jpa.provider.CodeSystemLookupWithPropertiesUtil.ourCode;
import static ca.uhn.fhir.jpa.provider.CodeSystemLookupWithPropertiesUtil.ourCodeSystemId;
import static ca.uhn.fhir.jpa.provider.CodeSystemLookupWithPropertiesUtil.ourCodeSystemUrl;
import static ca.uhn.fhir.jpa.provider.CodeSystemLookupWithPropertiesUtil.ourPropertyA;
import static ca.uhn.fhir.jpa.provider.CodeSystemLookupWithPropertiesUtil.ourPropertyB;
import static ca.uhn.fhir.jpa.provider.CodeSystemLookupWithPropertiesUtil.ourPropertyValueA;
import static ca.uhn.fhir.jpa.provider.CodeSystemLookupWithPropertiesUtil.ourPropertyValueB;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class ResourceProviderR5CodeSystemPropertiesTest extends BaseResourceProviderR5Test {
public static Stream<Arguments> parametersLookup() {
return CodeSystemLookupWithPropertiesUtil.parametersLookupWithProperties();
}
@ParameterizedTest
@MethodSource(value = "parametersLookup")
public void testLookup_withProperties_returnsCorrectParameters(List<String> theLookupProperties, List<String> theExpectedReturnedProperties) {
// setup
CodeSystem codeSystem = new CodeSystem();
codeSystem.setId(ourCodeSystemId);
codeSystem.setUrl(ourCodeSystemUrl);
CodeSystem.ConceptDefinitionComponent concept = codeSystem.addConcept().setCode(ourCode);
CodeSystem.ConceptPropertyComponent propertyComponent = new CodeSystem.ConceptPropertyComponent()
.setCode(ourPropertyA).setValue(new StringType(ourPropertyValueA));
concept.addProperty(propertyComponent);
propertyComponent = new CodeSystem.ConceptPropertyComponent()
.setCode(ourPropertyB).setValue(new StringType(ourPropertyValueB));
concept.addProperty(propertyComponent);
myCodeSystemDao.create(codeSystem, mySrd);
// test
IOperationUntypedWithInputAndPartialOutput<Parameters> respParam = myClient
.operation()
.onType(CodeSystem.class)
.named(JpaConstants.OPERATION_LOOKUP)
.withParameter(Parameters.class, "code", new CodeType(ourCode))
.andParameter("system", new UriType(ourCodeSystemUrl));
theLookupProperties.forEach(p -> respParam.andParameter("property", new CodeType(p)));
Parameters parameters = respParam.execute();
if (theExpectedReturnedProperties.isEmpty()) {
assertFalse(parameters.hasParameter("property"));
return;
}
assertTrue(parameters.hasParameter("property"));
Iterator<Parameters.ParametersParameterComponent> parameterPropertyIterator = parameters.getParameters("property").iterator();
Iterator<CodeSystem.ConceptPropertyComponent> propertyIterator = concept.getProperty().stream()
.filter(property -> theExpectedReturnedProperties.contains(property.getCode())).iterator();
while (propertyIterator.hasNext()) {
CodeSystem.ConceptPropertyComponent property = propertyIterator.next();
assertTrue(parameterPropertyIterator.hasNext());
Parameters.ParametersParameterComponent parameter = parameterPropertyIterator.next();
Iterator<Parameters.ParametersParameterComponent> parameterPartIterator = parameter.getPart().iterator();
parameter = parameterPartIterator.next();
assertEquals("code", parameter.getName());
assertEquals(property.getCode(), ((CodeType)parameter.getValue()).getCode());
parameter = parameterPartIterator.next();
assertEquals("value", parameter.getName());
assertTrue(property.getValue().equalsShallow(parameter.getValue()));
}
}
}

View File

@ -1,5 +1,6 @@
package ca.uhn.fhir.jpa.provider.r5;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
@ -12,7 +13,6 @@ import ca.uhn.fhir.jpa.entity.TermValueSetConcept;
import ca.uhn.fhir.jpa.entity.TermValueSetPreExpansionStatusEnum;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.provider.ValueSetOperationProvider;
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc;
import ca.uhn.fhir.jpa.term.api.ITermReadSvc;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
@ -1229,13 +1229,13 @@ public class ResourceProviderR5ValueSetTest extends BaseResourceProviderR5Test {
String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(respParam);
ourLog.info(resp);
assertEquals(ValueSetOperationProvider.RESULT, respParam.getParameter().get(0).getName());
assertEquals(IValidationSupport.CodeValidationResult.RESULT, respParam.getParameter().get(0).getName());
assertEquals(true, ((BooleanType) respParam.getParameter().get(0).getValue()).getValue());
assertEquals(ValueSetOperationProvider.DISPLAY, respParam.getParameter().get(1).getName());
assertEquals(IValidationSupport.CodeValidationResult.DISPLAY, respParam.getParameter().get(1).getName());
assertEquals("Male", ((StringType) respParam.getParameter().get(1).getValue()).getValue());
assertEquals(ValueSetOperationProvider.SOURCE_DETAILS, respParam.getParameter().get(2).getName());
assertEquals(IValidationSupport.CodeValidationResult.SOURCE_DETAILS, respParam.getParameter().get(2).getName());
assertEquals("Code was validated against in-memory expansion of ValueSet: http://hl7.org/fhir/ValueSet/administrative-gender", ((StringType) respParam.getParameter().get(2).getValue()).getValue());
}

View File

@ -0,0 +1,28 @@
package ca.uhn.fhir.jpa.provider;
import org.junit.jupiter.params.provider.Arguments;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;
import static org.junit.jupiter.params.provider.Arguments.arguments;
public class CodeSystemLookupWithPropertiesUtil {
public static final String ourCodeSystemId = "CodeSystem-Example",
ourCodeSystemUrl = "http://example/" + ourCodeSystemId;
public static final String ourCode = "Code-WithProperties";
public static final String ourPropertyA = "Property-A", ourPropertyB = "Property-B";
public static final String ourPropertyValueA = "Value-A", ourPropertyValueB = "Value-B";
public static Stream<Arguments> parametersLookupWithProperties() {
return Stream.of(
arguments(List.of(ourPropertyB), List.of(ourPropertyB)),
arguments(List.of(ourPropertyA, ourPropertyB), List.of(ourPropertyA, ourPropertyB)),
arguments(List.of(ourPropertyB, ourPropertyA), List.of(ourPropertyB, ourPropertyA)),
arguments(List.of(ourPropertyA, ourPropertyA), List.of(ourPropertyA, ourPropertyA)),
arguments(List.of(ourPropertyB, "ABC"), List.of(ourPropertyB)),
arguments(List.of("ABC", ourPropertyA), List.of(ourPropertyA)),
arguments(List.of("ABC"), Collections.emptyList()));
}
}

View File

@ -24,6 +24,7 @@ import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
import ca.uhn.fhir.context.RuntimePrimitiveDatatypeDefinition;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.context.support.LookupCodeRequest;
import ca.uhn.fhir.context.support.ValidationSupportContext;
import ca.uhn.fhir.interceptor.api.Hook;
import ca.uhn.fhir.interceptor.api.Pointcut;
@ -122,8 +123,8 @@ public class ResponseTerminologyDisplayPopulationInterceptor extends BaseRespons
ValidationSupportContext validationSupportContext = new ValidationSupportContext(myValidationSupport);
if (myValidationSupport.isCodeSystemSupported(validationSupportContext, system)) {
IValidationSupport.LookupCodeResult lookupCodeResult =
myValidationSupport.lookupCode(validationSupportContext, system, code);
IValidationSupport.LookupCodeResult lookupCodeResult = myValidationSupport.lookupCode(
validationSupportContext, new LookupCodeRequest(system, code));
if (lookupCodeResult != null && lookupCodeResult.isFound()) {
String newDisplay = lookupCodeResult.getCodeDisplay();
IPrimitiveType<?> newString = myStringDefinition.newInstance(newDisplay);

View File

@ -32,6 +32,7 @@ import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.r4.model.codesystems.ConceptSubsumptionOutcome;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collection;
import java.util.List;
import javax.annotation.Nonnull;
@ -55,6 +56,15 @@ public interface IFhirResourceDaoCodeSystem<T extends IBaseResource> extends IFh
IPrimitiveType<String> theDisplayLanguage,
RequestDetails theRequestDetails);
@Nonnull
IValidationSupport.LookupCodeResult lookupCode(
IPrimitiveType<String> theCode,
IPrimitiveType<String> theSystem,
IBaseCoding theCoding,
IPrimitiveType<String> theDisplayLanguage,
Collection<IPrimitiveType<String>> thePropertyNames,
RequestDetails theRequestDetails);
SubsumesResult subsumes(
IPrimitiveType<String> theCodeA,
IPrimitiveType<String> theCodeB,

View File

@ -3,6 +3,7 @@ package org.hl7.fhir.common.hapi.validation.support;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.support.ConceptValidationOptions;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.context.support.LookupCodeRequest;
import ca.uhn.fhir.context.support.TranslateConceptResults;
import ca.uhn.fhir.context.support.ValidationSupportContext;
import ca.uhn.fhir.context.support.ValueSetExpansionOptions;
@ -98,11 +99,8 @@ public abstract class BaseValidationSupportWrapper extends BaseValidationSupport
@Override
public LookupCodeResult lookupCode(
ValidationSupportContext theValidationSupportContext,
String theSystem,
String theCode,
String theDisplayLanguage) {
return myWrap.lookupCode(theValidationSupportContext, theSystem, theCode, theDisplayLanguage);
ValidationSupportContext theValidationSupportContext, @Nonnull LookupCodeRequest theLookupCodeRequest) {
return myWrap.lookupCode(theValidationSupportContext, theLookupCodeRequest);
}
@Override

View File

@ -3,6 +3,7 @@ package org.hl7.fhir.common.hapi.validation.support;
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
import ca.uhn.fhir.context.support.ConceptValidationOptions;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.context.support.LookupCodeRequest;
import ca.uhn.fhir.context.support.TranslateConceptResults;
import ca.uhn.fhir.context.support.ValidationSupportContext;
import ca.uhn.fhir.context.support.ValueSetExpansionOptions;
@ -195,15 +196,13 @@ public class CachingValidationSupport extends BaseValidationSupportWrapper imple
@Override
public LookupCodeResult lookupCode(
ValidationSupportContext theValidationSupportContext,
String theSystem,
String theCode,
String theDisplayLanguage) {
String key = "lookupCode " + theSystem + " " + theCode + " " + defaultIfBlank(theDisplayLanguage, "NO_LANG");
ValidationSupportContext theValidationSupportContext, @Nonnull LookupCodeRequest theLookupCodeRequest) {
String key = "lookupCode " + theLookupCodeRequest.getSystem() + " "
+ theLookupCodeRequest.getCode()
+ " " + defaultIfBlank(theLookupCodeRequest.getDisplayLanguage(), "NO_LANG")
+ " " + theLookupCodeRequest.getPropertyNames().toString();
return loadFromCache(
myLookupCodeCache,
key,
t -> super.lookupCode(theValidationSupportContext, theSystem, theCode, theDisplayLanguage));
myLookupCodeCache, key, t -> super.lookupCode(theValidationSupportContext, theLookupCodeRequest));
}
@Override

View File

@ -5,6 +5,7 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.support.ConceptValidationOptions;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.context.support.LookupCodeRequest;
import ca.uhn.fhir.context.support.ValidationSupportContext;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.util.ClasspathUtil;
@ -221,7 +222,8 @@ public class CommonCodeSystemsTerminologyService implements IValidationSupport {
@Nullable
public CodeValidationResult validateLookupCode(
ValidationSupportContext theValidationSupportContext, String theCode, String theSystem) {
LookupCodeResult lookupResult = lookupCode(theValidationSupportContext, theSystem, theCode);
LookupCodeResult lookupResult =
lookupCode(theValidationSupportContext, new LookupCodeRequest(theSystem, theCode));
CodeValidationResult validationResult = null;
if (lookupResult != null) {
if (lookupResult.isFound()) {
@ -240,18 +242,18 @@ public class CommonCodeSystemsTerminologyService implements IValidationSupport {
@Override
public LookupCodeResult lookupCode(
ValidationSupportContext theValidationSupportContext,
String theSystem,
String theCode,
String theDisplayLanguage) {
ValidationSupportContext theValidationSupportContext, @Nonnull LookupCodeRequest theLookupCodeRequest) {
final String code = theLookupCodeRequest.getCode();
final String system = theLookupCodeRequest.getSystem();
Map<String, String> map;
switch (theSystem) {
switch (system) {
case LANGUAGES_CODESYSTEM_URL:
return lookupLanguageCode(theCode);
return lookupLanguageCode(code);
case UCUM_CODESYSTEM_URL:
return lookupUcumCode(theCode);
return lookupUcumCode(code);
case MIMETYPES_CODESYSTEM_URL:
return lookupMimetypeCode(theCode);
return lookupMimetypeCode(code);
case COUNTRIES_CODESYSTEM_URL:
map = ISO_3166_CODES;
break;
@ -265,11 +267,11 @@ public class CommonCodeSystemsTerminologyService implements IValidationSupport {
return null;
}
String display = map.get(theCode);
String display = map.get(code);
if (isNotBlank(display)) {
LookupCodeResult retVal = new LookupCodeResult();
retVal.setSearchedForCode(theCode);
retVal.setSearchedForSystem(theSystem);
retVal.setSearchedForCode(code);
retVal.setSearchedForSystem(system);
retVal.setFound(true);
retVal.setCodeDisplay(display);
return retVal;
@ -277,10 +279,10 @@ public class CommonCodeSystemsTerminologyService implements IValidationSupport {
// If we get here it means we know the codesystem but the code was bad
LookupCodeResult retVal = new LookupCodeResult();
retVal.setSearchedForCode(theCode);
retVal.setSearchedForSystem(theSystem);
retVal.setSearchedForCode(code);
retVal.setSearchedForSystem(system);
retVal.setFound(false);
retVal.setErrorMessage("Code '" + theCode + "' is not valid for system: " + theSystem);
retVal.setErrorMessage("Code '" + code + "' is not valid for system: " + system);
return retVal;
}
@ -384,7 +386,7 @@ public class CommonCodeSystemsTerminologyService implements IValidationSupport {
String language = theNext.get("Subtag").asText();
ArrayNode descriptions = (ArrayNode) theNext.get("Description");
String description = null;
if (descriptions.size() > 0) {
if (!descriptions.isEmpty()) {
description = descriptions.get(0).asText();
}
theLanguagesMap.put(language, description);
@ -403,7 +405,7 @@ public class CommonCodeSystemsTerminologyService implements IValidationSupport {
@Nonnull
private LookupCodeResult lookupUcumCode(String theCode) {
InputStream input = ClasspathUtil.loadResourceAsStream("/ucum-essence.xml");
String outcome = null;
String outcome;
LookupCodeResult retVal = new LookupCodeResult();
retVal.setSearchedForCode(theCode);
retVal.setSearchedForSystem(UCUM_CODESYSTEM_URL);

View File

@ -4,6 +4,7 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.support.ConceptValidationOptions;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.context.support.LookupCodeRequest;
import ca.uhn.fhir.context.support.ValidationSupportContext;
import ca.uhn.fhir.context.support.ValueSetExpansionOptions;
import ca.uhn.fhir.i18n.Msg;
@ -611,16 +612,20 @@ public class InMemoryTerminologyServerValidationSupport implements IValidationSu
@Override
public LookupCodeResult lookupCode(
ValidationSupportContext theValidationSupportContext,
String theSystem,
String theCode,
String theDisplayLanguage) {
ValidationSupportContext theValidationSupportContext, @Nonnull LookupCodeRequest theLookupCodeRequest) {
final String code = theLookupCodeRequest.getCode();
final String system = theLookupCodeRequest.getSystem();
CodeValidationResult codeValidationResult = validateCode(
theValidationSupportContext, new ConceptValidationOptions(), theSystem, theCode, null, null);
theValidationSupportContext,
new ConceptValidationOptions(),
system,
code,
theLookupCodeRequest.getDisplayLanguage(),
null);
if (codeValidationResult == null) {
return null;
}
return codeValidationResult.asLookupCodeResult(theSystem, theCode);
return codeValidationResult.asLookupCodeResult(system, code);
}
@Nullable
@ -927,9 +932,7 @@ public class InMemoryTerminologyServerValidationSupport implements IValidationSu
.getRootValidationSupport()
.lookupCode(
theValidationSupportContext,
includeOrExcludeConceptSystemUrl,
theWantCode,
null);
new LookupCodeRequest(includeOrExcludeConceptSystemUrl, theWantCode));
if (lookup != null) {
ableToHandleCode = true;
if (lookup.isFound()) {

View File

@ -5,6 +5,7 @@ import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.support.ConceptValidationOptions;
import ca.uhn.fhir.context.support.DefaultProfileValidationSupport;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.context.support.LookupCodeRequest;
import ca.uhn.fhir.context.support.TranslateConceptResults;
import ca.uhn.fhir.context.support.ValidationSupportContext;
import ca.uhn.fhir.i18n.Msg;
@ -183,11 +184,11 @@ public class RemoteTerminologyServiceValidationSupport extends BaseValidationSup
@Override
public LookupCodeResult lookupCode(
ValidationSupportContext theValidationSupportContext,
String theSystem,
String theCode,
String theDisplayLanguage) {
Validate.notBlank(theCode, "theCode must be provided");
ValidationSupportContext theValidationSupportContext, @Nonnull LookupCodeRequest theLookupCodeRequest) {
final String code = theLookupCodeRequest.getCode();
final String system = theLookupCodeRequest.getSystem();
final String displayLanguage = theLookupCodeRequest.getDisplayLanguage();
Validate.notBlank(code, "theCode must be provided");
IGenericClient client = provideClient();
FhirContext fhirContext = client.getFhirContext();
@ -197,17 +198,20 @@ public class RemoteTerminologyServiceValidationSupport extends BaseValidationSup
case DSTU3:
case R4:
IBaseParameters params = ParametersUtil.newInstance(fhirContext);
ParametersUtil.addParameterToParametersString(fhirContext, params, "code", theCode);
if (!StringUtils.isEmpty(theSystem)) {
ParametersUtil.addParameterToParametersString(fhirContext, params, "system", theSystem);
ParametersUtil.addParameterToParametersString(fhirContext, params, "code", code);
if (!StringUtils.isEmpty(system)) {
ParametersUtil.addParameterToParametersString(fhirContext, params, "system", system);
}
if (!StringUtils.isEmpty(theDisplayLanguage)) {
ParametersUtil.addParameterToParametersString(fhirContext, params, "language", theDisplayLanguage);
if (!StringUtils.isEmpty(displayLanguage)) {
ParametersUtil.addParameterToParametersString(fhirContext, params, "language", displayLanguage);
}
Class<?> codeSystemClass =
for (String propertyName : theLookupCodeRequest.getPropertyNames()) {
ParametersUtil.addParameterToParametersString(fhirContext, params, "property", propertyName);
}
Class<? extends IBaseResource> codeSystemClass =
myCtx.getResourceDefinition("CodeSystem").getImplementingClass();
IBaseParameters outcome = client.operation()
.onType((Class<? extends IBaseResource>) codeSystemClass)
.onType(codeSystemClass)
.named("$lookup")
.withParameters(params)
.useHttpGet()
@ -216,10 +220,9 @@ public class RemoteTerminologyServiceValidationSupport extends BaseValidationSup
switch (fhirVersion) {
case DSTU3:
return generateLookupCodeResultDSTU3(
theCode, theSystem, (org.hl7.fhir.dstu3.model.Parameters) outcome);
code, system, (org.hl7.fhir.dstu3.model.Parameters) outcome);
case R4:
return generateLookupCodeResultR4(
theCode, theSystem, (org.hl7.fhir.r4.model.Parameters) outcome);
return generateLookupCodeResultR4(code, system, (org.hl7.fhir.r4.model.Parameters) outcome);
}
}
break;

View File

@ -2,6 +2,7 @@ package org.hl7.fhir.common.hapi.validation.support;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.support.ConceptValidationOptions;
import ca.uhn.fhir.context.support.LookupCodeRequest;
import ca.uhn.fhir.context.support.ValidationSupportContext;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.IBaseResource;
@ -51,12 +52,9 @@ public class UnknownCodeSystemWarningValidationSupport extends BaseValidationSup
@Nullable
@Override
public LookupCodeResult lookupCode(
ValidationSupportContext theValidationSupportContext,
String theSystem,
String theCode,
String theDisplayLanguage) {
ValidationSupportContext theValidationSupportContext, @Nonnull LookupCodeRequest theLookupCodeRequest) {
// filters out error/fatal
if (canValidateCodeSystem(theValidationSupportContext, theSystem)) {
if (canValidateCodeSystem(theValidationSupportContext, theLookupCodeRequest.getSystem())) {
return new LookupCodeResult().setFound(true);
}

View File

@ -5,6 +5,7 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.support.ConceptValidationOptions;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.context.support.LookupCodeRequest;
import ca.uhn.fhir.context.support.TranslateConceptResults;
import ca.uhn.fhir.context.support.ValidationSupportContext;
import ca.uhn.fhir.context.support.ValueSetExpansionOptions;
@ -416,20 +417,26 @@ public class ValidationSupportChain implements IValidationSupport {
@Override
public LookupCodeResult lookupCode(
ValidationSupportContext theValidationSupportContext,
String theSystem,
String theCode,
String theDisplayLanguage) {
ValidationSupportContext theValidationSupportContext, @Nonnull LookupCodeRequest theLookupCodeRequest) {
for (IValidationSupport next : myChain) {
if (next.isCodeSystemSupported(theValidationSupportContext, theSystem)) {
LookupCodeResult lookupCodeResult =
next.lookupCode(theValidationSupportContext, theSystem, theCode, theDisplayLanguage);
final String system = theLookupCodeRequest.getSystem();
final String code = theLookupCodeRequest.getCode();
final String displayLanguage = theLookupCodeRequest.getDisplayLanguage();
if (next.isCodeSystemSupported(theValidationSupportContext, system)) {
LookupCodeResult lookupCodeResult = next.lookupCode(theValidationSupportContext, theLookupCodeRequest);
if (lookupCodeResult == null) {
/*
This branch has been added as a fall-back mechanism for supporting lookupCode
methods marked as deprecated in interface IValidationSupport.
*/
lookupCodeResult = next.lookupCode(theValidationSupportContext, system, code, displayLanguage);
}
if (ourLog.isDebugEnabled()) {
ourLog.debug(
"Code {}|{}{} {} by {}",
theSystem,
theCode,
isBlank(theDisplayLanguage) ? "" : " (" + theDisplayLanguage + ")",
system,
code,
isBlank(displayLanguage) ? "" : " (" + theLookupCodeRequest.getDisplayLanguage() + ")",
lookupCodeResult != null && lookupCodeResult.isFound() ? "found" : "not found",
next.getName());
}

View File

@ -138,16 +138,6 @@ public class ResponseTerminologyDisplayPopulationInterceptorTest {
public boolean isCodeSystemSupported(ValidationSupportContext theValidationSupportContext, String theSystem) {
return true;
}
@Override
public LookupCodeResult lookupCode(ValidationSupportContext theValidationSupportContext, String theSystem, String theCode, String theDisplayLanguage) {
return null;
}
@Override
public LookupCodeResult lookupCode(ValidationSupportContext theValidationSupportContext, String theSystem, String theCode) {
return lookupCode(theValidationSupportContext, theSystem, theCode, null);
}
}
}

View File

@ -4,6 +4,7 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.support.ConceptValidationOptions;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.context.support.ValidationSupportContext;
import ca.uhn.fhir.context.support.LookupCodeRequest;
import ca.uhn.fhir.i18n.Msg;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.CodeSystem;
@ -31,35 +32,35 @@ public class CommonCodeSystemsTerminologyServiceTest {
@Test
public void testUcum_LookupCode_Good() {
IValidationSupport.LookupCodeResult outcome = mySvc.lookupCode(newSupport(), "http://unitsofmeasure.org", "Cel");
IValidationSupport.LookupCodeResult outcome = mySvc.lookupCode(newSupport(), new LookupCodeRequest("http://unitsofmeasure.org", "Cel"));
assert outcome != null;
assertTrue(outcome.isFound());
}
@Test
public void testUcum_LookupCode_Good2() {
IValidationSupport.LookupCodeResult outcome = mySvc.lookupCode(newSupport(), "http://unitsofmeasure.org", "kg/m2");
IValidationSupport.LookupCodeResult outcome = mySvc.lookupCode(newSupport(), new LookupCodeRequest("http://unitsofmeasure.org", "kg/m2"));
assert outcome != null;
assertTrue(outcome.isFound());
}
@Test
public void testUcum_LookupCode_Bad() {
IValidationSupport.LookupCodeResult outcome = mySvc.lookupCode(newSupport(), "http://unitsofmeasure.org", "AAAAA");
IValidationSupport.LookupCodeResult outcome = mySvc.lookupCode(newSupport(), new LookupCodeRequest("http://unitsofmeasure.org", "AAAAA"));
assert outcome != null;
assertFalse(outcome.isFound());
}
@Test
public void testUcum_LookupCode_UnknownSystem() {
IValidationSupport.LookupCodeResult outcome = mySvc.lookupCode(newSupport(), "http://foo", "AAAAA", null);
IValidationSupport.LookupCodeResult outcome = mySvc.lookupCode(newSupport(), new LookupCodeRequest("http://foo", "AAAAA"));
assertNull(outcome);
}
@Test
public void lookupCode_languageOnlyLookup_isCaseInsensitive() {
IValidationSupport.LookupCodeResult outcomeUpper = mySvc.lookupCode(newSupport(), "urn:ietf:bcp:47", "SGN", "Sign Languages");
IValidationSupport.LookupCodeResult outcomeLower = mySvc.lookupCode(newSupport(), "urn:ietf:bcp:47", "sgn", "Sign Languages");
IValidationSupport.LookupCodeResult outcomeUpper = mySvc.lookupCode(newSupport(), new LookupCodeRequest("urn:ietf:bcp:47", "SGN", "Sign Languages", null));
IValidationSupport.LookupCodeResult outcomeLower = mySvc.lookupCode(newSupport(), new LookupCodeRequest("urn:ietf:bcp:47", "sgn", "Sign Languages", null));
assertNotNull(outcomeUpper);
assertNotNull(outcomeLower);
assertTrue(outcomeLower.isFound());
@ -68,8 +69,8 @@ public class CommonCodeSystemsTerminologyServiceTest {
@Test
public void lookupCode_languageAndRegionLookup_isCaseInsensitive() {
IValidationSupport.LookupCodeResult outcomeUpper = mySvc.lookupCode(newSupport(), "urn:ietf:bcp:47", "EN-US", "English");
IValidationSupport.LookupCodeResult outcomeLower = mySvc.lookupCode(newSupport(), "urn:ietf:bcp:47", "en-us", "English");
IValidationSupport.LookupCodeResult outcomeUpper = mySvc.lookupCode(newSupport(), new LookupCodeRequest("urn:ietf:bcp:47", "EN-US", "English", null));
IValidationSupport.LookupCodeResult outcomeLower = mySvc.lookupCode(newSupport(), new LookupCodeRequest("urn:ietf:bcp:47", "en-us", "English", null));
assertNotNull(outcomeUpper);
assertNotNull(outcomeLower);
assertTrue(outcomeLower.isFound());
@ -131,14 +132,14 @@ public class CommonCodeSystemsTerminologyServiceTest {
@Test
public void testLanguages_CommonLanguagesVs_OnlyLanguage_NoRegion() {
IValidationSupport.LookupCodeResult nl = mySvc.lookupCode(newSupport(), "urn:ietf:bcp:47", "nl");
IValidationSupport.LookupCodeResult nl = mySvc.lookupCode(newSupport(), new LookupCodeRequest("urn:ietf:bcp:47", "nl"));
assertTrue(nl.isFound());
assertEquals("Dutch", nl.getCodeDisplay());
}
@Test
public void testLanguages_CommonLanguagesVs_LanguageAndRegion() {
IValidationSupport.LookupCodeResult nl = mySvc.lookupCode(newSupport(), "urn:ietf:bcp:47", "nl-NL");
IValidationSupport.LookupCodeResult nl = mySvc.lookupCode(newSupport(), new LookupCodeRequest("urn:ietf:bcp:47", "nl-NL"));
assertTrue(nl.isFound());
assertEquals("Dutch Netherlands", nl.getCodeDisplay());
}

View File

@ -5,6 +5,7 @@ import ca.uhn.fhir.context.support.ConceptValidationOptions;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.context.support.TranslateConceptResult;
import ca.uhn.fhir.context.support.TranslateConceptResults;
import ca.uhn.fhir.context.support.LookupCodeRequest;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.parser.IJsonLikeParser;
import ca.uhn.fhir.rest.annotation.IdParam;
@ -24,6 +25,7 @@ import ca.uhn.fhir.test.utilities.server.RestfulServerExtension;
import ca.uhn.fhir.util.ParametersUtil;
import com.google.common.collect.Lists;
import org.hl7.fhir.instance.model.api.IBaseCoding;
import org.hl7.fhir.instance.model.api.IBaseParameters;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.BooleanType;
import org.hl7.fhir.r4.model.CodeSystem;
@ -47,11 +49,14 @@ import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.lessThan;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
@ -60,8 +65,7 @@ public class RemoteTerminologyServiceValidationSupportTest {
private static final String DISPLAY = "DISPLAY";
private static final String LANGUAGE = "en";
private static final String CODE_SYSTEM = "CODE_SYS";
private static final String CODE_SYSTEM_VERSION = "2.1";
private static final String CODE_SYSTEM_VERSION_AS_TEXT = "v2.1.12";
private static final String CODE_SYSTEM_NAME = "Code System";
private static final String CODE = "CODE";
private static final String VALUE_SET_URL = "http://value.set/url";
private static final String TARGET_SYSTEM = "http://target.system/url";
@ -77,10 +81,10 @@ public class RemoteTerminologyServiceValidationSupportTest {
private static final String ERROR_MESSAGE = "This is an error message";
private static final String SUCCESS_MESSAGE = "This is a success message";
private static FhirContext ourCtx = FhirContext.forR4Cached();
private static final FhirContext ourCtx = FhirContext.forR4Cached();
@RegisterExtension
public RestfulServerExtension myRestfulServerExtension = new RestfulServerExtension(ourCtx);
public static RestfulServerExtension ourRestfulServerExtension = new RestfulServerExtension(ourCtx);
private MyValueSetProvider myValueSetProvider;
private RemoteTerminologyServiceValidationSupport mySvc;
@ -90,15 +94,15 @@ public class RemoteTerminologyServiceValidationSupportTest {
@BeforeEach
public void before() {
myValueSetProvider = new MyValueSetProvider();
myRestfulServerExtension.getRestfulServer().registerProvider(myValueSetProvider);
ourRestfulServerExtension.getRestfulServer().registerProvider(myValueSetProvider);
myCodeSystemProvider = new MyCodeSystemProvider();
myRestfulServerExtension.getRestfulServer().registerProvider(myCodeSystemProvider);
ourRestfulServerExtension.getRestfulServer().registerProvider(myCodeSystemProvider);
myConceptMapProvider = new MyConceptMapProvider();
myRestfulServerExtension.getRestfulServer().registerProvider(myConceptMapProvider);
ourRestfulServerExtension.getRestfulServer().registerProvider(myConceptMapProvider);
String baseUrl = "http://localhost:" + myRestfulServerExtension.getPort();
String baseUrl = "http://localhost:" + ourRestfulServerExtension.getPort();
mySvc = new RemoteTerminologyServiceValidationSupport(ourCtx);
mySvc.setBaseUrl(baseUrl);
@ -111,69 +115,98 @@ public class RemoteTerminologyServiceValidationSupportTest {
}
@Test
public void testValidateCode_SystemCodeDisplayUrl_BlankCode() {
public void testValidateCode_withBlankCode_returnsNull() {
IValidationSupport.CodeValidationResult outcome = mySvc.validateCode(null, null, CODE_SYSTEM, "", DISPLAY, VALUE_SET_URL);
assertEquals(null, outcome);
assertNull(outcome);
}
@Test
public void testLookupOperation_CodeSystem_Success() {
createNextCodeSystemLookupReturnParameters(true, CODE_SYSTEM_VERSION, CODE_SYSTEM_VERSION_AS_TEXT,
DISPLAY, null);
IValidationSupport.LookupCodeResult outcome = mySvc.lookupCode(null, CODE_SYSTEM, CODE);
@Test
public void testLookupCode_forCodeSystemWithAllParams_returnsCorrectParameters() {
myCodeSystemProvider.myNextLookupCodeResult = new IValidationSupport.LookupCodeResult();
myCodeSystemProvider.myNextLookupCodeResult.setFound(true);
myCodeSystemProvider.myNextLookupCodeResult.setCodeSystemVersion(CODE_SYSTEM);
myCodeSystemProvider.myNextLookupCodeResult.setSearchedForCode(CODE);
myCodeSystemProvider.myNextLookupCodeResult.setCodeSystemDisplayName(CODE_SYSTEM_NAME);
myCodeSystemProvider.myNextLookupCodeResult.setCodeDisplay(DISPLAY);
// property
String propertyName = "birthDate";
String propertyValue = "1930-01-01";
IValidationSupport.BaseConceptProperty property = new IValidationSupport.StringConceptProperty(propertyName, propertyValue);
myCodeSystemProvider.myNextLookupCodeResult.getProperties().add(property);
// designation
IValidationSupport.ConceptDesignation designation = new IValidationSupport.ConceptDesignation();
designation.setLanguage("en");
designation.setUseCode("code");
designation.setUseSystem("system");
designation.setUseDisplay("display");
designation.setValue("some value");
myCodeSystemProvider.myNextLookupCodeResult.getDesignations().add(designation);
IValidationSupport.LookupCodeResult outcome = mySvc.lookupCode(null, new LookupCodeRequest(CODE_SYSTEM, CODE, null, Set.of("birthDate")));
assertNotNull(outcome, "Call to lookupCode() should return a non-NULL result!");
assertEquals(DISPLAY, outcome.getCodeDisplay());
assertEquals(CODE_SYSTEM_VERSION, outcome.getCodeSystemVersion());
assertEquals(CODE_SYSTEM, outcome.getCodeSystemVersion());
assertEquals(CODE_SYSTEM_NAME, myCodeSystemProvider.myNextReturnParams.getParameterValue("name").toString());
assertEquals(CODE, myCodeSystemProvider.myLastCode.getCode());
assertEquals(CODE_SYSTEM, myCodeSystemProvider.myLastUrl.getValueAsString());
assertEquals(CODE_SYSTEM_VERSION_AS_TEXT, myCodeSystemProvider.myNextReturnParams.getParameterValue("name").toString());
assertTrue(Boolean.parseBoolean(myCodeSystemProvider.myNextReturnParams.getParameterValue("result").primitiveValue()));
Parameters.ParametersParameterComponent propertyComponent = myCodeSystemProvider.myNextReturnParams.getParameter("property");
assertNotNull(propertyComponent);
Iterator<Parameters.ParametersParameterComponent> propertyComponentIterator = propertyComponent.getPart().iterator();
propertyComponent = propertyComponentIterator.next();
assertEquals("code", propertyComponent.getName());
assertEquals(propertyName, ((StringType)propertyComponent.getValue()).getValue());
propertyComponent = propertyComponentIterator.next();
assertEquals("value", propertyComponent.getName());
assertEquals(propertyValue, ((StringType)propertyComponent.getValue()).getValue());
Parameters.ParametersParameterComponent designationComponent = myCodeSystemProvider.myNextReturnParams.getParameter("designation");
Iterator<Parameters.ParametersParameterComponent> partParameter = designationComponent.getPart().iterator();
designationComponent = partParameter.next();
assertEquals("language", designationComponent.getName());
assertEquals(LANGUAGE, designationComponent.getValue().toString());
designationComponent = partParameter.next();
assertEquals("use", designationComponent.getName());
Coding coding = (Coding)designationComponent.getValue();
assertNotNull(coding, "Coding value returned via designation use should NOT be NULL!");
assertEquals("code", coding.getCode());
assertEquals("system", coding.getSystem());
assertEquals("display", coding.getDisplay());
designationComponent = partParameter.next();
assertEquals("value", designationComponent.getName());
assertEquals("some value", designationComponent.getValue().toString());
}
@Test
public void testLookupOperationWithAllParams_CodeSystem_Success() {
createNextCodeSystemLookupReturnParameters(true, CODE_SYSTEM_VERSION, CODE_SYSTEM_VERSION_AS_TEXT,
DISPLAY, null);
addAdditionalReturnParameters();
IValidationSupport.LookupCodeResult outcome = mySvc.lookupCode(null, CODE_SYSTEM, CODE);
assertNotNull(outcome, "Call to lookupCode() should return a non-NULL result!");
assertEquals(DISPLAY, outcome.getCodeDisplay());
assertEquals(CODE_SYSTEM_VERSION, outcome.getCodeSystemVersion());
assertEquals(CODE_SYSTEM_VERSION_AS_TEXT, myCodeSystemProvider.myNextReturnParams.getParameterValue("name").toString());
assertEquals(CODE, myCodeSystemProvider.myLastCode.getCode());
assertEquals(CODE_SYSTEM, myCodeSystemProvider.myLastUrl.getValueAsString());
assertTrue(Boolean.parseBoolean(myCodeSystemProvider.myNextReturnParams.getParameterValue("result").primitiveValue()));
validateExtraCodeSystemParams();
public void testLookupCode_forCodeSystemWithBlankCode_throwsException() {
Assertions.assertThrows(IllegalArgumentException.class,
() -> mySvc.lookupCode(null, new LookupCodeRequest(CODE_SYSTEM, "")));
}
@Test
public void testLookupCode_BlankCode_ThrowsException() {
Assertions.assertThrows(IllegalArgumentException.class, () -> {
IValidationSupport.LookupCodeResult outcome = mySvc.lookupCode(null, CODE_SYSTEM,
"", null);
});
}
@Test
public void testValidateCode_ValueSet_Success() {
public void testValidateCode_forValueSet_returnsCorrectly() {
createNextValueSetReturnParameters(true, DISPLAY, null);
IValidationSupport.CodeValidationResult outcome = mySvc.validateCode(null, null, CODE_SYSTEM, CODE, DISPLAY, VALUE_SET_URL);
assertNotNull(outcome);
assertEquals(CODE, outcome.getCode());
assertEquals(DISPLAY, outcome.getDisplay());
assertEquals(null, outcome.getSeverity());
assertEquals(null, outcome.getMessage());
assertNull(outcome.getSeverity());
assertNull(outcome.getMessage());
assertEquals(CODE, myValueSetProvider.myLastCode.getCode());
assertEquals(DISPLAY, myValueSetProvider.myLastDisplay.getValue());
assertEquals(CODE_SYSTEM, myValueSetProvider.myLastSystem.getValue());
assertEquals(VALUE_SET_URL, myValueSetProvider.myLastUrl.getValue());
assertEquals(null, myValueSetProvider.myLastValueSet);
assertNull(myValueSetProvider.myLastValueSet);
}
@Test
@ -182,75 +215,20 @@ public class RemoteTerminologyServiceValidationSupportTest {
myValueSetProvider.myNextReturnValueSets = new ArrayList<>();
// when
IBaseResource valueSet = mySvc.fetchValueSet(VALUE_SET_URL);
mySvc.fetchValueSet(VALUE_SET_URL);
// then
assertEquals(SummaryEnum.FALSE, myValueSetProvider.myLastSummaryParam);
}
@Test
public void testValidateCodeWithAllParams_CodeSystem_Success() {
createNextCodeSystemReturnParameters(true, DISPLAY, null);
addAdditionalReturnParameters();
IValidationSupport.CodeValidationResult outcome = mySvc.validateCode(null, null, CODE_SYSTEM, CODE, DISPLAY, null);
assertEquals(CODE, outcome.getCode());
assertEquals(DISPLAY, outcome.getDisplay());
assertEquals(null, outcome.getSeverity());
assertEquals(null, outcome.getMessage());
validateExtraCodeSystemParams();
}
private void validateExtraCodeSystemParams() {
assertEquals(CODE, myCodeSystemProvider.myLastCode.getCode());
assertEquals(CODE_SYSTEM, myCodeSystemProvider.myLastUrl.getValueAsString());
for (Parameters.ParametersParameterComponent param : myCodeSystemProvider.myNextReturnParams.getParameter()) {
String paramName = param.getName();
if (paramName.equals("result")) {
assertEquals(true, ((BooleanType)param.getValue()).booleanValue());
} else if (paramName.equals("display")) {
assertEquals(DISPLAY, param.getValue().toString());
} else if (paramName.equals("property")) {
for (Parameters.ParametersParameterComponent propertyComponent : param.getPart()) {
switch(propertyComponent.getName()) {
case "name":
assertEquals("birthDate", propertyComponent.getValue().toString());
break;
case "value":
assertEquals("1930-01-01", propertyComponent.getValue().toString());
break;
}
}
} else if (paramName.equals("designation")) {
for (Parameters.ParametersParameterComponent designationComponent : param.getPart()) {
switch(designationComponent.getName()) {
case "language":
assertEquals(LANGUAGE, designationComponent.getValue().toString());
break;
case "use":
Coding coding = (Coding)designationComponent.getValue();
assertNotNull(coding, "Coding value returned via designation use should NOT be NULL!");
assertEquals("code", coding.getCode());
assertEquals("system", coding.getSystem());
assertEquals("display", coding.getDisplay());
break;
case "value":
assertEquals("some value", designationComponent.getValue().toString());
break;
}
}
}
}
}
@Test
public void testValidateCode_SystemCodeDisplayUrl_Error() {
public void testValidateCode_forSystemCodeWithError_returnsCorrectly() {
createNextValueSetReturnParameters(false, null, ERROR_MESSAGE);
IValidationSupport.CodeValidationResult outcome = mySvc.validateCode(null, null, CODE_SYSTEM, CODE, DISPLAY, VALUE_SET_URL);
assertEquals(null, outcome.getCode());
assertEquals(null, outcome.getDisplay());
assertNotNull(outcome);
assertNull(outcome.getCode());
assertNull(outcome.getDisplay());
assertEquals(IValidationSupport.IssueSeverity.ERROR, outcome.getSeverity());
assertEquals(ERROR_MESSAGE, outcome.getMessage());
@ -258,18 +236,24 @@ public class RemoteTerminologyServiceValidationSupportTest {
assertEquals(DISPLAY, myValueSetProvider.myLastDisplay.getValue());
assertEquals(CODE_SYSTEM, myValueSetProvider.myLastSystem.getValue());
assertEquals(VALUE_SET_URL, myValueSetProvider.myLastUrl.getValue());
assertEquals(null, myValueSetProvider.myLastValueSet);
assertNull(myValueSetProvider.myLastValueSet);
}
@Test
public void testValidateCodeInCodeSystem_Good() {
createNextCodeSystemReturnParameters(true, DISPLAY, null);
public void testValidateCode_forCodeSystem_returnsCorrectly() {
myCodeSystemProvider.myNextValidationResult = new IValidationSupport.CodeValidationResult();
myCodeSystemProvider.myNextValidationResult.setCodeSystemVersion(CODE_SYSTEM);
myCodeSystemProvider.myNextValidationResult.setCode(CODE);
myCodeSystemProvider.myNextValidationResult.setCodeSystemName(CODE_SYSTEM_NAME);
myCodeSystemProvider.myNextValidationResult.setDisplay(DISPLAY);
myCodeSystemProvider.myNextValidationResult.setMessage(SUCCESS_MESSAGE);
IValidationSupport.CodeValidationResult outcome = mySvc.validateCode(null, null, CODE_SYSTEM, CODE, DISPLAY, null);
assertNotNull(outcome);
assertEquals(CODE, outcome.getCode());
assertEquals(DISPLAY, outcome.getDisplay());
assertEquals(null, outcome.getSeverity());
assertEquals(null, outcome.getMessage());
assertNull(outcome.getSeverity());
assertNull(outcome.getMessage());
assertEquals(CODE, myCodeSystemProvider.myLastCode.getCode());
assertEquals(CODE_SYSTEM, myCodeSystemProvider.myLastUrl.getValueAsString());
@ -284,16 +268,17 @@ public class RemoteTerminologyServiceValidationSupportTest {
valueSet.setUrl(VALUE_SET_URL);
IValidationSupport.CodeValidationResult outcome = mySvc.validateCodeInValueSet(null, new ConceptValidationOptions(), CODE_SYSTEM, CODE, DISPLAY, valueSet);
assertNotNull(outcome);
assertEquals(CODE, outcome.getCode());
assertEquals(DISPLAY, outcome.getDisplay());
assertEquals(null, outcome.getSeverity());
assertEquals(null, outcome.getMessage());
assertNull(outcome.getSeverity());
assertNull(outcome.getMessage());
assertEquals(CODE, myValueSetProvider.myLastCode.getCode());
assertEquals(DISPLAY, myValueSetProvider.myLastDisplay.getValue());
assertEquals(CODE_SYSTEM, myValueSetProvider.myLastSystem.getValue());
assertEquals(VALUE_SET_URL, myValueSetProvider.myLastUrl.getValueAsString());
assertEquals(null, myValueSetProvider.myLastValueSet);
assertNull(myValueSetProvider.myLastValueSet);
}
/**
@ -307,7 +292,7 @@ public class RemoteTerminologyServiceValidationSupportTest {
valueSet.setUrl(VALUE_SET_URL);
IValidationSupport.CodeValidationResult outcome = mySvc.validateCodeInValueSet(null, new ConceptValidationOptions().setInferSystem(true), null, CODE, DISPLAY, valueSet);
assertEquals(null, outcome);
assertNull(outcome);
}
@Test
@ -350,7 +335,8 @@ public class RemoteTerminologyServiceValidationSupportTest {
TranslateConceptResults results = mySvc.translateConcept(request);
assertEquals(results.getResult(), true);
assertNotNull(results);
assertTrue(results.getResult());
assertEquals(results.getResults().size(), 2);
for(TranslateConceptResult result : results.getResults()) {
assertEquals(singleResult, result);
@ -374,8 +360,8 @@ public class RemoteTerminologyServiceValidationSupportTest {
IValidationSupport.TranslateCodeRequest request = new IValidationSupport.TranslateCodeRequest(codings, null);
TranslateConceptResults results = mySvc.translateConcept(request);
assertEquals(results.getResult(), false);
assertNotNull(results);
assertFalse(results.getResult());
assertEquals(results.getResults().size(), 0);
assertNull(myConceptMapProvider.myLastCodeableConcept);
@ -393,7 +379,7 @@ public class RemoteTerminologyServiceValidationSupportTest {
myCodeSystemProvider.myNextReturnCodeSystems = new ArrayList<>();
// when
IBaseResource codeSystem = mySvc.fetchCodeSystem("http://loinc.org");
mySvc.fetchCodeSystem("http://loinc.org");
// then
assertEquals(SummaryEnum.FALSE, myCodeSystemProvider.myLastSummaryParam);
@ -535,7 +521,7 @@ public class RemoteTerminologyServiceValidationSupportTest {
/**
* Captures the system parameter of the request
*/
private class TestClientInterceptor implements IClientInterceptor {
private static class TestClientInterceptor implements IClientInterceptor {
private String capturedSystemParameter;
@ -552,12 +538,12 @@ public class RemoteTerminologyServiceValidationSupportTest {
capturedSystemParameter = systemValues.get(0);
}
} catch (IOException theE) {
theE.printStackTrace();
// ignore
}
}
@Override
public void interceptResponse(IHttpResponse theResponse) throws IOException { }
public void interceptResponse(IHttpResponse theResponse) { }
public String getCapturedSystemParameter() { return capturedSystemParameter; }
}
@ -570,7 +556,7 @@ public class RemoteTerminologyServiceValidationSupportTest {
myValueSetProvider.myNextReturnValueSets = new ArrayList<>();
boolean outcome = mySvc.isValueSetSupported(null, "http://loinc.org/VS");
assertEquals(false, outcome);
assertFalse(outcome);
assertEquals("http://loinc.org/VS", myValueSetProvider.myLastUrlParam.getValue());
}
@ -580,7 +566,7 @@ public class RemoteTerminologyServiceValidationSupportTest {
myValueSetProvider.myNextReturnValueSets.add((ValueSet) new ValueSet().setId("ValueSet/123"));
boolean outcome = mySvc.isValueSetSupported(null, "http://loinc.org/VS");
assertEquals(true, outcome);
assertTrue(outcome);
assertEquals("http://loinc.org/VS", myValueSetProvider.myLastUrlParam.getValue());
}
@ -589,7 +575,7 @@ public class RemoteTerminologyServiceValidationSupportTest {
myCodeSystemProvider.myNextReturnCodeSystems = new ArrayList<>();
boolean outcome = mySvc.isCodeSystemSupported(null, "http://loinc.org");
assertEquals(false, outcome);
assertFalse(outcome);
assertEquals("http://loinc.org", myCodeSystemProvider.myLastUrlParam.getValue());
}
@ -599,31 +585,10 @@ public class RemoteTerminologyServiceValidationSupportTest {
myCodeSystemProvider.myNextReturnCodeSystems.add((CodeSystem) new CodeSystem().setId("CodeSystem/123"));
boolean outcome = mySvc.isCodeSystemSupported(null, "http://loinc.org");
assertEquals(true, outcome);
assertTrue(outcome);
assertEquals("http://loinc.org", myCodeSystemProvider.myLastUrlParam.getValue());
}
private void createNextCodeSystemReturnParameters(boolean theResult, String theDisplay, String theMessage) {
myCodeSystemProvider.myNextReturnParams = new Parameters();
myCodeSystemProvider.myNextReturnParams.addParameter("result", theResult);
myCodeSystemProvider.myNextReturnParams.addParameter("display", theDisplay);
if (theMessage != null) {
myCodeSystemProvider.myNextReturnParams.addParameter("message", theMessage);
}
}
private void createNextCodeSystemLookupReturnParameters(boolean theResult, String theVersion, String theVersionAsText,
String theDisplay, String theMessage) {
myCodeSystemProvider.myNextReturnParams = new Parameters();
myCodeSystemProvider.myNextReturnParams.addParameter("result", theResult);
myCodeSystemProvider.myNextReturnParams.addParameter("version", theVersion);
myCodeSystemProvider.myNextReturnParams.addParameter("name", theVersionAsText);
myCodeSystemProvider.myNextReturnParams.addParameter("display", theDisplay);
if (theMessage != null) {
myCodeSystemProvider.myNextReturnParams.addParameter("message", theMessage);
}
}
private void createNextValueSetReturnParameters(boolean theResult, String theDisplay, String theMessage) {
myValueSetProvider.myNextReturnParams = new Parameters();
myValueSetProvider.myNextReturnParams.addParameter("result", theResult);
@ -633,53 +598,33 @@ public class RemoteTerminologyServiceValidationSupportTest {
}
}
private void addAdditionalReturnParameters() {
// property
Parameters.ParametersParameterComponent param = myCodeSystemProvider.myNextReturnParams.addParameter().setName("property");
param.addPart().setName("name").setValue(new StringType("birthDate"));
param.addPart().setName("value").setValue(new StringType("1930-01-01"));
// designation
param = myCodeSystemProvider.myNextReturnParams.addParameter().setName("designation");
param.addPart().setName("language").setValue(new CodeType("en"));
Parameters.ParametersParameterComponent codingParam = param.addPart().setName("use");
Coding coding = new Coding();
coding.setCode("code");
coding.setSystem("system");
coding.setDisplay("display");
codingParam.setValue(coding);
param.addPart().setName("value").setValue(new StringType("some value"));
}
private static class MyCodeSystemProvider implements IResourceProvider {
private SummaryEnum myLastSummaryParam;
private UriParam myLastUrlParam;
private List<CodeSystem> myNextReturnCodeSystems;
private int myInvocationCount;
private UriType myLastUrl;
private CodeType myLastCode;
private Coding myLastCoding;
private StringType myLastVersion;
private Parameters myNextReturnParams;
private IValidationSupport.LookupCodeResult myNextLookupCodeResult;
private IValidationSupport.CodeValidationResult myNextValidationResult;
@Operation(name = "validate-code", idempotent = true, returnParameters = {
@OperationParam(name = "result", type = BooleanType.class, min = 1),
@OperationParam(name = "message", type = StringType.class),
@OperationParam(name = "display", type = StringType.class)
})
public Parameters validateCode(
public IBaseParameters validateCode(
HttpServletRequest theServletRequest,
@IdParam(optional = true) IdType theId,
@OperationParam(name = "url", min = 0, max = 1) UriType theCodeSystemUrl,
@OperationParam(name = "code", min = 0, max = 1) CodeType theCode,
@OperationParam(name = "display", min = 0, max = 1) StringType theDisplay
) {
myInvocationCount++;
myLastUrl = theCodeSystemUrl;
myLastCode = theCode;
myNextReturnParams = (Parameters)myNextValidationResult.toParameters(ourCtx);
return myNextReturnParams;
}
@Operation(name = JpaConstants.OPERATION_LOOKUP, idempotent = true, returnParameters= {
@ -687,22 +632,21 @@ public class RemoteTerminologyServiceValidationSupportTest {
@OperationParam(name="version", type=StringType.class, min=0),
@OperationParam(name="display", type=StringType.class, min=1),
@OperationParam(name="abstract", type=BooleanType.class, min=1),
@OperationParam(name="property", min = 0, max = OperationParam.MAX_UNLIMITED)
})
public Parameters lookup(
public IBaseParameters lookup(
HttpServletRequest theServletRequest,
@OperationParam(name="code", min=0, max=1) CodeType theCode,
@OperationParam(name="system", min=0, max=1) UriType theSystem,
@OperationParam(name="coding", min=0, max=1) Coding theCoding,
@OperationParam(name="version", min=0, max=1) StringType theVersion,
@OperationParam(name="displayLanguage", min=0, max=1) CodeType theDisplayLanguage,
@OperationParam(name="property", min = 0, max = OperationParam.MAX_UNLIMITED) List<CodeType> theProperties,
@OperationParam(name="property", min = 0, max = OperationParam.MAX_UNLIMITED) List<CodeType> thePropertyNames,
RequestDetails theRequestDetails
) {
myInvocationCount++;
myLastCode = theCode;
myLastUrl = theSystem;
myLastCoding = theCoding;
myLastVersion = theVersion;
myNextReturnParams = (Parameters)myNextLookupCodeResult.toParameters(theRequestDetails.getFhirContext(), thePropertyNames);
return myNextReturnParams;
}
@ -779,8 +723,6 @@ public class RemoteTerminologyServiceValidationSupportTest {
private UriType myLastTargetValueSet;
private UriType myLastTargetCodeSystem;
private BooleanType myLastReverse;
private int myInvocationCount;
private Parameters myNextReturnParams;
@Operation(name = JpaConstants.OPERATION_TRANSLATE, idempotent = true, returnParameters = {
@ -799,7 +741,6 @@ public class RemoteTerminologyServiceValidationSupportTest {
@OperationParam(name = "reverse", min = 0, max = 1) BooleanType theReverse,
RequestDetails theRequestDetails
) {
myInvocationCount++;
myLastConceptMapUrl = theConceptMapUrl;
myLastConceptMapVersion = theConceptMapVersion;
myLastCodeableConcept = theSourceCodeableConcept;

View File

@ -2,6 +2,7 @@ package org.hl7.fhir.dstu3.hapi.validation;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.context.support.LookupCodeRequest;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
@ -9,13 +10,11 @@ import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.test.utilities.server.RestfulServerExtension;
import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.common.hapi.validation.support.RemoteTerminologyServiceValidationSupport;
import org.hl7.fhir.dstu3.model.BooleanType;
import org.hl7.fhir.dstu3.model.CodeSystem;
import org.hl7.fhir.dstu3.model.CodeType;
import org.hl7.fhir.dstu3.model.Coding;
import org.hl7.fhir.dstu3.model.DateType;
import org.hl7.fhir.dstu3.model.Parameters;
import org.hl7.fhir.dstu3.model.StringType;
import org.hl7.fhir.dstu3.model.UriType;
@ -25,7 +24,9 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import javax.servlet.http.HttpServletRequest;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@ -34,14 +35,13 @@ public class RemoteTerminologyServiceValidationSupportDstu3Test {
private static final String DISPLAY = "DISPLAY";
private static final String LANGUAGE = "en";
private static final String CODE_SYSTEM = "CODE_SYS";
private static final String CODE_SYSTEM_VERSION = "2.1";
private static final String CODE_SYSTEM_VERSION_AS_TEXT = "v2.1.12";
private static final String CODE_SYSTEM_NAME = "Code System";
private static final String CODE = "CODE";
private static FhirContext ourCtx = FhirContext.forDstu3();
private static final FhirContext ourCtx = FhirContext.forDstu3();
@RegisterExtension
public RestfulServerExtension myRestfulServerExtension = new RestfulServerExtension(ourCtx);
public static RestfulServerExtension ourRestfulServerExtension = new RestfulServerExtension(ourCtx);
private RemoteTerminologyServiceValidationSupport mySvc;
private MyCodeSystemProvider myCodeSystemProvider;
@ -49,143 +49,98 @@ public class RemoteTerminologyServiceValidationSupportDstu3Test {
@BeforeEach
public void before() {
myCodeSystemProvider = new MyCodeSystemProvider();
myRestfulServerExtension.getRestfulServer().registerProvider(myCodeSystemProvider);
String baseUrl = "http://localhost:" + myRestfulServerExtension.getPort();
ourRestfulServerExtension.getRestfulServer().registerProvider(myCodeSystemProvider);
String baseUrl = "http://localhost:" + ourRestfulServerExtension.getPort();
mySvc = new RemoteTerminologyServiceValidationSupport(ourCtx);
mySvc.setBaseUrl(baseUrl);
mySvc.addClientInterceptor(new LoggingInterceptor(true));
}
@Test
public void testLookupOperation_CodeSystem_Success() {
createNextCodeSystemLookupReturnParameters(true, CODE_SYSTEM_VERSION, CODE_SYSTEM_VERSION_AS_TEXT, DISPLAY);
IValidationSupport.LookupCodeResult outcome = mySvc.lookupCode(null, CODE_SYSTEM, CODE);
assertNotNull(outcome, "Call to lookupCode() should return a non-NULL result!");
assertEquals(DISPLAY, outcome.getCodeDisplay());
assertEquals(CODE_SYSTEM_VERSION, outcome.getCodeSystemVersion());
assertEquals(CODE, myCodeSystemProvider.myLastCode.asStringValue());
assertEquals(CODE_SYSTEM, myCodeSystemProvider.myLastUrl.getValueAsString());
for (Parameters.ParametersParameterComponent param : myCodeSystemProvider.myNextReturnParams.getParameter()) {
String paramName = param.getName();
if (paramName.equals("result")) {
assertEquals(true, ((BooleanType)param.getValue()).booleanValue());
} else if (paramName.equals("version")) {
assertEquals(CODE_SYSTEM_VERSION, param.getValue().toString());
} else if (paramName.equals("display")) {
assertEquals(DISPLAY, param.getValue().toString());
} else if (paramName.equals("name")) {
assertEquals(CODE_SYSTEM_VERSION_AS_TEXT, param.getValue().toString());
}
}
}
@Test
public void testLookupOperationWithAllParams_CodeSystem_Success() {
createNextCodeSystemLookupReturnParameters(true, CODE_SYSTEM_VERSION, CODE_SYSTEM_VERSION_AS_TEXT, DISPLAY, LANGUAGE);
addAdditionalCodeSystemLookupReturnParameters();
myCodeSystemProvider.myNextLookupCodeResult = new IValidationSupport.LookupCodeResult();
myCodeSystemProvider.myNextLookupCodeResult.setFound(true);
myCodeSystemProvider.myNextLookupCodeResult.setCodeSystemVersion(CODE_SYSTEM);
myCodeSystemProvider.myNextLookupCodeResult.setSearchedForCode(CODE);
myCodeSystemProvider.myNextLookupCodeResult.setCodeSystemDisplayName(CODE_SYSTEM_NAME);
myCodeSystemProvider.myNextLookupCodeResult.setCodeDisplay(DISPLAY);
IValidationSupport.LookupCodeResult outcome = mySvc.lookupCode(null, CODE_SYSTEM, CODE, LANGUAGE);
// property
String propertyName = "birthDate";
String propertyValue = "1930-01-01";
IValidationSupport.BaseConceptProperty property = new IValidationSupport.StringConceptProperty(propertyName, propertyValue);
myCodeSystemProvider.myNextLookupCodeResult.getProperties().add(property);
// designation
IValidationSupport.ConceptDesignation designation = new IValidationSupport.ConceptDesignation();
designation.setLanguage("en");
designation.setUseCode("code");
designation.setUseSystem("system");
designation.setUseDisplay("display");
designation.setValue("some value");
myCodeSystemProvider.myNextLookupCodeResult.getDesignations().add(designation);
IValidationSupport.LookupCodeResult outcome = mySvc.lookupCode(null, new LookupCodeRequest(CODE_SYSTEM, CODE, LANGUAGE, Set.of("birthDate")));
assertNotNull(outcome, "Call to lookupCode() should return a non-NULL result!");
assertEquals(DISPLAY, outcome.getCodeDisplay());
assertEquals(CODE_SYSTEM_VERSION, outcome.getCodeSystemVersion());
assertEquals(CODE_SYSTEM, outcome.getCodeSystemVersion());
assertEquals(CODE, myCodeSystemProvider.myLastCode.asStringValue());
assertEquals(CODE_SYSTEM, myCodeSystemProvider.myLastUrl.getValueAsString());
for (Parameters.ParametersParameterComponent param : myCodeSystemProvider.myNextReturnParams.getParameter()) {
String paramName = param.getName();
if (paramName.equals("result")) {
assertEquals(true, ((BooleanType)param.getValue()).booleanValue());
} else if (paramName.equals("version")) {
assertEquals(CODE_SYSTEM_VERSION, param.getValue().toString());
} else if (paramName.equals("display")) {
assertEquals(DISPLAY, param.getValue().toString());
} else if (paramName.equals("name")) {
assertEquals(CODE_SYSTEM_VERSION_AS_TEXT, param.getValue().toString());
} else if (paramName.equals("language")) {
assertEquals(LANGUAGE, param.getValue().toString());
} else if (paramName.equals("property")) {
for (org.hl7.fhir.dstu3.model.Parameters.ParametersParameterComponent propertyComponent : param.getPart()) {
switch(propertyComponent.getName()) {
case "name":
assertEquals("birthDate", propertyComponent.getValue().toString());
break;
case "value":
assertEquals("1930-01-01", ((DateType)propertyComponent.getValue()).asStringValue());
break;
}
}
} else if (paramName.equals("designation")) {
for (org.hl7.fhir.dstu3.model.Parameters.ParametersParameterComponent designationComponent : param.getPart()) {
switch(designationComponent.getName()) {
case "language":
assertEquals(LANGUAGE, designationComponent.getValue().toString());
break;
case "use":
Coding coding = (Coding)designationComponent.getValue();
assertNotNull(coding, "Coding value returned via designation use should NOT be NULL!");
assertEquals("code", coding.getCode());
assertEquals("system", coding.getSystem());
assertEquals("display", coding.getDisplay());
break;
case "value":
assertEquals("some value", designationComponent.getValue().toString());
break;
}
}
Parameters.ParametersParameterComponent propertyComponent = null;
Parameters.ParametersParameterComponent designationComponent = null;
for (Parameters.ParametersParameterComponent parameterComponent : myCodeSystemProvider.myNextReturnParams.getParameter()) {
if ("property".equals(parameterComponent.getName())) {
propertyComponent = parameterComponent;
}
if ("designation".equals(parameterComponent.getName())) {
designationComponent = parameterComponent;
}
}
}
private void createNextCodeSystemLookupReturnParameters(boolean theResult, String theVersion, String theVersionAsText,
String theDisplay) {
createNextCodeSystemLookupReturnParameters(theResult, theVersion, theVersionAsText, theDisplay, null);
}
assertNotNull(propertyComponent);
private void createNextCodeSystemLookupReturnParameters(boolean theResult, String theVersion, String theVersionAsText,
String theDisplay, String theLanguage) {
myCodeSystemProvider.myNextReturnParams = new Parameters();
myCodeSystemProvider.myNextReturnParams.addParameter().setName("result").setValue(new BooleanType(theResult));
myCodeSystemProvider.myNextReturnParams.addParameter().setName("version").setValue(new StringType(theVersion));
myCodeSystemProvider.myNextReturnParams.addParameter().setName("name").setValue(new StringType(theVersionAsText));
myCodeSystemProvider.myNextReturnParams.addParameter().setName("display").setValue(new StringType(theDisplay));
if (!StringUtils.isBlank(theLanguage)) {
myCodeSystemProvider.myNextReturnParams.addParameter().setName("language").setValue(new StringType(theLanguage));
}
}
Iterator<Parameters.ParametersParameterComponent> propertyComponentIterator = propertyComponent.getPart().iterator();
propertyComponent = propertyComponentIterator.next();
assertEquals("code", propertyComponent.getName());
assertEquals(propertyName, ((StringType)propertyComponent.getValue()).getValue());
private void addAdditionalCodeSystemLookupReturnParameters() {
// property
Parameters.ParametersParameterComponent param = myCodeSystemProvider.myNextReturnParams.addParameter().setName("property");
param.addPart().setName("name").setValue(new StringType("birthDate"));
param.addPart().setName("value").setValue(new DateType("1930-01-01"));
// designation
param = myCodeSystemProvider.myNextReturnParams.addParameter().setName("designation");
param.addPart().setName("language").setValue(new CodeType("en"));
Parameters.ParametersParameterComponent codingParam = param.addPart().setName("use");
Coding coding = new Coding();
coding.setCode("code");
coding.setSystem("system");
coding.setDisplay("display");
codingParam.setValue(coding);
param.addPart().setName("value").setValue(new StringType("some value"));
propertyComponent = propertyComponentIterator.next();
assertEquals("value", propertyComponent.getName());
assertEquals(propertyValue, ((StringType)propertyComponent.getValue()).getValue());
assertNotNull(designationComponent);
Iterator<Parameters.ParametersParameterComponent> partParameter = designationComponent.getPart().iterator();
designationComponent = partParameter.next();
assertEquals("language", designationComponent.getName());
assertEquals(LANGUAGE, designationComponent.getValue().toString());
designationComponent = partParameter.next();
assertEquals("use", designationComponent.getName());
Coding coding = (Coding)designationComponent.getValue();
assertNotNull(coding, "Coding value returned via designation use should NOT be NULL!");
assertEquals("code", coding.getCode());
assertEquals("system", coding.getSystem());
assertEquals("display", coding.getDisplay());
designationComponent = partParameter.next();
assertEquals("value", designationComponent.getName());
assertEquals("some value", designationComponent.getValue().toString());
}
private static class MyCodeSystemProvider implements IResourceProvider {
private int myInvocationCount;
private UriType myLastUrl;
private CodeType myLastCode;
private Coding myLastCoding;
private StringType myLastVersion;
private CodeType myLastDisplayLanguage;
private Parameters myNextReturnParams;
private IValidationSupport.LookupCodeResult myNextLookupCodeResult;
@Operation(name = JpaConstants.OPERATION_LOOKUP, idempotent = true, returnParameters= {
@OperationParam(name="name", type=StringType.class, min=1),
@OperationParam(name="version", type=StringType.class, min=0),
@OperationParam(name="display", type=StringType.class, min=1),
@OperationParam(name="abstract", type=BooleanType.class, min=1),
@OperationParam(name="property", min = 0, max = OperationParam.MAX_UNLIMITED)
})
public Parameters lookup(
HttpServletRequest theServletRequest,
@ -194,15 +149,13 @@ public class RemoteTerminologyServiceValidationSupportDstu3Test {
@OperationParam(name="coding", min=0, max=1) Coding theCoding,
@OperationParam(name="version", min=0, max=1) StringType theVersion,
@OperationParam(name="displayLanguage", min=0, max=1) CodeType theDisplayLanguage,
@OperationParam(name="property", min = 0, max = OperationParam.MAX_UNLIMITED) List<CodeType> theProperties,
@OperationParam(name="property", min = 0, max = OperationParam.MAX_UNLIMITED) List<CodeType> thePropertyNames,
RequestDetails theRequestDetails
) {
myInvocationCount++;
myLastCode = theCode;
myLastUrl = theSystem;
myLastCoding = theCoding;
myLastVersion = theVersion;
myLastDisplayLanguage = theDisplayLanguage;
myNextReturnParams = (Parameters)myNextLookupCodeResult.toParameters(theRequestDetails.getFhirContext(), thePropertyNames);
return myNextReturnParams;
}

View File

@ -4,6 +4,7 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.support.ConceptValidationOptions;
import ca.uhn.fhir.context.support.DefaultProfileValidationSupport;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.context.support.LookupCodeRequest;
import ca.uhn.fhir.context.support.ValidationSupportContext;
import ca.uhn.fhir.context.support.ValueSetExpansionOptions;
import ca.uhn.fhir.rest.api.Constants;
@ -264,9 +265,10 @@ public class FhirInstanceValidatorR4Test extends BaseTest {
return retVal;
}
});
when(myMockSupport.lookupCode(any(), any(), any(), any())).thenAnswer(t -> {
String system = t.getArgument(1, String.class);
String code = t.getArgument(2, String.class);
when(myMockSupport.lookupCode(any(), any())).thenAnswer(t -> {
LookupCodeRequest request = t.getArgument(1, LookupCodeRequest.class);
String system = request.getSystem();
String code = request.getCode();
if (myValidConcepts.contains(system + "___" + code)) {
return new IValidationSupport.LookupCodeResult().setFound(true);
} else {

View File

@ -4,6 +4,7 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.support.ConceptValidationOptions;
import ca.uhn.fhir.context.support.DefaultProfileValidationSupport;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.context.support.LookupCodeRequest;
import ca.uhn.fhir.context.support.ValidationSupportContext;
import ca.uhn.fhir.context.support.ValueSetExpansionOptions;
import ca.uhn.fhir.rest.api.Constants;
@ -31,9 +32,33 @@ import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4b.conformance.ProfileUtilities;
import org.hl7.fhir.r4b.context.IWorkerContext;
import org.hl7.fhir.r4b.hapi.ctx.HapiWorkerContext;
import org.hl7.fhir.r4b.model.*;
import org.hl7.fhir.r4b.model.AllergyIntolerance;
import org.hl7.fhir.r4b.model.Base;
import org.hl7.fhir.r4b.model.Base64BinaryType;
import org.hl7.fhir.r4b.model.BooleanType;
import org.hl7.fhir.r4b.model.Bundle;
import org.hl7.fhir.r4b.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.r4b.model.CodeSystem;
import org.hl7.fhir.r4b.model.CodeType;
import org.hl7.fhir.r4b.model.Consent;
import org.hl7.fhir.r4b.model.ContactPoint;
import org.hl7.fhir.r4b.model.DateTimeType;
import org.hl7.fhir.r4b.model.Enumerations;
import org.hl7.fhir.r4b.model.Extension;
import org.hl7.fhir.r4b.model.Media;
import org.hl7.fhir.r4b.model.Narrative;
import org.hl7.fhir.r4b.model.Observation;
import org.hl7.fhir.r4b.model.OperationOutcome;
import org.hl7.fhir.r4b.model.Patient;
import org.hl7.fhir.r4b.model.Period;
import org.hl7.fhir.r4b.model.Practitioner;
import org.hl7.fhir.r4b.model.Procedure;
import org.hl7.fhir.r4b.model.QuestionnaireResponse;
import org.hl7.fhir.r4b.model.Reference;
import org.hl7.fhir.r4b.model.StringType;
import org.hl7.fhir.r4b.model.StructureDefinition;
import org.hl7.fhir.r4b.model.StructureDefinition.StructureDefinitionKind;
import org.hl7.fhir.r4b.model.ValueSet;
import org.hl7.fhir.r4b.model.ValueSet.ValueSetExpansionComponent;
import org.hl7.fhir.r4b.terminologies.ValueSetExpander;
import org.hl7.fhir.r4b.utils.FHIRPathEngine;
@ -72,7 +97,6 @@ import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.lessThan;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
@ -230,9 +254,10 @@ public class FhirInstanceValidatorR4BTest extends BaseTest {
return retVal;
}
});
when(myMockSupport.lookupCode(any(), any(), any(), any())).thenAnswer(t -> {
String system = t.getArgument(1, String.class);
String code = t.getArgument(2, String.class);
when(myMockSupport.lookupCode(any(), any())).thenAnswer(t -> {
LookupCodeRequest request = t.getArgument(1, LookupCodeRequest.class);
String system = request.getSystem();
String code = request.getCode();
if (myValidConcepts.contains(system + "___" + code)) {
return new IValidationSupport.LookupCodeResult().setFound(true);
} else {

View File

@ -1,8 +1,8 @@
package org.hl7.fhir.r5.validation;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.context.support.ValidationSupportContext;
import ca.uhn.fhir.context.support.LookupCodeRequest;
import ca.uhn.fhir.test.utilities.server.RestfulServerExtension;
import org.hl7.fhir.common.hapi.validation.support.RemoteTerminologyServiceValidationSupport;
import org.junit.jupiter.api.Assertions;
@ -12,9 +12,9 @@ import org.junit.jupiter.api.extension.RegisterExtension;
public class RemoteTerminologyServiceValidationSupportR5Test {
private static final String ANY_NONBLANK_VALUE = "anything";
private static FhirContext ourCtx = FhirContext.forR5Cached();
private static final FhirContext ourCtx = FhirContext.forR5Cached();
@RegisterExtension
public RestfulServerExtension myRestfulServerExtension = new RestfulServerExtension(ourCtx);
public static RestfulServerExtension myRestfulServerExtension = new RestfulServerExtension(ourCtx);
private RemoteTerminologyServiceValidationSupport mySvc;
@ -27,9 +27,9 @@ public class RemoteTerminologyServiceValidationSupportR5Test {
@Test
public void testLookupCode_R5_ThrowsException() {
Assertions.assertThrows(UnsupportedOperationException.class, () -> {
IValidationSupport.LookupCodeResult outcome = mySvc.lookupCode(
new ValidationSupportContext(ourCtx.getValidationSupport()), ANY_NONBLANK_VALUE, ANY_NONBLANK_VALUE);
});
Assertions.assertThrows(UnsupportedOperationException.class,
() -> mySvc.lookupCode(
new ValidationSupportContext(ourCtx.getValidationSupport()),
new LookupCodeRequest(ANY_NONBLANK_VALUE, ANY_NONBLANK_VALUE)));
}
}