Ks 20211203 mdm possible match (#3216)
* begin with failing test * fix issue * change log * code review
This commit is contained in:
parent
84a9609236
commit
0656037c8d
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
type: fix
|
||||
title: "MDM was throwing a NullPointerException when upgrading a match from POSSIBLE_MATCH to MATCH. This has been corrected."
|
|
@ -627,7 +627,7 @@ public class IdHelperService {
|
|||
}
|
||||
|
||||
@Nonnull
|
||||
public Long getPidOrThrowException(IAnyResource theResource) {
|
||||
public Long getPidOrThrowException(@Nonnull IAnyResource theResource) {
|
||||
Long retVal = (Long) theResource.getUserData(RESOURCE_PID);
|
||||
if (retVal == null) {
|
||||
throw new IllegalStateException(
|
||||
|
|
|
@ -30,7 +30,9 @@ import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
|||
import ca.uhn.fhir.mdm.api.paging.MdmPageRequest;
|
||||
import ca.uhn.fhir.mdm.log.Logs;
|
||||
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.slf4j.Logger;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Example;
|
||||
|
@ -146,6 +148,15 @@ public class MdmLinkDaoSvc {
|
|||
* @return the {@link MdmLink} that contains the Match information for the source.
|
||||
*/
|
||||
public Optional<MdmLink> getMatchedLinkForSource(IBaseResource theSourceResource) {
|
||||
return getMdmLinkWithMatchResult(theSourceResource, MdmMatchResultEnum.MATCH);
|
||||
}
|
||||
|
||||
public Optional<MdmLink> getPossibleMatchedLinkForSource(IBaseResource theSourceResource) {
|
||||
return getMdmLinkWithMatchResult(theSourceResource, MdmMatchResultEnum.POSSIBLE_MATCH);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Optional<MdmLink> getMdmLinkWithMatchResult(IBaseResource theSourceResource, MdmMatchResultEnum theMatchResult) {
|
||||
Long pid = myIdHelperService.getPidOrNull(theSourceResource);
|
||||
if (pid == null) {
|
||||
return Optional.empty();
|
||||
|
@ -153,7 +164,7 @@ public class MdmLinkDaoSvc {
|
|||
|
||||
MdmLink exampleLink = myMdmLinkFactory.newMdmLink();
|
||||
exampleLink.setSourcePid(pid);
|
||||
exampleLink.setMatchResult(MdmMatchResultEnum.MATCH);
|
||||
exampleLink.setMatchResult(theMatchResult);
|
||||
Example<MdmLink> example = Example.of(exampleLink);
|
||||
return myMdmLinkDao.findOne(example);
|
||||
}
|
||||
|
@ -298,4 +309,12 @@ public class MdmLinkDaoSvc {
|
|||
return myMdmLinkFactory.newMdmLink();
|
||||
}
|
||||
|
||||
public Optional<MdmLink> getMatchedOrPossibleMatchedLinkForSource(IAnyResource theResource) {
|
||||
// TODO KHS instead of two queries, just do one query with an OR
|
||||
Optional<MdmLink> retval = getMatchedLinkForSource(theResource);
|
||||
if (!retval.isPresent()) {
|
||||
retval = getPossibleMatchedLinkForSource(theResource);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ public class MdmEidUpdateService {
|
|||
} 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(theTargetResource, updateContext.getExistingGoldenResource(), updateContext.getMatchedGoldenResource(), theMdmTransactionContext);
|
||||
linkToNewGoldenResourceAndFlagAsDuplicate(theTargetResource, theMatchedGoldenResourceCandidate.getMatchResult(), updateContext.getExistingGoldenResource(), updateContext.getMatchedGoldenResource(), theMdmTransactionContext);
|
||||
|
||||
myMdmSurvivorshipService.applySurvivorshipRulesToGoldenResource(theTargetResource, updateContext.getMatchedGoldenResource(), theMdmTransactionContext);
|
||||
myMdmResourceDaoSvc.upsertGoldenResource(updateContext.getMatchedGoldenResource(), theMdmTransactionContext.getResourceType());
|
||||
|
@ -121,10 +121,10 @@ public class MdmEidUpdateService {
|
|||
myMdmLinkSvc.updateLink(newGoldenResource, theOldGoldenResource, MdmMatchOutcome.POSSIBLE_DUPLICATE, MdmLinkSourceEnum.AUTO, theMdmTransactionContext);
|
||||
}
|
||||
|
||||
private void linkToNewGoldenResourceAndFlagAsDuplicate(IAnyResource theResource, IAnyResource theOldGoldenResource, IAnyResource theNewGoldenResource, MdmTransactionContext theMdmTransactionContext) {
|
||||
private void linkToNewGoldenResourceAndFlagAsDuplicate(IAnyResource theResource, MdmMatchOutcome theMatchResult, IAnyResource theOldGoldenResource, IAnyResource theNewGoldenResource, MdmTransactionContext theMdmTransactionContext) {
|
||||
log(theMdmTransactionContext, "Changing a match link!");
|
||||
myMdmLinkSvc.deleteLink(theOldGoldenResource, theResource, theMdmTransactionContext);
|
||||
myMdmLinkSvc.updateLink(theNewGoldenResource, theResource, MdmMatchOutcome.NEW_GOLDEN_RESOURCE_MATCH, MdmLinkSourceEnum.AUTO, theMdmTransactionContext);
|
||||
myMdmLinkSvc.updateLink(theNewGoldenResource, theResource, theMatchResult, MdmLinkSourceEnum.AUTO, theMdmTransactionContext);
|
||||
log(theMdmTransactionContext, "Duplicate detected based on the fact that both resources have different external EIDs.");
|
||||
myMdmLinkSvc.updateLink(theNewGoldenResource, theOldGoldenResource, MdmMatchOutcome.POSSIBLE_DUPLICATE, MdmLinkSourceEnum.AUTO, theMdmTransactionContext);
|
||||
}
|
||||
|
@ -161,11 +161,11 @@ public class MdmEidUpdateService {
|
|||
myHasEidsInCommon = myEIDHelper.hasEidOverlap(myMatchedGoldenResource, theResource);
|
||||
myIncomingResourceHasAnEid = !myEIDHelper.getExternalEid(theResource).isEmpty();
|
||||
|
||||
Optional<MdmLink> theExistingMatchLink = myMdmLinkDaoSvc.getMatchedLinkForSource(theResource);
|
||||
Optional<MdmLink> theExistingMatchOrPossibleMatchLink = myMdmLinkDaoSvc.getMatchedOrPossibleMatchedLinkForSource(theResource);
|
||||
myExistingGoldenResource = null;
|
||||
|
||||
if (theExistingMatchLink.isPresent()) {
|
||||
MdmLink mdmLink = theExistingMatchLink.get();
|
||||
if (theExistingMatchOrPossibleMatchLink.isPresent()) {
|
||||
MdmLink mdmLink = theExistingMatchOrPossibleMatchLink.get();
|
||||
Long existingGoldenResourcePid = mdmLink.getGoldenResourcePid();
|
||||
myExistingGoldenResource = myMdmResourceDaoSvc.readGoldenResourceByPid(new ResourcePersistentId(existingGoldenResourcePid), resourceType);
|
||||
myRemainsMatchedToSameGoldenResource = candidateIsSameAsMdmLinkGoldenResource(mdmLink, theMatchedGoldenResourceCandidate);
|
||||
|
|
|
@ -36,6 +36,7 @@ import org.slf4j.Logger;
|
|||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.transaction.Transactional;
|
||||
import java.util.Optional;
|
||||
|
||||
|
@ -85,6 +86,9 @@ public class MdmLinkSvcImpl implements IMdmLinkSvc {
|
|||
|
||||
@Override
|
||||
public void deleteLink(IAnyResource theGoldenResource, IAnyResource theSourceResource, MdmTransactionContext theMdmTransactionContext) {
|
||||
if (theGoldenResource == null) {
|
||||
return;
|
||||
}
|
||||
Optional<MdmLink> optionalMdmLink = getMdmLinkForGoldenResourceSourceResourcePair(theGoldenResource, theSourceResource);
|
||||
if (optionalMdmLink.isPresent()) {
|
||||
MdmLink mdmLink = optionalMdmLink.get();
|
||||
|
@ -122,7 +126,7 @@ public class MdmLinkSvcImpl implements IMdmLinkSvc {
|
|||
return theIncomingSource == MdmLinkSourceEnum.AUTO && theExistingSource.isManual();
|
||||
}
|
||||
|
||||
private Optional<MdmLink> getMdmLinkForGoldenResourceSourceResourcePair(IAnyResource theGoldenResource, IAnyResource theCandidate) {
|
||||
private Optional<MdmLink> getMdmLinkForGoldenResourceSourceResourcePair(@Nonnull IAnyResource theGoldenResource, @Nonnull IAnyResource theCandidate) {
|
||||
if (theGoldenResource.getIdElement().getIdPart() == null || theCandidate.getIdElement().getIdPart() == null) {
|
||||
return Optional.empty();
|
||||
} else {
|
||||
|
|
|
@ -435,6 +435,33 @@ public class MdmMatchLinkSvcTest extends BaseMdmR4Test {
|
|||
assertThat(patient3, is(sameGoldenResourceAs(patient)));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testPossibleMatchUpdatedToMatch() {
|
||||
// setup
|
||||
Patient patient = buildJanePatient();
|
||||
patient.getNameFirstRep().setFamily("familyone");
|
||||
patient = createPatientAndUpdateLinks(patient);
|
||||
assertThat(patient, is(sameGoldenResourceAs(patient)));
|
||||
|
||||
Patient patient2 = buildJanePatient();
|
||||
patient2.getNameFirstRep().setFamily("pleasedonotmatchatall");
|
||||
patient2 = createPatientAndUpdateLinks(patient2);
|
||||
|
||||
assertThat(patient2, is(not(sameGoldenResourceAs(patient))));
|
||||
assertThat(patient2, is(not(linkedTo(patient))));
|
||||
assertThat(patient2, is(possibleMatchWith(patient)));
|
||||
|
||||
patient2.getNameFirstRep().setFamily(patient.getNameFirstRep().getFamily());
|
||||
|
||||
// execute
|
||||
updatePatientAndUpdateLinks(patient2);
|
||||
|
||||
// validate
|
||||
assertThat(patient2, is(linkedTo(patient)));
|
||||
assertThat(patient2, is(sameGoldenResourceAs(patient)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateGoldenResourceFromMdmTarget() {
|
||||
// Create Use Case #2 - adding patient with no EID
|
||||
|
|
Loading…
Reference in New Issue