diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmEidUpdateService.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmEidUpdateService.java index 4c6c5de1426..4d6600edd03 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmEidUpdateService.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmEidUpdateService.java @@ -65,21 +65,23 @@ public class MdmEidUpdateService { @Autowired private IMdmSurvivorshipService myMdmSurvivorshipService; - void handleMdmUpdate(IAnyResource theResource, MatchedGoldenResourceCandidate theMatchedGoldenResourceCandidate, MdmTransactionContext theMdmTransactionContext) { - MdmUpdateContext updateContext = new MdmUpdateContext(theMatchedGoldenResourceCandidate, theResource); + void handleMdmUpdate(IAnyResource theTargetResource, MatchedGoldenResourceCandidate theMatchedGoldenResourceCandidate, MdmTransactionContext theMdmTransactionContext) { + MdmUpdateContext updateContext = new MdmUpdateContext(theMatchedGoldenResourceCandidate, theTargetResource); + myMdmSurvivorshipService.applySurvivorshipRulesToGoldenResource(theTargetResource, updateContext.getMatchedGoldenResource(), theMdmTransactionContext); + if (updateContext.isRemainsMatchedToSameGoldenResource()) { // Copy over any new external EIDs which don't already exist. - myMdmSurvivorshipService.applySurvivorshipRulesToGoldenResource(theResource, updateContext.getMatchedGoldenResource(), theMdmTransactionContext); if (!updateContext.isIncomingResourceHasAnEid() || updateContext.isHasEidsInCommon()) { //update to patient that uses internal EIDs only. - myMdmLinkSvc.updateLink(updateContext.getMatchedGoldenResource(), theResource, theMatchedGoldenResourceCandidate.getMatchResult(), MdmLinkSourceEnum.AUTO, theMdmTransactionContext); + myMdmLinkSvc.updateLink(updateContext.getMatchedGoldenResource(), theTargetResource, theMatchedGoldenResourceCandidate.getMatchResult(), MdmLinkSourceEnum.AUTO, theMdmTransactionContext); } else if (!updateContext.isHasEidsInCommon()) { - handleNoEidsInCommon(theResource, theMatchedGoldenResourceCandidate, theMdmTransactionContext, updateContext); + handleNoEidsInCommon(theTargetResource, theMatchedGoldenResourceCandidate, theMdmTransactionContext, updateContext); } } else { //This is a new linking scenario. we have to break the existing link and link to the new Golden Resource. For now, we create duplicate. //updated patient has an EID that matches to a new candidate. Link them, and set the Golden Resources possible duplicates - linkToNewGoldenResourceAndFlagAsDuplicate(theResource, updateContext.getExistingGoldenResource(), updateContext.getMatchedGoldenResource(), theMdmTransactionContext); + linkToNewGoldenResourceAndFlagAsDuplicate(theTargetResource, updateContext.getExistingGoldenResource(), updateContext.getMatchedGoldenResource(), theMdmTransactionContext); + // TODO NG - Do we need to merge fields from the old golden resource to the new golden resource? } } @@ -111,7 +113,7 @@ public class MdmEidUpdateService { private void createNewGoldenResourceAndFlagAsDuplicate(IAnyResource theResource, MdmTransactionContext theMdmTransactionContext, IAnyResource theOldGoldenResource) { log(theMdmTransactionContext, "Duplicate detected based on the fact that both resources have different external EIDs."); - IAnyResource newGoldenResource = myGoldenResourceHelper.createGoldenResourceFromMdmSourceResource(theResource); + IAnyResource newGoldenResource = myGoldenResourceHelper.createGoldenResourceFromMdmSourceResource(theResource, theMdmTransactionContext); myMdmLinkSvc.updateLink(newGoldenResource, theResource, MdmMatchOutcome.NEW_GOLDEN_RESOURCE_MATCH, MdmLinkSourceEnum.AUTO, theMdmTransactionContext); myMdmLinkSvc.updateLink(newGoldenResource, theOldGoldenResource, MdmMatchOutcome.POSSIBLE_DUPLICATE, MdmLinkSourceEnum.AUTO, theMdmTransactionContext); 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 d1d894ba7e3..32bbbc8cf94 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 @@ -21,6 +21,7 @@ package ca.uhn.fhir.jpa.mdm.svc; */ import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.mdm.api.IMdmSurvivorshipService; import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum; import ca.uhn.fhir.mdm.api.MdmMatchResultEnum; import ca.uhn.fhir.mdm.api.IMdmLinkSvc; @@ -63,6 +64,8 @@ public class MdmLinkUpdaterSvcImpl implements IMdmLinkUpdaterSvc { IMdmSettings myMdmSettings; @Autowired MessageHelper myMessageHelper; + @Autowired + IMdmSurvivorshipService myMdmSurvivorshipService; @Transactional @Override diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvc.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvc.java index f034dc5d74c..5cac2826956 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvc.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvc.java @@ -122,7 +122,7 @@ public class MdmMatchLinkSvc { private void handleMdmWithNoCandidates(IAnyResource theResource, MdmTransactionContext theMdmTransactionContext) { log(theMdmTransactionContext, String.format("There were no matched candidates for MDM, creating a new %s.", theResource.getIdElement().getResourceType())); - IAnyResource newGoldenResource = myGoldenResourceHelper.createGoldenResourceFromMdmSourceResource(theResource); + IAnyResource newGoldenResource = myGoldenResourceHelper.createGoldenResourceFromMdmSourceResource(theResource, theMdmTransactionContext); // TODO GGG :) // 1. Get the right helper // 2. Create source resource for the MDM source @@ -136,13 +136,12 @@ public class MdmMatchLinkSvc { if (myGoldenResourceHelper.isPotentialDuplicate(golenResource, theSourceResource)) { log(theMdmTransactionContext, "Duplicate detected based on the fact that both resources have different external EIDs."); - IAnyResource newGoldenResource = myGoldenResourceHelper.createGoldenResourceFromMdmSourceResource(theSourceResource); + IAnyResource newGoldenResource = myGoldenResourceHelper.createGoldenResourceFromMdmSourceResource(theSourceResource, theMdmTransactionContext); myMdmLinkSvc.updateLink(newGoldenResource, theSourceResource, MdmMatchOutcome.NEW_GOLDEN_RESOURCE_MATCH, MdmLinkSourceEnum.AUTO, theMdmTransactionContext); myMdmLinkSvc.updateLink(newGoldenResource, golenResource, MdmMatchOutcome.POSSIBLE_DUPLICATE, MdmLinkSourceEnum.AUTO, theMdmTransactionContext); } else { if (theGoldenResourceCandidate.isMatch()) { myGoldenResourceHelper.handleExternalEidAddition(golenResource, theSourceResource, theMdmTransactionContext); - //TODO MDM GGG/NG: eventually we need to add survivorship rules of attributes here. Currently no data is copied over except EIDs. } myMdmLinkSvc.updateLink(golenResource, theSourceResource, theGoldenResourceCandidate.getMatchResult(), MdmLinkSourceEnum.AUTO, theMdmTransactionContext); } diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmLinkSvcTest.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmLinkSvcTest.java index a65bfad0f67..e1cef8a2400 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmLinkSvcTest.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmLinkSvcTest.java @@ -51,23 +51,16 @@ public class MdmLinkSvcTest extends BaseMdmR4Test { assertLinkCount(0); Patient goldenPatient = createGoldenPatient(); IdType sourcePatientId = goldenPatient.getIdElement().toUnqualifiedVersionless(); - // TODO NG should be ok to remove - assertEquals(0, goldenPatient.getLink().size()); Patient patient = createPatient(); { myMdmLinkSvc.updateLink(goldenPatient, patient, POSSIBLE_MATCH, MdmLinkSourceEnum.AUTO, createContextForCreate("Patient")); assertLinkCount(1); - // TODO NG should be ok to remove - // Patient newSourcePatient = myPatientDao.read(sourcePatientId); - // assertEquals(1, newSourcePatient.getLink().size()); } { myMdmLinkSvc.updateLink(goldenPatient, patient, MdmMatchOutcome.NO_MATCH, MdmLinkSourceEnum.MANUAL, createContextForCreate("Patient")); assertLinkCount(1); - // TODO NG should be ok to remove - // Patient newSourcePatient = myPatientDao.read(sourcePatientId); - // assertEquals(0, newSourcePatient.getLink().size()); } } @@ -129,7 +122,6 @@ public class MdmLinkSvcTest extends BaseMdmR4Test { @Test public void testManualMdmLinksCannotBeModifiedBySystem() { -// Patient goldenPatient = createGoldenPatient(buildJaneSourcePatient()); Patient goldenPatient = createGoldenPatient(buildJanePatient()); Patient patient = createPatient(buildJanePatient()); @@ -144,7 +136,6 @@ public class MdmLinkSvcTest extends BaseMdmR4Test { @Test public void testAutomaticallyAddedNO_MATCHMdmLinksAreNotAllowed() { -// Patient goldenPatient = createGoldenPatient(buildJaneSourcePatient()); Patient goldenPatient = createGoldenPatient(buildJanePatient()); Patient patient = createPatient(buildJanePatient()); @@ -159,7 +150,6 @@ public class MdmLinkSvcTest extends BaseMdmR4Test { @Test public void testSyncDoesNotSyncNoMatchLinks() { -// Patient sourcePatient = createGoldenPatient(buildJaneSourcePatient()); Patient goldenPatient = createGoldenPatient(buildJanePatient()); Patient patient1 = createPatient(buildJanePatient()); Patient patient2 = createPatient(buildJanePatient()); @@ -171,7 +161,6 @@ public class MdmLinkSvcTest extends BaseMdmR4Test { List targets = myMdmLinkDaoSvc.findMdmLinksByGoldenResource(goldenPatient); assertFalse(targets.isEmpty()); assertEquals(2, targets.size()); - // TODO NG - OK? original assertTrue(goldenPatient.hasLink()); //TODO GGG update this test once we decide what has to happen here. There is no more "syncing links" //assertEquals(patient1.getIdElement().toVersionless().getValue(), sourcePatient.getLinkFirstRep().getTarget().getReference()); diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvcTest.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvcTest.java index 7a8975da186..e469b28c08b 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvcTest.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvcTest.java @@ -8,6 +8,7 @@ import ca.uhn.fhir.mdm.api.MdmConstants; import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum; import ca.uhn.fhir.mdm.api.MdmMatchOutcome; import ca.uhn.fhir.mdm.model.CanonicalEID; +import ca.uhn.fhir.mdm.model.MdmTransactionContext; import ca.uhn.fhir.mdm.util.EIDHelper; import ca.uhn.fhir.mdm.util.GoldenResourceHelper; import ca.uhn.fhir.mdm.util.MdmResourceUtil; @@ -352,7 +353,7 @@ public class MdmMatchLinkSvcTest extends BaseMdmR4Test { //In a normal situation, janePatient2 would just match to jane patient, but here we need to hack it so they are their //own individual GoldenResource for the purpose of this test. - IAnyResource goldenResource = myGoldenResourceHelper.createGoldenResourceFromMdmSourceResource(janePatient2); + IAnyResource goldenResource = myGoldenResourceHelper.createGoldenResourceFromMdmSourceResource(janePatient2, new MdmTransactionContext()); myMdmLinkSvc.updateLink(goldenResource, janePatient2, MdmMatchOutcome.NEW_GOLDEN_RESOURCE_MATCH, MdmLinkSourceEnum.AUTO, createContextForCreate("Patient")); assertThat(janePatient, is(not(sameGoldenResourceAs(janePatient2)))); @@ -443,7 +444,7 @@ public class MdmMatchLinkSvcTest extends BaseMdmR4Test { public void testCreateGoldenResourceFromMdmTarget() { // Create Use Case #2 - adding patient with no EID Patient janePatient = buildJanePatient(); - Patient janeGoldenResourcePatient = myGoldenResourceHelper.createGoldenResourceFromMdmSourceResource(janePatient); + Patient janeGoldenResourcePatient = myGoldenResourceHelper.createGoldenResourceFromMdmSourceResource(janePatient, new MdmTransactionContext()); // golden record now contains HAPI-generated EID and HAPI tag assertTrue(MdmResourceUtil.isMdmManaged(janeGoldenResourcePatient)); diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/GoldenResourceHelper.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/GoldenResourceHelper.java index 07f9d93561b..a65da27a147 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/GoldenResourceHelper.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/GoldenResourceHelper.java @@ -73,17 +73,19 @@ public class GoldenResourceHelper { /** * Creates a copy of the specified resource. This method will carry over resource EID if it exists. If it does not exist, * a randomly generated UUID EID will be created. - * - * @param Supported MDM resource type (e.g. Patient, Practitioner) + * @param Supported MDM resource type (e.g. Patient, Practitioner) * @param theIncomingResource The resource that will be used as the starting point for the MDM linking. + * @param theMdmTransactionContext */ - public T createGoldenResourceFromMdmSourceResource(T theIncomingResource) { + public T createGoldenResourceFromMdmSourceResource(T theIncomingResource, MdmTransactionContext theMdmTransactionContext) { validateContextSupported(); // get a ref to the actual ID Field RuntimeResourceDefinition resourceDefinition = myFhirContext.getResourceDefinition(theIncomingResource); IBaseResource newGoldenResource = resourceDefinition.newInstance(); + myMdmSurvivorshipService.applySurvivorshipRulesToGoldenResource(theIncomingResource, newGoldenResource, theMdmTransactionContext); + // hapi has 2 metamodels: for children and types BaseRuntimeChildDefinition goldenResourceIdentifier = resourceDefinition.getChildByName(FIELD_NAME_IDENTIFIER);