Survivorship 2
This commit is contained in:
parent
f4cf4bf54a
commit
a4a173d5c7
|
@ -65,21 +65,23 @@ public class MdmEidUpdateService {
|
||||||
@Autowired
|
@Autowired
|
||||||
private IMdmSurvivorshipService myMdmSurvivorshipService;
|
private IMdmSurvivorshipService myMdmSurvivorshipService;
|
||||||
|
|
||||||
void handleMdmUpdate(IAnyResource theResource, MatchedGoldenResourceCandidate theMatchedGoldenResourceCandidate, MdmTransactionContext theMdmTransactionContext) {
|
void handleMdmUpdate(IAnyResource theTargetResource, MatchedGoldenResourceCandidate theMatchedGoldenResourceCandidate, MdmTransactionContext theMdmTransactionContext) {
|
||||||
MdmUpdateContext updateContext = new MdmUpdateContext(theMatchedGoldenResourceCandidate, theResource);
|
MdmUpdateContext updateContext = new MdmUpdateContext(theMatchedGoldenResourceCandidate, theTargetResource);
|
||||||
|
myMdmSurvivorshipService.applySurvivorshipRulesToGoldenResource(theTargetResource, updateContext.getMatchedGoldenResource(), theMdmTransactionContext);
|
||||||
|
|
||||||
if (updateContext.isRemainsMatchedToSameGoldenResource()) {
|
if (updateContext.isRemainsMatchedToSameGoldenResource()) {
|
||||||
// Copy over any new external EIDs which don't already exist.
|
// Copy over any new external EIDs which don't already exist.
|
||||||
myMdmSurvivorshipService.applySurvivorshipRulesToGoldenResource(theResource, updateContext.getMatchedGoldenResource(), theMdmTransactionContext);
|
|
||||||
if (!updateContext.isIncomingResourceHasAnEid() || updateContext.isHasEidsInCommon()) {
|
if (!updateContext.isIncomingResourceHasAnEid() || updateContext.isHasEidsInCommon()) {
|
||||||
//update to patient that uses internal EIDs only.
|
//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()) {
|
} else if (!updateContext.isHasEidsInCommon()) {
|
||||||
handleNoEidsInCommon(theResource, theMatchedGoldenResourceCandidate, theMdmTransactionContext, updateContext);
|
handleNoEidsInCommon(theTargetResource, theMatchedGoldenResourceCandidate, theMdmTransactionContext, updateContext);
|
||||||
}
|
}
|
||||||
} else {
|
} 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.
|
//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
|
//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) {
|
private void createNewGoldenResourceAndFlagAsDuplicate(IAnyResource theResource, MdmTransactionContext theMdmTransactionContext, IAnyResource theOldGoldenResource) {
|
||||||
log(theMdmTransactionContext, "Duplicate detected based on the fact that both resources have different external EIDs.");
|
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, theResource, MdmMatchOutcome.NEW_GOLDEN_RESOURCE_MATCH, MdmLinkSourceEnum.AUTO, theMdmTransactionContext);
|
||||||
myMdmLinkSvc.updateLink(newGoldenResource, theOldGoldenResource, MdmMatchOutcome.POSSIBLE_DUPLICATE, MdmLinkSourceEnum.AUTO, theMdmTransactionContext);
|
myMdmLinkSvc.updateLink(newGoldenResource, theOldGoldenResource, MdmMatchOutcome.POSSIBLE_DUPLICATE, MdmLinkSourceEnum.AUTO, theMdmTransactionContext);
|
||||||
|
|
|
@ -21,6 +21,7 @@ package ca.uhn.fhir.jpa.mdm.svc;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
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.MdmLinkSourceEnum;
|
||||||
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
||||||
import ca.uhn.fhir.mdm.api.IMdmLinkSvc;
|
import ca.uhn.fhir.mdm.api.IMdmLinkSvc;
|
||||||
|
@ -63,6 +64,8 @@ public class MdmLinkUpdaterSvcImpl implements IMdmLinkUpdaterSvc {
|
||||||
IMdmSettings myMdmSettings;
|
IMdmSettings myMdmSettings;
|
||||||
@Autowired
|
@Autowired
|
||||||
MessageHelper myMessageHelper;
|
MessageHelper myMessageHelper;
|
||||||
|
@Autowired
|
||||||
|
IMdmSurvivorshipService myMdmSurvivorshipService;
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -122,7 +122,7 @@ public class MdmMatchLinkSvc {
|
||||||
|
|
||||||
private void handleMdmWithNoCandidates(IAnyResource theResource, MdmTransactionContext theMdmTransactionContext) {
|
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()));
|
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 :)
|
// TODO GGG :)
|
||||||
// 1. Get the right helper
|
// 1. Get the right helper
|
||||||
// 2. Create source resource for the MDM source
|
// 2. Create source resource for the MDM source
|
||||||
|
@ -136,13 +136,12 @@ public class MdmMatchLinkSvc {
|
||||||
|
|
||||||
if (myGoldenResourceHelper.isPotentialDuplicate(golenResource, theSourceResource)) {
|
if (myGoldenResourceHelper.isPotentialDuplicate(golenResource, theSourceResource)) {
|
||||||
log(theMdmTransactionContext, "Duplicate detected based on the fact that both resources have different external EIDs.");
|
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, theSourceResource, MdmMatchOutcome.NEW_GOLDEN_RESOURCE_MATCH, MdmLinkSourceEnum.AUTO, theMdmTransactionContext);
|
||||||
myMdmLinkSvc.updateLink(newGoldenResource, golenResource, MdmMatchOutcome.POSSIBLE_DUPLICATE, MdmLinkSourceEnum.AUTO, theMdmTransactionContext);
|
myMdmLinkSvc.updateLink(newGoldenResource, golenResource, MdmMatchOutcome.POSSIBLE_DUPLICATE, MdmLinkSourceEnum.AUTO, theMdmTransactionContext);
|
||||||
} else {
|
} else {
|
||||||
if (theGoldenResourceCandidate.isMatch()) {
|
if (theGoldenResourceCandidate.isMatch()) {
|
||||||
myGoldenResourceHelper.handleExternalEidAddition(golenResource, theSourceResource, theMdmTransactionContext);
|
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);
|
myMdmLinkSvc.updateLink(golenResource, theSourceResource, theGoldenResourceCandidate.getMatchResult(), MdmLinkSourceEnum.AUTO, theMdmTransactionContext);
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,23 +51,16 @@ public class MdmLinkSvcTest extends BaseMdmR4Test {
|
||||||
assertLinkCount(0);
|
assertLinkCount(0);
|
||||||
Patient goldenPatient = createGoldenPatient();
|
Patient goldenPatient = createGoldenPatient();
|
||||||
IdType sourcePatientId = goldenPatient.getIdElement().toUnqualifiedVersionless();
|
IdType sourcePatientId = goldenPatient.getIdElement().toUnqualifiedVersionless();
|
||||||
// TODO NG should be ok to remove - assertEquals(0, goldenPatient.getLink().size());
|
|
||||||
Patient patient = createPatient();
|
Patient patient = createPatient();
|
||||||
|
|
||||||
{
|
{
|
||||||
myMdmLinkSvc.updateLink(goldenPatient, patient, POSSIBLE_MATCH, MdmLinkSourceEnum.AUTO, createContextForCreate("Patient"));
|
myMdmLinkSvc.updateLink(goldenPatient, patient, POSSIBLE_MATCH, MdmLinkSourceEnum.AUTO, createContextForCreate("Patient"));
|
||||||
assertLinkCount(1);
|
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"));
|
myMdmLinkSvc.updateLink(goldenPatient, patient, MdmMatchOutcome.NO_MATCH, MdmLinkSourceEnum.MANUAL, createContextForCreate("Patient"));
|
||||||
assertLinkCount(1);
|
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
|
@Test
|
||||||
public void testManualMdmLinksCannotBeModifiedBySystem() {
|
public void testManualMdmLinksCannotBeModifiedBySystem() {
|
||||||
// Patient goldenPatient = createGoldenPatient(buildJaneSourcePatient());
|
|
||||||
Patient goldenPatient = createGoldenPatient(buildJanePatient());
|
Patient goldenPatient = createGoldenPatient(buildJanePatient());
|
||||||
Patient patient = createPatient(buildJanePatient());
|
Patient patient = createPatient(buildJanePatient());
|
||||||
|
|
||||||
|
@ -144,7 +136,6 @@ public class MdmLinkSvcTest extends BaseMdmR4Test {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAutomaticallyAddedNO_MATCHMdmLinksAreNotAllowed() {
|
public void testAutomaticallyAddedNO_MATCHMdmLinksAreNotAllowed() {
|
||||||
// Patient goldenPatient = createGoldenPatient(buildJaneSourcePatient());
|
|
||||||
Patient goldenPatient = createGoldenPatient(buildJanePatient());
|
Patient goldenPatient = createGoldenPatient(buildJanePatient());
|
||||||
Patient patient = createPatient(buildJanePatient());
|
Patient patient = createPatient(buildJanePatient());
|
||||||
|
|
||||||
|
@ -159,7 +150,6 @@ public class MdmLinkSvcTest extends BaseMdmR4Test {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSyncDoesNotSyncNoMatchLinks() {
|
public void testSyncDoesNotSyncNoMatchLinks() {
|
||||||
// Patient sourcePatient = createGoldenPatient(buildJaneSourcePatient());
|
|
||||||
Patient goldenPatient = createGoldenPatient(buildJanePatient());
|
Patient goldenPatient = createGoldenPatient(buildJanePatient());
|
||||||
Patient patient1 = createPatient(buildJanePatient());
|
Patient patient1 = createPatient(buildJanePatient());
|
||||||
Patient patient2 = createPatient(buildJanePatient());
|
Patient patient2 = createPatient(buildJanePatient());
|
||||||
|
@ -171,7 +161,6 @@ public class MdmLinkSvcTest extends BaseMdmR4Test {
|
||||||
List<MdmLink> targets = myMdmLinkDaoSvc.findMdmLinksByGoldenResource(goldenPatient);
|
List<MdmLink> targets = myMdmLinkDaoSvc.findMdmLinksByGoldenResource(goldenPatient);
|
||||||
assertFalse(targets.isEmpty());
|
assertFalse(targets.isEmpty());
|
||||||
assertEquals(2, targets.size());
|
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"
|
//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());
|
//assertEquals(patient1.getIdElement().toVersionless().getValue(), sourcePatient.getLinkFirstRep().getTarget().getReference());
|
||||||
|
|
|
@ -8,6 +8,7 @@ import ca.uhn.fhir.mdm.api.MdmConstants;
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
|
import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
|
||||||
import ca.uhn.fhir.mdm.api.MdmMatchOutcome;
|
import ca.uhn.fhir.mdm.api.MdmMatchOutcome;
|
||||||
import ca.uhn.fhir.mdm.model.CanonicalEID;
|
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.EIDHelper;
|
||||||
import ca.uhn.fhir.mdm.util.GoldenResourceHelper;
|
import ca.uhn.fhir.mdm.util.GoldenResourceHelper;
|
||||||
import ca.uhn.fhir.mdm.util.MdmResourceUtil;
|
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
|
//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.
|
//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"));
|
myMdmLinkSvc.updateLink(goldenResource, janePatient2, MdmMatchOutcome.NEW_GOLDEN_RESOURCE_MATCH, MdmLinkSourceEnum.AUTO, createContextForCreate("Patient"));
|
||||||
assertThat(janePatient, is(not(sameGoldenResourceAs(janePatient2))));
|
assertThat(janePatient, is(not(sameGoldenResourceAs(janePatient2))));
|
||||||
|
|
||||||
|
@ -443,7 +444,7 @@ public class MdmMatchLinkSvcTest extends BaseMdmR4Test {
|
||||||
public void testCreateGoldenResourceFromMdmTarget() {
|
public void testCreateGoldenResourceFromMdmTarget() {
|
||||||
// Create Use Case #2 - adding patient with no EID
|
// Create Use Case #2 - adding patient with no EID
|
||||||
Patient janePatient = buildJanePatient();
|
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
|
// golden record now contains HAPI-generated EID and HAPI tag
|
||||||
assertTrue(MdmResourceUtil.isMdmManaged(janeGoldenResourcePatient));
|
assertTrue(MdmResourceUtil.isMdmManaged(janeGoldenResourcePatient));
|
||||||
|
|
|
@ -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,
|
* 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.
|
* a randomly generated UUID EID will be created.
|
||||||
*
|
* @param <T> Supported MDM resource type (e.g. Patient, Practitioner)
|
||||||
* @param <T> 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 theIncomingResource The resource that will be used as the starting point for the MDM linking.
|
||||||
|
* @param theMdmTransactionContext
|
||||||
*/
|
*/
|
||||||
public <T extends IAnyResource> T createGoldenResourceFromMdmSourceResource(T theIncomingResource) {
|
public <T extends IAnyResource> T createGoldenResourceFromMdmSourceResource(T theIncomingResource, MdmTransactionContext theMdmTransactionContext) {
|
||||||
validateContextSupported();
|
validateContextSupported();
|
||||||
|
|
||||||
// get a ref to the actual ID Field
|
// get a ref to the actual ID Field
|
||||||
RuntimeResourceDefinition resourceDefinition = myFhirContext.getResourceDefinition(theIncomingResource);
|
RuntimeResourceDefinition resourceDefinition = myFhirContext.getResourceDefinition(theIncomingResource);
|
||||||
IBaseResource newGoldenResource = resourceDefinition.newInstance();
|
IBaseResource newGoldenResource = resourceDefinition.newInstance();
|
||||||
|
|
||||||
|
myMdmSurvivorshipService.applySurvivorshipRulesToGoldenResource(theIncomingResource, newGoldenResource, theMdmTransactionContext);
|
||||||
|
|
||||||
// hapi has 2 metamodels: for children and types
|
// hapi has 2 metamodels: for children and types
|
||||||
BaseRuntimeChildDefinition goldenResourceIdentifier = resourceDefinition.getChildByName(FIELD_NAME_IDENTIFIER);
|
BaseRuntimeChildDefinition goldenResourceIdentifier = resourceDefinition.getChildByName(FIELD_NAME_IDENTIFIER);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue