From 620b46dd0ae915b9021a03ddca359d441b7a5c57 Mon Sep 17 00:00:00 2001 From: TipzCM Date: Fri, 5 Apr 2024 15:03:16 -0400 Subject: [PATCH] unify bulk export patient type and bulk export patient instance (#5822) * step one of unifying the bulk exports * adding changelog * review points * spotless --------- Co-authored-by: leif stawnyczy --- ...atient-type-and-instance-bulk-exports.yaml | 7 ++ .../jobs/export/BulkDataExportProvider.java | 90 +++++++++---------- 2 files changed, 49 insertions(+), 48 deletions(-) create mode 100644 hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/7_2_0/5820-unifying-patient-type-and-instance-bulk-exports.yaml diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/7_2_0/5820-unifying-patient-type-and-instance-bulk-exports.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/7_2_0/5820-unifying-patient-type-and-instance-bulk-exports.yaml new file mode 100644 index 00000000000..fd97471bc53 --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/7_2_0/5820-unifying-patient-type-and-instance-bulk-exports.yaml @@ -0,0 +1,7 @@ +--- +type: fix +issue: 5820 +title: "Unifying the code paths for Patient type export and Patient instance export. + These paths should be the same, since type is defined by spec, but instance + is just 'syntactic sugar' on top of that spec (and so should be the same). +" diff --git a/hapi-fhir-storage-batch2-jobs/src/main/java/ca/uhn/fhir/batch2/jobs/export/BulkDataExportProvider.java b/hapi-fhir-storage-batch2-jobs/src/main/java/ca/uhn/fhir/batch2/jobs/export/BulkDataExportProvider.java index 8882abc5c2e..05f5a95dbcc 100644 --- a/hapi-fhir-storage-batch2-jobs/src/main/java/ca/uhn/fhir/batch2/jobs/export/BulkDataExportProvider.java +++ b/hapi-fhir-storage-batch2-jobs/src/main/java/ca/uhn/fhir/batch2/jobs/export/BulkDataExportProvider.java @@ -37,7 +37,6 @@ import ca.uhn.fhir.jpa.batch.models.Batch2JobStartResponse; import ca.uhn.fhir.jpa.bulk.export.model.BulkExportResponseJson; import ca.uhn.fhir.jpa.model.util.JpaConstants; import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc; -import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.StringDt; import ca.uhn.fhir.rest.annotation.IdParam; import ca.uhn.fhir.rest.annotation.Operation; @@ -77,7 +76,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.List; @@ -293,11 +291,15 @@ public class BulkDataExportProvider { */ private void validateTargetsExists( RequestDetails theRequestDetails, String theTargetResourceName, Iterable theIdParams) { - RequestPartitionId partitionId = myRequestPartitionHelperService.determineReadPartitionForRequestForRead( - theRequestDetails, theTargetResourceName, theIdParams.iterator().next()); - SystemRequestDetails requestDetails = new SystemRequestDetails().setRequestPartitionId(partitionId); - for (IIdType nextId : theIdParams) { - myDaoRegistry.getResourceDao(theTargetResourceName).read(nextId, requestDetails); + if (theIdParams.iterator().hasNext()) { + RequestPartitionId partitionId = myRequestPartitionHelperService.determineReadPartitionForRequestForRead( + theRequestDetails, + theTargetResourceName, + theIdParams.iterator().next()); + SystemRequestDetails requestDetails = new SystemRequestDetails().setRequestPartitionId(partitionId); + for (IIdType nextId : theIdParams) { + myDaoRegistry.getResourceDao(theTargetResourceName).read(nextId, requestDetails); + } } } @@ -364,26 +366,18 @@ public class BulkDataExportProvider { @OperationParam(name = JpaConstants.PARAM_EXPORT_IDENTIFIER, min = 0, max = 1, typeName = "string") IPrimitiveType theExportIdentifier, ServletRequestDetails theRequestDetails) { - validatePreferAsyncHeader(theRequestDetails, ProviderConstants.OPERATION_EXPORT); - if (thePatient != null) { - validateTargetsExists( - theRequestDetails, - "Patient", - thePatient.stream().map(s -> new IdDt(s.getValue())).collect(Collectors.toList())); - } + List> patientIds = thePatient != null ? thePatient : new ArrayList<>(); - BulkExportJobParameters BulkExportJobParameters = buildPatientBulkExportOptions( + doPatientExport( + theRequestDetails, theOutputFormat, theType, theSince, - theTypeFilter, theExportIdentifier, - thePatient, - theTypePostFetchFilterUrl); - validateResourceTypesAllContainPatientSearchParams(BulkExportJobParameters.getResourceTypes()); - - startJob(theRequestDetails, BulkExportJobParameters); + theTypeFilter, + theTypePostFetchFilterUrl, + patientIds); } /** @@ -417,9 +411,34 @@ public class BulkDataExportProvider { @OperationParam(name = JpaConstants.PARAM_EXPORT_IDENTIFIER, min = 0, max = 1, typeName = "string") IPrimitiveType theExportIdentifier, ServletRequestDetails theRequestDetails) { + + // call the type-level export to ensure spec compliance + patientExport( + theOutputFormat, + theType, + theSince, + theTypeFilter, + theTypePostFetchFilterUrl, + List.of(theIdParam), + theExportIdentifier, + theRequestDetails); + } + + private void doPatientExport( + ServletRequestDetails theRequestDetails, + IPrimitiveType theOutputFormat, + IPrimitiveType theType, + IPrimitiveType theSince, + IPrimitiveType theExportIdentifier, + List> theTypeFilter, + List> theTypePostFetchFilterUrl, + List> thePatientIds) { validatePreferAsyncHeader(theRequestDetails, ProviderConstants.OPERATION_EXPORT); - validateTargetsExists(theRequestDetails, "Patient", List.of(theIdParam)); + validateTargetsExists( + theRequestDetails, + "Patient", + thePatientIds.stream().map(c -> new IdType(c.getValue())).collect(Collectors.toList())); BulkExportJobParameters BulkExportJobParameters = buildPatientBulkExportOptions( theOutputFormat, @@ -427,7 +446,7 @@ public class BulkDataExportProvider { theSince, theTypeFilter, theExportIdentifier, - theIdParam, + thePatientIds, theTypePostFetchFilterUrl); validateResourceTypesAllContainPatientSearchParams(BulkExportJobParameters.getResourceTypes()); @@ -670,31 +689,6 @@ public class BulkDataExportProvider { return BulkExportJobParameters; } - private BulkExportJobParameters buildPatientBulkExportOptions( - IPrimitiveType theOutputFormat, - IPrimitiveType theType, - IPrimitiveType theSince, - List> theTypeFilter, - IPrimitiveType theExportIdentifier, - IIdType thePatientId, - List> theTypePostFetchFilterUrl) { - IPrimitiveType type = theType; - if (type == null) { - // set type to all patient compartment resources if it is null - type = new StringDt(String.join(",", getPatientCompartmentResources())); - } - BulkExportJobParameters BulkExportJobParameters = buildBulkExportJobParameters( - theOutputFormat, - type, - theSince, - theTypeFilter, - theExportIdentifier, - ExportStyle.PATIENT, - theTypePostFetchFilterUrl); - BulkExportJobParameters.setPatientIds(Collections.singleton(thePatientId.getValue())); - return BulkExportJobParameters; - } - private BulkExportJobParameters buildBulkExportJobParameters( IPrimitiveType theOutputFormat, IPrimitiveType theType,