_id support (#1176)

* added support for _id in in-memory matcher
This commit is contained in:
Ken Stevens 2019-01-23 14:37:34 -05:00 committed by GitHub
parent f53130c9ae
commit 5a08593abd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 56 additions and 35 deletions

View File

@ -63,7 +63,7 @@ public class SubscriptionCanonicalizer<S extends IBaseResource> {
}
}
protected CanonicalSubscription canonicalizeDstu2(IBaseResource theSubscription) {
private CanonicalSubscription canonicalizeDstu2(IBaseResource theSubscription) {
ca.uhn.fhir.model.dstu2.resource.Subscription subscription = (ca.uhn.fhir.model.dstu2.resource.Subscription) theSubscription;
CanonicalSubscription retVal = new CanonicalSubscription();
@ -82,7 +82,7 @@ public class SubscriptionCanonicalizer<S extends IBaseResource> {
return retVal;
}
protected CanonicalSubscription canonicalizeDstu3(IBaseResource theSubscription) {
private CanonicalSubscription canonicalizeDstu3(IBaseResource theSubscription) {
org.hl7.fhir.dstu3.model.Subscription subscription = (org.hl7.fhir.dstu3.model.Subscription) theSubscription;
CanonicalSubscription retVal = new CanonicalSubscription();
@ -210,7 +210,7 @@ public class SubscriptionCanonicalizer<S extends IBaseResource> {
return null;
}
protected CanonicalSubscription canonicalizeR4(IBaseResource theSubscription) {
private CanonicalSubscription canonicalizeR4(IBaseResource theSubscription) {
org.hl7.fhir.r4.model.Subscription subscription = (org.hl7.fhir.r4.model.Subscription) theSubscription;
CanonicalSubscription retVal = new CanonicalSubscription();

View File

@ -20,6 +20,7 @@ package ca.uhn.fhir.jpa.subscription.module.matcher;
* #L%
*/
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.jpa.searchparam.MatchUrlService;
@ -30,8 +31,11 @@ import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.param.BaseParamWithPrefix;
import ca.uhn.fhir.rest.param.ReferenceParam;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -42,16 +46,18 @@ import java.util.function.Predicate;
@Service
public class CriteriaResourceMatcher {
public static final String CRITERIA = "CRITERIA";
private static final String CRITERIA = "CRITERIA";
@Autowired
private MatchUrlService myMatchUrlService;
@Autowired
ISearchParamRegistry mySearchParamRegistry;
@Autowired
FhirContext myFhirContext;
public SubscriptionMatchResult match(String theCriteria, RuntimeResourceDefinition theResourceDefinition, ResourceIndexedSearchParams theSearchParams) {
public SubscriptionMatchResult match(String theCriteria, IBaseResource theResource, ResourceIndexedSearchParams theSearchParams) {
SearchParameterMap searchParameterMap;
try {
searchParameterMap = myMatchUrlService.translateMatchUrl(theCriteria, theResourceDefinition);
searchParameterMap = myMatchUrlService.translateMatchUrl(theCriteria, myFhirContext.getResourceDefinition(theResource));
} catch (UnsupportedOperationException e) {
return new SubscriptionMatchResult(theCriteria, CRITERIA);
}
@ -63,7 +69,7 @@ public class CriteriaResourceMatcher {
for (Map.Entry<String, List<List<? extends IQueryParameterType>>> entry : searchParameterMap.entrySet()) {
String theParamName = entry.getKey();
List<List<? extends IQueryParameterType>> theAndOrParams = entry.getValue();
SubscriptionMatchResult result = matchIdsWithAndOr(theParamName, theAndOrParams, theResourceDefinition, theSearchParams);
SubscriptionMatchResult result = matchIdsWithAndOr(theParamName, theAndOrParams, theResource, theSearchParams);
if (!result.matched()){
return result;
}
@ -72,7 +78,7 @@ public class CriteriaResourceMatcher {
}
// This method is modelled from SearchBuilder.searchForIdsWithAndOr()
private SubscriptionMatchResult matchIdsWithAndOr(String theParamName, List<List<? extends IQueryParameterType>> theAndOrParams, RuntimeResourceDefinition theResourceDefinition, ResourceIndexedSearchParams theSearchParams) {
private SubscriptionMatchResult matchIdsWithAndOr(String theParamName, List<List<? extends IQueryParameterType>> theAndOrParams, IBaseResource theResource, ResourceIndexedSearchParams theSearchParams) {
if (theAndOrParams.isEmpty()) {
return new SubscriptionMatchResult(true, CRITERIA);
}
@ -90,30 +96,44 @@ public class CriteriaResourceMatcher {
if (hasChain(theAndOrParams)) {
return new SubscriptionMatchResult(theParamName, "Chained references are not supported");
}
if (theParamName.equals(IAnyResource.SP_RES_ID)) {
switch (theParamName) {
case IAnyResource.SP_RES_ID:
return new SubscriptionMatchResult(theParamName, CRITERIA);
return new SubscriptionMatchResult(matchIdsAndOr(theAndOrParams, theResource), CRITERIA);
} else if (theParamName.equals(IAnyResource.SP_RES_LANGUAGE)) {
case IAnyResource.SP_RES_LANGUAGE:
return new SubscriptionMatchResult(theParamName, CRITERIA);
return new SubscriptionMatchResult(theParamName, CRITERIA);
} else if (theParamName.equals(Constants.PARAM_HAS)) {
case Constants.PARAM_HAS:
return new SubscriptionMatchResult(theParamName, CRITERIA);
return new SubscriptionMatchResult(theParamName, CRITERIA);
} else if (theParamName.equals(Constants.PARAM_TAG) || theParamName.equals(Constants.PARAM_PROFILE) || theParamName.equals(Constants.PARAM_SECURITY)) {
case Constants.PARAM_TAG:
case Constants.PARAM_PROFILE:
case Constants.PARAM_SECURITY:
return new SubscriptionMatchResult(theParamName, CRITERIA);
return new SubscriptionMatchResult(theParamName, CRITERIA);
} else {
default:
String resourceName = theResourceDefinition.getName();
RuntimeSearchParam paramDef = mySearchParamRegistry.getActiveSearchParam(resourceName, theParamName);
return matchResourceParam(theParamName, theAndOrParams, theSearchParams, resourceName, paramDef);
String resourceName = myFhirContext.getResourceDefinition(theResource).getName();
RuntimeSearchParam paramDef = mySearchParamRegistry.getActiveSearchParam(resourceName, theParamName);
return matchResourceParam(theParamName, theAndOrParams, theSearchParams, resourceName, paramDef);
}
}
private boolean matchIdsAndOr(List<List<? extends IQueryParameterType>> theAndOrParams, IBaseResource theResource) {
return theAndOrParams.stream().allMatch(nextAnd -> matchIdsOr(nextAnd, theResource));
}
private boolean matchIdsOr(List<? extends IQueryParameterType> theOrParams, IBaseResource theResource) {
return theOrParams.stream().anyMatch(param -> param instanceof StringParam && matchId(((StringParam)param).getValue(), theResource.getIdElement()));
}
private boolean matchId(String theValue, IIdType theId) {
return theValue.equals(theId.getValue()) || theValue.equals(theId.getIdPart());
}
private SubscriptionMatchResult matchResourceParam(String theParamName, List<List<? extends IQueryParameterType>> theAndOrParams, ResourceIndexedSearchParams theSearchParams, String theResourceName, RuntimeSearchParam theParamDef) {
if (theParamDef != null) {
switch (theParamDef.getParamType()) {

View File

@ -21,7 +21,6 @@ package ca.uhn.fhir.jpa.subscription.module.matcher;
*/
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.searchparam.extractor.ResourceIndexedSearchParams;
import ca.uhn.fhir.jpa.searchparam.extractor.ResourceLinkExtractor;
@ -61,7 +60,6 @@ public class InMemorySubscriptionMatcher implements ISubscriptionMatcher {
ResourceIndexedSearchParams searchParams = new ResourceIndexedSearchParams();
mySearchParamExtractorService.extractFromResource(searchParams, entity, resource);
myResourceLinkExtractor.extractResourceLinks(searchParams, entity, resource, resource.getMeta().getLastUpdated(), myInlineResourceLinkResolver);
RuntimeResourceDefinition resourceDefinition = myContext.getResourceDefinition(resource);
return myCriteriaResourceMatcher.match(criteria, resourceDefinition, searchParams);
return myCriteriaResourceMatcher.match(criteria, resource, searchParams);
}
}

View File

@ -101,8 +101,8 @@ public class SubscriptionDeliveringRestHookSubscriber extends BaseSubscriptionDe
try {
operation.execute();
} catch (ResourceNotFoundException e) {
ourLog.error("Cannot reach " + theMsg.getSubscription().getEndpointUrl());
e.printStackTrace();
ourLog.error("Cannot reach {} ", theMsg.getSubscription().getEndpointUrl());
ourLog.error("Exception: ", e);
throw e;
}
}

View File

@ -12,6 +12,7 @@ import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Arrays;
import java.util.Collections;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@ -39,7 +40,6 @@ public class InMemorySubscriptionMatcherTestR3 extends BaseSubscriptionDstu3Test
}
@Test
@Ignore
public void testResourceById() {
ProcedureRequest pr = new ProcedureRequest();
@ -47,12 +47,12 @@ public class InMemorySubscriptionMatcherTestR3 extends BaseSubscriptionDstu3Test
pr.setIntent(ProcedureRequest.ProcedureRequestIntent.ORIGINALORDER);
assertMatched(pr, "ProcedureRequest?_id=123");
assertMatched(pr, "ProcedureRequest?_id=Patient/123");
assertMatched(pr, "ProcedureRequest?_id=Patient/123,Patient/999");
assertMatched(pr, "ProcedureRequest?_id=Patient/123&_id=Patient/123");
assertNotMatched(pr, "ProcedureRequest?_id=Patient/888");
assertNotMatched(pr, "ProcedureRequest?_id=Patient/888,Patient/999");
assertNotMatched(pr, "ProcedureRequest?_id=Patient/123&_id=Patient/888");
assertMatched(pr, "ProcedureRequest?_id=ProcedureRequest/123");
assertMatched(pr, "ProcedureRequest?_id=ProcedureRequest/123,ProcedureRequest/999");
assertMatched(pr, "ProcedureRequest?_id=ProcedureRequest/123&_id=ProcedureRequest/123");
assertNotMatched(pr, "ProcedureRequest?_id=ProcedureRequest/888");
assertNotMatched(pr, "ProcedureRequest?_id=ProcedureRequest/888,ProcedureRequest/999");
assertNotMatched(pr, "ProcedureRequest?_id=ProcedureRequest/123&_id=ProcedureRequest/888");
}
@ -301,7 +301,7 @@ public class InMemorySubscriptionMatcherTestR3 extends BaseSubscriptionDstu3Test
sp.setXpathUsage(SearchParameter.XPathUsageType.NORMAL);
sp.setStatus(Enumerations.PublicationStatus.ACTIVE);
IBundleProvider bundle = new SimpleBundleProvider(Arrays.asList(sp), "uuid");
IBundleProvider bundle = new SimpleBundleProvider(Collections.singletonList(sp), "uuid");
initSearchParamRegistry(bundle);
{
@ -333,7 +333,7 @@ public class InMemorySubscriptionMatcherTestR3 extends BaseSubscriptionDstu3Test
sp.setXpathUsage(SearchParameter.XPathUsageType.NORMAL);
sp.setStatus(Enumerations.PublicationStatus.ACTIVE);
IBundleProvider bundle = new SimpleBundleProvider(Arrays.asList(sp), "uuid");
IBundleProvider bundle = new SimpleBundleProvider(Collections.singletonList(sp), "uuid");
initSearchParamRegistry(bundle);
{
@ -425,7 +425,7 @@ public class InMemorySubscriptionMatcherTestR3 extends BaseSubscriptionDstu3Test
sp.setXpathUsage(SearchParameter.XPathUsageType.NORMAL);
sp.setStatus(Enumerations.PublicationStatus.ACTIVE);
IBundleProvider bundle = new SimpleBundleProvider(Arrays.asList(sp), "uuid");
IBundleProvider bundle = new SimpleBundleProvider(Collections.singletonList(sp), "uuid");
initSearchParamRegistry(bundle);
{

View File

@ -320,6 +320,9 @@
result in the 10th result being returned). This will now result in an empty
response Bundle as would be expected.
</action>
<action type="add">
Added support for _id in in-memory matcher
</action>
<action type="fix">
The casing of the base64Binary datatype was incorrect in the DSTU3 and R4 model classes.
This has been corrected.