Fixed code for UpdateLinkR4Test

This commit is contained in:
Nick Goupinets 2020-11-16 15:08:34 -05:00
parent 54f0021b29
commit 869814606d
7 changed files with 74 additions and 56 deletions

View File

@ -55,8 +55,8 @@ public class EmpiControllerSvcImpl implements IEmpiControllerSvc {
@Override
public IAnyResource mergeGoldenResources(String theFromPersonId, String theToPersonId, MdmTransactionContext theMdmTransactionContext) {
IAnyResource fromPerson = myEmpiControllerHelper.getLatestPersonFromIdOrThrowException(ProviderConstants.MDM_MERGE_GR_FROM_GOLDEN_RESOURCE_ID, theFromPersonId);
IAnyResource toPerson = myEmpiControllerHelper.getLatestPersonFromIdOrThrowException(ProviderConstants.MDM_MERGE_GR_TO_GOLDEN_RESOURCE_ID, theToPersonId);
IAnyResource fromPerson = myEmpiControllerHelper.getLatestGoldenResourceFromIdOrThrowException(ProviderConstants.MDM_MERGE_GR_FROM_GOLDEN_RESOURCE_ID, theFromPersonId);
IAnyResource toPerson = myEmpiControllerHelper.getLatestGoldenResourceFromIdOrThrowException(ProviderConstants.MDM_MERGE_GR_TO_GOLDEN_RESOURCE_ID, theToPersonId);
myEmpiControllerHelper.validateMergeResources(fromPerson, toPerson);
myEmpiControllerHelper.validateSameVersion(fromPerson, theFromPersonId);
myEmpiControllerHelper.validateSameVersion(toPerson, theToPersonId);
@ -80,11 +80,11 @@ public class EmpiControllerSvcImpl implements IEmpiControllerSvc {
}
@Override
public IAnyResource updateLink(String thePersonId, String theTargetId, String theMatchResult, MdmTransactionContext theEmpiContext) {
public IAnyResource updateLink(String theGoldenResourceId, String theTargetId, String theMatchResult, MdmTransactionContext theEmpiContext) {
EmpiMatchResultEnum matchResult = EmpiControllerUtil.extractMatchResultOrNull(theMatchResult);
IAnyResource person = myEmpiControllerHelper.getLatestPersonFromIdOrThrowException(ProviderConstants.MDM_UPDATE_LINK_GOLDEN_RESOURCE_ID, thePersonId);
IAnyResource person = myEmpiControllerHelper.getLatestGoldenResourceFromIdOrThrowException(ProviderConstants.MDM_UPDATE_LINK_GOLDEN_RESOURCE_ID, theGoldenResourceId);
IAnyResource target = myEmpiControllerHelper.getLatestTargetFromIdOrThrowException(ProviderConstants.MDM_UPDATE_LINK_RESOURCE_ID, theTargetId);
myEmpiControllerHelper.validateSameVersion(person, thePersonId);
myEmpiControllerHelper.validateSameVersion(person, theGoldenResourceId);
myEmpiControllerHelper.validateSameVersion(target, theTargetId);
return myIEmpiLinkUpdaterSvc.updateLink(person, target, matchResult, theEmpiContext);
@ -92,8 +92,8 @@ public class EmpiControllerSvcImpl implements IEmpiControllerSvc {
@Override
public void notDuplicateGoldenResource(String thePersonId, String theTargetPersonId, MdmTransactionContext theEmpiContext) {
IAnyResource person = myEmpiControllerHelper.getLatestPersonFromIdOrThrowException(ProviderConstants.MDM_UPDATE_LINK_GOLDEN_RESOURCE_ID, thePersonId);
IAnyResource target = myEmpiControllerHelper.getLatestPersonFromIdOrThrowException(ProviderConstants.MDM_UPDATE_LINK_RESOURCE_ID, theTargetPersonId);
IAnyResource person = myEmpiControllerHelper.getLatestGoldenResourceFromIdOrThrowException(ProviderConstants.MDM_UPDATE_LINK_GOLDEN_RESOURCE_ID, thePersonId);
IAnyResource target = myEmpiControllerHelper.getLatestGoldenResourceFromIdOrThrowException(ProviderConstants.MDM_UPDATE_LINK_RESOURCE_ID, theTargetPersonId);
myIEmpiLinkUpdaterSvc.notDuplicatePerson(person, target, theEmpiContext);
}

View File

@ -68,35 +68,36 @@ public class EmpiLinkUpdaterSvcImpl implements IEmpiLinkUpdaterSvc {
@Transactional
@Override
public IAnyResource updateLink(IAnyResource thePerson, IAnyResource theTarget, EmpiMatchResultEnum theMatchResult, MdmTransactionContext theEmpiContext) {
public IAnyResource updateLink(IAnyResource theGoldenResource, IAnyResource theTarget, EmpiMatchResultEnum theMatchResult, MdmTransactionContext theEmpiContext) {
String targetType = myFhirContext.getResourceType(theTarget);
validateUpdateLinkRequest(thePerson, theTarget, theMatchResult, targetType);
validateUpdateLinkRequest(theGoldenResource, theTarget, theMatchResult, targetType);
Long personId = myIdHelperService.getPidOrThrowException(thePerson);
Long goldenResourceId = myIdHelperService.getPidOrThrowException(theGoldenResource);
Long targetId = myIdHelperService.getPidOrThrowException(theTarget);
Optional<EmpiLink> oEmpiLink = myEmpiLinkDaoSvc.getLinkBySourceResourcePidAndTargetResourcePid(personId, targetId);
Optional<EmpiLink> oEmpiLink = myEmpiLinkDaoSvc.getLinkBySourceResourcePidAndTargetResourcePid(goldenResourceId, targetId);
if (!oEmpiLink.isPresent()) {
throw new InvalidRequestException(myMessageHelper.getMessageForNoLink(thePerson, theTarget));
}
EmpiLink empiLink = oEmpiLink.get();
if (empiLink.getMatchResult() == theMatchResult) {
ourLog.warn("EMPI Link for " + thePerson.getIdElement().toVersionless() + ", " + theTarget.getIdElement().toVersionless() + " already has value " + theMatchResult + ". Nothing to do.");
return thePerson;
throw new InvalidRequestException(myMessageHelper.getMessageForNoLink(theGoldenResource, theTarget));
}
ourLog.info("Manually updating EMPI Link for " + thePerson.getIdElement().toVersionless() + ", " + theTarget.getIdElement().toVersionless() + " from " + empiLink.getMatchResult() + " to " + theMatchResult + ".");
EmpiLink empiLink = oEmpiLink.get();
if (empiLink.getMatchResult() == theMatchResult) {
ourLog.warn("MDM Link for " + theGoldenResource.getIdElement().toVersionless() + ", " + theTarget.getIdElement().toVersionless() + " already has value " + theMatchResult + ". Nothing to do.");
return theGoldenResource;
}
ourLog.info("Manually updating MDM Link for " + theGoldenResource.getIdElement().toVersionless() + ", " + theTarget.getIdElement().toVersionless() + " from " + empiLink.getMatchResult() + " to " + theMatchResult + ".");
empiLink.setMatchResult(theMatchResult);
empiLink.setLinkSource(EmpiLinkSourceEnum.MANUAL);
myEmpiLinkDaoSvc.save(empiLink);
// myEmpiLinkSvc.syncEmpiLinksToPersonLinks(thePerson, theEmpiContext);
myEmpiResourceDaoSvc.upsertSourceResource(thePerson, theEmpiContext.getResourceType());
// myEmpiLinkSvc.syncEmpiLinksToPersonLinks(theGoldenResource, theEmpiContext);
myEmpiResourceDaoSvc.upsertSourceResource(theGoldenResource, theEmpiContext.getResourceType());
if (theMatchResult == EmpiMatchResultEnum.NO_MATCH) {
// Need to find a new Person to link this target to
myEmpiMatchLinkSvc.updateEmpiLinksForEmpiTarget(theTarget, theEmpiContext);
}
return thePerson;
return theGoldenResource;
}
private void validateUpdateLinkRequest(IAnyResource theGoldenRecord, IAnyResource theTarget, EmpiMatchResultEnum theMatchResult, String theTargetType) {

View File

@ -29,10 +29,13 @@ import ca.uhn.fhir.jpa.model.entity.TagTypeEnum;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
import ca.uhn.fhir.rest.param.TokenParam;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.IdType;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

View File

@ -31,7 +31,7 @@ public abstract class BaseLinkR4Test extends BaseProviderR4Test {
protected EmpiLink myLink;
protected StringType myPatientId;
protected StringType mySourcePatientId;
protected StringType myVersionlessPersonId;
protected StringType myVersionlessGodlenResourceId;
@Override
@BeforeEach
@ -43,7 +43,7 @@ public abstract class BaseLinkR4Test extends BaseProviderR4Test {
mySourcePatient = getGoldenResourceFromTargetResource(myPatient);
mySourcePatientId = new StringType(mySourcePatient.getIdElement().getValue());
myVersionlessPersonId = new StringType(mySourcePatient.getIdElement().toVersionless().getValue());
myVersionlessGodlenResourceId = new StringType(mySourcePatient.getIdElement().toVersionless().getValue());
myLink = getOnlyPatientLink();
// Tests require our initial link to be a POSSIBLE_MATCH

View File

@ -3,14 +3,11 @@ package ca.uhn.fhir.jpa.empi.provider;
import ca.uhn.fhir.empi.api.EmpiConstants;
import ca.uhn.fhir.empi.api.EmpiLinkSourceEnum;
import ca.uhn.fhir.empi.api.EmpiMatchResultEnum;
import ca.uhn.fhir.empi.api.IEmpiSettings;
import ca.uhn.fhir.empi.provider.EmpiControllerHelper;
import ca.uhn.fhir.empi.util.MessageHelper;
import ca.uhn.fhir.jpa.entity.EmpiLink;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
import org.hl7.fhir.r4.model.Patient;
import org.hl7.fhir.r4.model.Person;
import org.hl7.fhir.r4.model.StringType;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
@ -18,12 +15,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.matchesPattern;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.fail;
import static org.hamcrest.Matchers.*;
import static org.junit.jupiter.api.Assertions.*;
public class EmpiProviderUpdateLinkR4Test extends BaseLinkR4Test {
@ -33,7 +26,6 @@ public class EmpiProviderUpdateLinkR4Test extends BaseLinkR4Test {
@Test
public void testUpdateLinkNoMatch() {
assertLinkCount(1);
System.out.println(mySourcePatientId);
myEmpiProviderR4.updateLink(mySourcePatientId, myPatientId, NO_MATCH_RESULT, myRequestDetails);
assertLinkCount(2);
@ -59,39 +51,51 @@ public class EmpiProviderUpdateLinkR4Test extends BaseLinkR4Test {
@Test
public void testUpdateLinkTwiceFailsDueToWrongVersion() {
myEmpiProviderR4.updateLink(mySourcePatientId, myPatientId, MATCH_RESULT, myRequestDetails);
materiallyChangeGoldenPatient();
try {
myEmpiProviderR4.updateLink(mySourcePatientId, myPatientId, NO_MATCH_RESULT, myRequestDetails);
fail();
} catch (ResourceVersionConflictException e) {
assertThat(e.getMessage(), matchesPattern("Requested resource Person/\\d+/_history/1 is not the latest version. Latest version is Person/\\d+/_history/2"));
assertThat(e.getMessage(), matchesPattern("Requested resource Patient/\\d+/_history/1 is not the latest version. Latest version is Patient/\\d+/_history/2"));
}
}
private void materiallyChangeGoldenPatient() {
Patient materiallyChangedSourcePatientThatShouldTriggerVersionChange = (Patient) mySourcePatient;
materiallyChangedSourcePatientThatShouldTriggerVersionChange.getNameFirstRep().setFamily("NEW LAST NAME");
myPatientDao.update(materiallyChangedSourcePatientThatShouldTriggerVersionChange);
}
@Test
public void testUpdateLinkTwiceWorksWhenNoVersionProvided() {
public void testUpdateLinkTwiceDoesNotThrowValidationErrorWhenNoVersionIsProvided() {
myEmpiProviderR4.updateLink(mySourcePatientId, myPatientId, MATCH_RESULT, myRequestDetails);
Person person = (Person) myEmpiProviderR4.updateLink(myVersionlessPersonId, myPatientId, NO_MATCH_RESULT, myRequestDetails);
assertThat(person.getLink(), hasSize(0));
Patient patient = (Patient) myEmpiProviderR4.updateLink(myVersionlessGodlenResourceId, myPatientId, NO_MATCH_RESULT, myRequestDetails);
assertNotNull(patient); // if this wasn't allowed - a validation exception would be thrown
}
@Test
public void testUnlinkLink() {
myEmpiProviderR4.updateLink(mySourcePatientId, myPatientId, NO_MATCH_RESULT, myRequestDetails);
materiallyChangeGoldenPatient();
try {
myEmpiProviderR4.updateLink(mySourcePatientId, myPatientId, MATCH_RESULT, myRequestDetails);
fail();
} catch (ResourceVersionConflictException e) {
assertThat(e.getMessage(), matchesPattern("Requested resource Person/\\d+/_history/1 is not the latest version. Latest version is Person/\\d+/_history/2"));
assertThat(e.getMessage(), matchesPattern("Requested resource Patient/\\d+/_history/1 is not the latest version. Latest version is Patient/\\d+/_history/2"));
}
}
@Test
public void testUpdateIllegalResultPM() {
public void testUpdateIllegalResultForPossibleMatch() {
try {
myEmpiProviderR4.updateLink(mySourcePatientId, myPatientId, POSSIBLE_MATCH_RESULT, myRequestDetails);
fail();
} catch (InvalidRequestException e) {
assertEquals("$empi-update-link illegal matchResult value 'POSSIBLE_MATCH'. Must be NO_MATCH or MATCH", e.getMessage());
assertEquals("$mdm-update-link illegal matchResult value 'POSSIBLE_MATCH'. Must be NO_MATCH or MATCH", e.getMessage());
}
}
@ -101,27 +105,37 @@ public class EmpiProviderUpdateLinkR4Test extends BaseLinkR4Test {
myEmpiProviderR4.updateLink(mySourcePatientId, myPatientId, POSSIBLE_DUPLICATE_RESULT, myRequestDetails);
fail();
} catch (InvalidRequestException e) {
assertEquals("$empi-update-link illegal matchResult value 'POSSIBLE_DUPLICATE'. Must be NO_MATCH or MATCH", e.getMessage());
}
}
@Test
public void testUpdateIllegalFirstArg() {
try {
myEmpiProviderR4.updateLink(myPatientId, myPatientId, NO_MATCH_RESULT, myRequestDetails);
fail();
} catch (InvalidRequestException e) {
assertThat(e.getMessage(), endsWith(" must have form Person/<id> where <id> is the id of the person"));
assertEquals("$mdm-update-link illegal matchResult value 'POSSIBLE_DUPLICATE'. Must be NO_MATCH or MATCH", e.getMessage());
}
}
@Test
public void testUpdateIllegalSecondArg() {
try {
myEmpiProviderR4.updateLink(myPatientId, new StringType(""), NO_MATCH_RESULT, myRequestDetails);
fail();
} catch (InvalidRequestException e) {
assertThat(e.getMessage(), endsWith(" must have form <resourceType>/<id> where <id> is the id of the resource and <resourceType> is the type of the resource"));
}
}
@Test
public void testUpdateIllegalFirstArg() {
try {
myEmpiProviderR4.updateLink(new StringType(""), myPatientId, NO_MATCH_RESULT, myRequestDetails);
fail();
} catch (InvalidRequestException e) {
assertThat(e.getMessage(), endsWith(" must have form <resourceType>/<id> where <id> is the id of the resource"));
}
}
@Test
public void testAttemptingToModifyANonExistentLinkFails() {
try {
myEmpiProviderR4.updateLink(mySourcePatientId, mySourcePatientId, NO_MATCH_RESULT, myRequestDetails);
fail();
} catch (InvalidRequestException e) {
assertThat(e.getMessage(), endsWith("must have form Patient/<id> or Practitioner/<id> where <id> is the id of the resource"));
assertThat(e.getMessage(), startsWith("No link"));
}
}

View File

@ -62,7 +62,7 @@ public abstract class BaseEmpiProvider {
}
protected void validateUpdateLinkParameters(IPrimitiveType<String> theGoldenResourceId, IPrimitiveType<String> theResourceId, IPrimitiveType<String> theMatchResult) {
// TODO NG - Add validation to check that types are the same?
// TODO NG - Add validation to check that types are the same? - This is done deeper in the code, perhaps move here?
validateNotNull(ProviderConstants.MDM_UPDATE_LINK_GOLDEN_RESOURCE_ID, theGoldenResourceId);
validateNotNull(ProviderConstants.MDM_UPDATE_LINK_RESOURCE_ID, theResourceId);
validateNotNull(ProviderConstants.MDM_UPDATE_LINK_MATCH_RESULT, theMatchResult);

View File

@ -67,9 +67,9 @@ public class EmpiControllerHelper {
return new IdDt(theId).hasVersionIdPart();
}
public IAnyResource getLatestPersonFromIdOrThrowException(String theParamName, String theId) {
IdDt personId = EmpiControllerUtil.getGoldenIdDtOrThrowException(theParamName, theId);
return loadResource(personId.toUnqualifiedVersionless());
public IAnyResource getLatestGoldenResourceFromIdOrThrowException(String theParamName, String theGoldenResourceId) {
IdDt resourceId = EmpiControllerUtil.getGoldenIdDtOrThrowException(theParamName, theGoldenResourceId);
return loadResource(resourceId.toUnqualifiedVersionless());
}