Merge branch 'rel_5_4'

This commit is contained in:
jamesagnew 2021-05-17 09:10:58 -04:00
commit 926bf393d3
26 changed files with 174 additions and 154 deletions

View File

@ -82,6 +82,10 @@ public class FhirServerConfigCommon {
logger.error("----FhiServerConfigCommon: getDataSource: setting driver error: " + e.getMessage()); logger.error("----FhiServerConfigCommon: getDataSource: setting driver error: " + e.getMessage());
} }
dataSource.setUrl(dbUrl); dataSource.setUrl(dbUrl);
// A check for WS-2020-0287
assert dataSource.getJmxName() == null;
return dataSource; return dataSource;
} }

View File

@ -0,0 +1,4 @@
---
type: change
issue: 2648
title: "The ConsentInterceptor no longer fully runs on calls to `/metadata` or during the `$meta` operation."

View File

@ -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."

View File

@ -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."

View File

@ -126,3 +126,7 @@ With this interceptor in place, the following header can be added to individual
```http ```http
X-Retry-On-Version-Conflict: retry; max-retries=100 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(java.lang.Integer)) property.

View File

@ -97,6 +97,7 @@ public class DaoConfig {
/** /**
* Child Configurations * Child Configurations
*/ */
private static final Integer DEFAULT_INTERNAL_SYNCHRONOUS_SEARCH_SIZE = 10000;
private final ModelConfig myModelConfig = new ModelConfig(); private final ModelConfig myModelConfig = new ModelConfig();
/** /**
@ -163,6 +164,7 @@ public class DaoConfig {
private boolean myFilterParameterEnabled = false; private boolean myFilterParameterEnabled = false;
private StoreMetaSourceInformationEnum myStoreMetaSourceInformation = StoreMetaSourceInformationEnum.SOURCE_URI_AND_REQUEST_ID; private StoreMetaSourceInformationEnum myStoreMetaSourceInformation = StoreMetaSourceInformationEnum.SOURCE_URI_AND_REQUEST_ID;
private HistoryCountModeEnum myHistoryCountMode = DEFAULT_HISTORY_COUNT_MODE; private HistoryCountModeEnum myHistoryCountMode = DEFAULT_HISTORY_COUNT_MODE;
private int myInternalSynchronousSearchSize = DEFAULT_INTERNAL_SYNCHRONOUS_SEARCH_SIZE;
/** /**
* update setter javadoc if default changes * update setter javadoc if default changes
@ -2217,6 +2219,31 @@ public class DaoConfig {
// ignore // ignore
} }
/**
* <p>
* 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
* </p>
* @since 5.4.0
*/
public Integer getInternalSynchronousSearchSize() {
return myInternalSynchronousSearchSize;
}
/**
* <p>
* 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
* </p>
* @since 5.4.0
*/
public void setInternalSynchronousSearchSize(Integer theInternalSynchronousSearchSize) {
myInternalSynchronousSearchSize = theInternalSynchronousSearchSize;
}
/** /**
* If this is enabled (this is the default), this server will attempt to activate and run <b>Bulk Import</b> * If this is enabled (this is the default), this server will attempt to activate and run <b>Bulk Import</b>
* batch jobs. Otherwise, this server will not. * batch jobs. Otherwise, this server will not.

View File

@ -1447,7 +1447,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
@Override @Override
public Set<ResourcePersistentId> searchForIds(SearchParameterMap theParams, RequestDetails theRequest) { public Set<ResourcePersistentId> searchForIds(SearchParameterMap theParams, RequestDetails theRequest) {
return myTransactionService.execute(theRequest, tx -> { return myTransactionService.execute(theRequest, tx -> {
theParams.setLoadSynchronousUpTo(10000); theParams.setLoadSynchronousUpTo(myDaoConfig.getInternalSynchronousSearchSize());
ISearchBuilder builder = mySearchBuilderFactory.newSearchBuilder(this, getResourceName(), getResourceType()); ISearchBuilder builder = mySearchBuilderFactory.newSearchBuilder(this, getResourceName(), getResourceType());

View File

@ -69,8 +69,6 @@ public class DeleteExpungeService {
@Autowired @Autowired
private ResourceTableFKProvider myResourceTableFKProvider; private ResourceTableFKProvider myResourceTableFKProvider;
@Autowired @Autowired
private IResourceTableDao myResourceTableDao;
@Autowired
private IResourceLinkDao myResourceLinkDao; private IResourceLinkDao myResourceLinkDao;
@Autowired @Autowired
private IInterceptorBroadcaster myInterceptorBroadcaster; private IInterceptorBroadcaster myInterceptorBroadcaster;

View File

@ -61,7 +61,7 @@ import org.springframework.beans.factory.annotation.Required;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.Date; 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_ADD;
import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_META_DELETE; import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_META_DELETE;

View File

@ -21,37 +21,7 @@ package ca.uhn.fhir.jpa.provider;
*/ */
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; 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.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<T extends IResource> extends BaseJpaResourceProvider<T> { public class JpaResourceProviderDstu2<T extends IResource> extends BaseJpaResourceProvider<T> {

View File

@ -14,6 +14,7 @@ import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.annotation.Transaction; import ca.uhn.fhir.rest.annotation.Transaction;
import ca.uhn.fhir.rest.annotation.TransactionParam; import ca.uhn.fhir.rest.annotation.TransactionParam;
import ca.uhn.fhir.rest.api.server.RequestDetails; 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 ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import org.hl7.fhir.r4.model.IntegerType; import org.hl7.fhir.r4.model.IntegerType;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -163,7 +164,7 @@ public class JpaSystemProviderDstu2 extends BaseJpaSystemProviderDstu2Plus<Bundl
return retVal; return retVal;
} }
@Operation(name = JpaConstants.OPERATION_META, idempotent = true, returnParameters = { @Operation(name = ProviderConstants.OPERATION_META, idempotent = true, returnParameters = {
@OperationParam(name = "return", type = MetaDt.class) @OperationParam(name = "return", type = MetaDt.class)
}) })
public Parameters meta(RequestDetails theRequestDetails) { public Parameters meta(RequestDetails theRequestDetails) {

View File

@ -21,37 +21,9 @@ package ca.uhn.fhir.jpa.provider.dstu3;
*/ */
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.provider.BaseJpaResourceProvider; import ca.uhn.fhir.jpa.provider.BaseJpaResourceProvider;
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.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import org.hl7.fhir.dstu3.model.BooleanType;
import org.hl7.fhir.dstu3.model.IdType;
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.exceptions.FHIRException;
import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IIdType;
import javax.servlet.http.HttpServletRequest;
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;
import static org.hl7.fhir.convertors.conv30_40.Parameters30_40.convertParameters; import static org.hl7.fhir.convertors.conv30_40.Parameters30_40.convertParameters;
public class JpaResourceProviderDstu3<T extends IAnyResource> extends BaseJpaResourceProvider<T> { public class JpaResourceProviderDstu3<T extends IAnyResource> extends BaseJpaResourceProvider<T> {

View File

@ -1,42 +1,29 @@
package ca.uhn.fhir.jpa.provider.dstu3; package ca.uhn.fhir.jpa.provider.dstu3;
import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao; 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.model.util.JpaConstants;
import ca.uhn.fhir.jpa.provider.BaseJpaSystemProviderDstu2Plus; import ca.uhn.fhir.jpa.provider.BaseJpaSystemProviderDstu2Plus;
import ca.uhn.fhir.model.api.annotation.Description; 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.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam; import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.annotation.Transaction; import ca.uhn.fhir.rest.annotation.Transaction;
import ca.uhn.fhir.rest.annotation.TransactionParam; import ca.uhn.fhir.rest.annotation.TransactionParam;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.provider.ProviderConstants;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; 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.Bundle;
import org.hl7.fhir.dstu3.model.DecimalType;
import org.hl7.fhir.dstu3.model.IntegerType; import org.hl7.fhir.dstu3.model.IntegerType;
import org.hl7.fhir.dstu3.model.Meta; import org.hl7.fhir.dstu3.model.Meta;
import org.hl7.fhir.dstu3.model.Parameters; 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.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections; import java.util.Collections;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.TreeMap; import java.util.TreeMap;
import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; 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; import static org.hl7.fhir.convertors.conv30_40.Parameters30_40.convertParameters;
/* /*
@ -174,7 +161,7 @@ public class JpaSystemProviderDstu3 extends BaseJpaSystemProviderDstu2Plus<Bundl
return retVal; return retVal;
} }
@Operation(name = JpaConstants.OPERATION_META, idempotent = true, returnParameters = { @Operation(name = ProviderConstants.OPERATION_META, idempotent = true, returnParameters = {
@OperationParam(name = "return", type = Meta.class) @OperationParam(name = "return", type = Meta.class)
}) })
public Parameters meta(RequestDetails theRequestDetails) { public Parameters meta(RequestDetails theRequestDetails) {

View File

@ -21,35 +21,8 @@ package ca.uhn.fhir.jpa.provider.r4;
*/ */
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.provider.BaseJpaResourceProvider; import ca.uhn.fhir.jpa.provider.BaseJpaResourceProvider;
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.IAnyResource; import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.BooleanType;
import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r4.model.IntegerType;
import org.hl7.fhir.r4.model.Meta;
import org.hl7.fhir.r4.model.Parameters;
import javax.servlet.http.HttpServletRequest;
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 JpaResourceProviderR4<T extends IAnyResource> extends BaseJpaResourceProvider<T> { public class JpaResourceProviderR4<T extends IAnyResource> extends BaseJpaResourceProvider<T> {

View File

@ -9,6 +9,7 @@ import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.annotation.Transaction; import ca.uhn.fhir.rest.annotation.Transaction;
import ca.uhn.fhir.rest.annotation.TransactionParam; import ca.uhn.fhir.rest.annotation.TransactionParam;
import ca.uhn.fhir.rest.api.server.RequestDetails; 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 ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import org.hl7.fhir.r4.model.Bundle; import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.IntegerType; import org.hl7.fhir.r4.model.IntegerType;
@ -159,7 +160,7 @@ public class JpaSystemProviderR4 extends BaseJpaSystemProviderDstu2Plus<Bundle,
return retVal; return retVal;
} }
@Operation(name = JpaConstants.OPERATION_META, idempotent = true, returnParameters = { @Operation(name = ProviderConstants.OPERATION_META, idempotent = true, returnParameters = {
@OperationParam(name = "return", type = Meta.class) @OperationParam(name = "return", type = Meta.class)
}) })
public Parameters meta(RequestDetails theRequestDetails) { public Parameters meta(RequestDetails theRequestDetails) {

View File

@ -21,35 +21,8 @@ package ca.uhn.fhir.jpa.provider.r5;
*/ */
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.provider.BaseJpaResourceProvider; import ca.uhn.fhir.jpa.provider.BaseJpaResourceProvider;
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.IAnyResource; import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r5.model.BooleanType;
import org.hl7.fhir.r5.model.IdType;
import org.hl7.fhir.r5.model.IntegerType;
import org.hl7.fhir.r5.model.Meta;
import org.hl7.fhir.r5.model.Parameters;
import javax.servlet.http.HttpServletRequest;
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 JpaResourceProviderR5<T extends IAnyResource> extends BaseJpaResourceProvider<T> { public class JpaResourceProviderR5<T extends IAnyResource> extends BaseJpaResourceProvider<T> {

View File

@ -1,40 +1,29 @@
package ca.uhn.fhir.jpa.provider.r5; package ca.uhn.fhir.jpa.provider.r5;
import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao; 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.model.util.JpaConstants;
import ca.uhn.fhir.jpa.provider.BaseJpaSystemProviderDstu2Plus; import ca.uhn.fhir.jpa.provider.BaseJpaSystemProviderDstu2Plus;
import ca.uhn.fhir.model.api.annotation.Description; 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.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam; import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.annotation.Transaction; import ca.uhn.fhir.rest.annotation.Transaction;
import ca.uhn.fhir.rest.annotation.TransactionParam; import ca.uhn.fhir.rest.annotation.TransactionParam;
import ca.uhn.fhir.rest.api.server.RequestDetails; 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 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.Bundle;
import org.hl7.fhir.r5.model.DecimalType;
import org.hl7.fhir.r5.model.IntegerType; import org.hl7.fhir.r5.model.IntegerType;
import org.hl7.fhir.r5.model.Meta; import org.hl7.fhir.r5.model.Meta;
import org.hl7.fhir.r5.model.Parameters; 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.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections; import java.util.Collections;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.TreeMap; import java.util.TreeMap;
import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
import static org.apache.commons.lang3.StringUtils.isBlank;
/* /*
* #%L * #%L
@ -171,7 +160,7 @@ public class JpaSystemProviderR5 extends BaseJpaSystemProviderDstu2Plus<Bundle,
return retVal; return retVal;
} }
@Operation(name = JpaConstants.OPERATION_META, idempotent = true, returnParameters = { @Operation(name = ProviderConstants.OPERATION_META, idempotent = true, returnParameters = {
@OperationParam(name = "return", type = Meta.class) @OperationParam(name = "return", type = Meta.class)
}) })
public Parameters meta(RequestDetails theRequestDetails) { public Parameters meta(RequestDetails theRequestDetails) {

View File

@ -420,6 +420,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
} }
ValueSet valueSet = new ValueSet(); ValueSet valueSet = new ValueSet();
valueSet.setId(theValueSetToExpand.getId());
valueSet.setStatus(Enumerations.PublicationStatus.ACTIVE); valueSet.setStatus(Enumerations.PublicationStatus.ACTIVE);
valueSet.setCompose(theValueSetToExpand.getCompose()); valueSet.setCompose(theValueSetToExpand.getCompose());
valueSet.setExpansion(accumulator); valueSet.setExpansion(accumulator);
@ -1768,7 +1769,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
return null; 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) { } catch (Exception e) {
ourLog.error("Failed to pre-expand ValueSet: " + e.getMessage(), e); ourLog.error("Failed to pre-expand ValueSet: " + e.getMessage(), e);

View File

@ -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.api.model.DeleteMethodOutcome;
import ca.uhn.fhir.jpa.dao.r4.BaseJpaR4Test; import ca.uhn.fhir.jpa.dao.r4.BaseJpaR4Test;
import ca.uhn.fhir.jpa.model.util.JpaConstants; 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 ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.Organization; import org.hl7.fhir.r4.model.Organization;
@ -16,8 +18,12 @@ import org.springframework.beans.factory.annotation.Autowired;
import java.util.List; 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.assertEquals;
import static org.junit.jupiter.api.Assertions.fail; 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 { class DeleteExpungeServiceTest extends BaseJpaR4Test {
@ -29,6 +35,8 @@ class DeleteExpungeServiceTest extends BaseJpaR4Test {
myDaoConfig.setAllowMultipleDelete(true); myDaoConfig.setAllowMultipleDelete(true);
myDaoConfig.setExpungeEnabled(true); myDaoConfig.setExpungeEnabled(true);
myDaoConfig.setDeleteExpungeEnabled(true); myDaoConfig.setDeleteExpungeEnabled(true);
myDaoConfig.setInternalSynchronousSearchSize(new DaoConfig().getInternalSynchronousSearchSize());
} }
@AfterEach @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"); 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() {
//Given
myDaoConfig.setInternalSynchronousSearchSize(1);
Patient patient = new Patient();
myPatientDao.create(patient);
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));
//Then
assertThat(deleteMethodOutcome.getExpungedResourcesCount(), is(equalTo(1L)));
assertThat(remaining.size(), is(equalTo(1)));
//When
deleteMethodOutcome = myPatientDao.deleteByUrl("Patient?" + JpaConstants.PARAM_DELETE_EXPUNGE + "=true", mySrd);
remaining = myPatientDao.search(new SearchParameterMap().setLoadSynchronous(true));
//Then
assertThat(deleteMethodOutcome.getExpungedResourcesCount(), is(equalTo(1L)));
assertThat(remaining.size(), is(equalTo(0)));
}
@Test @Test
public void testDeleteExpungeNoThrowExceptionWhenLinkInSearchResults() { public void testDeleteExpungeNoThrowExceptionWhenLinkInSearchResults() {

View File

@ -162,6 +162,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
myDaoConfig.setEnforceReferentialIntegrityOnDelete(new DaoConfig().isEnforceReferentialIntegrityOnDelete()); myDaoConfig.setEnforceReferentialIntegrityOnDelete(new DaoConfig().isEnforceReferentialIntegrityOnDelete());
myDaoConfig.setEnforceReferenceTargetTypes(new DaoConfig().isEnforceReferenceTargetTypes()); myDaoConfig.setEnforceReferenceTargetTypes(new DaoConfig().isEnforceReferenceTargetTypes());
myDaoConfig.setIndexMissingFields(new DaoConfig().getIndexMissingFields()); myDaoConfig.setIndexMissingFields(new DaoConfig().getIndexMissingFields());
myDaoConfig.setInternalSynchronousSearchSize(new DaoConfig().getInternalSynchronousSearchSize());
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED); myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED);
myDaoConfig.setHistoryCountMode(DaoConfig.DEFAULT_HISTORY_COUNT_MODE); myDaoConfig.setHistoryCountMode(DaoConfig.DEFAULT_HISTORY_COUNT_MODE);
} }

View File

@ -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.TermConceptParentChildLink.RelationshipTypeEnum;
import ca.uhn.fhir.jpa.entity.TermValueSet; import ca.uhn.fhir.jpa.entity.TermValueSet;
import ca.uhn.fhir.jpa.entity.TermValueSetConcept; 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.entity.TermValueSetPreExpansionStatusEnum;
import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc; import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc;
@ -706,6 +705,7 @@ public class ResourceProviderR4ValueSetVerCSNoVerTest extends BaseResourceProvid
.execute(); .execute();
ourLog.info("Expanded: {}", myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(expanded)); ourLog.info("Expanded: {}", myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(expanded));
assertEquals(1, expanded.getExpansion().getContains().size()); assertEquals(1, expanded.getExpansion().getContains().size());
assertNotNull(expanded.getId());
} }
@Test @Test
@ -791,7 +791,7 @@ public class ResourceProviderR4ValueSetVerCSNoVerTest extends BaseResourceProvid
TermValueSet termValueSet = optionalValueSetByUrl.get(); TermValueSet termValueSet = optionalValueSetByUrl.get();
assertSame(optionalValueSetByResourcePid.get(), termValueSet); 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("http://www.healthintersections.com.au/fhir/ValueSet/extensional-case-2", termValueSet.getUrl());
assertEquals(theValueSetName, termValueSet.getName()); assertEquals(theValueSetName, termValueSet.getName());
assertEquals(0, termValueSet.getConcepts().size()); assertEquals(0, termValueSet.getConcepts().size());
@ -809,7 +809,7 @@ public class ResourceProviderR4ValueSetVerCSNoVerTest extends BaseResourceProvid
TermValueSet termValueSet = optionalValueSetByUrl.get(); TermValueSet termValueSet = optionalValueSetByUrl.get();
assertSame(optionalValueSetByResourcePid.get(), termValueSet); 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("http://www.healthintersections.com.au/fhir/ValueSet/extensional-case-2", termValueSet.getUrl());
assertEquals(theValueSetName, termValueSet.getName()); assertEquals(theValueSetName, termValueSet.getName());
assertEquals(theCodeSystem.getConcept().size(), termValueSet.getConcepts().size()); assertEquals(theCodeSystem.getConcept().size(), termValueSet.getConcepts().size());

View File

@ -122,6 +122,9 @@ public enum DriverTypeEnum {
dataSource.setUsername(theUsername); dataSource.setUsername(theUsername);
dataSource.setPassword(thePassword); dataSource.setPassword(thePassword);
// A check for WS-2020-0287
assert dataSource.getJmxName() == null;
return newConnectionProperties(dataSource); return newConnectionProperties(dataSource);
} }

View File

@ -93,10 +93,6 @@ public class JpaConstants {
* Operation name for the $get-resource-counts operation * Operation name for the $get-resource-counts operation
*/ */
public static final String OPERATION_GET_RESOURCE_COUNTS = "$get-resource-counts"; public static final String OPERATION_GET_RESOURCE_COUNTS = "$get-resource-counts";
/**
* Operation name for the $meta operation
*/
public static final String OPERATION_META = "$meta";
/** /**
* Operation name for the $validate operation * Operation name for the $validate operation
*/ */

View File

@ -44,6 +44,9 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger; 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 @Interceptor
public class ConsentInterceptor { public class ConsentInterceptor {
private static final AtomicInteger ourInstanceCount = new AtomicInteger(0); private static final AtomicInteger ourInstanceCount = new AtomicInteger(0);
@ -94,6 +97,9 @@ public class ConsentInterceptor {
@Hook(value = Pointcut.SERVER_INCOMING_REQUEST_PRE_HANDLED) @Hook(value = Pointcut.SERVER_INCOMING_REQUEST_PRE_HANDLED)
public void interceptPreHandled(RequestDetails theRequestDetails) { public void interceptPreHandled(RequestDetails theRequestDetails) {
if (isAllowListedRequest(theRequestDetails)) {
return;
}
ConsentOutcome outcome = myConsentService.startOperation(theRequestDetails, myContextConsentServices); ConsentOutcome outcome = myConsentService.startOperation(theRequestDetails, myContextConsentServices);
Validate.notNull(outcome, "Consent service returned null outcome"); Validate.notNull(outcome, "Consent service returned null outcome");
@ -129,6 +135,9 @@ public class ConsentInterceptor {
if (isRequestAuthorized(theRequestDetails)) { if (isRequestAuthorized(theRequestDetails)) {
return; return;
} }
if (isAllowListedRequest(theRequestDetails)) {
return;
}
for (int i = 0; i < thePreResourceAccessDetails.size(); i++) { for (int i = 0; i < thePreResourceAccessDetails.size(); i++) {
IBaseResource nextResource = thePreResourceAccessDetails.getResource(i); IBaseResource nextResource = thePreResourceAccessDetails.getResource(i);
@ -150,6 +159,9 @@ public class ConsentInterceptor {
if (isRequestAuthorized(theRequestDetails)) { if (isRequestAuthorized(theRequestDetails)) {
return; return;
} }
if (isAllowListedRequest(theRequestDetails)) {
return;
}
IdentityHashMap<IBaseResource, Boolean> alreadySeenResources = getAlreadySeenResourcesMap(theRequestDetails); IdentityHashMap<IBaseResource, Boolean> alreadySeenResources = getAlreadySeenResourcesMap(theRequestDetails);
for (int i = 0; i < thePreResourceShowDetails.size(); i++) { for (int i = 0; i < thePreResourceShowDetails.size(); i++) {
@ -198,6 +210,9 @@ public class ConsentInterceptor {
if (isRequestAuthorized(theRequestDetails)) { if (isRequestAuthorized(theRequestDetails)) {
return; return;
} }
if (isAllowListedRequest(theRequestDetails)) {
return;
}
IdentityHashMap<IBaseResource, Boolean> alreadySeenResources = getAlreadySeenResourcesMap(theRequestDetails); IdentityHashMap<IBaseResource, Boolean> alreadySeenResources = getAlreadySeenResourcesMap(theRequestDetails);
@ -330,4 +345,16 @@ public class ConsentInterceptor {
} }
return new ForbiddenOperationException("Rejected by consent service", operationOutcome); return new ForbiddenOperationException("Rejected by consent service", operationOutcome);
} }
private boolean isAllowListedRequest(RequestDetails theRequestDetails) {
return isMetadataPath(theRequestDetails) || isMetaOperation(theRequestDetails);
}
private boolean isMetaOperation(RequestDetails theRequestDetails) {
return OPERATION_META.equals(theRequestDetails.getOperation());
}
private boolean isMetadataPath(RequestDetails theRequestDetails) {
return URL_TOKEN_METADATA.equals(theRequestDetails.getRequestPath());
}
} }

View File

@ -97,4 +97,8 @@ public class ProviderConstants {
*/ */
public static final String CQL_EVALUATE_MEASURE = "$evaluate-measure"; public static final String CQL_EVALUATE_MEASURE = "$evaluate-measure";
/**
* Operation name for the $meta operation
* */
public static final String OPERATION_META = "$meta";
} }

View File

@ -2,6 +2,8 @@ package ca.uhn.fhir.rest.server.interceptor;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.api.BundleInclusionRule; 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.RequiredParam;
import ca.uhn.fhir.rest.annotation.Search; import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.api.Constants; 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.FifoMemoryPagingProvider;
import ca.uhn.fhir.rest.server.RestfulServer; import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; 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.ConsentInterceptor;
import ca.uhn.fhir.rest.server.interceptor.consent.ConsentOperationStatusEnum; 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.ConsentOutcome;
import ca.uhn.fhir.rest.server.interceptor.consent.IConsentService; import ca.uhn.fhir.rest.server.interceptor.consent.IConsentService;
import ca.uhn.fhir.rest.server.provider.HashMapResourceProvider; import ca.uhn.fhir.rest.server.provider.HashMapResourceProvider;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import ca.uhn.fhir.test.utilities.JettyUtil; import ca.uhn.fhir.test.utilities.JettyUtil;
import com.google.common.base.Charsets; import com.google.common.base.Charsets;
import org.apache.commons.io.IOUtils; 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.server.Server;
import org.eclipse.jetty.servlet.ServletHandler; import org.eclipse.jetty.servlet.ServletHandler;
import org.eclipse.jetty.servlet.ServletHolder; 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.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.Bundle; import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.OperationOutcome; import org.hl7.fhir.r4.model.OperationOutcome;
import org.hl7.fhir.r4.model.Parameters;
import org.hl7.fhir.r4.model.Patient; import org.hl7.fhir.r4.model.Patient;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterAll;
@ -70,6 +76,7 @@ public class ConsentInterceptorTest {
private static Server ourServer; private static Server ourServer;
private static DummyPatientResourceProvider ourPatientProvider; private static DummyPatientResourceProvider ourPatientProvider;
private static IGenericClient ourFhirClient; private static IGenericClient ourFhirClient;
private static DummySystemProvider ourSystemProvider;
@Mock @Mock
private IConsentService myConsentSvc; 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 @Test
public void testSearch_SeeResourceAuthorizesOuterBundle() throws IOException { public void testSearch_SeeResourceAuthorizesOuterBundle() throws IOException {
ourPatientProvider.store((Patient) new Patient().setActive(true).setId("PTA")); ourPatientProvider.store((Patient) new Patient().setActive(true).setId("PTA"));
@ -457,11 +486,13 @@ public class ConsentInterceptorTest {
ourServer = new Server(0); ourServer = new Server(0);
ourPatientProvider = new DummyPatientResourceProvider(ourCtx); ourPatientProvider = new DummyPatientResourceProvider(ourCtx);
ourSystemProvider = new DummySystemProvider();
ServletHandler servletHandler = new ServletHandler(); ServletHandler servletHandler = new ServletHandler();
ourServlet = new RestfulServer(ourCtx); ourServlet = new RestfulServer(ourCtx);
ourServlet.setDefaultPrettyPrint(true); ourServlet.setDefaultPrettyPrint(true);
ourServlet.setResourceProviders(ourPatientProvider); ourServlet.setResourceProviders(ourPatientProvider);
ourServlet.registerProvider(ourSystemProvider);
ourServlet.setBundleInclusionRule(BundleInclusionRule.BASED_ON_RESOURCE_PRESENCE); ourServlet.setBundleInclusionRule(BundleInclusionRule.BASED_ON_RESOURCE_PRESENCE);
ServletHolder servletHolder = new ServletHolder(ourServlet); ServletHolder servletHolder = new ServletHolder(ourServlet);
servletHandler.addServletWithMapping(servletHolder, "/*"); servletHandler.addServletWithMapping(servletHolder, "/*");
@ -478,4 +509,15 @@ public class ConsentInterceptorTest {
ourFhirClient = ourCtx.newRestfulGenericClient("http://localhost:" + ourPort); 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;
}
}
} }