From 9136231b3b5d81b45653960e5b586c5926a9af9c Mon Sep 17 00:00:00 2001 From: Ken Stevens Date: Wed, 3 Jun 2020 18:00:20 -0400 Subject: [PATCH] Empi 62 resource history (#1894) --- .../jpa/empi/provider/BaseLinkR4Test.java | 26 ++++++----- .../EmpiProviderMergePersonsR4Test.java | 12 ++--- .../provider/EmpiProviderQueryLinkR4Test.java | 12 +++-- .../EmpiProviderUpdateLinkR4Test.java | 46 ++++++++++++++++--- .../fhir/empi/provider/BaseEmpiProvider.java | 20 ++++++-- .../fhir/empi/provider/EmpiProviderDstu3.java | 12 +++-- .../fhir/empi/provider/EmpiProviderR4.java | 12 +++-- 7 files changed, 100 insertions(+), 40 deletions(-) diff --git a/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/provider/BaseLinkR4Test.java b/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/provider/BaseLinkR4Test.java index 4d417adf3ae..c0be68494a5 100644 --- a/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/provider/BaseLinkR4Test.java +++ b/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/provider/BaseLinkR4Test.java @@ -13,31 +13,35 @@ import javax.annotation.Nonnull; import static org.junit.Assert.assertEquals; public abstract class BaseLinkR4Test extends BaseProviderR4Test { + protected static final StringType NO_MATCH_RESULT = new StringType(EmpiMatchResultEnum.NO_MATCH.name()); + protected static final StringType MATCH_RESULT = new StringType(EmpiMatchResultEnum.MATCH.name()); + protected static final StringType POSSIBLE_MATCH_RESULT = new StringType(EmpiMatchResultEnum.POSSIBLE_MATCH.name()); + protected static final StringType POSSIBLE_DUPLICATE_RESULT = new StringType(EmpiMatchResultEnum.POSSIBLE_DUPLICATE.name()); + protected Patient myPatient; protected Person myPerson; protected EmpiLink myLink; protected StringType myPatientId; protected StringType myPersonId; - protected StringType myNoMatch; - protected StringType myPossibleMatch; - protected StringType myPossibleDuplicate; + protected StringType myVersionlessPersonId; + @Before public void before() { super.before(); myPatient = createPatientAndUpdateLinks(new Patient()); - myPatientId = new StringType(myPatient.getIdElement().toUnqualifiedVersionless().getValue()); + myPatientId = new StringType(myPatient.getIdElement().getValue()); myPerson = getPersonFromTarget(myPatient); - myPersonId = new StringType(myPerson.getIdElement().toUnqualifiedVersionless().getValue()); - myLink = getLink(); - assertEquals(EmpiLinkSourceEnum.AUTO, myLink.getLinkSource()); - assertEquals(EmpiMatchResultEnum.MATCH, myLink.getMatchResult()); + myPersonId = new StringType(myPerson.getIdElement().getValue()); + myVersionlessPersonId = new StringType(myPerson.getIdElement().toVersionless().getValue()); - myNoMatch = new StringType(EmpiMatchResultEnum.NO_MATCH.name()); - myPossibleMatch = new StringType(EmpiMatchResultEnum.POSSIBLE_MATCH.name()); - myPossibleDuplicate = new StringType(EmpiMatchResultEnum.POSSIBLE_DUPLICATE.name()); + myLink = getLink(); + // Tests require our initial link to be a POSSIBLE_MATCH + myLink.setMatchResult(EmpiMatchResultEnum.POSSIBLE_MATCH); + myEmpiLinkDao.save(myLink); + assertEquals(EmpiLinkSourceEnum.AUTO, myLink.getLinkSource()); } @Nonnull diff --git a/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/provider/EmpiProviderMergePersonsR4Test.java b/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/provider/EmpiProviderMergePersonsR4Test.java index b5e6a0fa04a..829339373ba 100644 --- a/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/provider/EmpiProviderMergePersonsR4Test.java +++ b/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/provider/EmpiProviderMergePersonsR4Test.java @@ -27,9 +27,9 @@ public class EmpiProviderMergePersonsR4Test extends BaseProviderR4Test { super.loadEmpiSearchParameters(); myFromPerson = createPerson(); - myFromPersonId = new StringType(myFromPerson.getIdElement().toUnqualifiedVersionless().getValue()); + myFromPersonId = new StringType(myFromPerson.getIdElement().getValue()); myToPerson = createPerson(); - myToPersonId = new StringType(myToPerson.getIdElement().toUnqualifiedVersionless().getValue()); + myToPersonId = new StringType(myToPerson.getIdElement().getValue()); } @Test @@ -55,8 +55,8 @@ public class EmpiProviderMergePersonsR4Test extends BaseProviderR4Test { @Test public void testUnmanagedMerge() { - StringType fromPersonId = new StringType(createUnmanagedPerson().getIdElement().toVersionless().getValue()); - StringType toPersonId = new StringType(createUnmanagedPerson().getIdElement().toVersionless().getValue()); + StringType fromPersonId = new StringType(createUnmanagedPerson().getIdElement().getValue()); + StringType toPersonId = new StringType(createUnmanagedPerson().getIdElement().getValue()); try { myEmpiProviderR4.mergePersons(fromPersonId, toPersonId, myRequestDetails); fail(); @@ -68,8 +68,8 @@ public class EmpiProviderMergePersonsR4Test extends BaseProviderR4Test { @Test public void testMergePatients() { try { - StringType patientId = new StringType(createPatient().getIdElement().toVersionless().getValue()); - StringType otherPatientId = new StringType(createPatient().getIdElement().toVersionless().getValue()); + StringType patientId = new StringType(createPatient().getIdElement().getValue()); + StringType otherPatientId = new StringType(createPatient().getIdElement().getValue()); myEmpiProviderR4.mergePersons(patientId, otherPatientId, myRequestDetails); fail(); } catch (InvalidRequestException e) { diff --git a/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/provider/EmpiProviderQueryLinkR4Test.java b/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/provider/EmpiProviderQueryLinkR4Test.java index 1f547dc9f8f..3cf4823491e 100644 --- a/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/provider/EmpiProviderQueryLinkR4Test.java +++ b/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/provider/EmpiProviderQueryLinkR4Test.java @@ -3,6 +3,7 @@ package ca.uhn.fhir.jpa.empi.provider; import ca.uhn.fhir.empi.api.EmpiLinkSourceEnum; import ca.uhn.fhir.empi.api.EmpiMatchResultEnum; import ca.uhn.fhir.jpa.entity.EmpiLink; +import ca.uhn.fhir.model.primitive.IdDt; import org.hl7.fhir.r4.model.IdType; import org.hl7.fhir.r4.model.Parameters; import org.hl7.fhir.r4.model.Patient; @@ -52,7 +53,7 @@ private static final Logger ourLog = LoggerFactory.getLogger(EmpiProviderQueryLi List list = result.getParameter(); assertThat(list, hasSize(1)); List part = list.get(0).getPart(); - assertEmpiLink(4, part, myPersonId.getValue(), myPatientId.getValue(), EmpiMatchResultEnum.MATCH); + assertEmpiLink(4, part, myPersonId.getValue(), myPatientId.getValue(), EmpiMatchResultEnum.POSSIBLE_MATCH); } @Test @@ -81,13 +82,12 @@ private static final Logger ourLog = LoggerFactory.getLogger(EmpiProviderQueryLi assertEmpiLink(2, part, myPerson1Id.getValue(), myPerson2Id.getValue(), EmpiMatchResultEnum.POSSIBLE_DUPLICATE); } - private void assertEmpiLink(int theExpectedSize, List thePart, String thePersonId, String theTargetId, EmpiMatchResultEnum theMatchResult) { assertThat(thePart, hasSize(theExpectedSize)); assertThat(thePart.get(0).getName(), is("personId")); - assertThat(thePart.get(0).getValue().toString(), is(thePersonId)); + assertThat(thePart.get(0).getValue().toString(), is(removeVersion(thePersonId))); assertThat(thePart.get(1).getName(), is("targetId")); - assertThat(thePart.get(1).getValue().toString(), is(theTargetId)); + assertThat(thePart.get(1).getValue().toString(), is(removeVersion(theTargetId))); if (theExpectedSize > 2) { assertThat(thePart.get(2).getName(), is("matchResult")); assertThat(thePart.get(2).getValue().toString(), is(theMatchResult.name())); @@ -95,4 +95,8 @@ private static final Logger ourLog = LoggerFactory.getLogger(EmpiProviderQueryLi assertThat(thePart.get(3).getValue().toString(), is("AUTO")); } } + + private String removeVersion(String theId) { + return new IdDt(theId).toVersionless().getValue(); + } } diff --git a/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/provider/EmpiProviderUpdateLinkR4Test.java b/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/provider/EmpiProviderUpdateLinkR4Test.java index dd7814d2c45..1fad4f502d9 100644 --- a/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/provider/EmpiProviderUpdateLinkR4Test.java +++ b/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/provider/EmpiProviderUpdateLinkR4Test.java @@ -4,6 +4,7 @@ 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.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; @@ -11,6 +12,8 @@ import org.junit.Test; 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.Assert.assertEquals; import static org.junit.Assert.fail; @@ -19,17 +22,46 @@ public class EmpiProviderUpdateLinkR4Test extends BaseLinkR4Test { @Test public void testUpdateLinkHappyPath() { - myEmpiProviderR4.updateLink(myPersonId, myPatientId, myNoMatch, myRequestDetails); + myEmpiProviderR4.updateLink(myPersonId, myPatientId, NO_MATCH_RESULT, myRequestDetails); myLink = getLink(); assertEquals(EmpiLinkSourceEnum.MANUAL, myLink.getLinkSource()); assertEquals(EmpiMatchResultEnum.NO_MATCH, myLink.getMatchResult()); } + @Test + public void testUpdateLinkTwiceFailsDueToWrongVersion() { + myEmpiProviderR4.updateLink(myPersonId, myPatientId, MATCH_RESULT, myRequestDetails); + try { + myEmpiProviderR4.updateLink(myPersonId, 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")); + } + } + + @Test + public void testUpdateLinkTwiceWorksWhenNoVersionProvided() { + myEmpiProviderR4.updateLink(myPersonId, myPatientId, MATCH_RESULT, myRequestDetails); + Person person = myEmpiProviderR4.updateLink(myVersionlessPersonId, myPatientId, NO_MATCH_RESULT, myRequestDetails); + assertThat(person.getLink(), hasSize(0)); + } + + @Test + public void testUnlinkLink() { + myEmpiProviderR4.updateLink(myPersonId, myPatientId, NO_MATCH_RESULT, myRequestDetails); + try { + myEmpiProviderR4.updateLink(myPersonId, 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")); + } + } + @Test public void testUpdateIllegalResultPM() { try { - myEmpiProviderR4.updateLink(myPersonId, myPatientId, myPossibleMatch, myRequestDetails); + myEmpiProviderR4.updateLink(myPersonId, 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()); @@ -39,7 +71,7 @@ public class EmpiProviderUpdateLinkR4Test extends BaseLinkR4Test { @Test public void testUpdateIllegalResultPD() { try { - myEmpiProviderR4.updateLink(myPersonId, myPatientId, myPossibleDuplicate, myRequestDetails); + myEmpiProviderR4.updateLink(myPersonId, 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()); @@ -49,7 +81,7 @@ public class EmpiProviderUpdateLinkR4Test extends BaseLinkR4Test { @Test public void testUpdateIllegalFirstArg() { try { - myEmpiProviderR4.updateLink(myPatientId, myPatientId, myNoMatch, myRequestDetails); + myEmpiProviderR4.updateLink(myPatientId, myPatientId, NO_MATCH_RESULT, myRequestDetails); fail(); } catch (InvalidRequestException e) { assertEquals("personId must have form Person/ where is the id of the person", e.getMessage()); @@ -59,7 +91,7 @@ public class EmpiProviderUpdateLinkR4Test extends BaseLinkR4Test { @Test public void testUpdateIllegalSecondArg() { try { - myEmpiProviderR4.updateLink(myPersonId, myPersonId, myNoMatch, myRequestDetails); + myEmpiProviderR4.updateLink(myPersonId, myPersonId, NO_MATCH_RESULT, myRequestDetails); fail(); } catch (InvalidRequestException e) { assertThat(e.getMessage(), endsWith("must have form Patient/ or Practitioner/ where is the id of the resource")); @@ -70,7 +102,7 @@ public class EmpiProviderUpdateLinkR4Test extends BaseLinkR4Test { public void testUpdateStrangePerson() { Person person = createUnmanagedPerson(); try { - myEmpiProviderR4.updateLink(new StringType(person.getIdElement().toVersionless().getValue()), myPatientId, myNoMatch, myRequestDetails); + myEmpiProviderR4.updateLink(new StringType(person.getIdElement().getValue()), myPatientId, NO_MATCH_RESULT, myRequestDetails); fail(); } catch (InvalidRequestException e) { assertEquals("Only EMPI Managed Person resources may be updated via this operation. The Person resource provided is not tagged as managed by hapi-empi", e.getMessage()); @@ -83,7 +115,7 @@ public class EmpiProviderUpdateLinkR4Test extends BaseLinkR4Test { patient.getMeta().addTag().setSystem(EmpiConstants.SYSTEM_EMPI_MANAGED).setCode(EmpiConstants.CODE_NO_EMPI_MANAGED); createPatient(patient); try { - myEmpiProviderR4.updateLink(myPersonId, new StringType(patient.getIdElement().toVersionless().getValue()), myNoMatch, myRequestDetails); + myEmpiProviderR4.updateLink(myPersonId, new StringType(patient.getIdElement().getValue()), NO_MATCH_RESULT, myRequestDetails); fail(); } catch (InvalidRequestException e) { assertEquals("The target is marked with the " + EmpiConstants.CODE_NO_EMPI_MANAGED + " tag which means it may not be EMPI linked.", e.getMessage()); diff --git a/hapi-fhir-server-empi/src/main/java/ca/uhn/fhir/empi/provider/BaseEmpiProvider.java b/hapi-fhir-server-empi/src/main/java/ca/uhn/fhir/empi/provider/BaseEmpiProvider.java index 7985603707d..aabff47a39f 100644 --- a/hapi-fhir-server-empi/src/main/java/ca/uhn/fhir/empi/provider/BaseEmpiProvider.java +++ b/hapi-fhir-server-empi/src/main/java/ca/uhn/fhir/empi/provider/BaseEmpiProvider.java @@ -30,6 +30,7 @@ import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.server.TransactionLogMessages; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; +import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException; import ca.uhn.fhir.rest.server.provider.ProviderConstants; import ca.uhn.fhir.validation.IResourceLoader; import org.hl7.fhir.instance.model.api.IAnyResource; @@ -47,9 +48,9 @@ public abstract class BaseEmpiProvider { myResourceLoader = theResourceLoader; } - protected IAnyResource getPersonFromIdOrThrowException(String theParamName, String theId) { + protected IAnyResource getLatestPersonFromIdOrThrowException(String theParamName, String theId) { IdDt personId = getPersonIdDtOrThrowException(theParamName, theId); - return loadResource(personId); + return loadResource(personId.toUnqualifiedVersionless()); } private IdDt getPersonIdDtOrThrowException(String theParamName, String theId) { @@ -61,9 +62,9 @@ public abstract class BaseEmpiProvider { return personId; } - protected IAnyResource getTargetFromIdOrThrowException(String theParamName, String theId) { + protected IAnyResource getLatestTargetFromIdOrThrowException(String theParamName, String theId) { IIdType targetId = getTargetIdDtOrThrowException(theParamName, theId); - return loadResource(targetId); + return loadResource(targetId.toUnqualifiedVersionless()); } protected IIdType getTargetIdDtOrThrowException(String theParamName, String theId) { @@ -168,4 +169,15 @@ public abstract class BaseEmpiProvider { return getTargetIdDtOrThrowException(theName, targetId); } + protected void validateSameVersion(IAnyResource theResource, IPrimitiveType theResourceId) { + String storedId = theResource.getIdElement().getValue(); + String requestedId = theResourceId.getValue(); + if (hasVersionIdPart(requestedId) && !storedId.equals(requestedId)) { + throw new ResourceVersionConflictException("Requested resource " + requestedId + " is not the latest version. Latest version is " + storedId); + } + } + + private boolean hasVersionIdPart(String theId) { + return new IdDt(theId).hasVersionIdPart(); + } } diff --git a/hapi-fhir-server-empi/src/main/java/ca/uhn/fhir/empi/provider/EmpiProviderDstu3.java b/hapi-fhir-server-empi/src/main/java/ca/uhn/fhir/empi/provider/EmpiProviderDstu3.java index cc413f85c8e..a82135ed253 100644 --- a/hapi-fhir-server-empi/src/main/java/ca/uhn/fhir/empi/provider/EmpiProviderDstu3.java +++ b/hapi-fhir-server-empi/src/main/java/ca/uhn/fhir/empi/provider/EmpiProviderDstu3.java @@ -91,9 +91,11 @@ public class EmpiProviderDstu3 extends BaseEmpiProvider { @OperationParam(name=ProviderConstants.EMPI_MERGE_PERSONS_TO_PERSON_ID, min = 1, max = 1) StringType theToPersonId, RequestDetails theRequestDetails) { validateMergeParameters(theFromPersonId, theToPersonId); - IAnyResource fromPerson = getPersonFromIdOrThrowException(ProviderConstants.EMPI_MERGE_PERSONS_FROM_PERSON_ID, theFromPersonId.getValue()); - IAnyResource toPerson = getPersonFromIdOrThrowException(ProviderConstants.EMPI_MERGE_PERSONS_TO_PERSON_ID, theToPersonId.getValue()); + IAnyResource fromPerson = getLatestPersonFromIdOrThrowException(ProviderConstants.EMPI_MERGE_PERSONS_FROM_PERSON_ID, theFromPersonId.getValue()); + IAnyResource toPerson = getLatestPersonFromIdOrThrowException(ProviderConstants.EMPI_MERGE_PERSONS_TO_PERSON_ID, theToPersonId.getValue()); validateMergeResources(fromPerson, toPerson); + validateSameVersion(fromPerson, theFromPersonId); + validateSameVersion(toPerson, theToPersonId); return (Person) myPersonMergerSvc.mergePersons(fromPerson, toPerson, createEmpiContext(theRequestDetails)); } @@ -106,8 +108,10 @@ public class EmpiProviderDstu3 extends BaseEmpiProvider { validateUpdateLinkParameters(thePersonId, theTargetId, theMatchResult); EmpiMatchResultEnum matchResult = extractMatchResultOrNull(theMatchResult); - IAnyResource person = getPersonFromIdOrThrowException(ProviderConstants.EMPI_UPDATE_LINK_PERSON_ID, thePersonId.getValue()); - IAnyResource target = getTargetFromIdOrThrowException(ProviderConstants.EMPI_UPDATE_LINK_TARGET_ID, theTargetId.getValue()); + IAnyResource person = getLatestPersonFromIdOrThrowException(ProviderConstants.EMPI_UPDATE_LINK_PERSON_ID, thePersonId.getValue()); + IAnyResource target = getLatestTargetFromIdOrThrowException(ProviderConstants.EMPI_UPDATE_LINK_TARGET_ID, theTargetId.getValue()); + validateSameVersion(person, thePersonId); + validateSameVersion(target, theTargetId); return (Person) myEmpiLinkUpdaterSvc.updateLink(person, target, matchResult, createEmpiContext(theRequestDetails)); } diff --git a/hapi-fhir-server-empi/src/main/java/ca/uhn/fhir/empi/provider/EmpiProviderR4.java b/hapi-fhir-server-empi/src/main/java/ca/uhn/fhir/empi/provider/EmpiProviderR4.java index 47d964619d8..5e958151303 100644 --- a/hapi-fhir-server-empi/src/main/java/ca/uhn/fhir/empi/provider/EmpiProviderR4.java +++ b/hapi-fhir-server-empi/src/main/java/ca/uhn/fhir/empi/provider/EmpiProviderR4.java @@ -92,9 +92,11 @@ public class EmpiProviderR4 extends BaseEmpiProvider { @OperationParam(name=ProviderConstants.EMPI_MERGE_PERSONS_TO_PERSON_ID, min = 1, max = 1) StringType theToPersonId, RequestDetails theRequestDetails) { validateMergeParameters(theFromPersonId, theToPersonId); - IAnyResource fromPerson = getPersonFromIdOrThrowException(ProviderConstants.EMPI_MERGE_PERSONS_FROM_PERSON_ID, theFromPersonId.getValue()); - IAnyResource toPerson = getPersonFromIdOrThrowException(ProviderConstants.EMPI_MERGE_PERSONS_TO_PERSON_ID, theToPersonId.getValue()); + IAnyResource fromPerson = getLatestPersonFromIdOrThrowException(ProviderConstants.EMPI_MERGE_PERSONS_FROM_PERSON_ID, theFromPersonId.getValue()); + IAnyResource toPerson = getLatestPersonFromIdOrThrowException(ProviderConstants.EMPI_MERGE_PERSONS_TO_PERSON_ID, theToPersonId.getValue()); validateMergeResources(fromPerson, toPerson); + validateSameVersion(fromPerson, theFromPersonId); + validateSameVersion(toPerson, theToPersonId); return (Person) myPersonMergerSvc.mergePersons(fromPerson, toPerson, createEmpiContext(theRequestDetails)); } @@ -107,8 +109,10 @@ public class EmpiProviderR4 extends BaseEmpiProvider { validateUpdateLinkParameters(thePersonId, theTargetId, theMatchResult); EmpiMatchResultEnum matchResult = extractMatchResultOrNull(theMatchResult); - IAnyResource person = getPersonFromIdOrThrowException(ProviderConstants.EMPI_UPDATE_LINK_PERSON_ID, thePersonId.getValue()); - IAnyResource target = getTargetFromIdOrThrowException(ProviderConstants.EMPI_UPDATE_LINK_TARGET_ID, theTargetId.getValue()); + IAnyResource person = getLatestPersonFromIdOrThrowException(ProviderConstants.EMPI_UPDATE_LINK_PERSON_ID, thePersonId.getValue()); + IAnyResource target = getLatestTargetFromIdOrThrowException(ProviderConstants.EMPI_UPDATE_LINK_TARGET_ID, theTargetId.getValue()); + validateSameVersion(person, thePersonId); + validateSameVersion(target, theTargetId); return (Person) myEmpiLinkUpdaterSvc.updateLink(person, target, matchResult, createEmpiContext(theRequestDetails)); }