Add test for exporting patients from group

This commit is contained in:
Tadgh 2021-03-03 21:30:40 -05:00
parent de09c7e2da
commit 3d628a4e9c
3 changed files with 62 additions and 2 deletions

View File

@ -37,7 +37,9 @@ import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.param.ReferenceOrListParam; import ca.uhn.fhir.rest.param.ReferenceOrListParam;
import ca.uhn.fhir.rest.param.ReferenceParam; import ca.uhn.fhir.rest.param.ReferenceParam;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType; import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.ItemReader;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -80,6 +82,11 @@ public class GroupBulkItemReader extends BaseBulkItemReader implements ItemReade
Iterator<ResourcePersistentId> getResourcePidIterator() { Iterator<ResourcePersistentId> getResourcePidIterator() {
List<ResourcePersistentId> myReadPids = new ArrayList<>(); List<ResourcePersistentId> myReadPids = new ArrayList<>();
//Short circuit out if we detect we are attempting to extract patients
if (myResourceType.equalsIgnoreCase("Patient")) {
return getExpandedPatientIterator();
}
//First lets expand the group so we get a list of all patient IDs of the group, and MDM-matched patient IDs of the group. //First lets expand the group so we get a list of all patient IDs of the group, and MDM-matched patient IDs of the group.
Set<String> expandedMemberResourceIds = expandAllPatientPidsFromGroup(); Set<String> expandedMemberResourceIds = expandAllPatientPidsFromGroup();
if (ourLog.isDebugEnabled()) { if (ourLog.isDebugEnabled()) {
@ -99,6 +106,31 @@ public class GroupBulkItemReader extends BaseBulkItemReader implements ItemReade
return myReadPids.iterator(); return myReadPids.iterator();
} }
/**
* In case we are doing a Group Bulk Export and resourceType `Patient` is requested, we can just return the group members,
* possibly expanded by MDM, and don't have to go and fetch other resource DAOs.
*/
private Iterator<ResourcePersistentId> getExpandedPatientIterator() {
Set<Long> patientPidsToExport = new HashSet<>();
//This gets all member pids
List<String> members = getMembers();
List<IIdType> ids = members.stream().map(member -> new IdDt("Patient/" + member)).collect(Collectors.toList());
List<Long> pidsOrThrowException = myIdHelperService.getPidsOrThrowException(ids);
patientPidsToExport.addAll(pidsOrThrowException);
if (Boolean.parseBoolean(myMdmEnabled)) {
IBaseResource group = myDaoRegistry.getResourceDao("Group").read(new IdDt(myGroupId));
Long pidOrNull = myIdHelperService.getPidOrNull(group);
List<List<Long>> lists = myMdmLinkDao.expandPidsFromGroupPidGivenMatchResult(pidOrNull, MdmMatchResultEnum.MATCH);
lists.forEach(patientPidsToExport::addAll);
}
List<ResourcePersistentId> resourcePersistentIds = patientPidsToExport
.stream()
.map(ResourcePersistentId::new)
.collect(Collectors.toList());
return resourcePersistentIds.iterator();
}
/** /**
* Given the local myGroupId, read this group, and find all members' patient references. * Given the local myGroupId, read this group, and find all members' patient references.
* @return A list of strings representing the Patient IDs of the members (e.g. ["P1", "P2", "P3"] * @return A list of strings representing the Patient IDs of the members (e.g. ["P1", "P2", "P3"]
@ -109,6 +141,8 @@ public class GroupBulkItemReader extends BaseBulkItemReader implements ItemReade
return evaluate.stream().map(IPrimitiveType::getValueAsString).collect(Collectors.toList()); return evaluate.stream().map(IPrimitiveType::getValueAsString).collect(Collectors.toList());
} }
/** /**
* Given the local myGroupId, perform an expansion to retrieve all resource IDs of member patients. * Given the local myGroupId, perform an expansion to retrieve all resource IDs of member patients.
* if myMdmEnabled is set to true, we also reach out to the IMdmLinkDao to attempt to also expand it into matched * if myMdmEnabled is set to true, we also reach out to the IMdmLinkDao to attempt to also expand it into matched
@ -122,7 +156,7 @@ public class GroupBulkItemReader extends BaseBulkItemReader implements ItemReade
Long pidOrNull = myIdHelperService.getPidOrNull(group); Long pidOrNull = myIdHelperService.getPidOrNull(group);
//Attempt to perform MDM Expansion of membership //Attempt to perform MDM Expansion of membership
if (Boolean.valueOf(myMdmEnabled)) { if (Boolean.parseBoolean(myMdmEnabled)) {
List<List<Long>> goldenPidTargetPidTuple = myMdmLinkDao.expandPidsFromGroupPidGivenMatchResult(pidOrNull, MdmMatchResultEnum.MATCH); List<List<Long>> goldenPidTargetPidTuple = myMdmLinkDao.expandPidsFromGroupPidGivenMatchResult(pidOrNull, MdmMatchResultEnum.MATCH);
//Now lets translate these pids into resource IDs //Now lets translate these pids into resource IDs
Set<Long> uniquePids = new HashSet<>(); Set<Long> uniquePids = new HashSet<>();

View File

@ -40,7 +40,7 @@ public interface IMdmLinkDao extends JpaRepository<MdmLink, Long> {
@Query("DELETE FROM MdmLink f WHERE (myGoldenResourcePid = :pid OR mySourcePid = :pid) AND myMatchResult <> :matchResult") @Query("DELETE FROM MdmLink f WHERE (myGoldenResourcePid = :pid OR mySourcePid = :pid) AND myMatchResult <> :matchResult")
int deleteWithAnyReferenceToPidAndMatchResultNot(@Param("pid") Long thePid, @Param("matchResult") MdmMatchResultEnum theMatchResult); int deleteWithAnyReferenceToPidAndMatchResultNot(@Param("pid") Long thePid, @Param("matchResult") MdmMatchResultEnum theMatchResult);
@Query("SELECT f.mySourcePid FROM MdmLink f WHERE f.myMatchResult=:matchResult AND f.myGoldenResourcePid IN (:pids)") @Query("SELECT f.myGoldenResourcePid, f.mySourcePid FROM MdmLink f WHERE f.myMatchResult=:matchResult AND f.myGoldenResourcePid IN (:pids)")
List<Long> expandGoldenResourcePids(@Param("pids")List<Long> theGoldenResourcePids, @Param("matchResult") MdmMatchResultEnum theMdmMatchResultEnum); List<Long> expandGoldenResourcePids(@Param("pids")List<Long> theGoldenResourcePids, @Param("matchResult") MdmMatchResultEnum theMdmMatchResultEnum);
@Query("SELECT f.myGoldenResourcePid FROM MdmLink f WHERE f.mySourcePid IN (:pids)") @Query("SELECT f.myGoldenResourcePid FROM MdmLink f WHERE f.mySourcePid IN (:pids)")

View File

@ -610,6 +610,32 @@ public class BulkDataExportSvcImplR4Test extends BaseJpaR4Test {
} }
} }
@Test
public void testMdmExpansionSuccessfullyExtractsPatients() throws JobParametersInvalidException {
createResources();
// Create a bulk job
IBulkDataExportSvc.JobInfo jobDetails = myBulkDataExportSvc.submitJob(new GroupBulkDataExportOptions(null, Sets.newHashSet("Patient"), null, null, myPatientGroupId, true));
myBulkDataExportSvc.buildExportFiles();
awaitAllBulkJobCompletions();
IBulkDataExportSvc.JobInfo jobInfo = myBulkDataExportSvc.getJobInfoOrThrowResourceNotFound(jobDetails.getJobId());
assertThat(jobInfo.getStatus(), equalTo(BulkJobStatusEnum.COMPLETE));
assertThat(jobInfo.getFiles().size(), equalTo(1));
assertThat(jobInfo.getFiles().get(0).getResourceType(), is(equalTo("Patient")));
Binary patientExportContent = myBinaryDao.read(jobInfo.getFiles().get(0).getResourceId());
assertEquals(Constants.CT_FHIR_NDJSON, patientExportContent.getContentType());
String nextContents = new String(patientExportContent.getContent(), Constants.CHARSET_UTF8);
ourLog.info("Next contents for type {}:\n{}", patientExportContent.getResourceType(), nextContents);
assertThat(jobInfo.getFiles().get(0).getResourceType(), is(equalTo("Patient")));
//Output contains The entire group, plus the Mdm expansion, plus the golden resource
assertEquals(11, nextContents.split("\n").length);
}
@Test @Test
public void testMdmExpansionWorksForGroupExportOnMatchedPatients() throws JobParametersInvalidException { public void testMdmExpansionWorksForGroupExportOnMatchedPatients() throws JobParametersInvalidException {
createResources(); createResources();