mdm duplicate identifier (#5563)

* test and fix bug

* cleanup

* cleanup
This commit is contained in:
Ken Stevens 2023-12-19 16:55:52 -05:00 committed by GitHub
parent ed012c2ce5
commit 32f5da37e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 52 additions and 16 deletions

View File

@ -97,21 +97,34 @@ public final class TerserUtil {
private TerserUtil() {}
/**
* Given an Child Definition of `identifier`, a R4/DSTU3 EID Identifier, and a new resource, clone the EID into that resources' identifier list.
* Given an Child Definition of `identifier`, a R4/DSTU3 Identifier, and a new resource, clone the identifier into that resources' identifier list if it is not already present.
*/
public static void cloneEidIntoResource(
public static void cloneIdentifierIntoResource(
FhirContext theFhirContext,
BaseRuntimeChildDefinition theIdentifierDefinition,
IBase theEid,
IBase theResourceToCloneEidInto) {
IBase theNewIdentifier,
IBaseResource theResourceToCloneInto) {
// FHIR choice types - fields within fhir where we have a choice of ids
BaseRuntimeElementCompositeDefinition<?> childIdentifier = (BaseRuntimeElementCompositeDefinition<?>)
BaseRuntimeElementCompositeDefinition<?> childIdentifierElementDefinition =
(BaseRuntimeElementCompositeDefinition<?>)
theIdentifierDefinition.getChildByName(FIELD_NAME_IDENTIFIER);
IBase resourceNewIdentifier = childIdentifier.newInstance();
List<IBase> existingIdentifiers = getValues(theFhirContext, theResourceToCloneInto, FIELD_NAME_IDENTIFIER);
if (existingIdentifiers != null) {
for (IBase existingIdentifier : existingIdentifiers) {
if (equals(existingIdentifier, theNewIdentifier)) {
ourLog.trace(
"Identifier {} already exists in resource {}", theNewIdentifier, theResourceToCloneInto);
return;
}
}
}
IBase newIdentifierBase = childIdentifierElementDefinition.newInstance();
FhirTerser terser = theFhirContext.newTerser();
terser.cloneInto(theEid, resourceNewIdentifier, true);
theIdentifierDefinition.getMutator().addValue(theResourceToCloneEidInto, resourceNewIdentifier);
terser.cloneInto(theNewIdentifier, newIdentifierBase, true);
theIdentifierDefinition.getMutator().addValue(theResourceToCloneInto, newIdentifierBase);
}
/**

View File

@ -0,0 +1,5 @@
---
type: fix
issue: 5563
title: "Previously, certain mdm configuration could lead to duplicate eid identifier
entries in golden resources. This has been corrected"

View File

@ -159,7 +159,7 @@ public class GoldenResourceHelper {
private void cloneMDMEidsIntoNewGoldenResource(
BaseRuntimeChildDefinition theGoldenResourceIdentifier,
IAnyResource theIncomingResource,
IBase theNewGoldenResource) {
IBaseResource theNewGoldenResource) {
String incomingResourceType = myFhirContext.getResourceType(theIncomingResource);
String mdmEIDSystem = myMdmSettings.getMdmRules().getEnterpriseEIDSystemForResourceType(incomingResourceType);
@ -182,7 +182,7 @@ public class GoldenResourceHelper {
ourLog.debug(
"Incoming resource EID System {} matches EID system in the MDM rules. Copying to Golden Resource.",
incomingIdentifierSystemString);
ca.uhn.fhir.util.TerserUtil.cloneEidIntoResource(
ca.uhn.fhir.util.TerserUtil.cloneIdentifierIntoResource(
myFhirContext,
theGoldenResourceIdentifier,
incomingResourceIdentifier,
@ -382,7 +382,7 @@ public class GoldenResourceHelper {
RuntimeResourceDefinition resourceDefinition = theFhirContext.getResourceDefinition(theResourceToCloneInto);
// hapi has 2 metamodels: for children and types
BaseRuntimeChildDefinition resourceIdentifier = resourceDefinition.getChildByName(FIELD_NAME_IDENTIFIER);
ca.uhn.fhir.util.TerserUtil.cloneEidIntoResource(
ca.uhn.fhir.util.TerserUtil.cloneIdentifierIntoResource(
theFhirContext,
resourceIdentifier,
IdentifierUtil.toId(theFhirContext, theEid),

View File

@ -117,7 +117,7 @@ class TerserUtilTest {
""";
@Test
void testCloneEidIntoResource() {
void cloneIdentifierIntoResource() {
Identifier identifier = new Identifier().setSystem("http://org.com/sys").setValue("123");
Patient p1 = new Patient();
@ -125,7 +125,25 @@ class TerserUtilTest {
Patient p2 = new Patient();
RuntimeResourceDefinition definition = ourFhirContext.getResourceDefinition(p1);
TerserUtil.cloneEidIntoResource(ourFhirContext, definition.getChildByName("identifier"), identifier, p2);
TerserUtil.cloneIdentifierIntoResource(ourFhirContext, definition.getChildByName("identifier"), identifier, p2);
assertEquals(1, p2.getIdentifier().size());
assertEquals(p1.getIdentifier().get(0).getSystem(), p2.getIdentifier().get(0).getSystem());
assertEquals(p1.getIdentifier().get(0).getValue(), p2.getIdentifier().get(0).getValue());
}
@Test
void cloneIdentifierIntoResourceNoDuplicates() {
Identifier identifier = new Identifier().setSystem("http://org.com/sys").setValue("123");
Patient p1 = new Patient();
p1.addIdentifier(identifier);
Patient p2 = new Patient();
Identifier dupIdentifier = new Identifier().setSystem("http://org.com/sys").setValue("123");
p2.addIdentifier(dupIdentifier);
RuntimeResourceDefinition definition = ourFhirContext.getResourceDefinition(p1);
TerserUtil.cloneIdentifierIntoResource(ourFhirContext, definition.getChildByName("identifier"), identifier, p2);
assertEquals(1, p2.getIdentifier().size());
assertEquals(p1.getIdentifier().get(0).getSystem(), p2.getIdentifier().get(0).getSystem());
@ -171,7 +189,7 @@ class TerserUtilTest {
}
@Test
void testCloneEidIntoResourceViaHelper() {
void cloneIdentifierIntoResourceViaHelper() {
TerserUtilHelper p1Helper = TerserUtilHelper.newHelper(ourFhirContext, "Patient");
p1Helper.setField("identifier.system", "http://org.com/sys");
p1Helper.setField("identifier.value", "123");
@ -182,7 +200,7 @@ class TerserUtilTest {
TerserUtilHelper p2Helper = TerserUtilHelper.newHelper(ourFhirContext, "Patient");
RuntimeResourceDefinition definition = p1Helper.getResourceDefinition();
TerserUtil.cloneEidIntoResource(ourFhirContext, definition.getChildByName("identifier"),
TerserUtil.cloneIdentifierIntoResource(ourFhirContext, definition.getChildByName("identifier"),
p1.getIdentifier().get(0), p2Helper.getResource());
assertEquals(1, p2Helper.getFieldValues("identifier").size());