improve in-memory error messages

This commit is contained in:
Ken Stevens 2019-10-21 16:44:52 -04:00
parent 842953eb1e
commit 347a66c429
3 changed files with 52 additions and 13 deletions

View File

@ -23,8 +23,9 @@ package ca.uhn.fhir.jpa.searchparam.matcher;
public class InMemoryMatchResult { public class InMemoryMatchResult {
public static final String PARSE_FAIL = "Failed to translate parse query string"; public static final String PARSE_FAIL = "Failed to translate parse query string";
public static final String STANDARD_PARAMETER = "Standard parameters not supported"; public static final String STANDARD_PARAMETER = "Standard parameters not supported";
public static final String CHAIN = "Chained references are not supported"; public static final String CHAIN = "Chained parameters are not supported";
public static final String PARAM = "Param not supported"; public static final String PARAM = "Parameter not supported";
public static final String QUALIFIER = "Qualified parameter not supported";
private final boolean myMatch; private final boolean myMatch;
private final boolean mySupported; private final boolean mySupported;

View File

@ -44,6 +44,7 @@ import org.springframework.stereotype.Service;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
@Service @Service
public class InMemoryResourceMatcher { public class InMemoryResourceMatcher {
@ -100,7 +101,15 @@ public class InMemoryResourceMatcher {
} }
if (hasQualifiers(theAndOrParams)) { if (hasQualifiers(theAndOrParams)) {
return InMemoryMatchResult.unsupportedFromParameterAndReason(theParamName, InMemoryMatchResult.STANDARD_PARAMETER); Optional<IQueryParameterType> optionalParameter = theAndOrParams.stream().flatMap(List::stream).filter(param -> param.getQueryParameterQualifier() != null).findAny();
if (optionalParameter.isPresent()) {
IQueryParameterType parameter = optionalParameter.get();
if (parameter instanceof ReferenceParam) {
ReferenceParam referenceParam = (ReferenceParam) parameter;
return InMemoryMatchResult.unsupportedFromParameterAndReason(theParamName + "." + referenceParam.getChain(), InMemoryMatchResult.CHAIN);
}
return InMemoryMatchResult.unsupportedFromParameterAndReason(theParamName + parameter.getQueryParameterQualifier(), InMemoryMatchResult.QUALIFIER);
}
} }
if (hasChain(theAndOrParams)) { if (hasChain(theAndOrParams)) {

View File

@ -9,7 +9,9 @@ import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
import ca.uhn.fhir.model.primitive.BaseDateTimeDt; import ca.uhn.fhir.model.primitive.BaseDateTimeDt;
import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum; import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum;
import ca.uhn.fhir.rest.param.ParamPrefixEnum; import ca.uhn.fhir.rest.param.ParamPrefixEnum;
import ca.uhn.fhir.rest.param.TokenParamModifier;
import org.hl7.fhir.r5.model.BaseDateTimeType; import org.hl7.fhir.r5.model.BaseDateTimeType;
import org.hl7.fhir.r5.model.CodeableConcept;
import org.hl7.fhir.r5.model.DateTimeType; import org.hl7.fhir.r5.model.DateTimeType;
import org.hl7.fhir.r5.model.Observation; import org.hl7.fhir.r5.model.Observation;
import org.junit.Before; import org.junit.Before;
@ -27,6 +29,7 @@ import java.util.Date;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
@ -34,6 +37,7 @@ public class InMemoryResourceMatcherR5Test {
public static final String OBSERVATION_DATE = "1970-10-17"; public static final String OBSERVATION_DATE = "1970-10-17";
private static final String EARLY_DATE = "1965-08-09"; private static final String EARLY_DATE = "1965-08-09";
private static final String LATE_DATE = "2000-06-29"; private static final String LATE_DATE = "2000-06-29";
public static final String OBSERVATION_CODE = "MATCH";
@Autowired @Autowired
private private
@ -64,24 +68,49 @@ public class InMemoryResourceMatcherR5Test {
@Before @Before
public void before() { public void before() {
RuntimeSearchParam searchParams = new RuntimeSearchParam(null, null, null, null, "Observation.effective", RestSearchParameterTypeEnum.DATE, null, null, null, RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE); RuntimeSearchParam dateSearchParam = new RuntimeSearchParam(null, null, null, null, "Observation.effective", RestSearchParameterTypeEnum.DATE, null, null, null, RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE);
when(mySearchParamRegistry.getSearchParamByName(any(), any())).thenReturn(searchParams); when(mySearchParamRegistry.getSearchParamByName(any(), eq("date"))).thenReturn(dateSearchParam);
when(mySearchParamRegistry.getActiveSearchParam("Observation", "date")).thenReturn(searchParams); when(mySearchParamRegistry.getActiveSearchParam("Observation", "date")).thenReturn(dateSearchParam);
RuntimeSearchParam codeSearchParam = new RuntimeSearchParam(null, null, null, null, "Observation.code", RestSearchParameterTypeEnum.TOKEN, null, null, null, RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE);
when(mySearchParamRegistry.getSearchParamByName(any(), eq("code"))).thenReturn(codeSearchParam);
when(mySearchParamRegistry.getActiveSearchParam("Observation", "code")).thenReturn(codeSearchParam);
RuntimeSearchParam encSearchParam = new RuntimeSearchParam(null, null, null, null, "Observation.encounter", RestSearchParameterTypeEnum.REFERENCE, null, null, null, RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE);
when(mySearchParamRegistry.getSearchParamByName(any(), eq("encounter"))).thenReturn(encSearchParam);
when(mySearchParamRegistry.getActiveSearchParam("Observation", "encounter")).thenReturn(encSearchParam);
myObservation = new Observation(); myObservation = new Observation();
myObservation.setEffective(new DateTimeType(OBSERVATION_DATE)); myObservation.setEffective(new DateTimeType(OBSERVATION_DATE));
CodeableConcept codeableConcept = new CodeableConcept();
codeableConcept.addCoding().setCode(OBSERVATION_CODE);
myObservation.setCode(codeableConcept);
mySearchParams = extractDateSearchParam(myObservation); mySearchParams = extractDateSearchParam(myObservation);
} }
@Test @Test
public void testDateUnsupportedOps() { public void testUnsupportedChained() {
testDateUnsupportedOp(ParamPrefixEnum.APPROXIMATE); InMemoryMatchResult result = myInMemoryResourceMatcher.match("encounter.class=FOO", myObservation, mySearchParams);
testDateUnsupportedOp(ParamPrefixEnum.STARTS_AFTER); assertFalse(result.supported());
testDateUnsupportedOp(ParamPrefixEnum.ENDS_BEFORE); assertEquals("Parameter: <encounter.class> Reason: Chained parameters are not supported", result.getUnsupportedReason());
testDateUnsupportedOp(ParamPrefixEnum.NOT_EQUAL);
} }
private void testDateUnsupportedOp(ParamPrefixEnum theOperator) { @Test
public void testUnsupportedNot() {
InMemoryMatchResult result = myInMemoryResourceMatcher.match("code" + TokenParamModifier.NOT.getValue() + "=" + OBSERVATION_CODE, myObservation, mySearchParams);
assertFalse(result.supported());
assertEquals("Parameter: <code:not> Reason: Qualified parameter not supported", result.getUnsupportedReason());
}
@Test
public void testDateUnsupportedDateOps() {
testDateUnsupportedDateOp(ParamPrefixEnum.APPROXIMATE);
testDateUnsupportedDateOp(ParamPrefixEnum.STARTS_AFTER);
testDateUnsupportedDateOp(ParamPrefixEnum.ENDS_BEFORE);
testDateUnsupportedDateOp(ParamPrefixEnum.NOT_EQUAL);
}
private void testDateUnsupportedDateOp(ParamPrefixEnum theOperator) {
InMemoryMatchResult result = myInMemoryResourceMatcher.match("date=" + theOperator.getValue() + OBSERVATION_DATE, myObservation, mySearchParams); InMemoryMatchResult result = myInMemoryResourceMatcher.match("date=" + theOperator.getValue() + OBSERVATION_DATE, myObservation, mySearchParams);
assertFalse(result.supported()); assertFalse(result.supported());
assertEquals("Parameter: <date> Reason: The prefix " + theOperator + " is not supported for param type DATE", result.getUnsupportedReason()); assertEquals("Parameter: <date> Reason: The prefix " + theOperator + " is not supported for param type DATE", result.getUnsupportedReason());