From 51a00065487bcd7e9483cd9959a0d5fa3c326d46 Mon Sep 17 00:00:00 2001 From: jamesagnew Date: Sun, 27 Oct 2019 20:04:33 -0400 Subject: [PATCH] Work on rationalizing search param extractor --- .../dstu3/FhirResourceDaoConceptMapDstu3.java | 1 + .../dao/r4/FhirResourceDaoConceptMapR4.java | 1 + ...rResourceDaoR4InvalidSubscriptionTest.java | 82 ------------------- ...rceptorRegisteredToDaoConfigDstu2Test.java | 31 ++++++- .../extractor/BaseSearchParamExtractor.java | 71 ++++++++-------- .../extractor/SearchParamExtractorDstu3.java | 18 ++-- .../extractor/SearchParamExtractorR4.java | 15 +--- .../fhir/jpa/searchparam/retry/Retrier.java | 4 +- .../cache/SubscriptionCanonicalizer.java | 15 ++-- .../parser/JsonParserHl7OrgDstu2Test.java | 9 +- .../example-patient-general-hl7orgdstu2.json | 4 +- 11 files changed, 96 insertions(+), 155 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoConceptMapDstu3.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoConceptMapDstu3.java index 4c3a2fcd113..6a1a6501226 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoConceptMapDstu3.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoConceptMapDstu3.java @@ -20,6 +20,7 @@ package ca.uhn.fhir.jpa.dao.dstu3; * #L% */ +import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao; import ca.uhn.fhir.jpa.dao.IFhirResourceDaoConceptMap; import ca.uhn.fhir.jpa.term.TranslationMatch; import ca.uhn.fhir.jpa.term.TranslationRequest; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoConceptMapR4.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoConceptMapR4.java index cc270004a27..8f9ebc9542b 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoConceptMapR4.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoConceptMapR4.java @@ -20,6 +20,7 @@ package ca.uhn.fhir.jpa.dao.r4; * #L% */ +import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao; import ca.uhn.fhir.jpa.dao.IFhirResourceDaoConceptMap; import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.entity.TermConceptMapGroupElement; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4InvalidSubscriptionTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4InvalidSubscriptionTest.java index 184374b1c04..1f430438ab3 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4InvalidSubscriptionTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4InvalidSubscriptionTest.java @@ -69,88 +69,6 @@ public class FhirResourceDaoR4InvalidSubscriptionTest extends BaseJpaR4Test { } } - /** - * Make sure that bad data in the database doesn't prevent startup - */ - @Test - public void testSubscriptionMarkedDeleted() { - BaseHapiFhirDao.setValidationDisabledForUnitTest(true); - - Subscription s = new Subscription(); - s.setStatus(Subscription.SubscriptionStatus.REQUESTED); - s.getChannel().setEndpoint("http://foo"); - s.getChannel().setPayload("application/fhir+json"); - s.setCriteria("Patient?foo"); - final IIdType id = mySubscriptionDao.create(s).getId().toUnqualifiedVersionless(); - assertNotNull(id.getIdPart()); - - BaseHapiFhirDao.setValidationDisabledForUnitTest(false); - - new TransactionTemplate(myTransactionMgr).execute(new TransactionCallbackWithoutResult() { - @Override - protected void doInTransactionWithoutResult(TransactionStatus status) { - Query q = myEntityManager.createNativeQuery("UPDATE HFJ_RESOURCE SET RES_DELETED_AT = RES_UPDATED WHERE RES_ID = " + id.getIdPart()); - q.executeUpdate(); - } - }); - - myEntityManager.clear(); - } - - /** - * Make sure that bad data in the database doesn't prevent startup - */ - @Test - public void testSubscriptionWithInvalidCriteria() throws InterruptedException { - BaseHapiFhirDao.setValidationDisabledForUnitTest(true); - - Subscription s = new Subscription(); - s.setStatus(Subscription.SubscriptionStatus.REQUESTED); - s.getChannel().setType(Subscription.SubscriptionChannelType.RESTHOOK); - s.getChannel().setEndpoint("http://foo"); - s.getChannel().setPayload("application/fhir+json"); - s.setCriteria("BLAH"); - IIdType id = mySubscriptionDao.create(s).getId().toUnqualifiedVersionless(); - assertNotNull(id.getIdPart()); - - BaseHapiFhirDao.setValidationDisabledForUnitTest(false); - } - - /** - * Make sure that bad data in the database doesn't prevent startup - */ - @Test - public void testSubscriptionWithNoStatus() { - BaseHapiFhirDao.setValidationDisabledForUnitTest(true); - - Subscription s = new Subscription(); - s.getChannel().setType(Subscription.SubscriptionChannelType.RESTHOOK); - s.getChannel().setEndpoint("http://foo"); - s.getChannel().setPayload("application/fhir+json"); - s.setCriteria("Patient?active=true"); - IIdType id = mySubscriptionDao.create(s).getId().toUnqualifiedVersionless(); - - BaseHapiFhirDao.setValidationDisabledForUnitTest(false); - } - - /** - * Make sure that bad data in the database doesn't prevent startup - */ - @Test - public void testSubscriptionWithNoType() { - BaseHapiFhirDao.setValidationDisabledForUnitTest(true); - - Subscription s = new Subscription(); - s.setStatus(Subscription.SubscriptionStatus.REQUESTED); - s.getChannel().setEndpoint("http://foo"); - s.getChannel().setPayload("application/fhir+json"); - s.setCriteria("Patient?foo"); - IIdType id = mySubscriptionDao.create(s).getId().toUnqualifiedVersionless(); - assertNotNull(id.getIdPart()); - - BaseHapiFhirDao.setValidationDisabledForUnitTest(false); - } - @AfterClass public static void afterClassClearContext() { TestUtil.clearAllStaticFieldsForUnitTest(); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/subscription/resthook/RestHookTestWithInterceptorRegisteredToDaoConfigDstu2Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/subscription/resthook/RestHookTestWithInterceptorRegisteredToDaoConfigDstu2Test.java index 26c1c48358c..f8b9dca35a8 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/subscription/resthook/RestHookTestWithInterceptorRegisteredToDaoConfigDstu2Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/subscription/resthook/RestHookTestWithInterceptorRegisteredToDaoConfigDstu2Test.java @@ -4,6 +4,7 @@ import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.jpa.dao.DaoConfig; import ca.uhn.fhir.jpa.provider.BaseResourceProviderDstu2Test; import ca.uhn.fhir.jpa.subscription.SubscriptionTestUtil; +import ca.uhn.fhir.jpa.subscription.module.cache.SubscriptionRegistry; import ca.uhn.fhir.model.dstu2.composite.CodeableConceptDt; import ca.uhn.fhir.model.dstu2.composite.CodingDt; import ca.uhn.fhir.model.dstu2.resource.Observation; @@ -19,7 +20,9 @@ import ca.uhn.fhir.rest.annotation.Update; import ca.uhn.fhir.rest.api.MethodOutcome; import ca.uhn.fhir.rest.server.IResourceProvider; import ca.uhn.fhir.rest.server.RestfulServer; +import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException; import ca.uhn.fhir.test.utilities.JettyUtil; +import ca.uhn.fhir.util.TestUtil; import com.google.common.collect.Lists; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.servlet.ServletContextHandler; @@ -31,6 +34,8 @@ import org.springframework.beans.factory.annotation.Autowired; import java.util.Collections; import java.util.List; +import static org.junit.Assert.fail; + /** * Test the rest-hook subscriptions */ @@ -43,7 +48,8 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigDstu2Test extends B private static Server ourListenerServer; private static String ourListenerServerBase; private static List ourUpdatedObservations = Collections.synchronizedList(Lists.newArrayList()); - + @Autowired + protected SubscriptionRegistry mySubscriptionRegistry; @Autowired private SubscriptionTestUtil mySubscriptionTestUtil; @@ -76,6 +82,22 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigDstu2Test extends B mySubscriptionTestUtil.waitForQueueToDrain(); } + protected void waitForActivatedSubscriptionCount(int theSize) throws Exception { + for (int i = 0; ; i++) { + if (i == 10) { + fail("Failed to init subscriptions"); + } + try { + mySubscriptionLoader.doSyncSubscriptionsForUnitTest(); + break; + } catch (ResourceVersionConflictException e) { + Thread.sleep(250); + } + } + + TestUtil.waitForSize(theSize, () -> mySubscriptionRegistry.size()); + Thread.sleep(500); + } private Subscription createSubscription(String criteria, String payload, String endpoint) throws InterruptedException { Subscription subscription = new Subscription(); @@ -125,6 +147,7 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigDstu2Test extends B Subscription subscription1 = createSubscription(criteria1, payload, ourListenerServerBase); Subscription subscription2 = createSubscription(criteria2, payload, ourListenerServerBase); + waitForActivatedSubscriptionCount(2); Observation observation1 = sendObservation(code, "SNOMED-CT"); @@ -198,11 +221,11 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigDstu2Test extends B Subscription subscription1 = createSubscription(criteria1, payload, ourListenerServerBase); Subscription subscription2 = createSubscription(criteria2, payload, ourListenerServerBase); + waitForActivatedSubscriptionCount(2); Observation observation1 = sendObservation(code, "SNOMED-CT"); // Should see 1 subscription notification - waitForQueueToDrain(); waitForSize(0, ourCreatedObservations); waitForSize(1, ourUpdatedObservations); @@ -302,8 +325,8 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigDstu2Test extends B ourListenerServer.setHandler(proxyHandler); JettyUtil.startServer(ourListenerServer); - ourListenerPort = JettyUtil.getPortForStartedServer(ourListenerServer); - ourListenerServerBase = "http://localhost:" + ourListenerPort + "/fhir/context"; + ourListenerPort = JettyUtil.getPortForStartedServer(ourListenerServer); + ourListenerServerBase = "http://localhost:" + ourListenerPort + "/fhir/context"; } @AfterClass diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/BaseSearchParamExtractor.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/BaseSearchParamExtractor.java index 97bed5b1a59..f2e8397ac5a 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/BaseSearchParamExtractor.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/BaseSearchParamExtractor.java @@ -110,7 +110,7 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor IBaseEnumeration obj = (IBaseEnumeration) value; String system = extractSystem(obj); String code = obj.getValueAsString(); - addTokenIfNotBlank(resourceTypeName, params, searchParam, system, code); + createTokenIndexIfNotBlank(resourceTypeName, params, searchParam, system, code); return; } @@ -124,7 +124,7 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor system = boundCode.getBinder().toSystemString(valueAsEnum); } String code = boundCode.getValueAsString(); - addTokenIfNotBlank(resourceTypeName, params, searchParam, system, code); + createTokenIndexIfNotBlank(resourceTypeName, params, searchParam, system, code); return; } @@ -138,7 +138,7 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor systemAsString = useSystem; } - addTokenIfNotBlank(resourceTypeName, params, searchParam, systemAsString, valueAsString); + createTokenIndexIfNotBlank(resourceTypeName, params, searchParam, systemAsString, valueAsString); return; } @@ -308,7 +308,7 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor if (value instanceof IPrimitiveType) { IPrimitiveType nextValue = (IPrimitiveType) value; String valueAsString = nextValue.getValueAsString(); - addSearchTermIfNotBlank(resourceType, params, searchParam, valueAsString); + createStringIndexIfNotBlank(resourceType, params, searchParam, valueAsString); return; } @@ -482,13 +482,13 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor String system = extractValueAsString(identifierSystemValueChild, theValue); String value = extractValueAsString(identifierValueValueChild, theValue); if (isNotBlank(value)) { - addTokenIfNotBlank(theResourceType, theParams, theSearchParam, system, value); + createTokenIndexIfNotBlank(theResourceType, theParams, theSearchParam, system, value); } Optional type = identifierTypeValueChild.getAccessor().getFirstValueOrNull(theValue); if (type.isPresent()) { String text = extractValueAsString(identifierTypeTextValueChild, type.get()); - addSearchTermIfNotBlank(theResourceType, theParams, theSearchParam, text); + createStringIndexIfNotBlank(theResourceType, theParams, theSearchParam, text); } } @@ -505,7 +505,7 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor String text = extractValueAsString(codeableConceptTextValueChild, theValue); if (isNotBlank(text)) { - addSearchTermIfNotBlank(theResourceType, theParams, theSearchParam, text); + createStringIndexIfNotBlank(theResourceType, theParams, theSearchParam, text); } } @@ -517,10 +517,10 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor String system = extractValueAsString(codingSystemValueChild, theValue); String code = extractValueAsString(codingCodeValueChild, theValue); - addTokenIfNotBlank(theResourceType, theParams, theSearchParam, system, code); + createTokenIndexIfNotBlank(theResourceType, theParams, theSearchParam, system, code); String text = extractValueAsString(codingDisplayValueChild, theValue); - addSearchTermIfNotBlank(theResourceType, theParams, theSearchParam, text); + createStringIndexIfNotBlank(theResourceType, theParams, theSearchParam, text); } private void addToken_ContactPoint(String theResourceType, Set theParams, RuntimeSearchParam theSearchParam, IBase theValue) { @@ -530,7 +530,7 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor String system = extractValueAsString(contactPointSystemValueChild, theValue); String value = extractValueAsString(contactPointValueValueChild, theValue); - addTokenIfNotBlank(theResourceType, theParams, theSearchParam, system, value); + createTokenIndexIfNotBlank(theResourceType, theParams, theSearchParam, system, value); } private void addToken_PatientCommunication(String theResourceType, Set theParams, RuntimeSearchParam theSearchParam, IBase theValue) { @@ -681,12 +681,12 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor List families = extractValuesAsStrings(humanNameFamilyValueChild, theValue); for (String next : families) { - addSearchTermIfNotBlank(theResourceType, theParams, theSearchParam, next); + createStringIndexIfNotBlank(theResourceType, theParams, theSearchParam, next); } List givens = extractValuesAsStrings(humanNameGivenValueChild, theValue); for (String next : givens) { - addSearchTermIfNotBlank(theResourceType, theParams, theSearchParam, next); + createStringIndexIfNotBlank(theResourceType, theParams, theSearchParam, next); } } @@ -697,7 +697,7 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor BigDecimal value = extractValueAsBigDecimal(quantityValueChild, theValue); if (value != null) { - addSearchTermIfNotBlank(theResourceType, theParams, theSearchParam, value.toPlainString()); + createStringIndexIfNotBlank(theResourceType, theParams, theSearchParam, value.toPlainString()); } } @@ -707,7 +707,7 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor BigDecimal value = extractValueAsBigDecimal(rangeLowValueChild, theValue); if (value != null) { - addSearchTermIfNotBlank(theResourceType, theParams, theSearchParam, value.toPlainString()); + createStringIndexIfNotBlank(theResourceType, theParams, theSearchParam, value.toPlainString()); } } @@ -717,7 +717,7 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor String value = extractValueAsString(contactPointValueValueChild, theValue); if (isNotBlank(value)) { - addSearchTermIfNotBlank(theResourceType, theParams, theSearchParam, value); + createStringIndexIfNotBlank(theResourceType, theParams, theSearchParam, value); } } @@ -752,7 +752,7 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor } for (String nextName : allNames) { - addSearchTermIfNotBlank(theResourceType, theParams, theSearchParam, nextName); + createStringIndexIfNotBlank(theResourceType, theParams, theSearchParam, nextName); } } @@ -809,7 +809,28 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor } } - private void addTokenIfNotBlank(String theResourceType, Set theParams, RuntimeSearchParam theSearchParam, String theSystem, String theValue) { + @SuppressWarnings({"unchecked", "UnnecessaryLocalVariable"}) + private void createStringIndexIfNotBlank(String theResourceType, Set theParams, RuntimeSearchParam theSearchParam, String theValue) { + String value = theValue; + if (isNotBlank(value)) { + if (value.length() > ResourceIndexedSearchParamString.MAX_LENGTH) { + value = value.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH); + } + + String searchParamName = theSearchParam.getName(); + String valueNormalized = StringNormalizer.normalizeString(value); + if (valueNormalized.length() > ResourceIndexedSearchParamString.MAX_LENGTH) { + valueNormalized = valueNormalized.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH); + } + + ResourceIndexedSearchParamString nextEntity = new ResourceIndexedSearchParamString(getModelConfig(), theResourceType, searchParamName, valueNormalized, value); + + Set params = theParams; + params.add(nextEntity); + } + } + + private void createTokenIndexIfNotBlank(String theResourceType, Set theParams, RuntimeSearchParam theSearchParam, String theSystem, String theValue) { String system = theSystem; String value = theValue; if (isNotBlank(system) || isNotBlank(value)) { @@ -826,22 +847,6 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor } } - @SuppressWarnings({"unchecked", "UnnecessaryLocalVariable"}) - private void addSearchTermIfNotBlank(String theResourceType, Set theParams, RuntimeSearchParam theSearchParam, String theValue) { - if (isNotBlank(theValue)) { - if (theValue.length() > ResourceIndexedSearchParamString.MAX_LENGTH) { - theValue = theValue.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH); - } - - String searchParamName = theSearchParam.getName(); - ResourceIndexedSearchParamString nextEntity = new ResourceIndexedSearchParamString(getModelConfig(), theResourceType, searchParamName, StringNormalizer.normalizeString(theValue), theValue); - - Set params = theParams; - params.add(nextEntity); - } - } - - @Override public String[] split(String thePaths) { if (getContext().getVersion().getVersion().isEqualOrNewerThan(FhirVersionEnum.R4)) { diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu3.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu3.java index 196eba99025..56ca8d14e30 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu3.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu3.java @@ -28,9 +28,6 @@ import org.hl7.fhir.dstu3.context.IWorkerContext; import org.hl7.fhir.dstu3.hapi.ctx.HapiWorkerContext; import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport; import org.hl7.fhir.dstu3.model.Base; -import org.hl7.fhir.dstu3.model.CodeSystem; -import org.hl7.fhir.dstu3.model.ConceptMap; -import org.hl7.fhir.dstu3.model.ValueSet; import org.hl7.fhir.dstu3.utils.FHIRPathEngine; import org.hl7.fhir.instance.model.api.IBase; import org.hl7.fhir.instance.model.api.IBaseResource; @@ -38,7 +35,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.context.event.EventListener; -import javax.annotation.PostConstruct; import java.util.ArrayList; import java.util.List; @@ -64,27 +60,27 @@ public class SearchParamExtractorDstu3 extends BaseSearchParamExtractor implemen public SearchParamExtractorDstu3(ModelConfig theModelConfig, FhirContext theCtx, IValidationSupport theValidationSupport, ISearchParamRegistry theSearchParamRegistry) { super(theCtx, theSearchParamRegistry); myValidationSupport = theValidationSupport; + start(null); } @Override - protected IValueExtractor getPathValueExtractor(IBaseResource theResource, String thePaths) { + protected IValueExtractor getPathValueExtractor(IBaseResource theResource, String theSinglePath) { return () -> { List values = new ArrayList<>(); - String[] nextPathsSplit = split(thePaths); - for (String nextPath : nextPathsSplit) { - List allValues = myFhirPathEngine.evaluate((Base) theResource, trim(nextPath)); + List allValues = myFhirPathEngine.evaluate((Base) theResource, theSinglePath); if (allValues.isEmpty() == false) { values.addAll(allValues); } - } - return values; + return values; }; } @EventListener public void start(ContextRefreshedEvent theEvent) { - myValidationSupport = myApplicationContext.getBean(IValidationSupport.class); + if (myValidationSupport == null) { + myValidationSupport = myApplicationContext.getBean(IValidationSupport.class); + } IWorkerContext worker = new HapiWorkerContext(getContext(), myValidationSupport); myFhirPathEngine = new FHIRPathEngine(worker); } diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorR4.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorR4.java index 7eae86c727b..775d86cc184 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorR4.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorR4.java @@ -24,7 +24,6 @@ import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.jpa.model.entity.ModelConfig; import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.Sets; import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.exceptions.PathEngineException; import org.hl7.fhir.instance.model.api.IBase; @@ -33,9 +32,7 @@ import org.hl7.fhir.r4.context.IWorkerContext; import org.hl7.fhir.r4.hapi.ctx.HapiWorkerContext; import org.hl7.fhir.r4.hapi.ctx.IValidationSupport; import org.hl7.fhir.r4.model.*; -import org.hl7.fhir.r4.model.Location.LocationPositionComponent; import org.hl7.fhir.r4.utils.FHIRPathEngine; -import org.springframework.beans.factory.annotation.Autowired; import javax.annotation.PostConstruct; import java.util.*; @@ -63,16 +60,10 @@ public class SearchParamExtractorR4 extends BaseSearchParamExtractor implements } @Override - protected IValueExtractor getPathValueExtractor(IBaseResource theResource, String thePaths) { + protected IValueExtractor getPathValueExtractor(IBaseResource theResource, String theSinglePath) { return () -> { - List values = new ArrayList<>(); - String[] nextPathsSplit = split(thePaths); - for (String nextPath : nextPathsSplit) { - List allValues = myFhirPathEngine.evaluate((Base) theResource, nextPath); - values.addAll(allValues); - } - - return values; + List allValues = myFhirPathEngine.evaluate((Base) theResource, theSinglePath); + return (List) new ArrayList(allValues); }; } diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/retry/Retrier.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/retry/Retrier.java index ad6cbc6b202..39c80184938 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/retry/Retrier.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/retry/Retrier.java @@ -76,10 +76,10 @@ public class Retrier { @Override public void onError(RetryContext context, RetryCallback callback, Throwable throwable) { super.onError(context, callback, throwable); - if (throwable instanceof NullPointerException) { + if (throwable instanceof NullPointerException || throwable instanceof UnsupportedOperationException) { ourLog.error("Retry failure {}/{}: {}", context.getRetryCount(), theMaxRetries, throwable.getMessage(), throwable); } else { - ourLog.error("Retry failure {}/{}: {}", context.getRetryCount(), theMaxRetries, throwable.getMessage()); + ourLog.error("Retry failure {}/{}: {}", context.getRetryCount(), theMaxRetries, throwable.toString()); } } }; diff --git a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/cache/SubscriptionCanonicalizer.java b/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/cache/SubscriptionCanonicalizer.java index d97899e1a4b..d398e20a4da 100644 --- a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/cache/SubscriptionCanonicalizer.java +++ b/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/cache/SubscriptionCanonicalizer.java @@ -31,10 +31,7 @@ import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException; import org.apache.commons.lang3.Validate; import org.hl7.fhir.exceptions.FHIRException; -import org.hl7.fhir.instance.model.api.IBaseMetaType; -import org.hl7.fhir.instance.model.api.IBaseReference; -import org.hl7.fhir.instance.model.api.IBaseResource; -import org.hl7.fhir.instance.model.api.IPrimitiveType; +import org.hl7.fhir.instance.model.api.*; import org.hl7.fhir.r4.model.Extension; import org.hl7.fhir.r5.model.Coding; import org.slf4j.Logger; @@ -371,7 +368,15 @@ public class SubscriptionCanonicalizer { IBaseMetaType meta = theSubscription.getMeta(); // Remove any existing strategy tag - meta.getTag().removeIf(t -> JpaConstants.EXT_SUBSCRIPTION_MATCHING_STRATEGY.equals(t.getSystem())); + meta + .getTag() + .stream() + .filter(t->JpaConstants.EXT_SUBSCRIPTION_MATCHING_STRATEGY.equals(t.getSystem())) + .forEach(t->{ + t.setCode(null); + t.setSystem(null); + t.setDisplay(null); + }); if (theStrategy == null) { return; diff --git a/hapi-fhir-structures-hl7org-dstu2/src/test/java/ca/uhn/fhir/parser/JsonParserHl7OrgDstu2Test.java b/hapi-fhir-structures-hl7org-dstu2/src/test/java/ca/uhn/fhir/parser/JsonParserHl7OrgDstu2Test.java index 35bc5bb1373..e26ffe9f5cc 100644 --- a/hapi-fhir-structures-hl7org-dstu2/src/test/java/ca/uhn/fhir/parser/JsonParserHl7OrgDstu2Test.java +++ b/hapi-fhir-structures-hl7org-dstu2/src/test/java/ca/uhn/fhir/parser/JsonParserHl7OrgDstu2Test.java @@ -32,6 +32,7 @@ import org.xml.sax.SAXException; import java.io.IOException; import java.io.StringReader; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.List; @@ -1133,7 +1134,7 @@ public class JsonParserHl7OrgDstu2Test { @Test public void testSimpleResourceEncode() throws IOException { - String xmlString = IOUtils.toString(JsonParser.class.getResourceAsStream("/example-patient-general-hl7orgdstu2.xml"), Charset.forName("UTF-8")); + String xmlString = IOUtils.toString(JsonParser.class.getResourceAsStream("/example-patient-general-hl7orgdstu2.xml"), StandardCharsets.UTF_8); Patient obs = ourCtx.newXmlParser().parseResource(Patient.class, xmlString); List undeclaredExtensions = obs.getContact().get(0).getName().getFamily().get(0).getExtension(); @@ -1146,7 +1147,7 @@ public class JsonParserHl7OrgDstu2Test { String encoded = jsonParser.encodeResourceToString(obs); ourLog.info(encoded); - String jsonString = IOUtils.toString(JsonParser.class.getResourceAsStream("/example-patient-general-hl7orgdstu2.json"), Charset.forName("UTF-8")); + String jsonString = IOUtils.toString(JsonParser.class.getResourceAsStream("/example-patient-general-hl7orgdstu2.json"), StandardCharsets.UTF_8); JSON expected = JSONSerializer.toJSON(jsonString); JSON actual = JSONSerializer.toJSON(encoded.trim()); @@ -1203,7 +1204,7 @@ public class JsonParserHl7OrgDstu2Test { @Test public void testSimpleResourceEncodeWithCustomType() throws IOException, SAXException { - String jsonString = IOUtils.toString(JsonParser.class.getResourceAsStream("/example-patient-general-hl7orgdstu2.json"), Charset.forName("UTF-8")); + String jsonString = IOUtils.toString(JsonParser.class.getResourceAsStream("/example-patient-general-hl7orgdstu2.json"), StandardCharsets.UTF_8); MyObservationWithExtensions obs = ourCtx.newJsonParser().parseResource(MyObservationWithExtensions.class, jsonString); { @@ -1226,7 +1227,7 @@ public class JsonParserHl7OrgDstu2Test { String encoded = xmlParser.encodeResourceToString(obs); encoded = encoded.replaceAll("", "").replace("\n", "").replace("\r", "").replaceAll(">\\s+<", "><"); - String xmlString = IOUtils.toString(JsonParser.class.getResourceAsStream("/example-patient-general-hl7orgdstu2.xml"), Charset.forName("UTF-8")); + String xmlString = IOUtils.toString(JsonParser.class.getResourceAsStream("/example-patient-general-hl7orgdstu2.xml"), StandardCharsets.UTF_8); xmlString = xmlString.replaceAll("", "").replace("\n", "").replace("\r", "").replaceAll(">\\s+<", "><"); ourLog.info("Expected: " + xmlString); diff --git a/hapi-fhir-structures-hl7org-dstu2/src/test/resources/example-patient-general-hl7orgdstu2.json b/hapi-fhir-structures-hl7org-dstu2/src/test/resources/example-patient-general-hl7orgdstu2.json index 2e740d86b27..af3844915f1 100644 --- a/hapi-fhir-structures-hl7org-dstu2/src/test/resources/example-patient-general-hl7orgdstu2.json +++ b/hapi-fhir-structures-hl7org-dstu2/src/test/resources/example-patient-general-hl7orgdstu2.json @@ -2,7 +2,7 @@ "resourceType":"Patient", "text":{ "status":"generated", - "div":"
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
NamePeter James Chalmers (\"Jim\")
Address534 Erewhon, Pleasantville, Vic, 3999
ContactsHome: unknown. Work: (03) 5555 6473
IdMRN: 12345 (Acme Healthcare)
\n
" + "div":"
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
NamePeter James Chalmers ("Jim")
Address534 Erewhon, Pleasantville, Vic, 3999
ContactsHome: unknown. Work: (03) 5555 6473
IdMRN: 12345 (Acme Healthcare)
\n
" }, "extension":[ { @@ -137,4 +137,4 @@ "managingOrganization":{ "reference":"Organization/1" } -} \ No newline at end of file +}