diff --git a/hapi-fhir-jpaserver-empi/src/main/java/ca/uhn/fhir/jpa/empi/broker/EmpiMessageHandler.java b/hapi-fhir-jpaserver-empi/src/main/java/ca/uhn/fhir/jpa/empi/broker/EmpiMessageHandler.java index 6c97cccbf14..2883d7a8c33 100644 --- a/hapi-fhir-jpaserver-empi/src/main/java/ca/uhn/fhir/jpa/empi/broker/EmpiMessageHandler.java +++ b/hapi-fhir-jpaserver-empi/src/main/java/ca/uhn/fhir/jpa/empi/broker/EmpiMessageHandler.java @@ -65,7 +65,7 @@ public class EmpiMessageHandler implements MessageHandler { ResourceModifiedMessage msg = ((ResourceModifiedJsonMessage) theMessage).getPayload(); try { - if (myEmpiResourceFileringSvc.shouldBeProcessed(msg)) { + if (myEmpiResourceFileringSvc.shouldBeProcessed(getResourceFromPayload(msg))) { matchEmpiAndUpdateLinks(msg); } } catch (Exception e) { diff --git a/hapi-fhir-jpaserver-empi/src/main/java/ca/uhn/fhir/jpa/empi/svc/EmpiMessageFilteringSvc.java b/hapi-fhir-jpaserver-empi/src/main/java/ca/uhn/fhir/jpa/empi/svc/EmpiMessageFilteringSvc.java index 00c1ae0556c..3a09e7d4190 100644 --- a/hapi-fhir-jpaserver-empi/src/main/java/ca/uhn/fhir/jpa/empi/svc/EmpiMessageFilteringSvc.java +++ b/hapi-fhir-jpaserver-empi/src/main/java/ca/uhn/fhir/jpa/empi/svc/EmpiMessageFilteringSvc.java @@ -1,25 +1,56 @@ package ca.uhn.fhir.jpa.empi.svc; +import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.empi.api.IEmpiSettings; +import ca.uhn.fhir.empi.log.Logs; import ca.uhn.fhir.empi.rules.json.EmpiResourceSearchParamJson; -import ca.uhn.fhir.jpa.subscription.model.ResourceModifiedMessage; +import org.hl7.fhir.instance.model.api.IAnyResource; +import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; +/** + * + */ @Service public class EmpiMessageFilteringSvc { + private static final Logger ourLog = Logs.getEmpiTroubleshootingLog(); @Autowired private IEmpiSettings empiSettings; - @Autowired EmpiSearchParamSvc myEmpiSearchParamSvc; + @Autowired + FhirContext myFhirContext; - public boolean shouldBeProcessed(ResourceModifiedMessage theMsg) { + /** + * Given a message from the EMPI Channel, determine whether or not EMPI processing should occur on the payload. + * EMPI processing should occur iff for any {@link EmpiResourceSearchParamJson) Search Param, the resource contains a value. + * + * If the payload has no attributes that appear in the Candidate Search Params, processing should be skipped, as there is not + * sufficient information to perform meaningful EMPI processing. (For example, how can EMPI processing occur on a patient that has _no_ attributes?) + * + * @param theMessage the message provided by the EMPI channel. + * + * @return whether or not EMPI processing should proceed + */ + public boolean shouldBeProcessed(IAnyResource theResource) { + String resourceType = myFhirContext.getResourceType(theResource); List candidateSearchParams = empiSettings.getEmpiRules().getCandidateSearchParams(); - List valuesFromResourceForSearchParam = myEmpiSearchParamSvc.getValueFromResourceForSearchParam(theResource, searchParam); + + boolean containsValueForSomeSearchParam = candidateSearchParams.stream() + .filter(csp -> searchParamIsValidForType(csp, resourceType)) + .flatMap(csp -> csp.getSearchParams().stream()) + .map(searchParam -> myEmpiSearchParamSvc.getValueFromResourceForSearchParam(theResource, searchParam)) + .anyMatch(valueList -> !valueList.isEmpty()); + + return containsValueForSomeSearchParam; + } + + private boolean searchParamIsValidForType(EmpiResourceSearchParamJson theSearchParamJson, String theResourceType) { + return theSearchParamJson.getResourceType().equalsIgnoreCase(theResourceType) || theSearchParamJson.getResourceType().equalsIgnoreCase("*"); } } diff --git a/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/interceptor/EmpiStorageInterceptorIT.java b/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/interceptor/EmpiStorageInterceptorIT.java index 5d8ab026733..e3575c743a7 100644 --- a/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/interceptor/EmpiStorageInterceptorIT.java +++ b/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/interceptor/EmpiStorageInterceptorIT.java @@ -19,7 +19,6 @@ import org.hl7.fhir.r4.model.Enumerations; import org.hl7.fhir.r4.model.Organization; import org.hl7.fhir.r4.model.Patient; import org.hl7.fhir.r4.model.Person; -import org.hl7.fhir.r4.model.Practitioner; import org.hl7.fhir.r4.model.SearchParameter; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -62,27 +61,21 @@ public class EmpiStorageInterceptorIT extends BaseEmpiR4Test { super.loadEmpiSearchParameters(); } - @Test - public void testCreatePatient() throws InterruptedException { - myEmpiHelper.createWithLatch(new Patient()); - assertLinkCount(1); - } - @Test public void testCreatePractitioner() throws InterruptedException { - myEmpiHelper.createWithLatch(new Practitioner()); + myEmpiHelper.createWithLatch(buildPractitionerWithNameAndId("somename", "some_id")); assertLinkCount(1); } @Test - public void testCreatePerson() throws InterruptedException { + public void testCreatePerson() { myPersonDao.create(new Person()); assertLinkCount(0); } @Test public void testDeletePersonDeletesLinks() throws InterruptedException { - myEmpiHelper.createWithLatch(new Patient()); + myEmpiHelper.createWithLatch(buildPaulPatient()); assertLinkCount(1); Person person = getOnlyActivePerson(); myPersonDao.delete(person.getIdElement()); @@ -175,7 +168,7 @@ public class EmpiStorageInterceptorIT extends BaseEmpiR4Test { public void testEmpiManagedPersonCannotBeModifiedByPersonUpdateRequest() throws InterruptedException { // When EMPI is enabled, only the EMPI system is allowed to modify Person links of Persons with the EMPI-MANAGED tag. Patient patient = new Patient(); - IIdType patientId = myEmpiHelper.createWithLatch(new Patient()).getDaoMethodOutcome().getId().toUnqualifiedVersionless(); + IIdType patientId = myEmpiHelper.createWithLatch(buildPaulPatient()).getDaoMethodOutcome().getId().toUnqualifiedVersionless(); patient.setId(patientId); @@ -275,7 +268,7 @@ public class EmpiStorageInterceptorIT extends BaseEmpiR4Test { @Test public void testPatientsWithNoEIDCanBeUpdated() throws InterruptedException { setPreventEidUpdates(true); - Patient p = new Patient(); + Patient p = buildPaulPatient(); EmpiHelperR4.OutcomeAndLogMessageWrapper wrapper = myEmpiHelper.createWithLatch(p); p.setId(wrapper.getDaoMethodOutcome().getId()); @@ -287,7 +280,7 @@ public class EmpiStorageInterceptorIT extends BaseEmpiR4Test { @Test public void testPatientsCanHaveEIDAddedInStrictMode() throws InterruptedException { setPreventEidUpdates(true); - Patient p = new Patient(); + Patient p = buildPaulPatient(); EmpiHelperR4.OutcomeAndLogMessageWrapper messageWrapper = myEmpiHelper.createWithLatch(p); p.setId(messageWrapper.getDaoMethodOutcome().getId()); addExternalEID(p, "external eid"); diff --git a/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/provider/BaseLinkR4Test.java b/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/provider/BaseLinkR4Test.java index 8e79c6092b3..83abb8c6f8e 100644 --- a/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/provider/BaseLinkR4Test.java +++ b/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/provider/BaseLinkR4Test.java @@ -31,7 +31,7 @@ public abstract class BaseLinkR4Test extends BaseProviderR4Test { public void before() { super.before(); - myPatient = createPatientAndUpdateLinks(new Patient()); + myPatient = createPatientAndUpdateLinks(buildPaulPatient()); myPatientId = new StringType(myPatient.getIdElement().getValue()); myPerson = getPersonFromTarget(myPatient); diff --git a/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/provider/EmpiProviderBatchR4Test.java b/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/provider/EmpiProviderBatchR4Test.java index cb486ef00fb..d6244ca1dcd 100644 --- a/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/provider/EmpiProviderBatchR4Test.java +++ b/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/provider/EmpiProviderBatchR4Test.java @@ -36,7 +36,7 @@ public class EmpiProviderBatchR4Test extends BaseLinkR4Test { @BeforeEach public void before() { super.before(); - myPractitioner = createPractitionerAndUpdateLinks(new Practitioner()); + myPractitioner = createPractitionerAndUpdateLinks(buildPractitionerWithNameAndId("some_pract", "some_pract_id")); myPractitionerId = new StringType(myPractitioner.getIdElement().getValue()); myPractitionerPerson = getPersonFromTarget(myPractitioner); myPractitionerPersonId = new StringType(myPractitionerPerson.getIdElement().getValue()); diff --git a/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/svc/EmpiBatchSvcImplTest.java b/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/svc/EmpiBatchSvcImplTest.java index 5a1c36a3bc4..5eaac317049 100644 --- a/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/svc/EmpiBatchSvcImplTest.java +++ b/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/svc/EmpiBatchSvcImplTest.java @@ -17,7 +17,7 @@ import java.util.Date; class EmpiBatchSvcImplTest extends BaseEmpiR4Test { @Autowired - IEmpiBatchSvc myEmpiBatchSvc; + IEmpiBatchSvc myEmpiBatchSvc; @Autowired IInterceptorService myInterceptorService; diff --git a/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/svc/EmpiMessageFilteringSvcTest.java b/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/svc/EmpiMessageFilteringSvcTest.java new file mode 100644 index 00000000000..3e79a04f399 --- /dev/null +++ b/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/svc/EmpiMessageFilteringSvcTest.java @@ -0,0 +1,39 @@ +package ca.uhn.fhir.jpa.empi.svc; + +import ca.uhn.fhir.jpa.empi.BaseEmpiR4Test; +import org.hl7.fhir.r4.model.BooleanType; +import org.hl7.fhir.r4.model.Patient; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +class EmpiMessageFilteringSvcTest extends BaseEmpiR4Test { + + @Autowired + private EmpiMessageFilteringSvc myEmpiMessageFilteringSvc; + + @Test + public void testFilterResourcesWhichHaveNoRelevantAttributes() { + Patient patient = new Patient(); + patient.setDeceased(new BooleanType(true)); //EMPI rules defined do not care about the deceased attribute. + + //SUT + boolean shouldBeProcessed = myEmpiMessageFilteringSvc.shouldBeProcessed(patient); + + assertThat(shouldBeProcessed, is(equalTo(false))); + } + + @Test + public void testDoNotFilterResourcesWithEMPIAttributes() { + Patient patient = new Patient(); + patient.addIdentifier().setValue("Hey I'm an ID! rules defined in empi-rules.json care about me!"); + + //SUT + boolean shouldBeProcessed = myEmpiMessageFilteringSvc.shouldBeProcessed(patient); + + assertThat(shouldBeProcessed, is(equalTo(true))); + } +} diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorService.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorService.java index 48d2f546737..371d8edb3f6 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorService.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorService.java @@ -399,6 +399,7 @@ public class SearchParamExtractorService { myInterceptorBroadcaster = theJpaInterceptorBroadcaster; } + @Nonnull public List extractParamValuesAsStrings(RuntimeSearchParam theActiveSearchParam, IBaseResource theResource) { return mySearchParamExtractor.extractParamValuesAsStrings(theActiveSearchParam, theResource); } diff --git a/hapi-fhir-server-empi/src/main/java/ca/uhn/fhir/empi/rules/json/EmpiResourceSearchParamJson.java b/hapi-fhir-server-empi/src/main/java/ca/uhn/fhir/empi/rules/json/EmpiResourceSearchParamJson.java index 6837ae4e56a..52c4c915310 100644 --- a/hapi-fhir-server-empi/src/main/java/ca/uhn/fhir/empi/rules/json/EmpiResourceSearchParamJson.java +++ b/hapi-fhir-server-empi/src/main/java/ca/uhn/fhir/empi/rules/json/EmpiResourceSearchParamJson.java @@ -54,7 +54,7 @@ public class EmpiResourceSearchParamJson implements IModelJson, Iterable return this; } - private List getSearchParams() { + public List getSearchParams() { if (mySearchParams == null) { mySearchParams = new ArrayList<>(); }