Empi 54 not duplicate (#1900)

add operation to unduplicate persons
This commit is contained in:
Ken Stevens 2020-06-05 12:21:09 -04:00 committed by GitHub
parent 5483c99e00
commit 558f419955
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 317 additions and 52 deletions

View File

@ -2,6 +2,8 @@
Several operations exist that can be used to manage EMPI links. These operations are supplied by a [plain provider](/docs/server_plain/resource_providers.html#plain-providers) called [EmpiProvider](/hapi-fhir/apidocs/hapi-fhir-server-empi/ca/uhn/fhir/empi/provider/EmpiProviderR4.html).
In cases where the operation changes data, if a resource id parameter contains a version (e.g. `Person/123/_history/1`), then the operation will fail with a 409 CONFLICT if that is not the latest version of that resource. This could be used to prevent update conflicts in an environment where multiple users are working on the same set of empi links.
## Query links
Ue the `$empi-query-links` operation to view empi links. The results returned are based on the parameters provided. All parameters are optional. This operation takes the following parameters:
@ -74,27 +76,25 @@ The following request body could be used to find all POSSIBLE_MATCH links in the
This operation returns a `Parameters` resource that looks like the following:
```json
<Parameters xmlns="http://hl7.org/fhir">
<parameter>
<name value="link"/>
<part>
<name value="personId"/>
<valueString value="Person/123"/>
</part>
<part>
<name value="targetId"/>
<valueString value="Patient/456"/>
</part>
<part>
<name value="matchResult"/>
<valueString value="MATCH"/>
</part>
<part>
<name value="linkSource"/>
<valueString value="AUTO"/>
</part>
</parameter>
</Parameters>
{
"resourceType": "Parameters",
"parameter": [ {
"name": "link",
"part": [ {
"name": "personId",
"valueString": "Person/123"
}, {
"name": "targetId",
"valueString": "Patient/456"
}, {
"name": "matchResult",
"valueString": "POSSIBLE_MATCH"
}, {
"name": "linkSource",
"valueString": "AUTO"
} ]
} ]
}
```
## Querying links via the Person resource
@ -155,19 +155,93 @@ This operation returns `Parameters` similar to `$empi-query-links`:
```json
<Parameters xmlns="http://hl7.org/fhir">
<parameter>
<name value="link"/>
<part>
<name value="personId"/>
<valueString value="Person/123"/>
</part>
<part>
<name value="targetId"/>
<valueString value="Person/789"/>
</part>
</parameter>
</Parameters>
{
"resourceType": "Parameters",
"parameter": [ {
"name": "link",
"part": [ {
"name": "personId",
"valueString": "Person/123"
}, {
"name": "targetId",
"valueString": "Person/456"
}, {
"name": "matchResult",
"valueString": "POSSIBLE_DUPLICATE"
}, {
"name": "linkSource",
"valueString": "AUTO"
} ]
} ]
}
```
## Unduplicate Persons
Use the `$empi-not-duplicate` operation to mark duplicate persons as not duplicates. This operation takes the following parameters:
<table class="table table-striped table-condensed">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Cardinality</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>personId</td>
<td>String</td>
<td>1..1</td>
<td>
The id of the Person resource.
</td>
</tr>
<tr>
<td>targetId</td>
<td>String</td>
<td>1..1</td>
<td>
The id of the Person that personId has a possible duplicate link to.
</td>
</tr>
</tbody>
</table>
### Example
Use an HTTP POST to the following URL to invoke this operation:
```url
http://example.com/$empi-not-duplicate
```
The following request body could be used:
```json
{
"resourceType": "Parameters",
"parameter": [ {
"name": "personId",
"valueString": "Person/123"
}, {
"name": "targetId",
"valueString": "Person/456"
} ]
}
```
When the operation is successful, it returns the following `Parameters`:
```json
{
"resourceType": "Parameters",
"parameter": [ {
"name": "success",
"valueBoolean": true
} ]
}
```
## Update Link

View File

@ -25,7 +25,6 @@ import ca.uhn.fhir.empi.api.EmpiMatchResultEnum;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.hibernate.annotations.OptimisticLock;
import javax.persistence.Column;
import javax.persistence.Entity;
@ -157,6 +156,10 @@ public class EmpiLink {
return myMatchResult == EmpiMatchResultEnum.POSSIBLE_MATCH;
}
public boolean isPossibleDuplicate() {
return myMatchResult == EmpiMatchResultEnum.POSSIBLE_DUPLICATE;
}
public EmpiLinkSourceEnum getLinkSource() {
return myLinkSource;
}

View File

@ -63,13 +63,19 @@ public class EmpiLinkSvcImpl implements IEmpiLinkSvc {
@Override
@Transactional
public void updateLink(IAnyResource thePerson, IAnyResource theResource, EmpiMatchResultEnum theMatchResult, EmpiLinkSourceEnum theLinkSource, EmpiTransactionContext theEmpiTransactionContext) {
IIdType resourceId = theResource.getIdElement().toUnqualifiedVersionless();
public void updateLink(IAnyResource thePerson, IAnyResource theTarget, EmpiMatchResultEnum theMatchResult, EmpiLinkSourceEnum theLinkSource, EmpiTransactionContext theEmpiTransactionContext) {
IIdType resourceId = theTarget.getIdElement().toUnqualifiedVersionless();
validateRequestIsLegal(thePerson, theResource, theMatchResult, theLinkSource);
if (theMatchResult == EmpiMatchResultEnum.POSSIBLE_DUPLICATE && personsLinkedAsNoMatch(thePerson, theTarget)) {
log(theEmpiTransactionContext, thePerson.getIdElement().toUnqualifiedVersionless() +
" is linked as NO_MATCH with " +
theTarget.getIdElement().toUnqualifiedVersionless() +
" not linking as POSSIBLE_DUPLICATE.");
return;
}
validateRequestIsLegal(thePerson, theTarget, theMatchResult, theLinkSource);
switch (theMatchResult) {
case MATCH:
//deleteCurrentMatch(theResource);
myPersonHelper.addOrUpdateLink(thePerson, resourceId, AssuranceLevelUtil.getAssuranceLevel(theMatchResult, theLinkSource), theEmpiTransactionContext);
myEmpiResourceDaoSvc.updatePerson(thePerson);
break;
@ -83,8 +89,15 @@ public class EmpiLinkSvcImpl implements IEmpiLinkSvc {
break;
}
myEmpiResourceDaoSvc.updatePerson(thePerson);
createOrUpdateLinkEntity(thePerson, theResource, theMatchResult, theLinkSource, theEmpiTransactionContext);
createOrUpdateLinkEntity(thePerson, theTarget, theMatchResult, theLinkSource, theEmpiTransactionContext);
}
private boolean personsLinkedAsNoMatch(IAnyResource thePerson, IAnyResource theTarget) {
Long personId = myIdHelperService.getPidOrThrowException(thePerson);
Long targetId = myIdHelperService.getPidOrThrowException(theTarget);
// TODO perf collapse into one query
return myEmpiLinkDaoSvc.getEmpiLinksByPersonPidTargetPidAndMatchResult(personId, targetId, EmpiMatchResultEnum.NO_MATCH).isPresent() ||
myEmpiLinkDaoSvc.getEmpiLinksByPersonPidTargetPidAndMatchResult(targetId, personId, EmpiMatchResultEnum.NO_MATCH).isPresent();
}
@Override

View File

@ -33,7 +33,11 @@ import ca.uhn.fhir.jpa.dao.EmpiLinkDaoSvc;
import ca.uhn.fhir.jpa.dao.index.IdHelperService;
import ca.uhn.fhir.jpa.entity.EmpiLink;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.provider.ProviderConstants;
import ca.uhn.fhir.util.ParametersUtil;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseParameters;
import org.hl7.fhir.r4.model.Parameters;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
@ -97,10 +101,10 @@ public class EmpiLinkUpdaterSvcImpl implements IEmpiLinkUpdaterSvc {
}
if (!"Person".equals(personType)) {
throw new InvalidRequestException("First argument to updateLink must be a Person. Was " + personType);
throw new InvalidRequestException("First argument to " + ProviderConstants.EMPI_UPDATE_LINK + " must be a Person. Was " + personType);
}
if (!EmpiUtil.supportedTargetType(theTargetType)) {
throw new InvalidRequestException("Second argument to updateLink must be a Patient or Practitioner. Was " + theTargetType);
throw new InvalidRequestException("Second argument to " + ProviderConstants.EMPI_UPDATE_LINK + " must be a Patient or Practitioner. Was " + theTargetType);
}
if (!EmpiUtil.isEmpiManaged(thePerson)) {
@ -111,4 +115,46 @@ public class EmpiLinkUpdaterSvcImpl implements IEmpiLinkUpdaterSvc {
throw new InvalidRequestException("The target is marked with the " + EmpiConstants.CODE_NO_EMPI_MANAGED + " tag which means it may not be EMPI linked.");
}
}
@Transactional
@Override
public IBaseParameters notDuplicatePerson(IAnyResource thePerson, IAnyResource theTarget, EmpiTransactionContext theEmpiContext) {
validateNotDuplicatePersonRequest(thePerson, theTarget);
Long personId = myIdHelperService.getPidOrThrowException(thePerson);
Long targetId = myIdHelperService.getPidOrThrowException(theTarget);
Optional<EmpiLink> oEmpiLink = myEmpiLinkDaoSvc.getLinkByPersonPidAndTargetPid(personId, targetId);
if (!oEmpiLink.isPresent()) {
throw new InvalidRequestException("No link exists between " + thePerson.getIdElement().toVersionless() + " and " + theTarget.getIdElement().toVersionless());
}
EmpiLink empiLink = oEmpiLink.get();
if (!empiLink.isPossibleDuplicate()) {
throw new InvalidRequestException(thePerson.getIdElement().toVersionless() + " and " + theTarget.getIdElement().toVersionless() + " are not linked as POSSIBLE_DUPLICATE.");
}
empiLink.setMatchResult(EmpiMatchResultEnum.NO_MATCH);
empiLink.setLinkSource(EmpiLinkSourceEnum.MANUAL);
myEmpiLinkDaoSvc.save(empiLink);
Parameters retval = (Parameters) ParametersUtil.newInstance(myFhirContext);
retval.addParameter("success", true);
return retval;
}
private void validateNotDuplicatePersonRequest(IAnyResource thePerson, IAnyResource theTarget) {
String personType = myFhirContext.getResourceType(thePerson);
String targetType = myFhirContext.getResourceType(theTarget);
if (!"Person".equals(personType)) {
throw new InvalidRequestException("First argument to " + ProviderConstants.EMPI_UPDATE_LINK + " must be a Person. Was " + personType);
}
if (!"Person".equals(targetType)) {
throw new InvalidRequestException("Second argument to " + ProviderConstants.EMPI_UPDATE_LINK + " must be a Person . Was " + targetType);
}
if (!EmpiUtil.isEmpiManaged(thePerson) || !EmpiUtil.isEmpiManaged(theTarget)) {
throw new InvalidRequestException("Only EMPI Managed Person resources may be updated via this operation. The Person resource provided is not tagged as managed by hapi-empi");
}
}
}

View File

@ -4,6 +4,8 @@ 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 ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import org.hl7.fhir.r4.model.BooleanType;
import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r4.model.Parameters;
import org.hl7.fhir.r4.model.Patient;
@ -19,12 +21,15 @@ import java.util.List;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
public class EmpiProviderQueryLinkR4Test extends BaseLinkR4Test {
private static final Logger ourLog = LoggerFactory.getLogger(EmpiProviderQueryLinkR4Test.class);
private static final Logger ourLog = LoggerFactory.getLogger(EmpiProviderQueryLinkR4Test.class);
private StringType myLinkSource;
private IdType myPerson1Id;
private IdType myPerson2Id;
private StringType myPerson1Id;
private StringType myPerson2Id;
@Before
public void before() {
@ -36,20 +41,20 @@ private static final Logger ourLog = LoggerFactory.getLogger(EmpiProviderQueryLi
// Add a possible duplicate
myLinkSource = new StringType(EmpiLinkSourceEnum.AUTO.name());
Person person1 = createPerson();
myPerson1Id = person1.getIdElement().toVersionless();
myPerson1Id = new StringType(person1.getIdElement().toVersionless().getValue());
Long person1Pid = myIdHelperService.getPidOrNull(person1);
Person person2 = createPerson();
myPerson2Id = person2.getIdElement().toVersionless();
myPerson2Id = new StringType(person2.getIdElement().toVersionless().getValue());
Long person2Pid = myIdHelperService.getPidOrNull(person2);
EmpiLink empiLink = new EmpiLink().setPersonPid(person1Pid).setTargetPid(person2Pid).setMatchResult(EmpiMatchResultEnum.POSSIBLE_DUPLICATE).setLinkSource(EmpiLinkSourceEnum.AUTO);
myEmpiLinkDaoSvc.save(empiLink);
EmpiLink possibleDuplicateEmpiLink = new EmpiLink().setPersonPid(person1Pid).setTargetPid(person2Pid).setMatchResult(EmpiMatchResultEnum.POSSIBLE_DUPLICATE).setLinkSource(EmpiLinkSourceEnum.AUTO);
myEmpiLinkDaoSvc.save(possibleDuplicateEmpiLink);
}
@Test
public void testQueryLinkOneMatch() {
Parameters result = myEmpiProviderR4.queryLinks(myPersonId, myPatientId, null, null, myRequestDetails);
ourLog.info(myFhirContext.newXmlParser().setPrettyPrint(true).encodeResourceToString(result));
ourLog.info(myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(result));
List<Parameters.ParametersParameterComponent> list = result.getParameter();
assertThat(list, hasSize(1));
List<Parameters.ParametersParameterComponent> part = list.get(0).getPart();
@ -82,6 +87,34 @@ private static final Logger ourLog = LoggerFactory.getLogger(EmpiProviderQueryLi
assertEmpiLink(2, part, myPerson1Id.getValue(), myPerson2Id.getValue(), EmpiMatchResultEnum.POSSIBLE_DUPLICATE);
}
@Test
public void testNotDuplicate() {
{
Parameters result = myEmpiProviderR4.getDuplicatePersons(myRequestDetails);
List<Parameters.ParametersParameterComponent> list = result.getParameter();
assertThat(list, hasSize(1));
}
{
Parameters result = myEmpiProviderR4.notDuplicate(myPerson1Id, myPerson2Id, myRequestDetails);
ourLog.info(myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(result));
assertEquals("success", result.getParameterFirstRep().getName());
assertTrue(((BooleanType) (result.getParameterFirstRep().getValue())).booleanValue());
}
Parameters result = myEmpiProviderR4.getDuplicatePersons(myRequestDetails);
List<Parameters.ParametersParameterComponent> list = result.getParameter();
assertThat(list, hasSize(0));
}
@Test
public void testNotDuplicateBadId() {
try {
myEmpiProviderR4.notDuplicate(myPerson1Id, new StringType("Person/notAnId123"), myRequestDetails);
fail();
} catch (ResourceNotFoundException e) {
assertEquals("Resource Person/notAnId123 is not known", e.getMessage());
}
}
private void assertEmpiLink(int theExpectedSize, List<Parameters.ParametersParameterComponent> thePart, String thePersonId, String theTargetId, EmpiMatchResultEnum theMatchResult) {
assertThat(thePart, hasSize(theExpectedSize));
assertThat(thePart.get(0).getName(), is("personId"));

View File

@ -16,6 +16,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@ -30,6 +31,7 @@ public class EmpiLinkSvcTest extends BaseEmpiR4Test {
myExpungeEverythingService.expungeEverythingByType(EmpiLink.class);
super.after();
}
@Test
public void compareEmptyPatients() {
Patient patient = new Patient();
@ -61,6 +63,62 @@ public class EmpiLinkSvcTest extends BaseEmpiR4Test {
}
}
@Test
public void testPossibleDuplicate() {
assertLinkCount(0);
Person person = createPerson();
Person target = createPerson();
myEmpiLinkSvc.updateLink(person, target, EmpiMatchResultEnum.POSSIBLE_DUPLICATE, EmpiLinkSourceEnum.AUTO, createContextForCreate());
assertLinkCount(1);
}
@Test
public void testNoMatchBlocksPossibleDuplicate() {
assertLinkCount(0);
Person person = createPerson();
Person target = createPerson();
Long personPid = myIdHelperService.getPidOrNull(person);
Long targetPid = myIdHelperService.getPidOrNull(target);
assertFalse(myEmpiLinkDaoSvc.getLinkByPersonPidAndTargetPid(personPid, targetPid).isPresent());
assertFalse(myEmpiLinkDaoSvc.getLinkByPersonPidAndTargetPid(targetPid, personPid).isPresent());
saveNoMatchLink(personPid, targetPid);
myEmpiLinkSvc.updateLink(person, target, EmpiMatchResultEnum.POSSIBLE_DUPLICATE, EmpiLinkSourceEnum.AUTO, createContextForCreate());
assertFalse(myEmpiLinkDaoSvc.getEmpiLinksByPersonPidTargetPidAndMatchResult(personPid, targetPid, EmpiMatchResultEnum.POSSIBLE_DUPLICATE).isPresent());
assertLinkCount(1);
}
@Test
public void testNoMatchBlocksPossibleDuplicateReversed() {
assertLinkCount(0);
Person person = createPerson();
Person target = createPerson();
Long personPid = myIdHelperService.getPidOrNull(person);
Long targetPid = myIdHelperService.getPidOrNull(target);
assertFalse(myEmpiLinkDaoSvc.getLinkByPersonPidAndTargetPid(personPid, targetPid).isPresent());
assertFalse(myEmpiLinkDaoSvc.getLinkByPersonPidAndTargetPid(targetPid, personPid).isPresent());
saveNoMatchLink(targetPid, personPid);
myEmpiLinkSvc.updateLink(person, target, EmpiMatchResultEnum.POSSIBLE_DUPLICATE, EmpiLinkSourceEnum.AUTO, createContextForCreate());
assertFalse(myEmpiLinkDaoSvc.getEmpiLinksByPersonPidTargetPidAndMatchResult(personPid, targetPid, EmpiMatchResultEnum.POSSIBLE_DUPLICATE).isPresent());
assertLinkCount(1);
}
private void saveNoMatchLink(Long thePersonPid, Long theTargetPid) {
EmpiLink noMatchLink = new EmpiLink()
.setPersonPid(thePersonPid)
.setTargetPid(theTargetPid)
.setLinkSource(EmpiLinkSourceEnum.MANUAL)
.setMatchResult(EmpiMatchResultEnum.NO_MATCH);
myEmpiLinkDaoSvc.save(noMatchLink);
}
@Test
public void testManualEmpiLinksCannotBeModifiedBySystem() {
Person person = createPerson(buildJanePerson());

View File

@ -22,7 +22,10 @@ package ca.uhn.fhir.empi.api;
import ca.uhn.fhir.empi.model.EmpiTransactionContext;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseParameters;
public interface IEmpiLinkUpdaterSvc {
IAnyResource updateLink(IAnyResource thePerson, IAnyResource theTarget, EmpiMatchResultEnum theMatchResult, EmpiTransactionContext theEmpiContext);
IBaseParameters notDuplicatePerson(IAnyResource thePerson, IAnyResource theTarget, EmpiTransactionContext theEmpiContext);
}

View File

@ -40,7 +40,7 @@ import org.hl7.fhir.instance.model.api.IPrimitiveType;
public abstract class BaseEmpiProvider {
private final FhirContext myFhirContext;
protected final FhirContext myFhirContext;
private final IResourceLoader myResourceLoader;
public BaseEmpiProvider(FhirContext theFhirContext, IResourceLoader theResourceLoader) {
@ -125,6 +125,11 @@ public abstract class BaseEmpiProvider {
}
}
protected void validateNotDuplicateParameters(IPrimitiveType<String> thePersonId, IPrimitiveType<String> theTargetId) {
validateNotNull(ProviderConstants.EMPI_UPDATE_LINK_PERSON_ID, thePersonId);
validateNotNull(ProviderConstants.EMPI_UPDATE_LINK_TARGET_ID, theTargetId);
}
protected EmpiTransactionContext createEmpiContext(RequestDetails theRequestDetails) {
TransactionLogMessages transactionLogMessages = TransactionLogMessages.createFromTransactionGuid(theRequestDetails.getTransactionGuid());
return new EmpiTransactionContext(transactionLogMessages, EmpiTransactionContext.OperationType.MERGE_PERSONS);

View File

@ -134,4 +134,19 @@ public class EmpiProviderDstu3 extends BaseEmpiProvider {
public Parameters getDuplicatePersons(ServletRequestDetails theRequestDetails) {
return (Parameters) myEmpiLinkQuerySvc.getPossibleDuplicates(createEmpiContext(theRequestDetails));
}
@Operation(name = ProviderConstants.EMPI_NOT_DUPLICATE)
// TODO KHS can this return void?
public Parameters notDuplicate(@OperationParam(name=ProviderConstants.EMPI_QUERY_LINKS_PERSON_ID, min = 1, max = 1) StringType thePersonId,
@OperationParam(name=ProviderConstants.EMPI_QUERY_LINKS_TARGET_ID, min = 1, max = 1) StringType theTargetId,
ServletRequestDetails theRequestDetails) {
validateNotDuplicateParameters(thePersonId, theTargetId);
IAnyResource person = getLatestPersonFromIdOrThrowException(ProviderConstants.EMPI_UPDATE_LINK_PERSON_ID, thePersonId.getValue());
IAnyResource target = getLatestPersonFromIdOrThrowException(ProviderConstants.EMPI_UPDATE_LINK_TARGET_ID, theTargetId.getValue());
validateSameVersion(person, thePersonId);
validateSameVersion(target, theTargetId);
return (Parameters) myEmpiLinkUpdaterSvc.notDuplicatePerson(person, target, createEmpiContext(theRequestDetails));
}
}

View File

@ -135,4 +135,18 @@ public class EmpiProviderR4 extends BaseEmpiProvider {
public Parameters getDuplicatePersons(ServletRequestDetails theRequestDetails) {
return (Parameters) myEmpiLinkQuerySvc.getPossibleDuplicates(createEmpiContext(theRequestDetails));
}
@Operation(name = ProviderConstants.EMPI_NOT_DUPLICATE)
public Parameters notDuplicate(@OperationParam(name=ProviderConstants.EMPI_QUERY_LINKS_PERSON_ID, min = 1, max = 1) StringType thePersonId,
@OperationParam(name=ProviderConstants.EMPI_QUERY_LINKS_TARGET_ID, min = 1, max = 1) StringType theTargetId,
ServletRequestDetails theRequestDetails) {
validateNotDuplicateParameters(thePersonId, theTargetId);
IAnyResource person = getLatestPersonFromIdOrThrowException(ProviderConstants.EMPI_UPDATE_LINK_PERSON_ID, thePersonId.getValue());
IAnyResource target = getLatestPersonFromIdOrThrowException(ProviderConstants.EMPI_UPDATE_LINK_TARGET_ID, theTargetId.getValue());
validateSameVersion(person, thePersonId);
validateSameVersion(target, theTargetId);
return (Parameters) myEmpiLinkUpdaterSvc.notDuplicatePerson(person, target, createEmpiContext(theRequestDetails));
}
}

View File

@ -80,4 +80,5 @@ public class ProviderConstants {
public static final String EMPI_QUERY_LINKS_LINK_SOURCE = "linkSource";
public static final String EMPI_DUPLICATE_PERSONS = "$empi-duplicate-persons";
public static final String EMPI_NOT_DUPLICATE = "$empi-not-duplicate";
}