Clean up rest hook interceptor a bit
This commit is contained in:
parent
d81565b87c
commit
b44bdeec88
|
@ -26,37 +26,6 @@ import ca.uhn.fhir.context.FhirContext;
|
|||
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
||||
|
||||
public interface IRestfulServerDefaults {
|
||||
|
||||
/**
|
||||
* Returns the list of interceptors registered against this server
|
||||
*/
|
||||
List<IServerInterceptor> getInterceptors();
|
||||
|
||||
/**
|
||||
* Gets the {@link FhirContext} associated with this server. For efficient processing, resource providers and plain
|
||||
* providers should generally use this context if one is needed, as opposed to
|
||||
* creating their own.
|
||||
*/
|
||||
FhirContext getFhirContext();
|
||||
|
||||
/**
|
||||
* Should the server "pretty print" responses by default (requesting clients can always override this default by
|
||||
* supplying an <code>Accept</code> header in the request, or a <code>_pretty</code>
|
||||
* parameter in the request URL.
|
||||
* <p>
|
||||
* The default is <code>false</code>
|
||||
* </p>
|
||||
*
|
||||
* @return Returns the default pretty print setting
|
||||
*/
|
||||
boolean isDefaultPrettyPrint();
|
||||
|
||||
/**
|
||||
* @return Returns the server support for ETags (will not be <code>null</code>). Default is
|
||||
* {@link RestfulServer#DEFAULT_ETAG_SUPPORT}
|
||||
*/
|
||||
ETagSupportEnum getETagSupport();
|
||||
|
||||
/**
|
||||
* @return Returns the setting for automatically adding profile tags
|
||||
* @deprecated As of HAPI FHIR 1.5, this property has been moved to
|
||||
|
@ -73,15 +42,46 @@ public interface IRestfulServerDefaults {
|
|||
EncodingEnum getDefaultResponseEncoding();
|
||||
|
||||
/**
|
||||
* @return If <code>true</code> the server will use browser friendly content-types (instead of standard FHIR ones)
|
||||
* when it detects that the request is coming from a browser
|
||||
* instead of a FHIR
|
||||
* @return Returns the server support for ETags (will not be <code>null</code>). Default is
|
||||
* {@link RestfulServer#DEFAULT_ETAG_SUPPORT}
|
||||
*/
|
||||
boolean isUseBrowserFriendlyContentTypes();
|
||||
ETagSupportEnum getETagSupport();
|
||||
|
||||
/**
|
||||
* Gets the {@link FhirContext} associated with this server. For efficient processing, resource providers and plain
|
||||
* providers should generally use this context if one is needed, as opposed to
|
||||
* creating their own.
|
||||
*/
|
||||
FhirContext getFhirContext();
|
||||
|
||||
/**
|
||||
* Returns the list of interceptors registered against this server
|
||||
*/
|
||||
List<IServerInterceptor> getInterceptors();
|
||||
|
||||
/**
|
||||
* Returns the paging provider for this server
|
||||
*/
|
||||
IPagingProvider getPagingProvider();
|
||||
|
||||
/**
|
||||
* Should the server "pretty print" responses by default (requesting clients can always override this default by
|
||||
* supplying an <code>Accept</code> header in the request, or a <code>_pretty</code>
|
||||
* parameter in the request URL.
|
||||
* <p>
|
||||
* The default is <code>false</code>
|
||||
* </p>
|
||||
*
|
||||
* @return Returns the default pretty print setting
|
||||
*/
|
||||
boolean isDefaultPrettyPrint();
|
||||
|
||||
/**
|
||||
* @return If <code>true</code> the server will use browser friendly content-types (instead of standard FHIR ones)
|
||||
* when it detects that the request is coming from a browser
|
||||
* instead of a FHIR
|
||||
*/
|
||||
boolean isUseBrowserFriendlyContentTypes();
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ import ca.uhn.fhir.rest.server.AddProfileTagEnum;
|
|||
import ca.uhn.fhir.rest.server.ETagSupportEnum;
|
||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.server.HardcodedServerAddressStrategy;
|
||||
import ca.uhn.fhir.rest.server.IPagingProvider;
|
||||
import ca.uhn.fhir.rest.server.IRestfulServerDefaults;
|
||||
import ca.uhn.fhir.rest.server.IServerAddressStrategy;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
|
@ -62,216 +63,246 @@ import ca.uhn.fhir.util.OperationOutcomeUtil;
|
|||
*/
|
||||
public abstract class AbstractJaxRsProvider implements IRestfulServerDefaults {
|
||||
|
||||
private final FhirContext CTX;
|
||||
private static final String ERROR = "error";
|
||||
|
||||
private static final String PROCESSING = "processing";
|
||||
private static final String ERROR = "error";
|
||||
private static final String PROCESSING = "processing";
|
||||
|
||||
/** the uri info */
|
||||
@Context
|
||||
private UriInfo theUriInfo;
|
||||
/** the http headers */
|
||||
@Context
|
||||
private HttpHeaders theHeaders;
|
||||
private final FhirContext CTX;
|
||||
/** the http headers */
|
||||
@Context
|
||||
private HttpHeaders theHeaders;
|
||||
|
||||
@Override
|
||||
public FhirContext getFhirContext() {
|
||||
return CTX;
|
||||
}
|
||||
/** the uri info */
|
||||
@Context
|
||||
private UriInfo theUriInfo;
|
||||
|
||||
/**
|
||||
* Default is DSTU2. Use {@link AbstractJaxRsProvider#AbstractJaxRsProvider(FhirContext)} to specify a DSTU3 context.
|
||||
*/
|
||||
protected AbstractJaxRsProvider() {
|
||||
CTX = FhirContext.forDstu2();
|
||||
}
|
||||
/**
|
||||
* Default is DSTU2. Use {@link AbstractJaxRsProvider#AbstractJaxRsProvider(FhirContext)} to specify a DSTU3 context.
|
||||
*/
|
||||
protected AbstractJaxRsProvider() {
|
||||
CTX = FhirContext.forDstu2();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param ctx the {@link FhirContext} to support.
|
||||
*/
|
||||
protected AbstractJaxRsProvider(final FhirContext ctx) {
|
||||
CTX = ctx;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param ctx
|
||||
* the {@link FhirContext} to support.
|
||||
*/
|
||||
protected AbstractJaxRsProvider(final FhirContext ctx) {
|
||||
CTX = ctx;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the query parameters
|
||||
* @return the query parameters
|
||||
*/
|
||||
public Map<String, String[]> getParameters() {
|
||||
final MultivaluedMap<String, String> queryParameters = getUriInfo().getQueryParameters();
|
||||
final HashMap<String, String[]> params = new HashMap<String, String[]>();
|
||||
for (final Entry<String, List<String>> paramEntry : queryParameters.entrySet()) {
|
||||
params.put(paramEntry.getKey(), paramEntry.getValue().toArray(new String[paramEntry.getValue().size()]));
|
||||
}
|
||||
return params;
|
||||
}
|
||||
private IBaseOperationOutcome createOutcome(final DataFormatException theException) {
|
||||
final IBaseOperationOutcome oo = OperationOutcomeUtil.newInstance(getFhirContext());
|
||||
final String detailsValue = theException.getMessage() + "\n\n" + ExceptionUtils.getStackTrace(theException);
|
||||
OperationOutcomeUtil.addIssue(getFhirContext(), oo, ERROR, detailsValue, null, PROCESSING);
|
||||
return oo;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the default server address strategy. The default strategy return the
|
||||
* base uri for the request {@link AbstractJaxRsProvider#getBaseForRequest() getBaseForRequest()}
|
||||
* @return
|
||||
*/
|
||||
public IServerAddressStrategy getServerAddressStrategy() {
|
||||
final HardcodedServerAddressStrategy addressStrategy = new HardcodedServerAddressStrategy();
|
||||
addressStrategy.setValue(getBaseForRequest());
|
||||
return addressStrategy;
|
||||
}
|
||||
/**
|
||||
* DEFAULT = AddProfileTagEnum.NEVER
|
||||
*/
|
||||
@Override
|
||||
public AddProfileTagEnum getAddProfileTag() {
|
||||
return AddProfileTagEnum.NEVER;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the server base, independent of the request or resource.
|
||||
* @see javax.ws.rs.core.UriInfo#getBaseUri()
|
||||
* @return the ascii string for the server base
|
||||
*/
|
||||
public String getBaseForServer() {
|
||||
final String url = getUriInfo().getBaseUri().toASCIIString();
|
||||
return StringUtils.isNotBlank(url) && url.endsWith("/") ? url.substring(0, url.length() - 1) : url;
|
||||
}
|
||||
/**
|
||||
* This method returns the server base, including the resource path.
|
||||
* {@link javax.ws.rs.core.UriInfo#getBaseUri() UriInfo#getBaseUri()}
|
||||
*
|
||||
* @return the ascii string for the base resource provider path
|
||||
*/
|
||||
public String getBaseForRequest() {
|
||||
return getBaseForServer();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the server base, including the resource path.
|
||||
* {@link javax.ws.rs.core.UriInfo#getBaseUri() UriInfo#getBaseUri()}
|
||||
* @return the ascii string for the base resource provider path
|
||||
*/
|
||||
public String getBaseForRequest() {
|
||||
return getBaseForServer();
|
||||
}
|
||||
/**
|
||||
* This method returns the server base, independent of the request or resource.
|
||||
*
|
||||
* @see javax.ws.rs.core.UriInfo#getBaseUri()
|
||||
* @return the ascii string for the server base
|
||||
*/
|
||||
public String getBaseForServer() {
|
||||
final String url = getUriInfo().getBaseUri().toASCIIString();
|
||||
return StringUtils.isNotBlank(url) && url.endsWith("/") ? url.substring(0, url.length() - 1) : url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default: an empty list of interceptors (Interceptors are not yet supported
|
||||
* in the JAX-RS server). Please get in touch if you'd like to help!
|
||||
*
|
||||
* @see ca.uhn.fhir.rest.server.IRestfulServer#getInterceptors()
|
||||
*/
|
||||
@Override
|
||||
public List<IServerInterceptor> getInterceptors() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
/**
|
||||
* DEFAULT = EncodingEnum.JSON
|
||||
*/
|
||||
@Override
|
||||
public EncodingEnum getDefaultResponseEncoding() {
|
||||
return EncodingEnum.JSON;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the uriInfo
|
||||
* @return the uri info
|
||||
*/
|
||||
public UriInfo getUriInfo() {
|
||||
return this.theUriInfo;
|
||||
}
|
||||
/**
|
||||
* DEFAULT = ETagSupportEnum.DISABLED
|
||||
*/
|
||||
@Override
|
||||
public ETagSupportEnum getETagSupport() {
|
||||
return ETagSupportEnum.DISABLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Uri Info
|
||||
* @param uriInfo the uri info
|
||||
*/
|
||||
public void setUriInfo(final UriInfo uriInfo) {
|
||||
this.theUriInfo = uriInfo;
|
||||
}
|
||||
@Override
|
||||
public FhirContext getFhirContext() {
|
||||
return CTX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the headers
|
||||
* @return the headers
|
||||
*/
|
||||
public HttpHeaders getHeaders() {
|
||||
return this.theHeaders;
|
||||
}
|
||||
/**
|
||||
* Get the headers
|
||||
*
|
||||
* @return the headers
|
||||
*/
|
||||
public HttpHeaders getHeaders() {
|
||||
return this.theHeaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the headers
|
||||
* @param headers the headers to set
|
||||
*/
|
||||
public void setHeaders(final HttpHeaders headers) {
|
||||
this.theHeaders = headers;
|
||||
}
|
||||
/**
|
||||
* Default: an empty list of interceptors (Interceptors are not yet supported
|
||||
* in the JAX-RS server). Please get in touch if you'd like to help!
|
||||
*
|
||||
* @see ca.uhn.fhir.rest.server.IRestfulServer#getInterceptors()
|
||||
*/
|
||||
@Override
|
||||
public List<IServerInterceptor> getInterceptors() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the requestbuilder for the server
|
||||
* @param requestType the type of the request
|
||||
* @param restOperation the rest operation type
|
||||
* @param theResourceName the resource name
|
||||
* @return the requestbuilder
|
||||
*/
|
||||
public Builder getRequest(final RequestTypeEnum requestType, final RestOperationTypeEnum restOperation, final String theResourceName) {
|
||||
return new JaxRsRequest.Builder(this, requestType, restOperation, theUriInfo.getRequestUri().toString(), theResourceName);
|
||||
}
|
||||
/**
|
||||
* By default, no paging provider is used
|
||||
*/
|
||||
@Override
|
||||
public IPagingProvider getPagingProvider() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the requestbuilder for the server
|
||||
* @param requestType the type of the request
|
||||
* @param restOperation the rest operation type
|
||||
* @return the requestbuilder
|
||||
*/
|
||||
public Builder getRequest(final RequestTypeEnum requestType, final RestOperationTypeEnum restOperation) {
|
||||
return getRequest(requestType, restOperation, null);
|
||||
}
|
||||
/**
|
||||
* This method returns the query parameters
|
||||
*
|
||||
* @return the query parameters
|
||||
*/
|
||||
public Map<String, String[]> getParameters() {
|
||||
final MultivaluedMap<String, String> queryParameters = getUriInfo().getQueryParameters();
|
||||
final HashMap<String, String[]> params = new HashMap<String, String[]>();
|
||||
for (final Entry<String, List<String>> paramEntry : queryParameters.entrySet()) {
|
||||
params.put(paramEntry.getKey(), paramEntry.getValue().toArray(new String[paramEntry.getValue().size()]));
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* DEFAULT = EncodingEnum.JSON
|
||||
*/
|
||||
@Override
|
||||
public EncodingEnum getDefaultResponseEncoding() {
|
||||
return EncodingEnum.JSON;
|
||||
}
|
||||
/**
|
||||
* Return the requestbuilder for the server
|
||||
*
|
||||
* @param requestType
|
||||
* the type of the request
|
||||
* @param restOperation
|
||||
* the rest operation type
|
||||
* @return the requestbuilder
|
||||
*/
|
||||
public Builder getRequest(final RequestTypeEnum requestType, final RestOperationTypeEnum restOperation) {
|
||||
return getRequest(requestType, restOperation, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* DEFAULT = true
|
||||
*/
|
||||
@Override
|
||||
public boolean isDefaultPrettyPrint() {
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Return the requestbuilder for the server
|
||||
*
|
||||
* @param requestType
|
||||
* the type of the request
|
||||
* @param restOperation
|
||||
* the rest operation type
|
||||
* @param theResourceName
|
||||
* the resource name
|
||||
* @return the requestbuilder
|
||||
*/
|
||||
public Builder getRequest(final RequestTypeEnum requestType, final RestOperationTypeEnum restOperation, final String theResourceName) {
|
||||
return new JaxRsRequest.Builder(this, requestType, restOperation, theUriInfo.getRequestUri().toString(), theResourceName);
|
||||
}
|
||||
|
||||
/**
|
||||
* DEFAULT = ETagSupportEnum.DISABLED
|
||||
*/
|
||||
@Override
|
||||
public ETagSupportEnum getETagSupport() {
|
||||
return ETagSupportEnum.DISABLED;
|
||||
}
|
||||
/**
|
||||
* This method returns the default server address strategy. The default strategy return the
|
||||
* base uri for the request {@link AbstractJaxRsProvider#getBaseForRequest() getBaseForRequest()}
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public IServerAddressStrategy getServerAddressStrategy() {
|
||||
final HardcodedServerAddressStrategy addressStrategy = new HardcodedServerAddressStrategy();
|
||||
addressStrategy.setValue(getBaseForRequest());
|
||||
return addressStrategy;
|
||||
}
|
||||
|
||||
/**
|
||||
* DEFAULT = AddProfileTagEnum.NEVER
|
||||
*/
|
||||
@Override
|
||||
public AddProfileTagEnum getAddProfileTag() {
|
||||
return AddProfileTagEnum.NEVER;
|
||||
}
|
||||
/**
|
||||
* Get the uriInfo
|
||||
*
|
||||
* @return the uri info
|
||||
*/
|
||||
public UriInfo getUriInfo() {
|
||||
return this.theUriInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* DEFAULT = false
|
||||
*/
|
||||
@Override
|
||||
public boolean isUseBrowserFriendlyContentTypes() {
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Convert an exception to a response
|
||||
*
|
||||
* @param theRequest
|
||||
* the incoming request
|
||||
* @param theException
|
||||
* the exception to convert
|
||||
* @return response
|
||||
* @throws IOException
|
||||
*/
|
||||
public Response handleException(final JaxRsRequest theRequest, final Throwable theException)
|
||||
throws IOException {
|
||||
if (theException instanceof JaxRsResponseException) {
|
||||
return new JaxRsExceptionInterceptor().convertExceptionIntoResponse(theRequest, (JaxRsResponseException) theException);
|
||||
} else if (theException instanceof DataFormatException) {
|
||||
return new JaxRsExceptionInterceptor().convertExceptionIntoResponse(theRequest, new JaxRsResponseException(
|
||||
new InvalidRequestException(theException.getMessage(), createOutcome((DataFormatException) theException))));
|
||||
} else {
|
||||
return new JaxRsExceptionInterceptor().convertExceptionIntoResponse(theRequest,
|
||||
new JaxRsExceptionInterceptor().convertException(this, theException));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DEFAULT = false
|
||||
*/
|
||||
public boolean withStackTrace() {
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* DEFAULT = true
|
||||
*/
|
||||
@Override
|
||||
public boolean isDefaultPrettyPrint() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an exception to a response
|
||||
* @param theRequest the incoming request
|
||||
* @param theException the exception to convert
|
||||
* @return response
|
||||
* @throws IOException
|
||||
*/
|
||||
public Response handleException(final JaxRsRequest theRequest, final Throwable theException)
|
||||
throws IOException {
|
||||
if (theException instanceof JaxRsResponseException) {
|
||||
return new JaxRsExceptionInterceptor().convertExceptionIntoResponse(theRequest, (JaxRsResponseException) theException);
|
||||
} else if (theException instanceof DataFormatException) {
|
||||
return new JaxRsExceptionInterceptor().convertExceptionIntoResponse(theRequest, new JaxRsResponseException(
|
||||
new InvalidRequestException(theException.getMessage(), createOutcome((DataFormatException) theException))));
|
||||
} else {
|
||||
return new JaxRsExceptionInterceptor().convertExceptionIntoResponse(theRequest,
|
||||
new JaxRsExceptionInterceptor().convertException(this, theException));
|
||||
}
|
||||
}
|
||||
/**
|
||||
* DEFAULT = false
|
||||
*/
|
||||
@Override
|
||||
public boolean isUseBrowserFriendlyContentTypes() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private IBaseOperationOutcome createOutcome(final DataFormatException theException) {
|
||||
final IBaseOperationOutcome oo = OperationOutcomeUtil.newInstance(getFhirContext());
|
||||
final String detailsValue = theException.getMessage() + "\n\n" + ExceptionUtils.getStackTrace(theException);
|
||||
OperationOutcomeUtil.addIssue(getFhirContext(), oo, ERROR, detailsValue, null, PROCESSING);
|
||||
return oo;
|
||||
}
|
||||
/**
|
||||
* Set the headers
|
||||
*
|
||||
* @param headers
|
||||
* the headers to set
|
||||
*/
|
||||
public void setHeaders(final HttpHeaders headers) {
|
||||
this.theHeaders = headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Uri Info
|
||||
*
|
||||
* @param uriInfo
|
||||
* the uri info
|
||||
*/
|
||||
public void setUriInfo(final UriInfo uriInfo) {
|
||||
this.theUriInfo = uriInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* DEFAULT = false
|
||||
*/
|
||||
public boolean withStackTrace() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -564,7 +564,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||
}
|
||||
|
||||
protected boolean isPagingProviderDatabaseBacked(RequestDetails theRequestDetails) {
|
||||
if (theRequestDetails == null) {
|
||||
if (theRequestDetails == null || theRequestDetails.getServer() == null) {
|
||||
return false;
|
||||
}
|
||||
if (theRequestDetails.getServer().getPagingProvider() instanceof DatabaseBackedPagingProvider) {
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
package ca.uhn.fhir.jpa.interceptor;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
|
||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
|
||||
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
||||
import ca.uhn.fhir.jpa.provider.ServletSubRequestDetails;
|
||||
import ca.uhn.fhir.rest.method.RequestDetails;
|
||||
import ca.uhn.fhir.rest.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.rest.server.interceptor.ServerOperationInterceptorAdapter;
|
||||
|
||||
public abstract class BaseRestHookSubscriptionInterceptor extends ServerOperationInterceptorAdapter {
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseRestHookSubscriptionInterceptor.class);
|
||||
|
||||
protected static final Integer MAX_SUBSCRIPTION_RESULTS = 10000;
|
||||
|
||||
protected abstract IFhirResourceDao<?> getSubscriptionDao();
|
||||
|
||||
protected void checkSubscriptionCriterias(String theCriteria) {
|
||||
try {
|
||||
IBundleProvider results = executeSubscriptionCriteria(theCriteria, null);
|
||||
} catch (Exception e) {
|
||||
ourLog.warn("Invalid criteria when creating subscription", e);
|
||||
throw new InvalidRequestException("Invalid criteria: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private IBundleProvider executeSubscriptionCriteria(String theCriteria, IIdType idType) {
|
||||
String criteria = theCriteria;
|
||||
|
||||
/*
|
||||
* Run the subscriptions query and look for matches, add the id as part of the criteria
|
||||
* to avoid getting matches of previous resources rather than the recent resource
|
||||
*/
|
||||
if (idType != null) {
|
||||
criteria += "&_id=" + idType.getResourceType() + "/" + idType.getIdPart();
|
||||
}
|
||||
|
||||
IBundleProvider results = getBundleProvider(criteria, true);
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search based on a query criteria
|
||||
*
|
||||
* @param theCheckOnly Is this just a test that the search works
|
||||
*/
|
||||
protected IBundleProvider getBundleProvider(String theCriteria, boolean theCheckOnly) {
|
||||
RuntimeResourceDefinition responseResourceDef = getSubscriptionDao().validateCriteriaAndReturnResourceDefinition(theCriteria);
|
||||
SearchParameterMap responseCriteriaUrl = BaseHapiFhirDao.translateMatchUrl(getSubscriptionDao(), getSubscriptionDao().getContext(), theCriteria, responseResourceDef);
|
||||
|
||||
RequestDetails req = new ServletSubRequestDetails();
|
||||
req.setSubRequest(true);
|
||||
|
||||
IFhirResourceDao<? extends IBaseResource> responseDao = getSubscriptionDao().getDao(responseResourceDef.getImplementingClass());
|
||||
|
||||
if (theCheckOnly) {
|
||||
responseCriteriaUrl.setLoadSynchronousUpTo(1);
|
||||
} else {
|
||||
responseCriteriaUrl.setLoadSynchronousUpTo(MAX_SUBSCRIPTION_RESULTS);
|
||||
}
|
||||
|
||||
IBundleProvider responseResults = responseDao.search(responseCriteriaUrl, req);
|
||||
return responseResults;
|
||||
}
|
||||
|
||||
}
|
|
@ -29,12 +29,9 @@ import javax.annotation.PostConstruct;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.methods.HttpPut;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.client.utils.URLEncodedUtils;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
@ -45,8 +42,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
|
||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
|
||||
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
||||
import ca.uhn.fhir.jpa.provider.ServletSubRequestDetails;
|
||||
|
@ -62,11 +57,9 @@ import ca.uhn.fhir.rest.param.TokenParam;
|
|||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.server.interceptor.*;
|
||||
|
||||
public class RestHookSubscriptionDstu2Interceptor extends ServerOperationInterceptorAdapter {
|
||||
public class RestHookSubscriptionDstu2Interceptor extends BaseRestHookSubscriptionInterceptor {
|
||||
|
||||
private static final Integer MAX_SUBSCRIPTION_RESULTS = 10000;
|
||||
private static volatile ExecutorService executor;
|
||||
private final static int MAX_THREADS = 1;
|
||||
|
||||
|
@ -75,13 +68,13 @@ public class RestHookSubscriptionDstu2Interceptor extends ServerOperationInterce
|
|||
@Autowired
|
||||
private FhirContext myFhirContext;
|
||||
|
||||
private boolean myNotifyOnDelete = false;
|
||||
|
||||
private final List<Subscription> myRestHookSubscriptions = new ArrayList<Subscription>();
|
||||
@Autowired
|
||||
@Qualifier("mySubscriptionDaoDstu2")
|
||||
private IFhirResourceDao<Subscription> mySubscriptionDao;
|
||||
|
||||
private boolean myNotifyOnDelete = false;
|
||||
private final List<Subscription> myRestHookSubscriptions = new ArrayList<Subscription>();
|
||||
|
||||
/**
|
||||
* Check subscriptions and send notifications or payload
|
||||
*
|
||||
|
@ -101,7 +94,7 @@ public class RestHookSubscriptionDstu2Interceptor extends ServerOperationInterce
|
|||
}
|
||||
|
||||
if (resourceType != null && subscription.getCriteria() != null && !criteriaResource.equals(resourceType)) {
|
||||
ourLog.info("Skipping subscription search for {} because it does not match the criteria {}", resourceType , subscription.getCriteria());
|
||||
ourLog.info("Skipping subscription search for {} because it does not match the criteria {}", resourceType, subscription.getCriteria());
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -110,7 +103,7 @@ public class RestHookSubscriptionDstu2Interceptor extends ServerOperationInterce
|
|||
criteria += "&_id=" + idType.getResourceType() + "/" + idType.getIdPart();
|
||||
criteria = massageCriteria(criteria);
|
||||
|
||||
IBundleProvider results = getBundleProvider(criteria);
|
||||
IBundleProvider results = getBundleProvider(criteria, false);
|
||||
|
||||
if (results.size() == 0) {
|
||||
continue;
|
||||
|
@ -195,25 +188,6 @@ public class RestHookSubscriptionDstu2Interceptor extends ServerOperationInterce
|
|||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search based on a query criteria
|
||||
*
|
||||
* @param criteria
|
||||
* @return
|
||||
*/
|
||||
private IBundleProvider getBundleProvider(String criteria) {
|
||||
RuntimeResourceDefinition responseResourceDef = mySubscriptionDao.validateCriteriaAndReturnResourceDefinition(criteria);
|
||||
SearchParameterMap responseCriteriaUrl = BaseHapiFhirDao.translateMatchUrl(mySubscriptionDao, mySubscriptionDao.getContext(), criteria, responseResourceDef);
|
||||
|
||||
RequestDetails req = new ServletSubRequestDetails();
|
||||
req.setSubRequest(true);
|
||||
|
||||
IFhirResourceDao<? extends IBaseResource> responseDao = mySubscriptionDao.getDao(responseResourceDef.getImplementingClass());
|
||||
responseCriteriaUrl.setCount(MAX_SUBSCRIPTION_RESULTS);
|
||||
IBundleProvider responseResults = responseDao.search(responseCriteriaUrl, req);
|
||||
return responseResults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get subscription from cache
|
||||
*
|
||||
|
@ -259,6 +233,27 @@ public class RestHookSubscriptionDstu2Interceptor extends ServerOperationInterce
|
|||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IFhirResourceDao<?> getSubscriptionDao() {
|
||||
return mySubscriptionDao;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incomingRequestPreHandled(RestOperationTypeEnum theOperation, ActionRequestDetails theDetails) {
|
||||
// check the subscription criteria to see if its valid before creating or updating a subscription
|
||||
if (RestOperationTypeEnum.CREATE.equals(theOperation) || RestOperationTypeEnum.UPDATE.equals(theOperation)) {
|
||||
String resourceType = theDetails.getResourceType();
|
||||
ourLog.info("prehandled resource type: " + resourceType);
|
||||
if (resourceType != null && resourceType.equals(Subscription.class.getSimpleName())) {
|
||||
Subscription subscription = (Subscription) theDetails.getResource();
|
||||
if (subscription != null) {
|
||||
checkSubscriptionCriterias(subscription.getCriteria());
|
||||
}
|
||||
}
|
||||
}
|
||||
super.incomingRequestPreHandled(theOperation, theDetails);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the existing subscriptions from the database
|
||||
*/
|
||||
|
@ -273,7 +268,7 @@ public class RestHookSubscriptionDstu2Interceptor extends ServerOperationInterce
|
|||
map.setCount(MAX_SUBSCRIPTION_RESULTS);
|
||||
IBundleProvider subscriptionBundleList = mySubscriptionDao.search(map, req);
|
||||
if (subscriptionBundleList.size() >= MAX_SUBSCRIPTION_RESULTS) {
|
||||
ourLog.error("Currently over "+MAX_SUBSCRIPTION_RESULTS+" subscriptions. Some subscriptions have not been loaded.");
|
||||
ourLog.error("Currently over " + MAX_SUBSCRIPTION_RESULTS + " subscriptions. Some subscriptions have not been loaded.");
|
||||
}
|
||||
|
||||
List<IBaseResource> resourceList = subscriptionBundleList.getResources(0, subscriptionBundleList.size());
|
||||
|
@ -409,57 +404,4 @@ public class RestHookSubscriptionDstu2Interceptor extends ServerOperationInterce
|
|||
mySubscriptionDao = theSubscriptionDao;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incomingRequestPreHandled(RestOperationTypeEnum theOperation, ActionRequestDetails theDetails) {
|
||||
//check the subscription criteria to see if its valid before creating or updating a subscription
|
||||
if (RestOperationTypeEnum.CREATE.equals(theOperation) || RestOperationTypeEnum.UPDATE.equals(theOperation)) {
|
||||
String resourceType = theDetails.getResourceType();
|
||||
ourLog.info("prehandled resource type: " + resourceType);
|
||||
if (resourceType != null && resourceType.equals(Subscription.class.getSimpleName())) {
|
||||
Subscription subscription = (Subscription) theDetails.getResource();
|
||||
if (subscription != null) {
|
||||
checkSubscriptionCriterias(subscription);
|
||||
}
|
||||
}
|
||||
}
|
||||
super.incomingRequestPreHandled(theOperation, theDetails);
|
||||
}
|
||||
|
||||
private void checkSubscriptionCriterias(Subscription subscription){
|
||||
try {
|
||||
IBundleProvider results = executeSubscriptionCriteria(subscription, null);
|
||||
}catch (Exception e){
|
||||
throw new InvalidRequestException("Invalid criteria");
|
||||
}
|
||||
}
|
||||
|
||||
private IBundleProvider executeSubscriptionCriteria(Subscription subscription, IIdType idType){
|
||||
//run the subscriptions query and look for matches, add the id as part of the criteria to avoid getting matches of previous resources rather than the recent resource
|
||||
String criteria = subscription.getCriteria();
|
||||
if(idType != null) {
|
||||
criteria += "&_id=" + idType.getResourceType() + "/" + idType.getIdPart();
|
||||
}
|
||||
|
||||
IBundleProvider results = getBundleProvider(criteria);
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the encoding from the criteria or return JSON encoding if its not found
|
||||
*
|
||||
* @param criteria
|
||||
* @return
|
||||
*/
|
||||
private EncodingEnum getEncoding(String criteria) {
|
||||
//check criteria
|
||||
String params = criteria.substring(criteria.indexOf('?') + 1);
|
||||
List<NameValuePair> paramValues = URLEncodedUtils.parse(params, Constants.CHARSET_UTF8, '&');
|
||||
for (NameValuePair nameValuePair : paramValues) {
|
||||
if (Constants.PARAM_FORMAT.equals(nameValuePair.getName())) {
|
||||
return EncodingEnum.forContentType(nameValuePair.getValue());
|
||||
}
|
||||
}
|
||||
return EncodingEnum.JSON;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -30,12 +30,9 @@ import javax.annotation.PostConstruct;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.methods.HttpPut;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.client.utils.URLEncodedUtils;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.hl7.fhir.dstu3.model.Subscription;
|
||||
|
@ -48,8 +45,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
|
||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
|
||||
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
||||
import ca.uhn.fhir.jpa.provider.ServletSubRequestDetails;
|
||||
|
@ -60,32 +55,31 @@ import ca.uhn.fhir.rest.param.TokenParam;
|
|||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.server.interceptor.*;
|
||||
|
||||
public class RestHookSubscriptionDstu3Interceptor extends ServerOperationInterceptorAdapter {
|
||||
public class RestHookSubscriptionDstu3Interceptor extends BaseRestHookSubscriptionInterceptor {
|
||||
|
||||
private static final Integer MAX_SUBSCRIPTION_RESULTS = 10000;
|
||||
private static volatile ExecutorService executor;
|
||||
private final static int MAX_THREADS = 1;
|
||||
|
||||
private final static int MAX_THREADS = 1;
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(RestHookSubscriptionDstu3Interceptor.class);
|
||||
|
||||
@Autowired
|
||||
private FhirContext myFhirContext;
|
||||
|
||||
private final List<Subscription> myRestHookSubscriptions = new ArrayList<Subscription>();
|
||||
|
||||
@Autowired
|
||||
@Qualifier("mySubscriptionDaoDstu3")
|
||||
private IFhirResourceDao<Subscription> mySubscriptionDao;
|
||||
|
||||
|
||||
private boolean notifyOnDelete = false;
|
||||
private final List<Subscription> myRestHookSubscriptions = new ArrayList<Subscription>();
|
||||
|
||||
/**
|
||||
* Check subscriptions and send notifications or payload
|
||||
*
|
||||
* @param idType
|
||||
* @param resourceType
|
||||
* @param theOperation
|
||||
* @param theOperation
|
||||
*/
|
||||
private void checkSubscriptions(IIdType idType, String resourceType, RestOperationTypeEnum theOperation) {
|
||||
for (Subscription subscription : myRestHookSubscriptions) {
|
||||
|
@ -99,7 +93,7 @@ public class RestHookSubscriptionDstu3Interceptor extends ServerOperationInterce
|
|||
}
|
||||
|
||||
if (resourceType != null && subscription.getCriteria() != null && !criteriaResource.equals(resourceType)) {
|
||||
ourLog.info("Skipping subscription search for {} because it does not match the criteria {}", resourceType , subscription.getCriteria());
|
||||
ourLog.info("Skipping subscription search for {} because it does not match the criteria {}", resourceType, subscription.getCriteria());
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -108,7 +102,7 @@ public class RestHookSubscriptionDstu3Interceptor extends ServerOperationInterce
|
|||
criteria += "&_id=" + idType.getResourceType() + "/" + idType.getIdPart();
|
||||
criteria = massageCriteria(criteria);
|
||||
|
||||
IBundleProvider results = getBundleProvider(criteria);
|
||||
IBundleProvider results = getBundleProvider(criteria, false);
|
||||
|
||||
if (results.size() == 0) {
|
||||
continue;
|
||||
|
@ -134,13 +128,13 @@ public class RestHookSubscriptionDstu3Interceptor extends ServerOperationInterce
|
|||
while (url.endsWith("/")) {
|
||||
url = url.substring(0, url.length() - 1);
|
||||
}
|
||||
|
||||
|
||||
HttpUriRequest request = null;
|
||||
String resourceName = myFhirContext.getResourceDefinition(theResource).getName();
|
||||
String resourceName = myFhirContext.getResourceDefinition(theResource).getName();
|
||||
|
||||
String payload = theSubscription.getChannel().getPayload();
|
||||
String resourceId = theResource.getIdElement().getIdPart();
|
||||
|
||||
|
||||
// HTTP put
|
||||
if (theOperation == RestOperationTypeEnum.UPDATE && EncodingEnum.XML.equals(EncodingEnum.forContentType(payload))) {
|
||||
ourLog.info("XML payload found");
|
||||
|
@ -186,25 +180,6 @@ public class RestHookSubscriptionDstu3Interceptor extends ServerOperationInterce
|
|||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search based on a query criteria
|
||||
*
|
||||
* @param criteria
|
||||
* @return
|
||||
*/
|
||||
private IBundleProvider getBundleProvider(String criteria) {
|
||||
RuntimeResourceDefinition responseResourceDef = mySubscriptionDao.validateCriteriaAndReturnResourceDefinition(criteria);
|
||||
SearchParameterMap responseCriteriaUrl = BaseHapiFhirDao.translateMatchUrl(mySubscriptionDao, mySubscriptionDao.getContext(), criteria, responseResourceDef);
|
||||
|
||||
RequestDetails req = new ServletSubRequestDetails();
|
||||
req.setSubRequest(true);
|
||||
|
||||
IFhirResourceDao<? extends IBaseResource> responseDao = mySubscriptionDao.getDao(responseResourceDef.getImplementingClass());
|
||||
responseCriteriaUrl.setCount(MAX_SUBSCRIPTION_RESULTS);
|
||||
IBundleProvider responseResults = responseDao.search(responseCriteriaUrl, req);
|
||||
return responseResults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get subscription from cache
|
||||
*
|
||||
|
@ -250,6 +225,27 @@ public class RestHookSubscriptionDstu3Interceptor extends ServerOperationInterce
|
|||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IFhirResourceDao<?> getSubscriptionDao() {
|
||||
return mySubscriptionDao;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incomingRequestPreHandled(RestOperationTypeEnum theOperation, ActionRequestDetails theDetails) {
|
||||
// check the subscription criteria to see if its valid before creating or updating a subscription
|
||||
if (RestOperationTypeEnum.CREATE.equals(theOperation) || RestOperationTypeEnum.UPDATE.equals(theOperation)) {
|
||||
String resourceType = theDetails.getResourceType();
|
||||
ourLog.info("prehandled resource type: " + resourceType);
|
||||
if (resourceType != null && resourceType.equals(Subscription.class.getSimpleName())) {
|
||||
Subscription subscription = (Subscription) theDetails.getResource();
|
||||
if (subscription != null) {
|
||||
checkSubscriptionCriterias(subscription.getCriteria());
|
||||
}
|
||||
}
|
||||
}
|
||||
super.incomingRequestPreHandled(theOperation, theDetails);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the existing subscriptions from the database
|
||||
*/
|
||||
|
@ -264,7 +260,7 @@ public class RestHookSubscriptionDstu3Interceptor extends ServerOperationInterce
|
|||
map.setCount(MAX_SUBSCRIPTION_RESULTS);
|
||||
IBundleProvider subscriptionBundleList = mySubscriptionDao.search(map, req);
|
||||
if (subscriptionBundleList.size() >= MAX_SUBSCRIPTION_RESULTS) {
|
||||
ourLog.error("Currently over "+MAX_SUBSCRIPTION_RESULTS+" subscriptions. Some subscriptions have not been loaded.");
|
||||
ourLog.error("Currently over " + MAX_SUBSCRIPTION_RESULTS + " subscriptions. Some subscriptions have not been loaded.");
|
||||
}
|
||||
|
||||
List<IBaseResource> resourceList = subscriptionBundleList.getResources(0, subscriptionBundleList.size());
|
||||
|
@ -400,57 +396,4 @@ public class RestHookSubscriptionDstu3Interceptor extends ServerOperationInterce
|
|||
mySubscriptionDao = theSubscriptionDao;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incomingRequestPreHandled(RestOperationTypeEnum theOperation, ActionRequestDetails theDetails) {
|
||||
//check the subscription criteria to see if its valid before creating or updating a subscription
|
||||
if (RestOperationTypeEnum.CREATE.equals(theOperation) || RestOperationTypeEnum.UPDATE.equals(theOperation)) {
|
||||
String resourceType = theDetails.getResourceType();
|
||||
ourLog.info("prehandled resource type: " + resourceType);
|
||||
if (resourceType != null && resourceType.equals(Subscription.class.getSimpleName())) {
|
||||
Subscription subscription = (Subscription) theDetails.getResource();
|
||||
if (subscription != null) {
|
||||
checkSubscriptionCriterias(subscription);
|
||||
}
|
||||
}
|
||||
}
|
||||
super.incomingRequestPreHandled(theOperation, theDetails);
|
||||
}
|
||||
|
||||
private void checkSubscriptionCriterias(Subscription subscription){
|
||||
try {
|
||||
IBundleProvider results = executeSubscriptionCriteria(subscription, null);
|
||||
}catch (Exception e){
|
||||
throw new InvalidRequestException("Invalid criteria");
|
||||
}
|
||||
}
|
||||
|
||||
private IBundleProvider executeSubscriptionCriteria(Subscription subscription, IIdType idType){
|
||||
//run the subscriptions query and look for matches, add the id as part of the criteria to avoid getting matches of previous resources rather than the recent resource
|
||||
String criteria = subscription.getCriteria();
|
||||
if(idType != null) {
|
||||
criteria += "&_id=" + idType.getResourceType() + "/" + idType.getIdPart();
|
||||
}
|
||||
|
||||
IBundleProvider results = getBundleProvider(criteria);
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the encoding from the criteria or return JSON encoding if its not found
|
||||
*
|
||||
* @param criteria
|
||||
* @return
|
||||
*/
|
||||
private EncodingEnum getEncoding(String criteria) {
|
||||
//check criteria
|
||||
String params = criteria.substring(criteria.indexOf('?') + 1);
|
||||
List<NameValuePair> paramValues = URLEncodedUtils.parse(params, Constants.CHARSET_UTF8, '&');
|
||||
for (NameValuePair nameValuePair : paramValues) {
|
||||
if (Constants.PARAM_FORMAT.equals(nameValuePair.getName())) {
|
||||
return EncodingEnum.forContentType(nameValuePair.getValue());
|
||||
}
|
||||
}
|
||||
return EncodingEnum.JSON;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -196,8 +196,6 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
|||
ids = toUnqualifiedVersionlessIdValues(results);
|
||||
assertThat(ids, hasItems(enc1Id, enc2Id));
|
||||
|
||||
System.exit(0);
|
||||
|
||||
map = new SearchParameterMap();
|
||||
map.add(Encounter.SP_SUBJECT, new ReferenceParam("subject:Patient", "foo|bar").setChain("identifier"));
|
||||
results = myEncounterDao.search(map);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
package ca.uhn.fhir.jpa.subscription;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -36,6 +36,7 @@ import ca.uhn.fhir.rest.annotation.Update;
|
|||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
/**
|
||||
|
@ -58,13 +59,12 @@ public class RestHookTestDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
ourClient.delete().resourceConditionalByUrl("Subscription?status=active").execute();
|
||||
ourLog.info("Done deleting all subscriptions");
|
||||
myDaoConfig.setAllowMultipleDelete(new DaoConfig().isAllowMultipleDelete());
|
||||
|
||||
|
||||
ourRestServer.unregisterInterceptor(ourRestHookSubscriptionInterceptor);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void beforeRegisterRestHookListener() {
|
||||
// ourRestHookSubscriptionInterceptor.set
|
||||
ourRestServer.registerInterceptor(ourRestHookSubscriptionInterceptor);
|
||||
}
|
||||
|
||||
|
@ -127,22 +127,21 @@ public class RestHookTestDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
Thread.sleep(500);
|
||||
assertEquals(1, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
|
||||
Subscription subscriptionTemp = ourClient.read(Subscription.class, subscription2.getId());
|
||||
Assert.assertNotNull(subscriptionTemp);
|
||||
|
||||
subscriptionTemp.setCriteria(criteria1);
|
||||
ourClient.update().resource(subscriptionTemp).withId(subscriptionTemp.getIdElement()).execute();
|
||||
|
||||
|
||||
Observation observation2 = sendObservation(code, "SNOMED-CT");
|
||||
|
||||
// Should see two subscription notifications
|
||||
Thread.sleep(500);
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
ourClient.delete().resourceById(new IdDt("Subscription/"+ subscription2.getId())).execute();
|
||||
|
||||
ourClient.delete().resourceById(new IdDt("Subscription/" + subscription2.getId())).execute();
|
||||
|
||||
Observation observationTemp3 = sendObservation(code, "SNOMED-CT");
|
||||
|
||||
|
@ -183,6 +182,20 @@ public class RestHookTestDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
Assert.assertFalse(observation2.getId().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRestHookSubscriptionInvalidCriteria() throws Exception {
|
||||
String payload = "application/xml";
|
||||
|
||||
String criteria1 = "Observation?codeeeee=SNOMED-CT";
|
||||
|
||||
try {
|
||||
createSubscription(criteria1, payload, ourListenerServerBase);
|
||||
fail();
|
||||
} catch (InvalidRequestException e) {
|
||||
assertEquals("HTTP 400 Bad Request: Invalid criteria: Failed to parse match URL[Observation?codeeeee=SNOMED-CT] - Resource type Observation does not have a parameter with name: codeeeee", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRestHookSubscriptionXml() throws Exception {
|
||||
String payload = "application/xml";
|
||||
|
@ -200,22 +213,21 @@ public class RestHookTestDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
Thread.sleep(500);
|
||||
assertEquals(1, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
|
||||
Subscription subscriptionTemp = ourClient.read(Subscription.class, subscription2.getId());
|
||||
Assert.assertNotNull(subscriptionTemp);
|
||||
|
||||
subscriptionTemp.setCriteria(criteria1);
|
||||
ourClient.update().resource(subscriptionTemp).withId(subscriptionTemp.getIdElement()).execute();
|
||||
|
||||
|
||||
Observation observation2 = sendObservation(code, "SNOMED-CT");
|
||||
|
||||
// Should see two subscription notifications
|
||||
Thread.sleep(500);
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
ourClient.delete().resourceById(new IdDt("Subscription/"+ subscription2.getId())).execute();
|
||||
|
||||
ourClient.delete().resourceById(new IdDt("Subscription/" + subscription2.getId())).execute();
|
||||
|
||||
Observation observationTemp3 = sendObservation(code, "SNOMED-CT");
|
||||
|
||||
|
@ -256,7 +268,6 @@ public class RestHookTestDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
Assert.assertFalse(observation2.getId().isEmpty());
|
||||
}
|
||||
|
||||
|
||||
@BeforeClass
|
||||
public static void startListenerServer() throws Exception {
|
||||
ourListenerPort = PortUtil.findFreePort();
|
||||
|
|
|
@ -27,6 +27,7 @@ import ca.uhn.fhir.rest.api.MethodOutcome;
|
|||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
|
||||
/**
|
||||
* Test the rest-hook subscriptions
|
||||
|
@ -65,6 +66,21 @@ public class RestHookTestDstu3Test extends BaseResourceProviderDstu3Test {
|
|||
ourUpdatedObservations.clear();
|
||||
ourContentTypes.clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRestHookSubscriptionInvalidCriteria() throws Exception {
|
||||
String payload = "application/xml";
|
||||
|
||||
String criteria1 = "Observation?codeeeee=SNOMED-CT";
|
||||
|
||||
try {
|
||||
createSubscription(criteria1, payload, ourListenerServerBase);
|
||||
fail();
|
||||
} catch (InvalidRequestException e) {
|
||||
assertEquals("HTTP 400 Bad Request: Invalid criteria: Failed to parse match URL[Observation?codeeeee=SNOMED-CT] - Resource type Observation does not have a parameter with name: codeeeee", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Subscription createSubscription(String theCriteria, String thePayload, String theEndpoint) {
|
||||
Subscription subscription = new Subscription();
|
||||
|
|
Loading…
Reference in New Issue