Jd 20240704 fix mdm phonetic matching on humanname exception (#6078)
* failing test * fix and changelog * edit changelog issue number * mvn spotless * address code review comment --------- Co-authored-by: jdar <justin.dar@smiledigitalhealth.com>
This commit is contained in:
parent
40d42f3ba5
commit
ec7538c78f
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
type: fix
|
||||||
|
issue: 6077
|
||||||
|
title: "Previously, when a MDM rule tried to perform a phonetic match by HumanName (eg. Patient.name), a
|
||||||
|
`ClassCastException` was thrown. This has now been fixed."
|
|
@ -45,9 +45,17 @@ public class PhoneticEncoderMatcher implements IMdmFieldMatcher {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(IBase theLeftBase, IBase theRightBase, MdmMatcherJson theParams) {
|
public boolean matches(IBase theLeftBase, IBase theRightBase, MdmMatcherJson theParams) {
|
||||||
String leftString = StringMatcherUtils.extractString((IPrimitiveType<?>) theLeftBase, theParams.getExact());
|
if (theLeftBase instanceof IPrimitiveType && theRightBase instanceof IPrimitiveType) {
|
||||||
String rightString = StringMatcherUtils.extractString((IPrimitiveType<?>) theRightBase, theParams.getExact());
|
String leftString = StringMatcherUtils.extractString((IPrimitiveType<?>) theLeftBase, theParams.getExact());
|
||||||
|
String rightString =
|
||||||
|
StringMatcherUtils.extractString((IPrimitiveType<?>) theRightBase, theParams.getExact());
|
||||||
|
|
||||||
return matches(leftString, rightString);
|
return matches(leftString, rightString);
|
||||||
|
}
|
||||||
|
ourLog.warn(
|
||||||
|
"Unable to evaluate match between {} and {} because they are not an instance of PrimitiveType.",
|
||||||
|
theLeftBase.getClass().getSimpleName(),
|
||||||
|
theRightBase.getClass().getSimpleName());
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,15 +6,29 @@ import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
||||||
import ca.uhn.fhir.mdm.rules.json.MdmFieldMatchJson;
|
import ca.uhn.fhir.mdm.rules.json.MdmFieldMatchJson;
|
||||||
import ca.uhn.fhir.mdm.rules.json.MdmMatcherJson;
|
import ca.uhn.fhir.mdm.rules.json.MdmMatcherJson;
|
||||||
import ca.uhn.fhir.mdm.rules.json.MdmRulesJson;
|
import ca.uhn.fhir.mdm.rules.json.MdmRulesJson;
|
||||||
|
import ca.uhn.fhir.mdm.rules.matcher.fieldmatchers.PhoneticEncoderMatcher;
|
||||||
import ca.uhn.fhir.mdm.rules.matcher.models.MatchTypeEnum;
|
import ca.uhn.fhir.mdm.rules.matcher.models.MatchTypeEnum;
|
||||||
|
import ch.qos.logback.classic.Level;
|
||||||
|
import ch.qos.logback.classic.Logger;
|
||||||
|
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||||
|
import ch.qos.logback.core.Appender;
|
||||||
import org.hl7.fhir.r4.model.HumanName;
|
import org.hl7.fhir.r4.model.HumanName;
|
||||||
import org.hl7.fhir.r4.model.Patient;
|
import org.hl7.fhir.r4.model.Patient;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.Captor;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
public class ResourceMatcherR4Test extends BaseMdmRulesR4Test {
|
public class ResourceMatcherR4Test extends BaseMdmRulesR4Test {
|
||||||
|
@ -23,6 +37,10 @@ public class ResourceMatcherR4Test extends BaseMdmRulesR4Test {
|
||||||
public static final String PHONE_NUMBER = "123 456789";
|
public static final String PHONE_NUMBER = "123 456789";
|
||||||
private Patient myLeft;
|
private Patient myLeft;
|
||||||
private Patient myRight;
|
private Patient myRight;
|
||||||
|
@Mock
|
||||||
|
private Appender<ILoggingEvent> myAppender;
|
||||||
|
@Captor
|
||||||
|
ArgumentCaptor<ILoggingEvent> myLoggingEvent;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
|
@ -61,6 +79,41 @@ public class ResourceMatcherR4Test extends BaseMdmRulesR4Test {
|
||||||
assertMatchResult(MdmMatchResultEnum.MATCH, 7L, 3.0, false, false, result);
|
assertMatchResult(MdmMatchResultEnum.MATCH, 7L, 3.0, false, false, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMetaphoneOnName() {
|
||||||
|
Logger logger = (Logger) LoggerFactory.getLogger(PhoneticEncoderMatcher.class);
|
||||||
|
logger.addAppender(myAppender);
|
||||||
|
|
||||||
|
// Given: MDM rules that match by Patient.name using some phonetic algorithm
|
||||||
|
MdmFieldMatchJson lastNameMatchField = new MdmFieldMatchJson()
|
||||||
|
.setName(PATIENT_FAMILY)
|
||||||
|
.setResourceType("Patient")
|
||||||
|
.setResourcePath("name")
|
||||||
|
.setMatcher(new MdmMatcherJson().setAlgorithm(MatchTypeEnum.METAPHONE));
|
||||||
|
|
||||||
|
MdmRulesJson retval = new MdmRulesJson();
|
||||||
|
retval.setVersion("test version");
|
||||||
|
retval.addMatchField(lastNameMatchField);
|
||||||
|
retval.setMdmTypes(List.of("Patient"));
|
||||||
|
retval.putMatchResult(PATIENT_FAMILY, MdmMatchResultEnum.MATCH);
|
||||||
|
|
||||||
|
// When
|
||||||
|
MdmResourceMatcherSvc matcherSvc = buildMatcher(retval);
|
||||||
|
MdmMatchOutcome result = matcherSvc.match(myLeft, myRight);
|
||||||
|
|
||||||
|
// Then: expect a logged message notifying that we are unable to phonetically match by HumanName
|
||||||
|
verify(myAppender, times(1)).doAppend(myLoggingEvent.capture());
|
||||||
|
ILoggingEvent event = myLoggingEvent.getValue();
|
||||||
|
assertEquals(Level.WARN, event.getLevel());
|
||||||
|
assertEquals("Unable to evaluate match between HumanName and HumanName because they are not an instance of PrimitiveType.", event.getFormattedMessage());
|
||||||
|
|
||||||
|
logger.detachAppender(myAppender);
|
||||||
|
verifyNoMoreInteractions(myAppender);
|
||||||
|
System.clearProperty("unit_test");
|
||||||
|
|
||||||
|
assertMatchResult(MdmMatchResultEnum.NO_MATCH, 0L, 0.0, false, false, result);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStringMatchResult() {
|
public void testStringMatchResult() {
|
||||||
MdmResourceMatcherSvc matcherSvc = buildMatcher(buildNamePhoneRules(MatchTypeEnum.STRING));
|
MdmResourceMatcherSvc matcherSvc = buildMatcher(buildNamePhoneRules(MatchTypeEnum.STRING));
|
||||||
|
|
Loading…
Reference in New Issue