diff --git a/hapi-fhir-storage/src/main/java/ca/uhn/fhir/storage/interceptor/balp/BalpAuditCaptureInterceptor.java b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/storage/interceptor/balp/BalpAuditCaptureInterceptor.java index d7ae427a476..82258417b37 100644 --- a/hapi-fhir-storage/src/main/java/ca/uhn/fhir/storage/interceptor/balp/BalpAuditCaptureInterceptor.java +++ b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/storage/interceptor/balp/BalpAuditCaptureInterceptor.java @@ -198,8 +198,11 @@ public class BalpAuditCaptureInterceptor { Set compartmentOwners = determinePatientCompartmentOwnersForResources(resources, theRequestDetails); if (!compartmentOwners.isEmpty()) { - AuditEvent auditEvent = createAuditEventPatientQuery(theRequestDetails, compartmentOwners); - myAuditEventSink.recordAuditEvent(auditEvent); + for (String owner : compartmentOwners) { + AuditEvent auditEvent = createAuditEventPatientQuery(theRequestDetails, Set.of(owner)); + myAuditEventSink.recordAuditEvent(auditEvent); + } + } else { AuditEvent auditEvent = createAuditEventBasicQuery(theRequestDetails); myAuditEventSink.recordAuditEvent(auditEvent); diff --git a/hapi-fhir-storage/src/test/java/ca/uhn/fhir/storage/interceptor/balp/BalpAuditCaptureInterceptorTest.java b/hapi-fhir-storage/src/test/java/ca/uhn/fhir/storage/interceptor/balp/BalpAuditCaptureInterceptorTest.java index 0720d9fd6f4..c7b3b57080b 100644 --- a/hapi-fhir-storage/src/test/java/ca/uhn/fhir/storage/interceptor/balp/BalpAuditCaptureInterceptorTest.java +++ b/hapi-fhir-storage/src/test/java/ca/uhn/fhir/storage/interceptor/balp/BalpAuditCaptureInterceptorTest.java @@ -820,6 +820,43 @@ public class BalpAuditCaptureInterceptorTest implements ITestDataBuilder { .execute(); verify(myAuditEventSink, times(2)).recordAuditEvent(myAuditEventCaptor.capture()); + List values = myAuditEventCaptor.getAllValues(); + verifyAuditEvent(values.get(0), "Patient/P1/_history/1"); + verifyAuditEvent(values.get(1),"Patient/P2/_history/1"); + } + + @Test + public void testSearchObservationsAmongMultiplePatients() + { + Patient p1 = buildResource("Patient", withId("P1"), withFamily("Simpson"), withGiven("Homer")); + Patient p2 = buildResource("Patient", withId("P2"), withFamily("Simpson"), withGiven("Marge")); + myPatientProvider.store(p1); + myPatientProvider.store(p2); + + createObservation(withId("O1"), withSubject("Patient/P1")); + createObservation(withId("O2"), withSubject("Patient/P2")); + + Bundle outcome = myClient + .search() + .forResource(Observation.class) + .returnBundle(Bundle.class) + .execute(); + + verify(myAuditEventSink, times(2)).recordAuditEvent(myAuditEventCaptor.capture()); + List values = myAuditEventCaptor.getAllValues(); + verifyAuditEvent(values.get(0), "Patient/P1"); + verifyAuditEvent(values.get(1),"Patient/P2"); + } + + private void verifyAuditEvent(AuditEvent auditEvent, String id) { + ourLog.info("Audit Event: {}", ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(auditEvent)); + assertAuditEventValidatesAgainstBalpProfile(auditEvent); + assertHasProfile(auditEvent, BalpProfileEnum.PATIENT_QUERY); + assertType(auditEvent); + assertSubType(auditEvent, "search-type"); + assertEquals(AuditEvent.AuditEventAction.E, auditEvent.getAction()); + assertEquals(AuditEvent.AuditEventOutcome._0, auditEvent.getOutcome()); + assertHasPatientEntities(auditEvent, id); } private void create10Observations(String... thePatientIds) {