From 424ec2118bd957746ea1dab9a37d58dd2acf8d79 Mon Sep 17 00:00:00 2001 From: Tadgh Date: Tue, 11 May 2021 10:31:29 -0400 Subject: [PATCH 1/8] Add implementation. Add test. Add changelog --- .../fhir/jpa/demo/FhirServerConfigCommon.java | 4 ++ .../5_4_0/2648-consent-on-metadata.yaml | 6 +++ .../uhn/fhir/jpa/migrate/DriverTypeEnum.java | 3 ++ .../consent/ConsentInterceptor.java | 27 ++++++++++++ .../interceptor/ConsentInterceptorTest.java | 42 +++++++++++++++++++ 5 files changed, 82 insertions(+) create mode 100644 hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_4_0/2648-consent-on-metadata.yaml diff --git a/example-projects/hapi-fhir-jpaserver-dynamic/src/main/java/ca/uhn/fhir/jpa/demo/FhirServerConfigCommon.java b/example-projects/hapi-fhir-jpaserver-dynamic/src/main/java/ca/uhn/fhir/jpa/demo/FhirServerConfigCommon.java index 76cd73dc002..5aa2bb96a1c 100644 --- a/example-projects/hapi-fhir-jpaserver-dynamic/src/main/java/ca/uhn/fhir/jpa/demo/FhirServerConfigCommon.java +++ b/example-projects/hapi-fhir-jpaserver-dynamic/src/main/java/ca/uhn/fhir/jpa/demo/FhirServerConfigCommon.java @@ -82,6 +82,10 @@ public class FhirServerConfigCommon { logger.error("----FhiServerConfigCommon: getDataSource: setting driver error: " + e.getMessage()); } dataSource.setUrl(dbUrl); + + // A check for WS-2020-0287 + assert dataSource.getJmxName() == null; + return dataSource; } diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_4_0/2648-consent-on-metadata.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_4_0/2648-consent-on-metadata.yaml new file mode 100644 index 00000000000..4896f5333f7 --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_4_0/2648-consent-on-metadata.yaml @@ -0,0 +1,6 @@ +--- +type: change +issue: 2648 +title: "The ConsentInterceptor no longer fully runs on calls to `/metadata` or during the `$meta` operation." + + diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/DriverTypeEnum.java b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/DriverTypeEnum.java index 3c71aa69964..e3ffc87b834 100644 --- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/DriverTypeEnum.java +++ b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/DriverTypeEnum.java @@ -122,6 +122,9 @@ public enum DriverTypeEnum { dataSource.setUsername(theUsername); dataSource.setPassword(thePassword); + // A check for WS-2020-0287 + assert dataSource.getJmxName() == null; + return newConnectionProperties(dataSource); } diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/consent/ConsentInterceptor.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/consent/ConsentInterceptor.java index cce264c81a6..410679e6ab2 100644 --- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/consent/ConsentInterceptor.java +++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/consent/ConsentInterceptor.java @@ -44,6 +44,8 @@ import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; +import static ca.uhn.fhir.rest.api.Constants.URL_TOKEN_METADATA; + @Interceptor public class ConsentInterceptor { private static final AtomicInteger ourInstanceCount = new AtomicInteger(0); @@ -51,6 +53,7 @@ public class ConsentInterceptor { private final String myRequestAuthorizedKey = ConsentInterceptor.class.getName() + "_" + myInstanceIndex + "_AUTHORIZED"; private final String myRequestCompletedKey = ConsentInterceptor.class.getName() + "_" + myInstanceIndex + "_COMPLETED"; private final String myRequestSeenResourcesKey = ConsentInterceptor.class.getName() + "_" + myInstanceIndex + "_SEENRESOURCES"; + public static final String META_OPERATION_NAME = "$meta"; private IConsentService myConsentService; private IConsentContextServices myContextConsentServices; @@ -94,6 +97,9 @@ public class ConsentInterceptor { @Hook(value = Pointcut.SERVER_INCOMING_REQUEST_PRE_HANDLED) public void interceptPreHandled(RequestDetails theRequestDetails) { + if (isAllowListedRequest(theRequestDetails)) { + return; + } ConsentOutcome outcome = myConsentService.startOperation(theRequestDetails, myContextConsentServices); Validate.notNull(outcome, "Consent service returned null outcome"); @@ -129,6 +135,9 @@ public class ConsentInterceptor { if (isRequestAuthorized(theRequestDetails)) { return; } + if (isAllowListedRequest(theRequestDetails)) { + return; + } for (int i = 0; i < thePreResourceAccessDetails.size(); i++) { IBaseResource nextResource = thePreResourceAccessDetails.getResource(i); @@ -150,6 +159,9 @@ public class ConsentInterceptor { if (isRequestAuthorized(theRequestDetails)) { return; } + if (isAllowListedRequest(theRequestDetails)) { + return; + } IdentityHashMap alreadySeenResources = getAlreadySeenResourcesMap(theRequestDetails); for (int i = 0; i < thePreResourceShowDetails.size(); i++) { @@ -198,6 +210,9 @@ public class ConsentInterceptor { if (isRequestAuthorized(theRequestDetails)) { return; } + if (isAllowListedRequest(theRequestDetails)) { + return; + } IdentityHashMap alreadySeenResources = getAlreadySeenResourcesMap(theRequestDetails); @@ -330,4 +345,16 @@ public class ConsentInterceptor { } return new ForbiddenOperationException("Rejected by consent service", operationOutcome); } + + private boolean isAllowListedRequest(RequestDetails theRequestDetails) { + return isMetadataPath(theRequestDetails) || isMetaOperation(theRequestDetails); + } + + private boolean isMetaOperation(RequestDetails theRequestDetails) { + return META_OPERATION_NAME.equals(theRequestDetails.getOperation()); + } + + private boolean isMetadataPath(RequestDetails theRequestDetails) { + return URL_TOKEN_METADATA.equals(theRequestDetails.getRequestPath()); + } } diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/interceptor/ConsentInterceptorTest.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/interceptor/ConsentInterceptorTest.java index 077eddc20ec..6c880e0f2df 100644 --- a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/interceptor/ConsentInterceptorTest.java +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/interceptor/ConsentInterceptorTest.java @@ -2,6 +2,8 @@ package ca.uhn.fhir.rest.server.interceptor; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.api.BundleInclusionRule; +import ca.uhn.fhir.rest.annotation.Operation; +import ca.uhn.fhir.rest.annotation.OperationParam; import ca.uhn.fhir.rest.annotation.RequiredParam; import ca.uhn.fhir.rest.annotation.Search; import ca.uhn.fhir.rest.api.Constants; @@ -11,11 +13,13 @@ import ca.uhn.fhir.rest.param.StringParam; import ca.uhn.fhir.rest.server.FifoMemoryPagingProvider; import ca.uhn.fhir.rest.server.RestfulServer; import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; +import ca.uhn.fhir.rest.server.interceptor.auth.SearchNarrowingInterceptorTest; import ca.uhn.fhir.rest.server.interceptor.consent.ConsentInterceptor; import ca.uhn.fhir.rest.server.interceptor.consent.ConsentOperationStatusEnum; import ca.uhn.fhir.rest.server.interceptor.consent.ConsentOutcome; import ca.uhn.fhir.rest.server.interceptor.consent.IConsentService; import ca.uhn.fhir.rest.server.provider.HashMapResourceProvider; +import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; import ca.uhn.fhir.test.utilities.JettyUtil; import com.google.common.base.Charsets; import org.apache.commons.io.IOUtils; @@ -27,9 +31,11 @@ import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.servlet.ServletHandler; import org.eclipse.jetty.servlet.ServletHolder; +import org.hl7.fhir.instance.model.api.IBaseParameters; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.r4.model.Bundle; import org.hl7.fhir.r4.model.OperationOutcome; +import org.hl7.fhir.r4.model.Parameters; import org.hl7.fhir.r4.model.Patient; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.AfterAll; @@ -70,6 +76,7 @@ public class ConsentInterceptorTest { private static Server ourServer; private static DummyPatientResourceProvider ourPatientProvider; private static IGenericClient ourFhirClient; + private static DummySystemProvider ourSystemProvider; @Mock private IConsentService myConsentSvc; @@ -163,6 +170,28 @@ public class ConsentInterceptorTest { } + @Test + public void testMetadataCallHasChecksSkipped() throws IOException{ + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/metadata"); + try (CloseableHttpResponse status = ourClient.execute(httpGet)) { + assertEquals(200, status.getStatusLine().getStatusCode()); + String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + ourLog.info("Response: {}", responseContent); + } + + httpGet = new HttpGet("http://localhost:" + ourPort + "/$meta"); + try (CloseableHttpResponse status = ourClient.execute(httpGet)) { + assertEquals(200, status.getStatusLine().getStatusCode()); + String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + ourLog.info("Response: {}", responseContent); + } + + verify(myConsentSvc, times(0)).canSeeResource(any(), any(), any()); + verify(myConsentSvc, times(0)).willSeeResource(any(), any(), any()); + verify(myConsentSvc, times(0)).startOperation(any(), any()); + verify(myConsentSvc, times(2)).completeOperationSuccess(any(), any()); + } + @Test public void testSearch_SeeResourceAuthorizesOuterBundle() throws IOException { ourPatientProvider.store((Patient) new Patient().setActive(true).setId("PTA")); @@ -457,11 +486,13 @@ public class ConsentInterceptorTest { ourServer = new Server(0); ourPatientProvider = new DummyPatientResourceProvider(ourCtx); + ourSystemProvider = new DummySystemProvider(); ServletHandler servletHandler = new ServletHandler(); ourServlet = new RestfulServer(ourCtx); ourServlet.setDefaultPrettyPrint(true); ourServlet.setResourceProviders(ourPatientProvider); + ourServlet.registerProvider(ourSystemProvider); ourServlet.setBundleInclusionRule(BundleInclusionRule.BASED_ON_RESOURCE_PRESENCE); ServletHolder servletHolder = new ServletHolder(ourServlet); servletHandler.addServletWithMapping(servletHolder, "/*"); @@ -478,4 +509,15 @@ public class ConsentInterceptorTest { ourFhirClient = ourCtx.newRestfulGenericClient("http://localhost:" + ourPort); } + private static class DummySystemProvider{ + + @Operation(name = "$meta", idempotent = true, returnParameters = { + @OperationParam(name = "return", typeName = "Meta") + }) + public IBaseParameters meta(ServletRequestDetails theRequestDetails) { + Parameters retval = new Parameters(); + retval.addParameter("Meta", "Yes"); + return retval; + } + } } From d6252526c35d247f7b0a0c6683aaa61eb2242299 Mon Sep 17 00:00:00 2001 From: Tadgh Date: Tue, 11 May 2021 10:53:10 -0400 Subject: [PATCH 2/8] Move member variable --- .../jpa/provider/BaseJpaResourceProvider.java | 2 +- .../provider/JpaResourceProviderDstu2.java | 30 ------------------- .../jpa/provider/JpaSystemProviderDstu2.java | 3 +- .../dstu3/JpaResourceProviderDstu3.java | 28 ----------------- .../dstu3/JpaSystemProviderDstu3.java | 17 ++--------- .../provider/r4/JpaResourceProviderR4.java | 27 ----------------- .../jpa/provider/r4/JpaSystemProviderR4.java | 3 +- .../provider/r5/JpaResourceProviderR5.java | 27 ----------------- .../jpa/provider/r5/JpaSystemProviderR5.java | 15 ++-------- .../uhn/fhir/jpa/model/util/JpaConstants.java | 4 --- .../consent/ConsentInterceptor.java | 1 - .../server/provider/ProviderConstants.java | 4 +++ 12 files changed, 13 insertions(+), 148 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/BaseJpaResourceProvider.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/BaseJpaResourceProvider.java index 307625c456a..887b2cd2b46 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/BaseJpaResourceProvider.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/BaseJpaResourceProvider.java @@ -61,7 +61,7 @@ import org.springframework.beans.factory.annotation.Required; import javax.servlet.http.HttpServletRequest; import java.util.Date; -import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_META; +import static ca.uhn.fhir.rest.server.provider.ProviderConstants.OPERATION_META; import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_META_ADD; import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_META_DELETE; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/JpaResourceProviderDstu2.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/JpaResourceProviderDstu2.java index 53f0ca41d3e..165d30a3be0 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/JpaResourceProviderDstu2.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/JpaResourceProviderDstu2.java @@ -21,37 +21,7 @@ package ca.uhn.fhir.jpa.provider; */ import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; -import ca.uhn.fhir.jpa.model.util.JpaConstants; import ca.uhn.fhir.model.api.IResource; -import ca.uhn.fhir.model.dstu2.composite.MetaDt; -import ca.uhn.fhir.model.dstu2.resource.Parameters; -import ca.uhn.fhir.model.primitive.BooleanDt; -import ca.uhn.fhir.model.primitive.IdDt; -import ca.uhn.fhir.model.primitive.IntegerDt; -import ca.uhn.fhir.rest.annotation.ConditionalUrlParam; -import ca.uhn.fhir.rest.annotation.Create; -import ca.uhn.fhir.rest.annotation.Delete; -import ca.uhn.fhir.rest.annotation.IdParam; -import ca.uhn.fhir.rest.annotation.Operation; -import ca.uhn.fhir.rest.annotation.OperationParam; -import ca.uhn.fhir.rest.annotation.ResourceParam; -import ca.uhn.fhir.rest.annotation.Update; -import ca.uhn.fhir.rest.annotation.Validate; -import ca.uhn.fhir.rest.api.EncodingEnum; -import ca.uhn.fhir.rest.api.MethodOutcome; -import ca.uhn.fhir.rest.api.ValidationModeEnum; -import ca.uhn.fhir.rest.api.server.RequestDetails; -import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; -import org.hl7.fhir.instance.model.api.IIdType; - -import javax.servlet.http.HttpServletRequest; - -import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_DELETED_RESOURCES; -import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_PREVIOUS_VERSIONS; -import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_EXPUNGE_PARAM_LIMIT; -import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_META; -import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_META_ADD; -import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_META_DELETE; public class JpaResourceProviderDstu2 extends BaseJpaResourceProvider { diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/JpaSystemProviderDstu2.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/JpaSystemProviderDstu2.java index b7c5f32596b..1c784824f4e 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/JpaSystemProviderDstu2.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/JpaSystemProviderDstu2.java @@ -14,6 +14,7 @@ import ca.uhn.fhir.rest.annotation.OperationParam; import ca.uhn.fhir.rest.annotation.Transaction; import ca.uhn.fhir.rest.annotation.TransactionParam; import ca.uhn.fhir.rest.api.server.RequestDetails; +import ca.uhn.fhir.rest.server.provider.ProviderConstants; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; import org.hl7.fhir.r4.model.IntegerType; import org.springframework.beans.factory.annotation.Autowired; @@ -163,7 +164,7 @@ public class JpaSystemProviderDstu2 extends BaseJpaSystemProviderDstu2Plus extends BaseJpaResourceProvider { diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/JpaSystemProviderDstu3.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/JpaSystemProviderDstu3.java index 18f89c03889..e622c3d82dc 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/JpaSystemProviderDstu3.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/JpaSystemProviderDstu3.java @@ -1,42 +1,29 @@ package ca.uhn.fhir.jpa.provider.dstu3; import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao; -import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc; import ca.uhn.fhir.jpa.model.util.JpaConstants; import ca.uhn.fhir.jpa.provider.BaseJpaSystemProviderDstu2Plus; import ca.uhn.fhir.model.api.annotation.Description; -import ca.uhn.fhir.rest.annotation.IdParam; import ca.uhn.fhir.rest.annotation.Operation; import ca.uhn.fhir.rest.annotation.OperationParam; import ca.uhn.fhir.rest.annotation.Transaction; import ca.uhn.fhir.rest.annotation.TransactionParam; import ca.uhn.fhir.rest.api.server.RequestDetails; -import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; -import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; +import ca.uhn.fhir.rest.server.provider.ProviderConstants; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; -import org.hl7.fhir.dstu3.model.BooleanType; import org.hl7.fhir.dstu3.model.Bundle; -import org.hl7.fhir.dstu3.model.DecimalType; import org.hl7.fhir.dstu3.model.IntegerType; import org.hl7.fhir.dstu3.model.Meta; import org.hl7.fhir.dstu3.model.Parameters; -import org.hl7.fhir.dstu3.model.Parameters.ParametersParameterComponent; -import org.hl7.fhir.dstu3.model.StringType; -import org.hl7.fhir.exceptions.FHIRException; -import org.hl7.fhir.instance.model.api.IBaseBundle; -import org.hl7.fhir.instance.model.api.IIdType; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; -import javax.servlet.http.HttpServletRequest; import java.util.Collections; -import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.TreeMap; import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; -import static org.apache.commons.lang3.StringUtils.isBlank; import static org.hl7.fhir.convertors.conv30_40.Parameters30_40.convertParameters; /* @@ -174,7 +161,7 @@ public class JpaSystemProviderDstu3 extends BaseJpaSystemProviderDstu2Plus extends BaseJpaResourceProvider { diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r4/JpaSystemProviderR4.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r4/JpaSystemProviderR4.java index b77a4a05c54..a5dac12a4d6 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r4/JpaSystemProviderR4.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r4/JpaSystemProviderR4.java @@ -9,6 +9,7 @@ import ca.uhn.fhir.rest.annotation.OperationParam; import ca.uhn.fhir.rest.annotation.Transaction; import ca.uhn.fhir.rest.annotation.TransactionParam; import ca.uhn.fhir.rest.api.server.RequestDetails; +import ca.uhn.fhir.rest.server.provider.ProviderConstants; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; import org.hl7.fhir.r4.model.Bundle; import org.hl7.fhir.r4.model.IntegerType; @@ -159,7 +160,7 @@ public class JpaSystemProviderR4 extends BaseJpaSystemProviderDstu2Plus extends BaseJpaResourceProvider { diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r5/JpaSystemProviderR5.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r5/JpaSystemProviderR5.java index 631645099b4..73df5644272 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r5/JpaSystemProviderR5.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r5/JpaSystemProviderR5.java @@ -1,40 +1,29 @@ package ca.uhn.fhir.jpa.provider.r5; import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao; -import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc; import ca.uhn.fhir.jpa.model.util.JpaConstants; import ca.uhn.fhir.jpa.provider.BaseJpaSystemProviderDstu2Plus; import ca.uhn.fhir.model.api.annotation.Description; -import ca.uhn.fhir.rest.annotation.IdParam; import ca.uhn.fhir.rest.annotation.Operation; import ca.uhn.fhir.rest.annotation.OperationParam; import ca.uhn.fhir.rest.annotation.Transaction; import ca.uhn.fhir.rest.annotation.TransactionParam; import ca.uhn.fhir.rest.api.server.RequestDetails; -import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; +import ca.uhn.fhir.rest.server.provider.ProviderConstants; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; -import org.hl7.fhir.instance.model.api.IBaseBundle; -import org.hl7.fhir.instance.model.api.IIdType; -import org.hl7.fhir.r5.model.BooleanType; import org.hl7.fhir.r5.model.Bundle; -import org.hl7.fhir.r5.model.DecimalType; import org.hl7.fhir.r5.model.IntegerType; import org.hl7.fhir.r5.model.Meta; import org.hl7.fhir.r5.model.Parameters; -import org.hl7.fhir.r5.model.Parameters.ParametersParameterComponent; -import org.hl7.fhir.r5.model.StringType; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; -import javax.servlet.http.HttpServletRequest; import java.util.Collections; -import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.TreeMap; import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; -import static org.apache.commons.lang3.StringUtils.isBlank; /* * #%L @@ -171,7 +160,7 @@ public class JpaSystemProviderR5 extends BaseJpaSystemProviderDstu2Plus Date: Tue, 11 May 2021 10:53:36 -0400 Subject: [PATCH 3/8] Reflect move in comparison --- .../rest/server/interceptor/consent/ConsentInterceptor.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/consent/ConsentInterceptor.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/consent/ConsentInterceptor.java index a3401dc8e59..536636952cc 100644 --- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/consent/ConsentInterceptor.java +++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/consent/ConsentInterceptor.java @@ -45,6 +45,7 @@ import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import static ca.uhn.fhir.rest.api.Constants.URL_TOKEN_METADATA; +import static ca.uhn.fhir.rest.server.provider.ProviderConstants.OPERATION_META; @Interceptor public class ConsentInterceptor { @@ -350,7 +351,7 @@ public class ConsentInterceptor { } private boolean isMetaOperation(RequestDetails theRequestDetails) { - return META_OPERATION_NAME.equals(theRequestDetails.getOperation()); + return OPERATION_META.equals(theRequestDetails.getOperation()); } private boolean isMetadataPath(RequestDetails theRequestDetails) { From d70b1866c1be42b33d4909f21a52534f897497a6 Mon Sep 17 00:00:00 2001 From: Tadgh Date: Tue, 11 May 2021 10:54:14 -0400 Subject: [PATCH 4/8] Remvoe dead space --- .../uhn/hapi/fhir/changelog/5_4_0/2648-consent-on-metadata.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_4_0/2648-consent-on-metadata.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_4_0/2648-consent-on-metadata.yaml index 4896f5333f7..1f92f6edbe7 100644 --- a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_4_0/2648-consent-on-metadata.yaml +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_4_0/2648-consent-on-metadata.yaml @@ -2,5 +2,3 @@ type: change issue: 2648 title: "The ConsentInterceptor no longer fully runs on calls to `/metadata` or during the `$meta` operation." - - From 316e7e0d6dc7e17ae732540bd5a7235ad098851a Mon Sep 17 00:00:00 2001 From: Ken Stevens Date: Wed, 12 May 2021 21:38:29 -0400 Subject: [PATCH 5/8] Ks 20210512 value set expansion id (#2654) * tested and fixed * changelog --- .../fhir/changelog/5_4_0/2654-value-set-expansion-id.yaml | 5 +++++ .../main/java/ca/uhn/fhir/jpa/term/BaseTermReadSvcImpl.java | 3 ++- .../r4/ResourceProviderR4ValueSetVerCSNoVerTest.java | 6 +++--- 3 files changed, 10 insertions(+), 4 deletions(-) create mode 100644 hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_4_0/2654-value-set-expansion-id.yaml diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_4_0/2654-value-set-expansion-id.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_4_0/2654-value-set-expansion-id.yaml new file mode 100644 index 00000000000..3f360af2d2a --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_4_0/2654-value-set-expansion-id.yaml @@ -0,0 +1,5 @@ +--- +type: fix +issue: 2654 +title: "The id of ValueSet resources in ValueSet expansions was null. This has been corrected. The id of the expanded +value set is now the same as the id of the value set that was expanded." diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/BaseTermReadSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/BaseTermReadSvcImpl.java index b66ec988a8e..3d8c9f0ce28 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/BaseTermReadSvcImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/BaseTermReadSvcImpl.java @@ -420,6 +420,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc { } ValueSet valueSet = new ValueSet(); + valueSet.setId(theValueSetToExpand.getId()); valueSet.setStatus(Enumerations.PublicationStatus.ACTIVE); valueSet.setCompose(theValueSetToExpand.getCompose()); valueSet.setExpansion(accumulator); @@ -1765,7 +1766,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc { return null; }); - ourLog.info("Pre-expanded ValueSet[{}] with URL[{}] - Saved {} concepts in {}", valueSet.getId(), valueSet.getUrl(), accumulator.getConceptsSaved(), sw.toString()); + ourLog.info("Pre-expanded ValueSet[{}] with URL[{}] - Saved {} concepts in {}", valueSet.getId(), valueSet.getUrl(), accumulator.getConceptsSaved(), sw); } catch (Exception e) { ourLog.error("Failed to pre-expand ValueSet: " + e.getMessage(), e); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ValueSetVerCSNoVerTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ValueSetVerCSNoVerTest.java index e55fcbadf86..811786e9c5a 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ValueSetVerCSNoVerTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ValueSetVerCSNoVerTest.java @@ -8,7 +8,6 @@ import ca.uhn.fhir.jpa.entity.TermConcept; import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink.RelationshipTypeEnum; import ca.uhn.fhir.jpa.entity.TermValueSet; import ca.uhn.fhir.jpa.entity.TermValueSetConcept; -import ca.uhn.fhir.jpa.entity.TermValueSetConceptDesignation; import ca.uhn.fhir.jpa.entity.TermValueSetPreExpansionStatusEnum; import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc; @@ -706,6 +705,7 @@ public class ResourceProviderR4ValueSetVerCSNoVerTest extends BaseResourceProvid .execute(); ourLog.info("Expanded: {}", myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(expanded)); assertEquals(1, expanded.getExpansion().getContains().size()); + assertNotNull(expanded.getId()); } @Test @@ -791,7 +791,7 @@ public class ResourceProviderR4ValueSetVerCSNoVerTest extends BaseResourceProvid TermValueSet termValueSet = optionalValueSetByUrl.get(); assertSame(optionalValueSetByResourcePid.get(), termValueSet); - ourLog.info("ValueSet:\n" + termValueSet.toString()); + ourLog.info("ValueSet:\n" + termValueSet); assertEquals("http://www.healthintersections.com.au/fhir/ValueSet/extensional-case-2", termValueSet.getUrl()); assertEquals(theValueSetName, termValueSet.getName()); assertEquals(0, termValueSet.getConcepts().size()); @@ -809,7 +809,7 @@ public class ResourceProviderR4ValueSetVerCSNoVerTest extends BaseResourceProvid TermValueSet termValueSet = optionalValueSetByUrl.get(); assertSame(optionalValueSetByResourcePid.get(), termValueSet); - ourLog.info("ValueSet:\n" + termValueSet.toString()); + ourLog.info("ValueSet:\n" + termValueSet); assertEquals("http://www.healthintersections.com.au/fhir/ValueSet/extensional-case-2", termValueSet.getUrl()); assertEquals(theValueSetName, termValueSet.getName()); assertEquals(theCodeSystem.getConcept().size(), termValueSet.getConcepts().size()); From 3428d710233c123470654821cb80d0eee49d22b7 Mon Sep 17 00:00:00 2001 From: Tadgh Date: Thu, 13 May 2021 10:29:07 -0400 Subject: [PATCH 6/8] Add toggle. Add test. Add changelog. add docs --- ...655-configurable-internal-search-size.yaml | 5 +++ .../fhir/docs/server_jpa/configuration.md | 4 +++ .../ca/uhn/fhir/jpa/api/config/DaoConfig.java | 26 +++++++++++++++ .../fhir/jpa/dao/BaseHapiFhirResourceDao.java | 2 +- .../jpa/dao/expunge/DeleteExpungeService.java | 2 -- .../dao/expunge/DeleteExpungeServiceTest.java | 33 +++++++++++++++++++ .../jpa/dao/r4/FhirResourceDaoR4Test.java | 1 + 7 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_4_0/2655-configurable-internal-search-size.yaml diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_4_0/2655-configurable-internal-search-size.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_4_0/2655-configurable-internal-search-size.yaml new file mode 100644 index 00000000000..bb2250718e7 --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_4_0/2655-configurable-internal-search-size.yaml @@ -0,0 +1,5 @@ +--- +type: change +issue: 2655 +title: "Added a new configuration option to DaoConfig, `setInternalSynchronousSearchSize()`, this controls the loadSynchronousUpTo() + during internal operations such as delete with expunge, and certain CodeSystem searches." diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/configuration.md b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/configuration.md index d8e759edd5f..26f2b4d77ce 100644 --- a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/configuration.md +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/configuration.md @@ -126,3 +126,7 @@ With this interceptor in place, the following header can be added to individual ```http X-Retry-On-Version-Conflict: retry; max-retries=100 ``` + +# Controlling Delete with Expunge size + +During delete with expunge operations there is an internal synchronous search which locates all the resources to be deleted. By default the maximum size of this search is 10000. This can be configured via the [Internal Synchronous Search Size](/hapi-fhir/apidocs/hapi-fhir-jpaserver-api/ca/uhn/fhir/jpa/api/config/DaoConfig.html#setInternalSynchronousSearchSize(int)) diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/config/DaoConfig.java b/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/config/DaoConfig.java index b418a5d8e08..52b9e5d1a1d 100644 --- a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/config/DaoConfig.java +++ b/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/config/DaoConfig.java @@ -89,6 +89,7 @@ public class DaoConfig { /** * Child Configurations */ + private static final Integer DEFAULT_INTERNAL_SYNCHRONOUS_SEARCH_SIZE = 10000; private final ModelConfig myModelConfig = new ModelConfig(); /** @@ -155,6 +156,7 @@ public class DaoConfig { private boolean myFilterParameterEnabled = false; private StoreMetaSourceInformationEnum myStoreMetaSourceInformation = StoreMetaSourceInformationEnum.SOURCE_URI_AND_REQUEST_ID; private HistoryCountModeEnum myHistoryCountMode = DEFAULT_HISTORY_COUNT_MODE; + private int myInternalSynchronousSearchSize = DEFAULT_INTERNAL_SYNCHRONOUS_SEARCH_SIZE; /** * update setter javadoc if default changes @@ -2181,6 +2183,30 @@ public class DaoConfig { // ignore } + /** + *

+ * This determines the internal search size that is run synchronously during operations such as: + * 1. Delete with _expunge parameter. + * 2. Searching for Code System IDs by System and Code + *

+ * @since 5.4.0 + */ + public Integer getInternalSynchronousSearchSize() { + return myInternalSynchronousSearchSize; + } + + /** + *

+ * This determines the internal search size that is run synchronously during operations such as: + * 1. Delete with _expunge parameter. + * 2. Searching for Code System IDs by System and Code + *

+ * @since 5.4.0 + */ + public void setInternalSynchronousSearchSize(Integer theInternalSynchronousSearchSize) { + myInternalSynchronousSearchSize = theInternalSynchronousSearchSize; + } + public enum StoreMetaSourceInformationEnum { NONE(false, false), SOURCE_URI(true, false), diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java index 2287c17b97e..f0e2d39aa8c 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java @@ -1446,7 +1446,7 @@ public abstract class BaseHapiFhirResourceDao extends B @Override public Set searchForIds(SearchParameterMap theParams, RequestDetails theRequest) { return myTransactionService.execute(theRequest, tx -> { - theParams.setLoadSynchronousUpTo(10000); + theParams.setLoadSynchronousUpTo(myDaoConfig.getInternalSynchronousSearchSize()); ISearchBuilder builder = mySearchBuilderFactory.newSearchBuilder(this, getResourceName(), getResourceType()); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeService.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeService.java index 8f93ce690e5..bf780638986 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeService.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeService.java @@ -69,8 +69,6 @@ public class DeleteExpungeService { @Autowired private ResourceTableFKProvider myResourceTableFKProvider; @Autowired - private IResourceTableDao myResourceTableDao; - @Autowired private IResourceLinkDao myResourceLinkDao; @Autowired private IInterceptorBroadcaster myInterceptorBroadcaster; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeServiceTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeServiceTest.java index dda5d92be0f..e06676f8038 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeServiceTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeServiceTest.java @@ -4,6 +4,8 @@ import ca.uhn.fhir.jpa.api.config.DaoConfig; import ca.uhn.fhir.jpa.api.model.DeleteMethodOutcome; import ca.uhn.fhir.jpa.dao.r4.BaseJpaR4Test; import ca.uhn.fhir.jpa.model.util.JpaConstants; +import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; +import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.r4.model.Organization; @@ -16,8 +18,12 @@ import org.springframework.beans.factory.annotation.Autowired; import java.util.List; +import static org.hamcrest.Matchers.hasSize; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; class DeleteExpungeServiceTest extends BaseJpaR4Test { @@ -29,6 +35,8 @@ class DeleteExpungeServiceTest extends BaseJpaR4Test { myDaoConfig.setAllowMultipleDelete(true); myDaoConfig.setExpungeEnabled(true); myDaoConfig.setDeleteExpungeEnabled(true); + myDaoConfig.setInternalSynchronousSearchSize(new DaoConfig().getInternalSynchronousSearchSize()); + } @AfterEach @@ -57,6 +65,31 @@ class DeleteExpungeServiceTest extends BaseJpaR4Test { assertEquals(e.getMessage(), "DELETE with _expunge=true failed. Unable to delete " + organizationId.toVersionless() + " because " + patientId.toVersionless() + " refers to it via the path Patient.managingOrganization"); } } + @Test + public void testDeleteExpungeRespectsSynchronousSize() { + //When + myDaoConfig.setInternalSynchronousSearchSize(1); + + Patient patient = new Patient(); + myPatientDao.create(patient); + + Patient otherPatient = new Patient(); + myPatientDao.create(otherPatient); + + + //Then + DeleteMethodOutcome deleteMethodOutcome = myPatientDao.deleteByUrl("Patient?" + JpaConstants.PARAM_DELETE_EXPUNGE + "=true", mySrd); + assertThat(deleteMethodOutcome.getExpungedResourcesCount(), is(equalTo(1L))); + + IBundleProvider search = myPatientDao.search(new SearchParameterMap().setLoadSynchronous(true)); + assertThat(search.size(), is(equalTo(1))); + + deleteMethodOutcome = myPatientDao.deleteByUrl("Patient?" + JpaConstants.PARAM_DELETE_EXPUNGE + "=true", mySrd); + assertThat(deleteMethodOutcome.getExpungedResourcesCount(), is(equalTo(1L))); + + search = myPatientDao.search(new SearchParameterMap().setLoadSynchronous(true)); + assertThat(search.size(), is(equalTo(0))); + } @Test public void testDeleteExpungeNoThrowExceptionWhenLinkInSearchResults() { diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4Test.java index 19093ac9ef6..d63231787fd 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4Test.java @@ -162,6 +162,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test { myDaoConfig.setEnforceReferentialIntegrityOnDelete(new DaoConfig().isEnforceReferentialIntegrityOnDelete()); myDaoConfig.setEnforceReferenceTargetTypes(new DaoConfig().isEnforceReferenceTargetTypes()); myDaoConfig.setIndexMissingFields(new DaoConfig().getIndexMissingFields()); + myDaoConfig.setInternalSynchronousSearchSize(new DaoConfig().getInternalSynchronousSearchSize()); myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED); myDaoConfig.setHistoryCountMode(DaoConfig.DEFAULT_HISTORY_COUNT_MODE); } From 15ea4fb55527e97a01e1b669ad65d5665a48fd4e Mon Sep 17 00:00:00 2001 From: Tadgh Date: Thu, 13 May 2021 10:47:26 -0400 Subject: [PATCH 7/8] Tidy test --- .../fhir/docs/server_jpa/configuration.md | 2 +- .../dao/expunge/DeleteExpungeServiceTest.java | 21 ++++++++++--------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/configuration.md b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/configuration.md index 26f2b4d77ce..0800e823f6d 100644 --- a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/configuration.md +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/configuration.md @@ -129,4 +129,4 @@ X-Retry-On-Version-Conflict: retry; max-retries=100 # Controlling Delete with Expunge size -During delete with expunge operations there is an internal synchronous search which locates all the resources to be deleted. By default the maximum size of this search is 10000. This can be configured via the [Internal Synchronous Search Size](/hapi-fhir/apidocs/hapi-fhir-jpaserver-api/ca/uhn/fhir/jpa/api/config/DaoConfig.html#setInternalSynchronousSearchSize(int)) +During the delete with expunge operation there is an internal synchronous search which locates all the resources to be deleted. The default maximum size of this search is 10000. This can be configured via the [Internal Synchronous Search Size](/hapi-fhir/apidocs/hapi-fhir-jpaserver-api/ca/uhn/fhir/jpa/api/config/DaoConfig.html#setInternalSynchronousSearchSize(int)) property. diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeServiceTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeServiceTest.java index e06676f8038..bccfb85a692 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeServiceTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeServiceTest.java @@ -67,28 +67,29 @@ class DeleteExpungeServiceTest extends BaseJpaR4Test { } @Test public void testDeleteExpungeRespectsSynchronousSize() { - //When + //Given myDaoConfig.setInternalSynchronousSearchSize(1); - Patient patient = new Patient(); myPatientDao.create(patient); - Patient otherPatient = new Patient(); myPatientDao.create(otherPatient); - //Then + //When DeleteMethodOutcome deleteMethodOutcome = myPatientDao.deleteByUrl("Patient?" + JpaConstants.PARAM_DELETE_EXPUNGE + "=true", mySrd); + IBundleProvider remaining = myPatientDao.search(new SearchParameterMap().setLoadSynchronous(true)); + + //Then assertThat(deleteMethodOutcome.getExpungedResourcesCount(), is(equalTo(1L))); + assertThat(remaining.size(), is(equalTo(1))); - IBundleProvider search = myPatientDao.search(new SearchParameterMap().setLoadSynchronous(true)); - assertThat(search.size(), is(equalTo(1))); - + //When deleteMethodOutcome = myPatientDao.deleteByUrl("Patient?" + JpaConstants.PARAM_DELETE_EXPUNGE + "=true", mySrd); - assertThat(deleteMethodOutcome.getExpungedResourcesCount(), is(equalTo(1L))); + remaining = myPatientDao.search(new SearchParameterMap().setLoadSynchronous(true)); - search = myPatientDao.search(new SearchParameterMap().setLoadSynchronous(true)); - assertThat(search.size(), is(equalTo(0))); + //Then + assertThat(deleteMethodOutcome.getExpungedResourcesCount(), is(equalTo(1L))); + assertThat(remaining.size(), is(equalTo(0))); } @Test From 57bb11797e16e19af612b2667a59030e18e29c7d Mon Sep 17 00:00:00 2001 From: Tadgh Date: Thu, 13 May 2021 15:46:26 -0400 Subject: [PATCH 8/8] fix --- .../resources/ca/uhn/hapi/fhir/docs/server_jpa/configuration.md | 2 +- .../ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeServiceTest.java | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/configuration.md b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/configuration.md index 0800e823f6d..ef3881dddfc 100644 --- a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/configuration.md +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/configuration.md @@ -129,4 +129,4 @@ X-Retry-On-Version-Conflict: retry; max-retries=100 # Controlling Delete with Expunge size -During the delete with expunge operation there is an internal synchronous search which locates all the resources to be deleted. The default maximum size of this search is 10000. This can be configured via the [Internal Synchronous Search Size](/hapi-fhir/apidocs/hapi-fhir-jpaserver-api/ca/uhn/fhir/jpa/api/config/DaoConfig.html#setInternalSynchronousSearchSize(int)) property. +During the delete with expunge operation there is an internal synchronous search which locates all the resources to be deleted. The default maximum size of this search is 10000. This can be configured via the [Internal Synchronous Search Size](/hapi-fhir/apidocs/hapi-fhir-jpaserver-api/ca/uhn/fhir/jpa/api/config/DaoConfig.html#setInternalSynchronousSearchSize(java.lang.Integer)) property. diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeServiceTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeServiceTest.java index bccfb85a692..45503106d66 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeServiceTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeServiceTest.java @@ -74,7 +74,6 @@ class DeleteExpungeServiceTest extends BaseJpaR4Test { Patient otherPatient = new Patient(); myPatientDao.create(otherPatient); - //When DeleteMethodOutcome deleteMethodOutcome = myPatientDao.deleteByUrl("Patient?" + JpaConstants.PARAM_DELETE_EXPUNGE + "=true", mySrd); IBundleProvider remaining = myPatientDao.search(new SearchParameterMap().setLoadSynchronous(true));