From 5b75ff2425b745191e45ae1711bb6a2d9ed853d7 Mon Sep 17 00:00:00 2001 From: Tadgh Date: Fri, 5 Mar 2021 10:35:52 -0500 Subject: [PATCH] WIP working out bug in typefilters --- .../fhir/jpa/bulk/job/BaseBulkItemReader.java | 1 + .../bulk/provider/BulkDataExportProvider.java | 8 +- .../jpa/bulk/svc/BulkDataExportSvcImpl.java | 3 +- .../jpa/bulk/BulkDataExportProviderTest.java | 77 ++++++++++++++++++- 4 files changed, 85 insertions(+), 4 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/job/BaseBulkItemReader.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/job/BaseBulkItemReader.java index 49b8f8495db..b759571561f 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/job/BaseBulkItemReader.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/job/BaseBulkItemReader.java @@ -87,6 +87,7 @@ public abstract class BaseBulkItemReader implements ItemReader requestUrl = UrlUtil.parseQueryStrings(jobEntity.getRequest()); String[] typeFilters = requestUrl.get(JpaConstants.PARAM_EXPORT_TYPE_FILTER); if (typeFilters != null) { + //TODO GGG START HERE Optional filter = Arrays.stream(typeFilters).filter(t -> t.startsWith(myResourceType + "?")).findFirst(); if (filter.isPresent()) { String matchUrl = filter.get(); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/provider/BulkDataExportProvider.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/provider/BulkDataExportProvider.java index df3fcf2aeb9..39a624c4ba1 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/provider/BulkDataExportProvider.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/provider/BulkDataExportProvider.java @@ -48,6 +48,8 @@ import org.springframework.beans.factory.annotation.Autowired; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Date; +import java.util.HashSet; +import java.util.List; import java.util.Set; public class BulkDataExportProvider { @@ -75,7 +77,7 @@ public class BulkDataExportProvider { @OperationParam(name = JpaConstants.PARAM_EXPORT_OUTPUT_FORMAT, min = 0, max = 1, typeName = "string") IPrimitiveType theOutputFormat, @OperationParam(name = JpaConstants.PARAM_EXPORT_TYPE, min = 0, max = 1, typeName = "string") IPrimitiveType theType, @OperationParam(name = JpaConstants.PARAM_EXPORT_SINCE, min = 0, max = 1, typeName = "instant") IPrimitiveType theSince, - @OperationParam(name = JpaConstants.PARAM_EXPORT_TYPE_FILTER, min = 0, max = OperationParam.MAX_UNLIMITED, typeName = "string") IPrimitiveType theTypeFilter, + @OperationParam(name = JpaConstants.PARAM_EXPORT_TYPE_FILTER, min = 0, max = 1, typeName = "string") IPrimitiveType theTypeFilter, ServletRequestDetails theRequestDetails ) { @@ -97,9 +99,11 @@ public class BulkDataExportProvider { since = theSince.getValue(); } - Set filters = null; + Set filters = new HashSet<>(); if (theTypeFilter != null) { +// theTypeFilter.stream().forEach(filter -> filters.addAll(ArrayUtil.commaSeparatedListToCleanSet(filter.getValueAsString()))); filters = ArrayUtil.commaSeparatedListToCleanSet(theTypeFilter.getValueAsString()); +// theTypeFilter.stream().forEach(filter -> filters.addAll(ArrayUtil.commaSeparatedListToCleanSet(filter.getValueAsString()))); } IBulkDataExportSvc.JobInfo outcome = myBulkDataExportSvc.submitJob(new BulkDataExportOptions(outputFormat, resourceTypes, since, filters, true)); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/svc/BulkDataExportSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/svc/BulkDataExportSvcImpl.java index d2f989814bb..55d135412cf 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/svc/BulkDataExportSvcImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/svc/BulkDataExportSvcImpl.java @@ -312,7 +312,8 @@ public class BulkDataExportSvcImpl implements IBulkDataExportSvc { requestBuilder.append("&").append(JpaConstants.PARAM_EXPORT_SINCE).append("=").append(new InstantType(since).setTimeZoneZulu(true).getValueAsString()); } if (theBulkDataExportOptions.getFilters() != null && theBulkDataExportOptions.getFilters().size() > 0) { - requestBuilder.append("&").append(JpaConstants.PARAM_EXPORT_TYPE_FILTER).append("=").append(String.join(",", escapeUrlParams(theBulkDataExportOptions.getFilters()))); + theBulkDataExportOptions.getFilters().stream() + .forEach(filter -> requestBuilder.append("&").append(JpaConstants.PARAM_EXPORT_TYPE_FILTER).append("=").append(escapeUrlParam(filter))); } if (theBulkDataExportOptions instanceof GroupBulkDataExportOptions) { GroupBulkDataExportOptions groupOptions = (GroupBulkDataExportOptions) theBulkDataExportOptions; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/bulk/BulkDataExportProviderTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/bulk/BulkDataExportProviderTest.java index 45ea95c7afb..4fc4bc2091c 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/bulk/BulkDataExportProviderTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/bulk/BulkDataExportProviderTest.java @@ -267,7 +267,6 @@ public class BulkDataExportProviderTest { assertEquals("Patient", responseJson.getOutput().get(2).getType()); assertEquals("http://localhost:" + myPort + "/Binary/333", responseJson.getOutput().get(2).getUrl()); } - } @Test @@ -339,4 +338,80 @@ public class BulkDataExportProviderTest { assertEquals(GROUP_ID, options.getGroupId().getValue()); assertThat(options.isMdm(), is(equalTo(true))); } + + @Test + public void testInitiateWithGetAndMultipleTypeFilters() throws IOException { + //TODO GGG FIX ME + IBulkDataExportSvc.JobInfo jobInfo = new IBulkDataExportSvc.JobInfo() + .setJobId(A_JOB_ID); + when(myBulkDataExportSvc.submitJob(any())).thenReturn(jobInfo); + + InstantType now = InstantType.now(); + + String url = "http://localhost:" + myPort + "/" + JpaConstants.OPERATION_EXPORT + + "?" + JpaConstants.PARAM_EXPORT_OUTPUT_FORMAT + "=" + UrlUtil.escapeUrlParam(Constants.CT_FHIR_NDJSON) + + "&" + JpaConstants.PARAM_EXPORT_TYPE + "=" + UrlUtil.escapeUrlParam("Patient, Practitioner") + + "&" + JpaConstants.PARAM_EXPORT_SINCE + "=" + UrlUtil.escapeUrlParam(now.getValueAsString()) +// + "&" + JpaConstants.PARAM_EXPORT_TYPE_FILTER + "=" + UrlUtil.escapeUrlParam("Patient?identifier=foo") +// + "&" + JpaConstants.PARAM_EXPORT_TYPE_FILTER + "=" + UrlUtil.escapeUrlParam("Practitioner?identifier=bar") +// + "&" + JpaConstants.PARAM_EXPORT_TYPE_FILTER + "=" + UrlUtil.escapeUrlParam("Patient?name=zoop"); + + "&" + JpaConstants.PARAM_EXPORT_TYPE_FILTER + "=" + // "MedicationRequest%3Fstatus%3Dactive,MedicationRequest%3Fstatus%3Dcompleted%26date%3Dgt2018-07-01T00%3A00%3A00Z"; + "Immunization?patient.identifier%3DSC378274-MRN%7C009999997%2CSC378274-MRN%7C009999998%2CSC378274-MRN%7C009999999%26date%3D2020-01-02"; + + HttpGet get = new HttpGet(url); + get.addHeader(Constants.HEADER_PREFER, Constants.HEADER_PREFER_RESPOND_ASYNC); + ourLog.info("Request: {}", url); + try (CloseableHttpResponse response = myClient.execute(get)) { + ourLog.info("Response: {}", response.toString()); + + assertEquals(202, response.getStatusLine().getStatusCode()); + assertEquals("Accepted", response.getStatusLine().getReasonPhrase()); + assertEquals("http://localhost:" + myPort + "/$export-poll-status?_jobId=" + A_JOB_ID, response.getFirstHeader(Constants.HEADER_CONTENT_LOCATION).getValue()); + } + + verify(myBulkDataExportSvc, times(1)).submitJob(myBulkDataExportOptionsCaptor.capture()); + BulkDataExportOptions options = myBulkDataExportOptionsCaptor.getValue(); + assertEquals(Constants.CT_FHIR_NDJSON, options.getOutputFormat()); + assertThat(options.getResourceTypes(), containsInAnyOrder("Patient", "Practitioner")); + assertThat(options.getSince(), notNullValue()); + assertThat(options.getFilters(), containsInAnyOrder("Patient?identifier=foo", "Practitioner?identifier=bar", "Patient?name=zoop")); + } + + @Test + public void testInitiateWithPostAndMultipleTypeFilters() throws IOException { + + IBulkDataExportSvc.JobInfo jobInfo = new IBulkDataExportSvc.JobInfo() + .setJobId(A_JOB_ID); + when(myBulkDataExportSvc.submitJob(any())).thenReturn(jobInfo); + + InstantType now = InstantType.now(); + + Parameters input = new Parameters(); + input.addParameter(JpaConstants.PARAM_EXPORT_OUTPUT_FORMAT, new StringType(Constants.CT_FHIR_NDJSON)); + input.addParameter(JpaConstants.PARAM_EXPORT_TYPE, new StringType("Patient, Practitioner")); + input.addParameter(JpaConstants.PARAM_EXPORT_SINCE, now); + input.addParameter(JpaConstants.PARAM_EXPORT_TYPE_FILTER, new StringType("Patient?identifier=foo")); + + ourLog.info(myCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(input)); + + HttpPost post = new HttpPost("http://localhost:" + myPort + "/" + JpaConstants.OPERATION_EXPORT); + post.addHeader(Constants.HEADER_PREFER, Constants.HEADER_PREFER_RESPOND_ASYNC); + post.setEntity(new ResourceEntity(myCtx, input)); + ourLog.info("Request: {}", post); + try (CloseableHttpResponse response = myClient.execute(post)) { + ourLog.info("Response: {}", response.toString()); + + assertEquals(202, response.getStatusLine().getStatusCode()); + assertEquals("Accepted", response.getStatusLine().getReasonPhrase()); + assertEquals("http://localhost:" + myPort + "/$export-poll-status?_jobId=" + A_JOB_ID, response.getFirstHeader(Constants.HEADER_CONTENT_LOCATION).getValue()); + } + + verify(myBulkDataExportSvc, times(1)).submitJob(myBulkDataExportOptionsCaptor.capture()); + BulkDataExportOptions options = myBulkDataExportOptionsCaptor.getValue(); + assertEquals(Constants.CT_FHIR_NDJSON, options.getOutputFormat()); + assertThat(options.getResourceTypes(), containsInAnyOrder("Patient", "Practitioner")); + assertThat(options.getSince(), notNullValue()); + assertThat(options.getFilters(), containsInAnyOrder("Patient?identifier=foo")); + } + }