diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/rules/matcher/ExtensionMatcher.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/rules/matcher/ExtensionMatcher.java new file mode 100644 index 00000000000..e89ef96091c --- /dev/null +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/rules/matcher/ExtensionMatcher.java @@ -0,0 +1,39 @@ +package ca.uhn.fhir.mdm.rules.matcher; + +import ca.uhn.fhir.context.FhirContext; +import org.hl7.fhir.instance.model.api.IBase; +import org.hl7.fhir.instance.model.api.IBaseExtension; +import org.hl7.fhir.instance.model.api.IBaseHasExtensions; +import org.hl7.fhir.r4.model.Extension; +import org.hl7.fhir.r4.model.StringType; + +import java.util.List; + +public class ExtensionMatcher implements IMdmFieldMatcher{ + @Override + public boolean matches(FhirContext theFhirContext, IBase theLeftBase, IBase theRightBase, boolean theExact, String theIdentifierSystem) { + List> leftExtension = null; + List> rightExtension = null; + if (theLeftBase instanceof IBaseHasExtensions && theRightBase instanceof IBaseHasExtensions){ + leftExtension = ((IBaseHasExtensions) theLeftBase).getExtension(); + rightExtension = ((IBaseHasExtensions) theRightBase).getExtension(); + } + else{ + return false; + } + + boolean match = false; + + for (IBaseExtension leftExtensionValue : leftExtension) { + if (leftExtensionValue.getUrl().equals(theIdentifierSystem) || theIdentifierSystem == null) { + for (IBaseExtension rightExtensionValue : rightExtension) { + if (rightExtensionValue.getUrl().equals(theIdentifierSystem) || theIdentifierSystem == null) { + match |= ((StringType) ((Extension) leftExtensionValue).getValue()).getValueAsString().equals(((StringType) ((Extension) rightExtensionValue).getValue()).getValueAsString()) + && leftExtensionValue.getUrl().equals(rightExtensionValue.getUrl()); + } + } + } + } + return match; + } +} diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/rules/matcher/MdmMatcherEnum.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/rules/matcher/MdmMatcherEnum.java index e95a2d961e3..458387d14d3 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/rules/matcher/MdmMatcherEnum.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/rules/matcher/MdmMatcherEnum.java @@ -50,7 +50,8 @@ public enum MdmMatcherEnum { IDENTIFIER(new IdentifierMatcher()), - EMPTY_FIELD(new EmptyFieldMatcher()); + EMPTY_FIELD(new EmptyFieldMatcher()), + EXTENSION_ANY_ORDER(new ExtensionMatcher()); private final IMdmFieldMatcher myMdmFieldMatcher; diff --git a/hapi-fhir-server-mdm/src/test/java/ca/uhn/fhir/mdm/rules/config/MdmRuleValidatorTest.java b/hapi-fhir-server-mdm/src/test/java/ca/uhn/fhir/mdm/rules/config/MdmRuleValidatorTest.java index 514d4da0eb6..755bd168814 100644 --- a/hapi-fhir-server-mdm/src/test/java/ca/uhn/fhir/mdm/rules/config/MdmRuleValidatorTest.java +++ b/hapi-fhir-server-mdm/src/test/java/ca/uhn/fhir/mdm/rules/config/MdmRuleValidatorTest.java @@ -151,6 +151,16 @@ public class MdmRuleValidatorTest extends BaseR4Test { } } + @Test + public void testMatcherExtensionJson() throws IOException { + try { + setMdmRuleJson("rules-extension-search.json"); + } + catch (ConfigurationException e){ + fail("Unable to validate extension matcher"); + } + } + private void setMdmRuleJson(String theTheS) throws IOException { MdmRuleValidator mdmRuleValidator = new MdmRuleValidator(ourFhirContext, mySearchParamRetriever); MdmSettings mdmSettings = new MdmSettings(mdmRuleValidator); diff --git a/hapi-fhir-server-mdm/src/test/java/ca/uhn/fhir/mdm/rules/matcher/ExtensionMatcherR4Test.java b/hapi-fhir-server-mdm/src/test/java/ca/uhn/fhir/mdm/rules/matcher/ExtensionMatcherR4Test.java new file mode 100644 index 00000000000..3b437794adc --- /dev/null +++ b/hapi-fhir-server-mdm/src/test/java/ca/uhn/fhir/mdm/rules/matcher/ExtensionMatcherR4Test.java @@ -0,0 +1,73 @@ +package ca.uhn.fhir.mdm.rules.matcher; + + +import org.hl7.fhir.r4.model.Patient; +import org.hl7.fhir.r4.model.StringType; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class ExtensionMatcherR4Test extends BaseMatcherR4Test { + @Test + public void testPatientWithMatchingExtension(){ + Patient patient1 = new Patient(); + Patient patient2 = new Patient(); + + patient1.addExtension("asd",new StringType("Patient1")); + patient2.addExtension("asd",new StringType("Patient1")); + + assertTrue(MdmMatcherEnum.EXTENSION_ANY_ORDER.match(ourFhirContext, patient1, patient2, false, null)); + } + + @Test + public void testPatientWithoutMatchingExtension(){ + Patient patient1 = new Patient(); + Patient patient2 = new Patient(); + + patient1.addExtension("asd",new StringType("Patient1")); + patient2.addExtension("asd",new StringType("Patient2")); + + assertFalse(MdmMatcherEnum.EXTENSION_ANY_ORDER.match(ourFhirContext, patient1, patient2, false, null)); + } + + @Test + public void testPatientSameValueDifferentUrl(){ + Patient patient1 = new Patient(); + Patient patient2 = new Patient(); + + patient1.addExtension("asd",new StringType("Patient1")); + patient2.addExtension("asd1",new StringType("Patient1")); + + assertFalse(MdmMatcherEnum.EXTENSION_ANY_ORDER.match(ourFhirContext, patient1, patient2, false, null)); + } + + @Test + public void testPatientWithMultipleExtensionOneMatching(){ + Patient patient1 = new Patient(); + Patient patient2 = new Patient(); + + patient1.addExtension("asd",new StringType("Patient1")); + patient1.addExtension("url1", new StringType("asd")); + patient2.addExtension("asd",new StringType("Patient1")); + patient2.addExtension("asdasd", new StringType("some value")); + + assertTrue(MdmMatcherEnum.EXTENSION_ANY_ORDER.match(ourFhirContext, patient1, patient2, false, null)); + } + + @Test + public void testSpecificIdentifierSystem(){ + Patient patient1 = new Patient(); + Patient patient2 = new Patient(); + + patient1.addExtension("asd",new StringType("Patient1")); + patient1.addExtension("url1", new StringType("asd")); + patient2.addExtension("asd",new StringType("Patient1")); + patient2.addExtension("asdasd", new StringType("some value")); + patient2.addExtension("url1", new StringType("some value 123")); + + assertTrue(MdmMatcherEnum.EXTENSION_ANY_ORDER.match(ourFhirContext, patient1, patient2, false, null)); + assertTrue(MdmMatcherEnum.EXTENSION_ANY_ORDER.match(ourFhirContext, patient1, patient2, false, "asd")); + assertFalse(MdmMatcherEnum.EXTENSION_ANY_ORDER.match(ourFhirContext, patient1, patient2, false, "url1")); + } +} diff --git a/hapi-fhir-server-mdm/src/test/resources/rules-extension-search.json b/hapi-fhir-server-mdm/src/test/resources/rules-extension-search.json new file mode 100644 index 00000000000..706180de603 --- /dev/null +++ b/hapi-fhir-server-mdm/src/test/resources/rules-extension-search.json @@ -0,0 +1,17 @@ +{ + "version": "1", + "mdmTypes": ["Organization"], + "candidateSearchParams" : [], + "candidateFilterSearchParams" : [], + "matchFields" : [ { + "name" : "Organization-extension", + "resourceType" : "Organization", + "resourcePath" : "identifier", + "matcher" : { + "algorithm": "EXTENSION_ANY_ORDER" + } + }], + "matchResultMap" : { + "Organization-extension" : "MATCH" + } +}