public static SubscriptionMatchResult successfulMatch() { return new SubscriptionMatchResult(true); }
@Bean public InMemorySubscriptionMatcher inMemorySubscriptionMatcher() { return new InMemorySubscriptionMatcher(); }
private SubscriptionMatchResult matchIdsWithAndOr(String theParamName, List<List<? extends IQueryParameterType>> theAndOrParams, RuntimeResourceDefinition theResourceDefinition, IBaseResource theResource, ResourceIndexedSearchParams theSearchParams) { if (theAndOrParams.isEmpty()) { return SubscriptionMatchResult.successfulMatch(); } if (hasQualifiers(theAndOrParams)) { return SubscriptionMatchResult.unsupportedFromParameterAndReason(theParamName, SubscriptionMatchResult.STANDARD_PARAMETER); } if (hasPrefixes(theAndOrParams)) { return SubscriptionMatchResult.unsupportedFromParameterAndReason(theParamName, SubscriptionMatchResult.PREFIX); } if (hasChain(theAndOrParams)) { return SubscriptionMatchResult.unsupportedFromParameterAndReason(theParamName, SubscriptionMatchResult.CHAIN); } switch (theParamName) { case IAnyResource.SP_RES_ID: return SubscriptionMatchResult.fromBoolean(matchIdsAndOr(theAndOrParams, theResource)); case IAnyResource.SP_RES_LANGUAGE: case Constants.PARAM_HAS: case Constants.PARAM_TAG: case Constants.PARAM_PROFILE: case Constants.PARAM_SECURITY: return SubscriptionMatchResult.unsupportedFromParameterAndReason(theParamName, SubscriptionMatchResult.PARAM); default: String resourceName = theResourceDefinition.getName(); RuntimeSearchParam paramDef = mySearchParamRegistry.getActiveSearchParam(resourceName, theParamName); return matchResourceParam(theParamName, theAndOrParams, theSearchParams, resourceName, paramDef); } }
@Override public SubscriptionMatchResult match(CanonicalSubscription theSubscription, ResourceModifiedMessage theMsg) { SubscriptionMatchResult result; if (myDaoConfig.isEnableInMemorySubscriptionMatching()) { result = myInMemorySubscriptionMatcher.match(theSubscription, theMsg); if (result.supported()) { // TODO KHS test result.setInMemory(true); } else { ourLog.info("Criteria {} for Subscription {} not supported by InMemoryMatcher: {}. Reverting to DatabaseMatcher", theSubscription.getCriteriaString(), theSubscription.getIdElementString(), result.getUnsupportedReason()); result = myDaoSubscriptionMatcher.match(theSubscription, theMsg); } } else { result = myDaoSubscriptionMatcher.match(theSubscription, theMsg); } return result; } }
private SubscriptionMatchResult matchResourceParam(String theParamName, List<List<? extends IQueryParameterType>> theAndOrParams, ResourceIndexedSearchParams theSearchParams, String theResourceName, RuntimeSearchParam theParamDef) { if (theParamDef != null) { switch (theParamDef.getParamType()) { case QUANTITY: case TOKEN: case STRING: case NUMBER: case URI: case DATE: case REFERENCE: if (theSearchParams == null) { return SubscriptionMatchResult.successfulMatch(); } else { return SubscriptionMatchResult.fromBoolean(theAndOrParams.stream().anyMatch(nextAnd -> matchParams(theResourceName, theParamName, theParamDef, nextAnd, theSearchParams))); } case COMPOSITE: case HAS: case SPECIAL: default: return SubscriptionMatchResult.unsupportedFromParameterAndReason(theParamName, SubscriptionMatchResult.PARAM); } } else { if (Constants.PARAM_CONTENT.equals(theParamName) || Constants.PARAM_TEXT.equals(theParamName)) { return SubscriptionMatchResult.unsupportedFromParameterAndReason(theParamName, SubscriptionMatchResult.PARAM); } else { throw new InvalidRequestException("Unknown search parameter " + theParamName + " for resource type " + theResourceName); } } }
searchParameterMap = myMatchUrlService.translateMatchUrl(theCriteria, resourceDefinition); } catch (UnsupportedOperationException e) { return SubscriptionMatchResult.unsupportedFromReason(SubscriptionMatchResult.PARSE_FAIL); return SubscriptionMatchResult.unsupportedFromParameterAndReason(Constants.PARAM_LASTUPDATED, SubscriptionMatchResult.STANDARD_PARAMETER); String theParamName = entry.getKey(); List<List<? extends IQueryParameterType>> theAndOrParams = entry.getValue(); SubscriptionMatchResult result = matchIdsWithAndOr(theParamName, theAndOrParams, resourceDefinition, theResource, theSearchParams); if (!result.matched()){ return result; return SubscriptionMatchResult.successfulMatch();
SubscriptionMatchResult matchResult = mySubscriptionMatcher.match(nextActiveSubscription.getSubscription(), theMsg); if (!matchResult.matched()) { continue; nextActiveSubscription.getSubscription().getIdElement(myFhirContext).getValue(), resourceId.toUnqualifiedVersionless().getValue(), matchResult.isInMemory() ? "in-memory" : "by querying the repository");
@Override public SubscriptionMatchResult match(CanonicalSubscription theSubscription, ResourceModifiedMessage theMsg) { try { return match(theSubscription.getCriteriaString(), theMsg.getNewPayload(myContext)); } catch (Exception e) { throw new InternalErrorException("Failure processing resource ID[" + theMsg.getId(myContext) + "] for subscription ID[" + theSubscription.getIdElementString() + "]: " + e.getMessage(), e); } }
@Override public SubscriptionMatchResult match(CanonicalSubscription theSubscription, ResourceModifiedMessage theMsg) { IIdType id = theMsg.getId(myCtx); String resourceType = id.getResourceType(); String resourceId = id.getIdPart(); String criteria = theSubscription.getCriteriaString(); // run the subscriptions query and look for matches, add the id as part of the criteria to avoid getting matches of previous resources rather than the recent resource criteria += "&_id=" + resourceType + "/" + resourceId; IBundleProvider results = performSearch(criteria); ourLog.debug("Subscription check found {} results for query: {}", results.size(), criteria); return SubscriptionMatchResult.fromBoolean(results.size() > 0); }
public void validateCriteriaAndAddStrategy(final IBaseResource theResource) { String criteria = mySubscriptionCanonicalizer.getCriteria(theResource); try { SubscriptionMatchingStrategy strategy = mySubscriptionStrategyEvaluator.determineStrategy(criteria); mySubscriptionCanonicalizer.setMatchingStrategyTag(myFhirContext, theResource, strategy); } catch (InvalidRequestException | DataFormatException e) { throw new UnprocessableEntityException("Invalid subscription criteria submitted: " + criteria + " " + e.getMessage()); } }
private boolean matchIdsAndOr(List<List<? extends IQueryParameterType>> theAndOrParams, IBaseResource theResource) { if (theResource == null) { return true; } return theAndOrParams.stream().allMatch(nextAnd -> matchIdsOr(nextAnd, theResource)); } private boolean matchIdsOr(List<? extends IQueryParameterType> theOrParams, IBaseResource theResource) {
private boolean matchIdsOr(List<? extends IQueryParameterType> theOrParams, IBaseResource theResource) { if (theResource == null) { return true; } return theOrParams.stream().anyMatch(param -> param instanceof StringParam && matchId(((StringParam)param).getValue(), theResource.getIdElement())); }
public void setMatchingStrategyTag(FhirContext theFhirContext, IBaseResource theSubscription, SubscriptionMatchingStrategy theStrategy) { IBaseMetaType meta = theSubscription.getMeta(); String value = theStrategy.toString(); String display; if (theStrategy == SubscriptionMatchingStrategy.DATABASE) { display = "Database"; } else if (theStrategy == SubscriptionMatchingStrategy.IN_MEMORY) { display = "In-memory"; } else { throw new IllegalStateException("Unknown " + SubscriptionMatchingStrategy.class.getSimpleName() + ": "+theStrategy); } meta.addTag().setSystem(SubscriptionConstants.EXT_SUBSCRIPTION_MATCHING_STRATEGY).setCode(value).setDisplay(display); } }
SubscriptionMatchResult match(String criteria, IBaseResource resource) { ResourceTable entity = new ResourceTable(); String resourceType = myContext.getResourceDefinition(resource).getName(); entity.setResourceType(resourceType); ResourceIndexedSearchParams searchParams = new ResourceIndexedSearchParams(); mySearchParamExtractorService.extractFromResource(searchParams, entity, resource); myResourceLinkExtractor.extractResourceLinks(searchParams, entity, resource, resource.getMeta().getLastUpdated(), myInlineResourceLinkResolver, false); return myCriteriaResourceMatcher.match(criteria, resource, searchParams); } }
public static SubscriptionMatchResult fromBoolean(boolean theMatched) { return new SubscriptionMatchResult(theMatched); }
@Bean public InMemorySubscriptionMatcher inMemorySubscriptionMatcher() { return new InMemorySubscriptionMatcher(); }
public void validateCriteriaAndAddStrategy(final IBaseResource theResource) { String criteria = mySubscriptionCanonicalizer.getCriteria(theResource); try { SubscriptionMatchingStrategy strategy = mySubscriptionStrategyEvaluator.determineStrategy(criteria); mySubscriptionCanonicalizer.setMatchingStrategyTag(myFhirContext, theResource, strategy); } catch (InvalidRequestException | DataFormatException e) { throw new UnprocessableEntityException("Invalid subscription criteria submitted: " + criteria + " " + e.getMessage()); } }
public static SubscriptionMatchResult unsupportedFromReason(String theUnsupportedReason) { return new SubscriptionMatchResult(null, theUnsupportedReason); }
public static SubscriptionMatchResult unsupportedFromParameterAndReason(String theUnsupportedParameter, String theUnsupportedReason) { return new SubscriptionMatchResult(theUnsupportedParameter, theUnsupportedReason); }