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() {} 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, FhirContext theFhirContext,
BaseRuntimeChildDefinition theIdentifierDefinition, BaseRuntimeChildDefinition theIdentifierDefinition,
IBase theEid, IBase theNewIdentifier,
IBase theResourceToCloneEidInto) { IBaseResource theResourceToCloneInto) {
// FHIR choice types - fields within fhir where we have a choice of ids // FHIR choice types - fields within fhir where we have a choice of ids
BaseRuntimeElementCompositeDefinition<?> childIdentifier = (BaseRuntimeElementCompositeDefinition<?>) BaseRuntimeElementCompositeDefinition<?> childIdentifierElementDefinition =
theIdentifierDefinition.getChildByName(FIELD_NAME_IDENTIFIER); (BaseRuntimeElementCompositeDefinition<?>)
IBase resourceNewIdentifier = childIdentifier.newInstance(); theIdentifierDefinition.getChildByName(FIELD_NAME_IDENTIFIER);
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(); FhirTerser terser = theFhirContext.newTerser();
terser.cloneInto(theEid, resourceNewIdentifier, true); terser.cloneInto(theNewIdentifier, newIdentifierBase, true);
theIdentifierDefinition.getMutator().addValue(theResourceToCloneEidInto, resourceNewIdentifier); 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( private void cloneMDMEidsIntoNewGoldenResource(
BaseRuntimeChildDefinition theGoldenResourceIdentifier, BaseRuntimeChildDefinition theGoldenResourceIdentifier,
IAnyResource theIncomingResource, IAnyResource theIncomingResource,
IBase theNewGoldenResource) { IBaseResource theNewGoldenResource) {
String incomingResourceType = myFhirContext.getResourceType(theIncomingResource); String incomingResourceType = myFhirContext.getResourceType(theIncomingResource);
String mdmEIDSystem = myMdmSettings.getMdmRules().getEnterpriseEIDSystemForResourceType(incomingResourceType); String mdmEIDSystem = myMdmSettings.getMdmRules().getEnterpriseEIDSystemForResourceType(incomingResourceType);
@ -182,7 +182,7 @@ public class GoldenResourceHelper {
ourLog.debug( ourLog.debug(
"Incoming resource EID System {} matches EID system in the MDM rules. Copying to Golden Resource.", "Incoming resource EID System {} matches EID system in the MDM rules. Copying to Golden Resource.",
incomingIdentifierSystemString); incomingIdentifierSystemString);
ca.uhn.fhir.util.TerserUtil.cloneEidIntoResource( ca.uhn.fhir.util.TerserUtil.cloneIdentifierIntoResource(
myFhirContext, myFhirContext,
theGoldenResourceIdentifier, theGoldenResourceIdentifier,
incomingResourceIdentifier, incomingResourceIdentifier,
@ -382,7 +382,7 @@ public class GoldenResourceHelper {
RuntimeResourceDefinition resourceDefinition = theFhirContext.getResourceDefinition(theResourceToCloneInto); RuntimeResourceDefinition resourceDefinition = theFhirContext.getResourceDefinition(theResourceToCloneInto);
// hapi has 2 metamodels: for children and types // hapi has 2 metamodels: for children and types
BaseRuntimeChildDefinition resourceIdentifier = resourceDefinition.getChildByName(FIELD_NAME_IDENTIFIER); BaseRuntimeChildDefinition resourceIdentifier = resourceDefinition.getChildByName(FIELD_NAME_IDENTIFIER);
ca.uhn.fhir.util.TerserUtil.cloneEidIntoResource( ca.uhn.fhir.util.TerserUtil.cloneIdentifierIntoResource(
theFhirContext, theFhirContext,
resourceIdentifier, resourceIdentifier,
IdentifierUtil.toId(theFhirContext, theEid), IdentifierUtil.toId(theFhirContext, theEid),

View File

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