Fix NPE in iterator, fix empi-rules.json, add extra tests
This commit is contained in:
parent
2da64119bb
commit
698b18eb2f
|
@ -27,6 +27,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
@ -43,10 +44,10 @@ public class EmpiCandidateSearchCriteriaBuilderSvc {
|
||||||
* Patient?active=true&name.given=Gary,Grant&name.family=Graham
|
* Patient?active=true&name.given=Gary,Grant&name.family=Graham
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public Optional<String> buildResourceQueryString(String theResourceType, IAnyResource theResource, List<String> theFilterCriteria, EmpiResourceSearchParamJson resourceSearchParam) {
|
public Optional<String> buildResourceQueryString(String theResourceType, IAnyResource theResource, List<String> theFilterCriteria, @Nullable EmpiResourceSearchParamJson resourceSearchParam) {
|
||||||
List<String> criteria = new ArrayList<>();
|
List<String> criteria = new ArrayList<>();
|
||||||
|
|
||||||
//If there is no candidateSearchParams, then we want to just use the filters.
|
// If there are candidate search params, then make use of them, otherwise, search with only the filters.
|
||||||
if (resourceSearchParam != null) {
|
if (resourceSearchParam != null) {
|
||||||
resourceSearchParam.iterator().forEachRemaining(searchParam -> {
|
resourceSearchParam.iterator().forEachRemaining(searchParam -> {
|
||||||
//to compare it to all known PERSON objects, using the overlapping search parameters that they have.
|
//to compare it to all known PERSON objects, using the overlapping search parameters that they have.
|
||||||
|
@ -55,6 +56,20 @@ public class EmpiCandidateSearchCriteriaBuilderSvc {
|
||||||
criteria.add(buildResourceMatchQuery(searchParam, valuesFromResourceForSearchParam));
|
criteria.add(buildResourceMatchQuery(searchParam, valuesFromResourceForSearchParam));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//TODO GGG/KHS, here's a question: What scenario would be actually want to return this empty optional.
|
||||||
|
//In the case where the resource being matched doesnt have any of the values that the EmpiResourceSearchParamJson wants?
|
||||||
|
//e.g. if i have a patient with name 'gary', but no birthdate, and i have a search param saying
|
||||||
|
// {
|
||||||
|
// "resourceType": "Patient",
|
||||||
|
// "searchParams": ["birthdate"]
|
||||||
|
// },
|
||||||
|
// do I actually want it to return Zero candidates? if so, this following conditional is valid. However
|
||||||
|
// What if I still want to match that person? Will they be unmatchable since they have no birthdate?
|
||||||
|
|
||||||
|
if (criteria.isEmpty()) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
criteria.addAll(theFilterCriteria);
|
criteria.addAll(theFilterCriteria);
|
||||||
|
|
|
@ -75,12 +75,12 @@ public class EmpiCandidateSearchSvc {
|
||||||
*/
|
*/
|
||||||
public Collection<IAnyResource> findCandidates(String theResourceType, IAnyResource theResource) {
|
public Collection<IAnyResource> findCandidates(String theResourceType, IAnyResource theResource) {
|
||||||
Map<Long, IAnyResource> matchedPidsToResources = new HashMap<>();
|
Map<Long, IAnyResource> matchedPidsToResources = new HashMap<>();
|
||||||
|
|
||||||
List<EmpiFilterSearchParamJson> filterSearchParams = myEmpiConfig.getEmpiRules().getCandidateFilterSearchParams();
|
List<EmpiFilterSearchParamJson> filterSearchParams = myEmpiConfig.getEmpiRules().getCandidateFilterSearchParams();
|
||||||
|
|
||||||
List<String> filterCriteria = buildFilterQuery(filterSearchParams, theResourceType);
|
List<String> filterCriteria = buildFilterQuery(filterSearchParams, theResourceType);
|
||||||
|
|
||||||
List<EmpiResourceSearchParamJson> candidateSearchParams = myEmpiConfig.getEmpiRules().getCandidateSearchParams();
|
List<EmpiResourceSearchParamJson> candidateSearchParams = myEmpiConfig.getEmpiRules().getCandidateSearchParams();
|
||||||
|
|
||||||
|
//If there are zero EmpiResourceSearchParamJson, we end up only making a single search, otherwise we
|
||||||
|
//must perform one search per EmpiResourceSearchParamJson.
|
||||||
if (candidateSearchParams == null || candidateSearchParams.isEmpty()) {
|
if (candidateSearchParams == null || candidateSearchParams.isEmpty()) {
|
||||||
searchForIdsAndAddToMap(theResourceType, theResource, matchedPidsToResources, filterCriteria, null);
|
searchForIdsAndAddToMap(theResourceType, theResource, matchedPidsToResources, filterCriteria, null);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
package ca.uhn.fhir.jpa.empi.provider;
|
||||||
|
|
||||||
|
import org.hl7.fhir.r4.model.Bundle;
|
||||||
|
import org.hl7.fhir.r4.model.Patient;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
public class EmpiProviderMatchR4Test extends BaseProviderR4Test {
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@BeforeEach
|
||||||
|
public void before() {
|
||||||
|
super.before();
|
||||||
|
super.loadEmpiSearchParameters();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMatch() {
|
||||||
|
Patient jane = buildJanePatient();
|
||||||
|
jane.setActive(true);
|
||||||
|
Patient createdJane = createPatient(jane);
|
||||||
|
Patient newJane = buildJanePatient();
|
||||||
|
|
||||||
|
Bundle result = myEmpiProviderR4.match(newJane);
|
||||||
|
assertEquals(1, result.getEntry().size());
|
||||||
|
assertEquals(createdJane.getId(), result.getEntryFirstRep().getResource().getId());
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,8 +5,6 @@ import ca.uhn.fhir.empi.api.EmpiMatchResultEnum;
|
||||||
import ca.uhn.fhir.empi.util.AssuranceLevelUtil;
|
import ca.uhn.fhir.empi.util.AssuranceLevelUtil;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||||
import org.hl7.fhir.r4.model.Bundle;
|
|
||||||
import org.hl7.fhir.r4.model.Patient;
|
|
||||||
import org.hl7.fhir.r4.model.Person;
|
import org.hl7.fhir.r4.model.Person;
|
||||||
import org.hl7.fhir.r4.model.StringType;
|
import org.hl7.fhir.r4.model.StringType;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
@ -39,18 +37,6 @@ public class EmpiProviderMergePersonsR4Test extends BaseProviderR4Test {
|
||||||
myToPersonId = new StringType(myToPerson.getIdElement().getValue());
|
myToPersonId = new StringType(myToPerson.getIdElement().getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testMatch() {
|
|
||||||
Patient jane = buildJanePatient();
|
|
||||||
jane.setActive(true);
|
|
||||||
Patient createdJane = createPatient(jane);
|
|
||||||
Patient newJane = buildJanePatient();
|
|
||||||
|
|
||||||
Bundle result = myEmpiProviderR4.match(newJane);
|
|
||||||
assertEquals(1, result.getEntry().size());
|
|
||||||
assertEquals(createdJane.getId(), result.getEntryFirstRep().getResource().getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMerge() {
|
public void testMerge() {
|
||||||
Person mergedPerson = myEmpiProviderR4.mergePersons(myFromPersonId, myToPersonId, myRequestDetails);
|
Person mergedPerson = myEmpiProviderR4.mergePersons(myFromPersonId, myToPersonId, myRequestDetails);
|
||||||
|
|
|
@ -9,11 +9,13 @@ import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.Matchers.anyOf;
|
import static org.hamcrest.Matchers.anyOf;
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
@ -67,4 +69,21 @@ public class EmpiCandidateSearchCriteriaBuilderSvcTest extends BaseEmpiR4Test {
|
||||||
assertTrue(result.isPresent());
|
assertTrue(result.isPresent());
|
||||||
assertEquals(result.get(), "Patient?identifier=urn:oid:1.2.36.146.595.217.0.1|12345");
|
assertEquals(result.get(), "Patient?identifier=urn:oid:1.2.36.146.595.217.0.1|12345");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOmittingCandidateSearchParamsIsAllowed() {
|
||||||
|
Patient patient = new Patient();
|
||||||
|
Optional<String> result = myEmpiCandidateSearchCriteriaBuilderSvc.buildResourceQueryString("Patient", patient, Collections.emptyList(), null);
|
||||||
|
assertThat(result.isPresent(), is(true));
|
||||||
|
assertThat(result.get(), is(equalTo("Patient?")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEmptyCandidateSearchParamsWorksInConjunctionWithFilterParams() {
|
||||||
|
Patient patient = new Patient();
|
||||||
|
List<String> filterParams = Collections.singletonList("active=true");
|
||||||
|
Optional<String> result = myEmpiCandidateSearchCriteriaBuilderSvc.buildResourceQueryString("Patient", patient, filterParams, null);
|
||||||
|
assertThat(result.isPresent(), is(true));
|
||||||
|
assertThat(result.get(), is(equalTo("Patient?active=true")));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,18 @@
|
||||||
{
|
{
|
||||||
"version": "1",
|
"version": "1",
|
||||||
"candidateSearchParams": [
|
"candidateSearchParams": [
|
||||||
|
{
|
||||||
|
"resourceType": "Patient",
|
||||||
|
"searchParams": ["birthdate"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceType": "*",
|
||||||
|
"searchParams": ["identifier"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceType": "Patient",
|
||||||
|
"searchParams": ["general-practitioner"]
|
||||||
|
}
|
||||||
],
|
],
|
||||||
"candidateFilterSearchParams": [
|
"candidateFilterSearchParams": [
|
||||||
{
|
{
|
||||||
|
|
|
@ -46,14 +46,18 @@ public class EmpiResourceSearchParamJson implements IModelJson, Iterable<String>
|
||||||
}
|
}
|
||||||
|
|
||||||
public Iterator<String> iterator() {
|
public Iterator<String> iterator() {
|
||||||
return mySearchParams.iterator();
|
return getSearchParams().iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
public EmpiResourceSearchParamJson addSearchParam(String theSearchParam) {
|
public EmpiResourceSearchParamJson addSearchParam(String theSearchParam) {
|
||||||
|
getSearchParams().add(theSearchParam);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> getSearchParams() {
|
||||||
if (mySearchParams == null) {
|
if (mySearchParams == null) {
|
||||||
mySearchParams = new ArrayList<>();
|
mySearchParams = new ArrayList<>();
|
||||||
}
|
}
|
||||||
mySearchParams.add(theSearchParam);
|
return mySearchParams;
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue