Fixed code for use case #2 test case

This commit is contained in:
Nick Goupinets 2020-11-09 15:29:50 -05:00
parent ac3b1e3e17
commit 4865e8a410
8 changed files with 159 additions and 81 deletions

View File

@ -29,6 +29,8 @@ import ca.uhn.fhir.empi.model.EmpiTransactionContext;
import ca.uhn.fhir.jpa.dao.data.IEmpiLinkDao;
import ca.uhn.fhir.jpa.dao.index.IdHelperService;
import ca.uhn.fhir.jpa.entity.EmpiLink;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
@ -308,6 +310,26 @@ public class EmpiLinkDaoSvc {
return myEmpiLinkDao.findAll(example);
}
/**
* Finds all {@link EmpiLink} entities in which theSourceResource's PID is the source
* of the relationship.
*
* @param theSourceResource the source resource to find links for.
*
* @return all links for the source.
*/
public List<EmpiLink> findEmpiMatchLinksBySource(IBaseResource theSourceResource) {
Long pid = myIdHelperService.getPidOrNull(theSourceResource);
if (pid == null) {
return Collections.emptyList();
}
EmpiLink exampleLink = myEmpiLinkFactory.newEmpiLink().setSourceResourcePid(pid);
exampleLink.setMatchResult(EmpiMatchResultEnum.MATCH);
Example<EmpiLink> example = Example.of(exampleLink);
return myEmpiLinkDao.findAll(example);
}
/**
* Factory delegation method, whenever you need a new EmpiLink, use this factory method.
* //TODO Should we make the constructor private for EmpiLink? or work out some way to ensure they can only be instantiated via factory.

View File

@ -71,14 +71,14 @@ public class EmpiEidUpdateService {
// myPersonHelper.updatePersonFromUpdatedEmpiTarget(updateContext.getMatchedPerson(), theResource, theEmpiTransactionContext);
if (!updateContext.isIncomingResourceHasAnEid() || updateContext.isHasEidsInCommon()) {
//update to patient that uses internal EIDs only.
myEmpiLinkSvc.updateLink(updateContext.getMatchedPerson(), theResource, theMatchedSourceResourceCandidate.getMatchResult(), EmpiLinkSourceEnum.AUTO, theEmpiTransactionContext);
myEmpiLinkSvc.updateLink(updateContext.getMatchedSourceResource(), theResource, theMatchedSourceResourceCandidate.getMatchResult(), EmpiLinkSourceEnum.AUTO, theEmpiTransactionContext);
} else if (!updateContext.isHasEidsInCommon()) {
handleNoEidsInCommon(theResource, theMatchedSourceResourceCandidate, theEmpiTransactionContext, updateContext);
}
} else {
//This is a new linking scenario. we have to break the existing link and link to the new person. For now, we create duplicate.
//updated patient has an EID that matches to a new candidate. Link them, and set the persons possible duplicates
linkToNewPersonAndFlagAsDuplicate(theResource, updateContext.getExistingPerson(), updateContext.getMatchedPerson(), theEmpiTransactionContext);
linkToNewPersonAndFlagAsDuplicate(theResource, updateContext.getExistingPerson(), updateContext.getMatchedSourceResource(), theEmpiTransactionContext);
}
}
@ -86,15 +86,16 @@ public class EmpiEidUpdateService {
// the user is simply updating their EID. We propagate this change to the Person.
//overwrite. No EIDS in common, but still same person.
if (myEmpiSettings.isPreventMultipleEids()) {
if (myPersonHelper.getLinkCount(theUpdateContext.getMatchedPerson()) <= 1) { // If there is only 0/1 link on the person, we can safely overwrite the EID.
handleExternalEidOverwrite(theUpdateContext.getMatchedPerson(), theResource, theEmpiTransactionContext);
if (myEmpiLinkDaoSvc.findEmpiMatchLinksBySource(theUpdateContext.getMatchedSourceResource()).size() <= 1) { // If there is only 0/1 link on the person, we can safely overwrite the EID.
// if (myPersonHelper.getLinkCount(theUpdateContext.getMatchedSourceResource()) <= 1) { // If there is only 0/1 link on the person, we can safely overwrite the EID.
handleExternalEidOverwrite(theUpdateContext.getMatchedSourceResource(), theResource, theEmpiTransactionContext);
} else { // If the person has multiple patients tied to it, we can't just overwrite the EID, so we split the person.
createNewPersonAndFlagAsDuplicate(theResource, theEmpiTransactionContext, theUpdateContext.getExistingPerson());
}
} else {
myPersonHelper.handleExternalEidAddition(theUpdateContext.getMatchedPerson(), theResource, theEmpiTransactionContext);
myPersonHelper.handleExternalEidAddition(theUpdateContext.getMatchedSourceResource(), theResource, theEmpiTransactionContext);
}
myEmpiLinkSvc.updateLink(theUpdateContext.getMatchedPerson(), theResource, theMatchedSourceResourceCandidate.getMatchResult(), EmpiLinkSourceEnum.AUTO, theEmpiTransactionContext);
myEmpiLinkSvc.updateLink(theUpdateContext.getMatchedSourceResource(), theResource, theMatchedSourceResourceCandidate.getMatchResult(), EmpiLinkSourceEnum.AUTO, theEmpiTransactionContext);
}
private void handleExternalEidOverwrite(IAnyResource thePerson, IAnyResource theResource, EmpiTransactionContext theEmpiTransactionContext) {
@ -138,17 +139,17 @@ public class EmpiEidUpdateService {
private IAnyResource myExistingPerson;
private boolean myRemainsMatchedToSamePerson;
public IAnyResource getMatchedPerson() {
return myMatchedPerson;
public IAnyResource getMatchedSourceResource() {
return myMatchedSourceResource;
}
private final IAnyResource myMatchedPerson;
private final IAnyResource myMatchedSourceResource;
EmpiUpdateContext(MatchedSourceResourceCandidate theMatchedSourceResourceCandidate, IAnyResource theResource) {
final String resourceType = theResource.getIdElement().getResourceType();
myMatchedPerson = myEmpiSourceResourceFindingSvc.getSourceResourceFromMatchedSourceResourceCandidate(theMatchedSourceResourceCandidate, resourceType);
myMatchedSourceResource = myEmpiSourceResourceFindingSvc.getSourceResourceFromMatchedSourceResourceCandidate(theMatchedSourceResourceCandidate, resourceType);
myHasEidsInCommon = myEIDHelper.hasEidOverlap(myMatchedPerson, theResource);
myHasEidsInCommon = myEIDHelper.hasEidOverlap(myMatchedSourceResource, theResource);
myIncomingResourceHasAnEid = !myEIDHelper.getExternalEid(theResource).isEmpty();
Optional<EmpiLink> theExistingMatchLink = myEmpiLinkDaoSvc.getMatchedLinkForTarget(theResource);

View File

@ -105,7 +105,8 @@ public class EmpiLinkSvcImpl implements IEmpiLinkSvc {
@Override
@Transactional
public void syncEmpiLinksToPersonLinks(IAnyResource thePersonResource, EmpiTransactionContext theEmpiTransactionContext) {
int origLinkCount = myPersonHelper.getLinkCount(thePersonResource);
// int origLinkCount = myPersonHelper.getLinkCount(thePersonResource);
int origLinkCount = myEmpiLinkDaoSvc.findEmpiMatchLinksBySource(thePersonResource).size();
List<EmpiLink> empiLinks = myEmpiLinkDaoSvc.findEmpiLinksByPerson(thePersonResource);

View File

@ -73,8 +73,8 @@ public class EmpiResourceDaoSvc {
map.setLoadSynchronous(true);
map.add("identifier", new TokenParam(myEmpiConfig.getEmpiRules().getEnterpriseEIDSystem(), theEid));
// TODO NG - During person dedup do we set this to false? We might be setting a person to inactive...
// map.add("active", new TokenParam("true"));
map.add("_tag", new TokenParam(EmpiConstants.SYSTEM_EMPI_MANAGED, EmpiConstants.CODE_HAPI_EMPI_MANAGED));
map.add("active", new TokenParam("true"));
// map.add("_tag", new TokenParam(EmpiConstants.SYSTEM_EMPI_MANAGED, EmpiConstants.CODE_HAPI_EMPI_MANAGED));
IFhirResourceDao resourceDao = myDaoRegistry.getResourceDao(theResourceType);
IBundleProvider search = resourceDao.search(map);

View File

@ -24,7 +24,7 @@ public class IsSameSourceResourceAs extends BaseSourceResourceMatcher {
sourceResourcePidsToMatch = myBaseResources.stream().map(this::getMatchedResourcePidFromResource).collect(Collectors.toList());
boolean allToCheckAreSame = sourceResourcePidsToMatch.stream().allMatch(pid -> pid.equals(sourceResourcePidsToMatch.get(0)));
if (!allToCheckAreSame) {
throw new IllegalStateException("You wanted to do a source resource comparison, but the pool of persons you submitted for checking don't match! We won't even check the incoming person against them.");
throw new IllegalStateException("You wanted to do a source resource comparison, but the pool of source resources you submitted for checking don't match! We won't even check the incoming source resource against them.");
}
return sourceResourcePidsToMatch.contains(incomingSourceResourcePid);
}

View File

@ -41,14 +41,15 @@ import static org.junit.jupiter.api.Assertions.*;
import static org.slf4j.LoggerFactory.getLogger;
public class EmpiMatchLinkSvcTest extends BaseEmpiR4Test {
private static final Logger ourLog = getLogger(EmpiMatchLinkSvcTest.class);
@Autowired
IEmpiLinkSvc myEmpiLinkSvc;
@Autowired
private EIDHelper myEidHelper;
@Autowired
private PersonHelper myPersonHelper;
@Autowired
private EmpiResourceDaoSvc myEmpiResourceDaoSvc; // TODO NG - remove?
@ -117,19 +118,26 @@ public class EmpiMatchLinkSvcTest extends BaseEmpiR4Test {
@Test
public void testWhenPOSSIBLE_MATCHOccursOnPersonThatHasBeenManuallyNOMATCHedThatItIsBlocked() {
Patient originalJane = createPatientAndUpdateLinks(buildJanePatient());
IBundleProvider search = myPersonDao.search(new SearchParameterMap());
IBundleProvider search = myPatientDao.search(new SearchParameterMap());
IAnyResource janePerson = (IAnyResource) search.getResources(0, 1).get(0);
Patient unmatchedPatient = createPatient(buildJanePatient());
//This simulates an admin specifically saying that unmatchedPatient does NOT match janePerson.
myEmpiLinkSvc.updateLink(janePerson, unmatchedPatient, EmpiMatchOutcome.NO_MATCH, EmpiLinkSourceEnum.MANUAL, createContextForCreate("Patient"));
//TODO change this so that it will only partially match.
// TODO change this so that it will only partially match.
//Now normally, when we run update links, it should link to janePerson. However, this manual NO_MATCH link
//should cause a whole new Person to be created.
myEmpiMatchLinkSvc.updateEmpiLinksForEmpiTarget(unmatchedPatient, createContextForCreate("Patient"));
System.out.println("Unmatched Patient");
print(unmatchedPatient);
System.out.println("Jane");
print(janePerson);
assertThat(unmatchedPatient, is(not(sameSourceResourceAs(janePerson))));
assertThat(unmatchedPatient, is(not(linkedTo(originalJane))));
@ -225,35 +233,9 @@ public class EmpiMatchLinkSvcTest extends BaseEmpiR4Test {
Patient patient1 = addExternalEID(buildJanePatient(), "uniqueid");
createPatientAndUpdateLinks(patient1);
{
// state is now > Patient/ID.JANE.123[name=jane & EID = uniqueid] <-- EMPI Link -- Patient/[name=jane & EDI = uniqueid & EMPI_MANAGED = true]
IBundleProvider bundle = myPatientDao.search(new SearchParameterMap());
List<IBaseResource> resources = bundle.getResources(0, bundle.size());
resources.forEach(r -> {
print(r);
assertFalse(myEidHelper.getExternalEid(r).isEmpty());
});
assertEquals(2, resources.size());
IBaseResource testPatient1 = resources.get(0);
IBaseResource testPatient2 = resources.get(1);
assertThat((Patient) testPatient1, is(sameSourceResourceAs((Patient) testPatient2)));
Optional<EmpiLink> empiLinkByTarget = myEmpiLinkDaoSvc.findEmpiLinkByTarget(patient1);
assertTrue(empiLinkByTarget.isPresent());
System.out.println(empiLinkByTarget.get());
}
Patient patient2 = buildPaulPatient();
patient2.setActive(true);
patient2 = addExternalEID(patient2, "uniqueid");
createPatientAndUpdateLinks(patient2);
// state should be > Patient/ID.JANE.123[name=jane & EID = uniqueid] <--> Patient/[name=jane & EDI = uniqueid] <--> Patient/[name=paul & EDI = uniqueid]
IBundleProvider search = myPatientDao.search(new SearchParameterMap());
search.getResources(0, search.size()).forEach( r -> {
print(r);
}
);
assertThat(patient1, is(sameSourceResourceAs(patient2)));
}
@ -552,8 +534,8 @@ public class EmpiMatchLinkSvcTest extends BaseEmpiR4Test {
}
@Test
//Test Case #2
public void testSinglyLinkedPersonThatGetsAnUpdatedEidSimplyUpdatesEID() {
//Use Case # 2
String EID_1 = "123";
String EID_2 = "456";
@ -568,7 +550,12 @@ public class EmpiMatchLinkSvcTest extends BaseEmpiR4Test {
clearExternalEIDs(paul);
addExternalEID(paul, EID_2);
System.out.println("Paul Before");
print(paul);
Patient pailTemp = paul;
paul = updatePatientAndUpdateLinks(paul);
System.out.println("Paul After");
print(pailTemp);
assertNoDuplicates();

View File

@ -48,5 +48,4 @@ public interface IEmpiLinkSvc {
* @param theResource
*/
void deleteLink(IAnyResource theExistingPerson, IAnyResource theResource, EmpiTransactionContext theEmpiTransactionContext);
}

View File

@ -32,6 +32,7 @@ import ca.uhn.fhir.empi.model.CanonicalEID;
import ca.uhn.fhir.empi.model.CanonicalIdentityAssuranceLevel;
import ca.uhn.fhir.empi.model.EmpiTransactionContext;
import ca.uhn.fhir.fhirpath.IFhirPath;
import ca.uhn.fhir.model.primitive.BooleanDt;
import ca.uhn.fhir.util.FhirTerser;
import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.instance.model.api.IAnyResource;
@ -43,6 +44,7 @@ import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.r4.model.Address;
import org.hl7.fhir.r4.model.BooleanType;
import org.hl7.fhir.r4.model.ContactPoint;
import org.hl7.fhir.r4.model.HumanName;
import org.hl7.fhir.r4.model.Identifier;
@ -243,9 +245,20 @@ public class PersonHelper {
populateMetaTag(newSourceResource);
setActive(newSourceResource, resourceDefinition);
return (T) newSourceResource;
}
private void setActive(IBaseResource theNewSourceResource, RuntimeResourceDefinition theResourceDefinition) {
BaseRuntimeChildDefinition activeChildDefinition = theResourceDefinition.getChildByName("active");
if (activeChildDefinition == null) {
ourLog.warn(String.format("Unable to set active flag on the provided source resource %s.", theNewSourceResource));
return;
}
activeChildDefinition.getMutator().setValue(theNewSourceResource, toBooleanType(true));
}
/**
* If there are no external EIDs on the incoming resource, create a new HAPI EID on the new SourceResource.
*/
@ -262,19 +275,19 @@ public class PersonHelper {
/**
* Given an Child Definition of `identifier`, a R4/DSTU3 EID Identifier, and a new resource, clone the EID into that resources' identifier list.
*/
private void cloneExternalEidIntoNewSourceResource(BaseRuntimeChildDefinition sourceResourceIdentifier, IBase theEid, IBase newSourceResource) {
private void cloneExternalEidIntoNewSourceResource(BaseRuntimeChildDefinition theSourceResourceIdentifier, IBase theEid, IBase theNewSourceResource) {
// FHIR choice types - fields within fhir where we have a choice of ids
BaseRuntimeElementCompositeDefinition<?> childIdentifier = (BaseRuntimeElementCompositeDefinition<?>) sourceResourceIdentifier.getChildByName("identifier");
BaseRuntimeElementCompositeDefinition<?> childIdentifier = (BaseRuntimeElementCompositeDefinition<?>) theSourceResourceIdentifier.getChildByName("identifier");
FhirTerser terser = myFhirContext.newTerser();
IBase sourceResourceNewIdentifier = childIdentifier.newInstance();
terser.cloneInto(theEid, sourceResourceNewIdentifier, true);
sourceResourceIdentifier.getMutator().addValue(newSourceResource, sourceResourceNewIdentifier);
theSourceResourceIdentifier.getMutator().addValue(theNewSourceResource, sourceResourceNewIdentifier);
}
private void cloneAllExternalEidsIntoNewSourceResource(BaseRuntimeChildDefinition sourceResourceIdentifier, IBase theSourceResource, IBase newSourceResource) {
private void cloneAllExternalEidsIntoNewSourceResource(BaseRuntimeChildDefinition theSourceResourceIdentifier, IBase theSourceResource, IBase theNewSourceResource) {
// FHIR choice types - fields within fhir where we have a choice of ids
IFhirPath fhirPath = myFhirContext.newFhirPath();
List<IBase> sourceResourceIdentifiers = sourceResourceIdentifier.getAccessor().getValues(theSourceResource);
List<IBase> sourceResourceIdentifiers = theSourceResourceIdentifier.getAccessor().getValues(theSourceResource);
for (IBase base : sourceResourceIdentifiers) {
Optional<IPrimitiveType> system = fhirPath.evaluateFirst(base, "system", IPrimitiveType.class);
@ -282,8 +295,8 @@ public class PersonHelper {
String empiSystem = myEmpiConfig.getEmpiRules().getEnterpriseEIDSystem();
String baseSystem = system.get().getValueAsString();
if (Objects.equals(baseSystem, empiSystem)) {
cloneExternalEidIntoNewSourceResource(sourceResourceIdentifier, base, newSourceResource);
} else {
cloneExternalEidIntoNewSourceResource(theSourceResourceIdentifier, base, theNewSourceResource);
} else if (ourLog.isDebugEnabled()) {
ourLog.debug(String.format("System %s differs from system in the EMPI rules %s", baseSystem, empiSystem));
}
} else {
@ -336,25 +349,67 @@ public class PersonHelper {
return theSourceResource;
}
public IBaseResource overwriteExternalEids(IBaseResource thePerson, List<CanonicalEID> theNewEid) {
clearExternalEids(thePerson);
addCanonicalEidsToSourceResourceIfAbsent(thePerson, theNewEid);
return thePerson;
public IBaseResource overwriteExternalEids(IBaseResource theSourceResource, List<CanonicalEID> theNewEid) {
clearExternalEids(theSourceResource);
addCanonicalEidsToSourceResourceIfAbsent(theSourceResource, theNewEid);
return theSourceResource;
}
private void clearExternalEids(IBaseResource thePerson) {
switch (myFhirContext.getVersion().getVersion()) {
case R4:
Person personR4 = (Person) thePerson;
personR4.getIdentifier().removeIf(theIdentifier -> theIdentifier.getSystem().equalsIgnoreCase(myEmpiConfig.getEmpiRules().getEnterpriseEIDSystem()));
break;
case DSTU3:
org.hl7.fhir.dstu3.model.Person personDstu3 = (org.hl7.fhir.dstu3.model.Person) thePerson;
personDstu3.getIdentifier().removeIf(theIdentifier -> theIdentifier.getSystem().equalsIgnoreCase(myEmpiConfig.getEmpiRules().getEnterpriseEIDSystem()));
break;
default:
throw new UnsupportedOperationException("Version not supported: " + myFhirContext.getVersion().getVersion());
private void clearExternalEidsFromTheSourceResource(BaseRuntimeChildDefinition theSourceResourceIdentifier, IBase theSourceResource) {
IFhirPath fhirPath = myFhirContext.newFhirPath();
List<IBase> sourceResourceIdentifiers = theSourceResourceIdentifier.getAccessor().getValues(theSourceResource);
List<IBase> clonedIdentifiers = new ArrayList<>();
for (IBase base : sourceResourceIdentifiers) {
Optional<IPrimitiveType> system = fhirPath.evaluateFirst(base, "system", IPrimitiveType.class);
if (system.isPresent()) {
String empiSystem = myEmpiConfig.getEmpiRules().getEnterpriseEIDSystem();
String baseSystem = system.get().getValueAsString();
if (Objects.equals(baseSystem, empiSystem)) {
if (ourLog.isDebugEnabled()) {
ourLog.debug(String.format("Found EID confirming to EMPI rules %s. It should not be copied, skipping", baseSystem));
}
continue;
}
}
if (ourLog.isDebugEnabled()) {
ourLog.debug("Copying non-EMPI EID");
}
BaseRuntimeElementCompositeDefinition<?> childIdentifier = (BaseRuntimeElementCompositeDefinition<?>)
theSourceResourceIdentifier.getChildByName("identifier");
FhirTerser terser = myFhirContext.newTerser();
IBase sourceResourceNewIdentifier = childIdentifier.newInstance();
terser.cloneInto(base, sourceResourceNewIdentifier, true);
clonedIdentifiers.add(sourceResourceNewIdentifier);
}
sourceResourceIdentifiers.clear();
sourceResourceIdentifiers.addAll(clonedIdentifiers);
}
private void clearExternalEids(IBaseResource theSourceResource) {
// validate the system - if it's set to EID system - then clear it - type and STU version
validateContextSupported();
// get a ref to the actual ID Field
RuntimeResourceDefinition resourceDefinition = myFhirContext.getResourceDefinition(theSourceResource);
BaseRuntimeChildDefinition sourceResourceIdentifier = resourceDefinition.getChildByName("identifier");
clearExternalEidsFromTheSourceResource(sourceResourceIdentifier, theSourceResource);
// switch (myFhirContext.getVersion().getVersion()) {
// case R4:
// Person personR4 = (Person) theSourceResource;
// personR4.getIdentifier().removeIf(theIdentifier -> theIdentifier.getSystem().equalsIgnoreCase(myEmpiConfig.getEmpiRules().getEnterpriseEIDSystem()));
// break;
// case DSTU3:
// org.hl7.fhir.dstu3.model.Person personDstu3 = (org.hl7.fhir.dstu3.model.Person) theSourceResource;
// personDstu3.getIdentifier().removeIf(theIdentifier -> theIdentifier.getSystem().equalsIgnoreCase(myEmpiConfig.getEmpiRules().getEnterpriseEIDSystem()));
// break;
// default:
// throw new UnsupportedOperationException("Version not supported: " + myFhirContext.getVersion().getVersion());
// }
}
/**
@ -376,6 +431,8 @@ public class PersonHelper {
}
}
private <T> T toId(CanonicalEID eid) {
switch (myFhirContext.getVersion().getVersion()) {
case R4:
@ -386,6 +443,17 @@ public class PersonHelper {
throw new IllegalStateException("Unsupported FHIR version " + myFhirContext.getVersion().getVersion());
}
private <T extends IBase> T toBooleanType(boolean theFlag) {
switch (myFhirContext.getVersion().getVersion()) {
case R4:
return (T) new BooleanType(theFlag);
case DSTU3:
return (T) new org.hl7.fhir.dstu3.model.BooleanType(theFlag);
}
throw new IllegalStateException("Unsupported FHIR version " + myFhirContext.getVersion().getVersion());
}
/**
* To avoid adding duplicate
*
@ -534,18 +602,18 @@ public class PersonHelper {
person.setLink(links);
}
public int getLinkCount(IAnyResource thePerson) {
switch (myFhirContext.getVersion().getVersion()) {
case R4:
Person personR4 = (Person) thePerson;
return personR4.getLink().size();
case DSTU3:
org.hl7.fhir.dstu3.model.Person personStu3 = (org.hl7.fhir.dstu3.model.Person) thePerson;
return personStu3.getLink().size();
default:
throw new UnsupportedOperationException("Version not supported: " + myFhirContext.getVersion().getVersion());
}
}
// public int getLinkCount(IAnyResource theSourceResource) {
// switch (myFhirContext.getVersion().getVersion()) {
// case R4:
// Person personR4 = (Person) theSourceResource;
// return personR4.getLink().size();
// case DSTU3:
// org.hl7.fhir.dstu3.model.Person personStu3 = (org.hl7.fhir.dstu3.model.Person) theSourceResource;
// return personStu3.getLink().size();
// default:
// throw new UnsupportedOperationException("Version not supported: " + myFhirContext.getVersion().getVersion());
// }
// }
private void log(EmpiTransactionContext theEmpiTransactionContext, String theMessage) {
theEmpiTransactionContext.addTransactionLogMessage(theMessage);