3524 export poll status returning the wrong partition in the url (#3526)
* test added and bulk data export provider fixed * add test and change jira number * change test * modify tests
This commit is contained in:
parent
5ccb4effb0
commit
4c9667c92a
|
@ -0,0 +1,4 @@
|
||||||
|
type: fix
|
||||||
|
issue: 3524
|
||||||
|
jira: SMILE-3672
|
||||||
|
title: "Previously if partitioning was enabled, the URL returned from `$export-poll-status` provided a location in the wrong partition. This has been fixed and all Bulk Exports will be stored in the `DEFAULT` partition."
|
|
@ -1,15 +1,27 @@
|
||||||
package ca.uhn.fhir.jpa.provider.r4;
|
package ca.uhn.fhir.jpa.provider.r4;
|
||||||
|
|
||||||
import ca.uhn.fhir.i18n.Msg;
|
import ca.uhn.fhir.i18n.Msg;
|
||||||
|
import ca.uhn.fhir.jpa.batch.config.BatchConstants;
|
||||||
|
import ca.uhn.fhir.jpa.bulk.export.api.IBulkDataExportJobSchedulingHelper;
|
||||||
|
import ca.uhn.fhir.jpa.bulk.export.api.IBulkDataExportSvc;
|
||||||
|
import ca.uhn.fhir.jpa.bulk.export.model.BulkExportJobStatusEnum;
|
||||||
|
import ca.uhn.fhir.jpa.bulk.export.model.BulkExportResponseJson;
|
||||||
|
import ca.uhn.fhir.jpa.bulk.export.provider.BulkDataExportProvider;
|
||||||
import ca.uhn.fhir.jpa.entity.PartitionEntity;
|
import ca.uhn.fhir.jpa.entity.PartitionEntity;
|
||||||
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
|
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
|
||||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||||
import ca.uhn.fhir.jpa.model.util.JpaConstants;
|
import ca.uhn.fhir.jpa.model.util.JpaConstants;
|
||||||
import ca.uhn.fhir.jpa.partition.SystemRequestDetails;
|
import ca.uhn.fhir.jpa.partition.SystemRequestDetails;
|
||||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
|
import ca.uhn.fhir.rest.api.server.bulk.BulkDataExportOptions;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
|
import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||||
import ca.uhn.fhir.test.utilities.ITestDataBuilder;
|
import ca.uhn.fhir.test.utilities.ITestDataBuilder;
|
||||||
|
import ca.uhn.fhir.util.JsonUtil;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
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.IIdType;
|
||||||
import org.hl7.fhir.r4.model.Bundle;
|
import org.hl7.fhir.r4.model.Bundle;
|
||||||
|
@ -18,17 +30,23 @@ import org.hl7.fhir.r4.model.Condition;
|
||||||
import org.hl7.fhir.r4.model.IdType;
|
import org.hl7.fhir.r4.model.IdType;
|
||||||
import org.hl7.fhir.r4.model.Organization;
|
import org.hl7.fhir.r4.model.Organization;
|
||||||
import org.hl7.fhir.r4.model.Patient;
|
import org.hl7.fhir.r4.model.Patient;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.empty;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.hasSize;
|
import static org.hamcrest.Matchers.hasSize;
|
||||||
|
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.assertNotNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
|
@ -36,6 +54,11 @@ import static org.junit.jupiter.api.Assertions.fail;
|
||||||
@SuppressWarnings("Duplicates")
|
@SuppressWarnings("Duplicates")
|
||||||
public class MultitenantServerR4Test extends BaseMultitenantResourceProviderR4Test implements ITestDataBuilder {
|
public class MultitenantServerR4Test extends BaseMultitenantResourceProviderR4Test implements ITestDataBuilder {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IBulkDataExportSvc myBulkDataExportSvc;
|
||||||
|
@Autowired
|
||||||
|
private IBulkDataExportJobSchedulingHelper myBulkDataExportJobSchedulingHelper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@AfterEach
|
@AfterEach
|
||||||
public void after() throws Exception {
|
public void after() throws Exception {
|
||||||
|
@ -370,6 +393,56 @@ public class MultitenantServerR4Test extends BaseMultitenantResourceProviderR4Te
|
||||||
assertThat(response.getEntry(), hasSize(2));
|
assertThat(response.getEntry(), hasSize(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBulkExportForDifferentPartitions() throws IOException {
|
||||||
|
setBulkDataExportProvider();
|
||||||
|
testBulkExport(TENANT_A);
|
||||||
|
testBulkExport(TENANT_B);
|
||||||
|
testBulkExport(JpaConstants.DEFAULT_PARTITION_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testBulkExport(String createInPartition) throws IOException {
|
||||||
|
// Create a patient
|
||||||
|
IBaseResource patientA = buildPatient(withActiveTrue());
|
||||||
|
SystemRequestDetails requestDetails = new SystemRequestDetails();
|
||||||
|
requestDetails.setTenantId(createInPartition);
|
||||||
|
myPatientDao.create((Patient) patientA, requestDetails);
|
||||||
|
|
||||||
|
// Create a bulk job
|
||||||
|
BulkDataExportOptions options = new BulkDataExportOptions();
|
||||||
|
options.setResourceTypes(Sets.newHashSet("Patient"));
|
||||||
|
options.setExportStyle(BulkDataExportOptions.ExportStyle.SYSTEM);
|
||||||
|
|
||||||
|
IBulkDataExportSvc.JobInfo jobDetails = myBulkDataExportSvc.submitJob(options, false, requestDetails);
|
||||||
|
assertNotNull(jobDetails.getJobId());
|
||||||
|
|
||||||
|
// Run a scheduled pass to build the export and wait for completion
|
||||||
|
myBulkDataExportJobSchedulingHelper.startSubmittedJobs();
|
||||||
|
myBatchJobHelper.awaitAllBulkJobCompletions(
|
||||||
|
BatchConstants.BULK_EXPORT_JOB_NAME
|
||||||
|
);
|
||||||
|
|
||||||
|
//perform export-poll-status
|
||||||
|
HttpGet get = new HttpGet(buildExportUrl(createInPartition, jobDetails.getJobId()));
|
||||||
|
try (CloseableHttpResponse response = ourHttpClient.execute(get)) {
|
||||||
|
String responseString = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
|
BulkExportResponseJson responseJson = JsonUtil.deserialize(responseString, BulkExportResponseJson.class);
|
||||||
|
assertThat(responseJson.getOutput().get(0).getUrl(), containsString(JpaConstants.DEFAULT_PARTITION_NAME + "/Binary/"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setBulkDataExportProvider() {
|
||||||
|
BulkDataExportProvider provider = new BulkDataExportProvider();
|
||||||
|
provider.setBulkDataExportSvcForUnitTests(myBulkDataExportSvc);
|
||||||
|
provider.setFhirContextForUnitTest(myFhirContext);
|
||||||
|
ourRestServer.registerProvider(provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildExportUrl(String createInPartition, String jobId) {
|
||||||
|
return myClient.getServerBase() + "/" + createInPartition + "/" + JpaConstants.OPERATION_EXPORT_POLL_STATUS + "?"
|
||||||
|
+ JpaConstants.PARAM_EXPORT_POLL_STATUS_JOB_ID + "=" + jobId;
|
||||||
|
}
|
||||||
|
|
||||||
private void createConditionWithAllowedUnqualified(IIdType idA) {
|
private void createConditionWithAllowedUnqualified(IIdType idA) {
|
||||||
myPartitionSettings.setAllowReferencesAcrossPartitions(PartitionSettings.CrossPartitionReferenceMode.ALLOWED_UNQUALIFIED);
|
myPartitionSettings.setAllowReferencesAcrossPartitions(PartitionSettings.CrossPartitionReferenceMode.ALLOWED_UNQUALIFIED);
|
||||||
IIdType idB = createResource("Condition", withTenant(TENANT_A), withObservationCode("http://cs", "A"));
|
IIdType idB = createResource("Condition", withTenant(TENANT_A), withObservationCode("http://cs", "A"));
|
||||||
|
|
|
@ -106,6 +106,15 @@ public class BulkDataExportProvider {
|
||||||
return StringUtils.removeEnd(theRequestDetails.getServerBaseForRequest(), "/");
|
return StringUtils.removeEnd(theRequestDetails.getServerBaseForRequest(), "/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getDefaultPartitionServerBase(ServletRequestDetails theRequestDetails) {
|
||||||
|
if (theRequestDetails.getTenantId() == null || theRequestDetails.getTenantId().equals(JpaConstants.DEFAULT_PARTITION_NAME)) {
|
||||||
|
return getServerBase(theRequestDetails);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return StringUtils.removeEnd(theRequestDetails.getServerBaseForRequest().replace(theRequestDetails.getTenantId(), JpaConstants.DEFAULT_PARTITION_NAME), "/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Group/Id/$export
|
* Group/Id/$export
|
||||||
*/
|
*/
|
||||||
|
@ -197,7 +206,7 @@ public class BulkDataExportProvider {
|
||||||
bulkResponseDocument.setTransactionTime(status.getStatusTime());
|
bulkResponseDocument.setTransactionTime(status.getStatusTime());
|
||||||
bulkResponseDocument.setRequest(status.getRequest());
|
bulkResponseDocument.setRequest(status.getRequest());
|
||||||
for (IBulkDataExportSvc.FileEntry nextFile : status.getFiles()) {
|
for (IBulkDataExportSvc.FileEntry nextFile : status.getFiles()) {
|
||||||
String serverBase = getServerBase(theRequestDetails);
|
String serverBase = getDefaultPartitionServerBase(theRequestDetails);
|
||||||
String nextUrl = serverBase + "/" + nextFile.getResourceId().toUnqualifiedVersionless().getValue();
|
String nextUrl = serverBase + "/" + nextFile.getResourceId().toUnqualifiedVersionless().getValue();
|
||||||
bulkResponseDocument
|
bulkResponseDocument
|
||||||
.addOutput()
|
.addOutput()
|
||||||
|
|
Loading…
Reference in New Issue