From 32651e1c364fa13e531796eeb278bb1ab96f8d48 Mon Sep 17 00:00:00 2001 From: Jake Gillberg Date: Mon, 7 Oct 2024 11:06:08 -0500 Subject: [PATCH] [Bugfix] mdm pointcut missing link update (#6296) * add failing test * add side-effect link updates to link event * add to contributor list --- .../jpa/mdm/svc/MdmLinkUpdaterSvcImpl.java | 6 +++ .../mdm/provider/MdmOperationPointcutsIT.java | 50 +++++++++++++++++++ pom.xml | 5 ++ 3 files changed, 61 insertions(+) diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmLinkUpdaterSvcImpl.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmLinkUpdaterSvcImpl.java index 9c77cc0639b..262f27deee6 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmLinkUpdaterSvcImpl.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmLinkUpdaterSvcImpl.java @@ -188,6 +188,12 @@ public class MdmLinkUpdaterSvcImpl implements IMdmLinkUpdaterSvc { // pointcut for MDM_POST_UPDATE_LINK MdmLinkEvent event = new MdmLinkEvent(); event.addMdmLink(myModelConverter.toJson(mdmLink)); + + // add any link updates from side effects + mdmContext.getMdmLinks().stream().forEach(link -> { + event.addMdmLink(myModelConverter.toJson(link)); + }); + HookParams hookParams = new HookParams(); hookParams.add(RequestDetails.class, theParams.getRequestDetails()).add(MdmLinkEvent.class, event); myInterceptorBroadcaster.callHooks(Pointcut.MDM_POST_UPDATE_LINK, hookParams); diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/provider/MdmOperationPointcutsIT.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/provider/MdmOperationPointcutsIT.java index f67ca767685..1933531c280 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/provider/MdmOperationPointcutsIT.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/provider/MdmOperationPointcutsIT.java @@ -601,5 +601,55 @@ public class MdmOperationPointcutsIT extends BaseProviderR4Test { assertFalse(retval.isEmpty()); } + @Test + public void updateLink_NoMatch_LinkEvent_allUpdates() { + // When a Link is set to "NO_MATCH", it can cause other link updates. + // If a source record would be left unlinked to any + // golden record, a new link / golden record would be created. + + // setup + String inputState = """ + GP1, AUTO, MATCH, P1 + """; + MDMState state = new MDMState<>(); + state.setInputState(inputState); + + // we won't use for validation, just setup + myMdmLinkHelper.setup(state); + + Patient patient = state.getParameter("P1"); + Patient originalPatientGolden = state.getParameter("GP1"); + + AtomicBoolean called = new AtomicBoolean(false); + + Object interceptor = new Object() { + @Hook(Pointcut.MDM_POST_UPDATE_LINK) + void onUpdate(RequestDetails theDetails, MdmLinkEvent theEvent) { + called.getAndSet(true); + assertThat(theEvent.getMdmLinks()).hasSize(2); + + MdmLinkJson originalLink = theEvent.getMdmLinks().get(0); + MdmLinkJson newLink = theEvent.getMdmLinks().get(1); + String original_target = "Patient/" + originalPatientGolden.getIdPart(); + + assertThat(originalLink.getGoldenResourceId()).isEqualTo(original_target); + assertThat(newLink.getGoldenResourceId()).isNotEqualTo(original_target); + } + }; + myInterceptors.add(interceptor); + myInterceptorService.registerInterceptor(interceptor); + + // test + myMdmProvider.updateLink( + new StringType("Patient/" + originalPatientGolden.getIdPart()), + new StringType("Patient/" + patient.getIdPart()), + new StringType("NO_MATCH"), + new ServletRequestDetails() + ); + + // verify + assertTrue(called.get()); + } + } diff --git a/pom.xml b/pom.xml index 8ba126cd114..fdf01913533 100644 --- a/pom.xml +++ b/pom.xml @@ -921,6 +921,11 @@ Adrienne Sox Galileo, Inc. + + Jake-Gillberg + Jake Gillberg + Galileo, Inc. + melihaydogd Ahmet Melih Aydoğdu