Fix exception handling
This commit is contained in:
parent
462ae8cb1f
commit
6e1b848ea6
|
@ -10,7 +10,7 @@ package ca.uhn.fhir.jaxrs.server;
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -22,8 +22,6 @@ package ca.uhn.fhir.jaxrs.server;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.interceptor.Interceptors;
|
import javax.interceptor.Interceptors;
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
|
@ -41,7 +39,6 @@ import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.jaxrs.server.interceptor.JaxRsExceptionInterceptor;
|
import ca.uhn.fhir.jaxrs.server.interceptor.JaxRsExceptionInterceptor;
|
||||||
import ca.uhn.fhir.jaxrs.server.interceptor.JaxRsResponseException;
|
|
||||||
import ca.uhn.fhir.jaxrs.server.util.JaxRsMethodBindings;
|
import ca.uhn.fhir.jaxrs.server.util.JaxRsMethodBindings;
|
||||||
import ca.uhn.fhir.jaxrs.server.util.JaxRsRequest;
|
import ca.uhn.fhir.jaxrs.server.util.JaxRsRequest;
|
||||||
import ca.uhn.fhir.jaxrs.server.util.JaxRsRequest.Builder;
|
import ca.uhn.fhir.jaxrs.server.util.JaxRsRequest.Builder;
|
||||||
|
@ -60,47 +57,45 @@ import ca.uhn.fhir.rest.server.IRestfulServer;
|
||||||
* @author Peter Van Houte | peter.vanhoute@agfa.com | Agfa Healthcare
|
* @author Peter Van Houte | peter.vanhoute@agfa.com | Agfa Healthcare
|
||||||
*/
|
*/
|
||||||
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN })
|
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN })
|
||||||
@Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_JSON, Constants.CT_FHIR_JSON,
|
@Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_JSON, Constants.CT_FHIR_JSON, Constants.CT_FHIR_XML })
|
||||||
Constants.CT_FHIR_XML })
|
|
||||||
@Interceptors(JaxRsExceptionInterceptor.class)
|
@Interceptors(JaxRsExceptionInterceptor.class)
|
||||||
public abstract class AbstractJaxRsResourceProvider<R extends IBaseResource> extends AbstractJaxRsProvider
|
public abstract class AbstractJaxRsResourceProvider<R extends IBaseResource> extends AbstractJaxRsProvider
|
||||||
|
|
||||||
implements IRestfulServer<JaxRsRequest>, IResourceProvider {
|
implements IRestfulServer<JaxRsRequest>, IResourceProvider {
|
||||||
|
|
||||||
/** the method bindings for this class */
|
/** the method bindings for this class */
|
||||||
private final JaxRsMethodBindings theBindings;
|
private final JaxRsMethodBindings theBindings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default constructor. The method bindings are retrieved from the class
|
* The default constructor. The method bindings are retrieved from the class
|
||||||
* being constructed.
|
* being constructed.
|
||||||
*/
|
*/
|
||||||
protected AbstractJaxRsResourceProvider() {
|
protected AbstractJaxRsResourceProvider() {
|
||||||
super();
|
super();
|
||||||
theBindings = JaxRsMethodBindings.getMethodBindings(this, getClass());
|
theBindings = JaxRsMethodBindings.getMethodBindings(this, getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the ability to specify the {@link FhirContext}.
|
* Provides the ability to specify the {@link FhirContext}.
|
||||||
* @param ctx the {@link FhirContext} instance.
|
* @param ctx the {@link FhirContext} instance.
|
||||||
*/
|
*/
|
||||||
protected AbstractJaxRsResourceProvider(FhirContext ctx) {
|
protected AbstractJaxRsResourceProvider(final FhirContext ctx) {
|
||||||
super(ctx);
|
super(ctx);
|
||||||
theBindings = JaxRsMethodBindings.getMethodBindings(this, getClass());
|
theBindings = JaxRsMethodBindings.getMethodBindings(this, getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
/**
|
* This constructor takes in an explicit interface class. This subclass
|
||||||
* This constructor takes in an explicit interface class. This subclass
|
* should be identical to the class being constructed but is given
|
||||||
* should be identical to the class being constructed but is given
|
* explicitly in order to avoid issues with proxy classes in a jee
|
||||||
* explicitly in order to avoid issues with proxy classes in a jee
|
* environment.
|
||||||
* environment.
|
*
|
||||||
*
|
* @param theProviderClass the interface of the class
|
||||||
* @param theProviderClass the interface of the class
|
*/
|
||||||
*/
|
protected AbstractJaxRsResourceProvider(final Class<? extends AbstractJaxRsProvider> theProviderClass) {
|
||||||
protected AbstractJaxRsResourceProvider(Class<? extends AbstractJaxRsProvider> theProviderClass) {
|
super();
|
||||||
super();
|
theBindings = JaxRsMethodBindings.getMethodBindings(this, theProviderClass);
|
||||||
theBindings = JaxRsMethodBindings.getMethodBindings(this, theProviderClass);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This constructor takes in an explicit interface class. This subclass
|
* This constructor takes in an explicit interface class. This subclass
|
||||||
|
@ -111,62 +106,66 @@ public abstract class AbstractJaxRsResourceProvider<R extends IBaseResource> ext
|
||||||
* @param ctx the {@link FhirContext} instance.
|
* @param ctx the {@link FhirContext} instance.
|
||||||
* @param theProviderClass the interface of the class
|
* @param theProviderClass the interface of the class
|
||||||
*/
|
*/
|
||||||
protected AbstractJaxRsResourceProvider(FhirContext ctx, Class<? extends AbstractJaxRsProvider> theProviderClass) {
|
protected AbstractJaxRsResourceProvider(final FhirContext ctx, final Class<? extends AbstractJaxRsProvider> theProviderClass) {
|
||||||
super(ctx);
|
super(ctx);
|
||||||
theBindings = JaxRsMethodBindings.getMethodBindings(this, theProviderClass);
|
theBindings = JaxRsMethodBindings.getMethodBindings(this, theProviderClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The base for request for a resource provider has the following form:</br>
|
* The base for request for a resource provider has the following form:</br>
|
||||||
* {@link AbstractJaxRsResourceProvider#getBaseForServer()
|
* {@link AbstractJaxRsResourceProvider#getBaseForServer()
|
||||||
* getBaseForServer()} + "/" +
|
* getBaseForServer()} + "/" +
|
||||||
* {@link AbstractJaxRsResourceProvider#getResourceType() getResourceType()}
|
* {@link AbstractJaxRsResourceProvider#getResourceType() getResourceType()}
|
||||||
* .{@link java.lang.Class#getSimpleName() getSimpleName()}
|
* .{@link java.lang.Class#getSimpleName() getSimpleName()}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getBaseForRequest() {
|
public String getBaseForRequest() {
|
||||||
try {
|
try {
|
||||||
return new URL(getUriInfo().getBaseUri().toURL(), getResourceType().getSimpleName()).toExternalForm();
|
return new URL(getUriInfo().getBaseUri().toURL(), getResourceType().getSimpleName()).toExternalForm();
|
||||||
} catch (Exception e) {
|
}
|
||||||
// cannot happen
|
catch (final Exception e) {
|
||||||
return null;
|
// cannot happen
|
||||||
}
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new resource with a server assigned id
|
* Create a new resource with a server assigned id
|
||||||
*
|
*
|
||||||
* @param resource the body of the post method containing resource being created in a xml/json form
|
* @param resource the body of the post method containing resource being created in a xml/json form
|
||||||
* @return the response
|
* @return the response
|
||||||
* @see <a href="https://www.hl7.org/fhir/http.html#create">https://www.hl7. org/fhir/http.html#create</a>
|
* @see <a href="https://www.hl7.org/fhir/http.html#create">https://www.hl7. org/fhir/http.html#create</a>
|
||||||
*/
|
*/
|
||||||
@POST
|
@POST
|
||||||
public Response create(final String resource) throws IOException {
|
public Response create(final String resource)
|
||||||
return execute(getResourceRequest(RequestTypeEnum.POST, RestOperationTypeEnum.CREATE).resource(resource));
|
throws IOException {
|
||||||
}
|
return execute(getResourceRequest(RequestTypeEnum.POST, RestOperationTypeEnum.CREATE).resource(resource));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search the resource type based on some filter criteria
|
* Search the resource type based on some filter criteria
|
||||||
*
|
*
|
||||||
* @return the response
|
* @return the response
|
||||||
* @see <a href="https://www.hl7.org/fhir/http.html#search">https://www.hl7.org/fhir/http.html#search</a>
|
* @see <a href="https://www.hl7.org/fhir/http.html#search">https://www.hl7.org/fhir/http.html#search</a>
|
||||||
*/
|
*/
|
||||||
@POST
|
@POST
|
||||||
@Path("/_search")
|
@Path("/_search")
|
||||||
public Response searchWithPost() throws IOException {
|
public Response searchWithPost()
|
||||||
return execute(getResourceRequest(RequestTypeEnum.POST, RestOperationTypeEnum.SEARCH_TYPE));
|
throws IOException {
|
||||||
}
|
return execute(getResourceRequest(RequestTypeEnum.POST, RestOperationTypeEnum.SEARCH_TYPE));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search the resource type based on some filter criteria
|
* Search the resource type based on some filter criteria
|
||||||
*
|
*
|
||||||
* @return the response
|
* @return the response
|
||||||
* @see <a href="https://www.hl7.org/fhir/http.html#search">https://www.hl7.org/fhir/http.html#search</a>
|
* @see <a href="https://www.hl7.org/fhir/http.html#search">https://www.hl7.org/fhir/http.html#search</a>
|
||||||
*/
|
*/
|
||||||
@GET
|
@GET
|
||||||
public Response search() throws IOException {
|
public Response search()
|
||||||
return execute(getResourceRequest(RequestTypeEnum.GET, RestOperationTypeEnum.SEARCH_TYPE));
|
throws IOException {
|
||||||
}
|
return execute(getResourceRequest(RequestTypeEnum.GET, RestOperationTypeEnum.SEARCH_TYPE));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update an existing resource based on the given condition
|
* Update an existing resource based on the given condition
|
||||||
|
@ -175,23 +174,25 @@ public abstract class AbstractJaxRsResourceProvider<R extends IBaseResource> ext
|
||||||
* @see <a href="https://www.hl7.org/fhir/http.html#update">https://www.hl7.org/fhir/http.html#update</a>
|
* @see <a href="https://www.hl7.org/fhir/http.html#update">https://www.hl7.org/fhir/http.html#update</a>
|
||||||
*/
|
*/
|
||||||
@PUT
|
@PUT
|
||||||
public Response conditionalUpdate(final String resource) throws IOException {
|
public Response conditionalUpdate(final String resource)
|
||||||
|
throws IOException {
|
||||||
return execute(getResourceRequest(RequestTypeEnum.PUT, RestOperationTypeEnum.UPDATE).resource(resource));
|
return execute(getResourceRequest(RequestTypeEnum.PUT, RestOperationTypeEnum.UPDATE).resource(resource));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update an existing resource by its id (or create it if it is new)
|
* Update an existing resource by its id (or create it if it is new)
|
||||||
*
|
*
|
||||||
* @param id the id of the resource
|
* @param id the id of the resource
|
||||||
* @param resource the body contents for the put method
|
* @param resource the body contents for the put method
|
||||||
* @return the response
|
* @return the response
|
||||||
* @see <a href="https://www.hl7.org/fhir/http.html#update">https://www.hl7.org/fhir/http.html#update</a>
|
* @see <a href="https://www.hl7.org/fhir/http.html#update">https://www.hl7.org/fhir/http.html#update</a>
|
||||||
*/
|
*/
|
||||||
@PUT
|
@PUT
|
||||||
@Path("/{id}")
|
@Path("/{id}")
|
||||||
public Response update(@PathParam("id") final String id, final String resource) throws IOException {
|
public Response update(@PathParam("id") final String id, final String resource)
|
||||||
return execute(getResourceRequest(RequestTypeEnum.PUT, RestOperationTypeEnum.UPDATE).id(id).resource(resource));
|
throws IOException {
|
||||||
}
|
return execute(getResourceRequest(RequestTypeEnum.PUT, RestOperationTypeEnum.UPDATE).id(id).resource(resource));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a resource based on the given condition
|
* Delete a resource based on the given condition
|
||||||
|
@ -200,157 +201,163 @@ public abstract class AbstractJaxRsResourceProvider<R extends IBaseResource> ext
|
||||||
* @see <a href="https://www.hl7.org/fhir/http.html#delete">https://www.hl7.org/fhir/http.html#delete</a>
|
* @see <a href="https://www.hl7.org/fhir/http.html#delete">https://www.hl7.org/fhir/http.html#delete</a>
|
||||||
*/
|
*/
|
||||||
@DELETE
|
@DELETE
|
||||||
public Response delete() throws IOException {
|
public Response delete()
|
||||||
|
throws IOException {
|
||||||
return execute(getResourceRequest(RequestTypeEnum.DELETE, RestOperationTypeEnum.DELETE));
|
return execute(getResourceRequest(RequestTypeEnum.DELETE, RestOperationTypeEnum.DELETE));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a resource
|
* Delete a resource
|
||||||
*
|
*
|
||||||
* @param id the id of the resource to delete
|
* @param id the id of the resource to delete
|
||||||
* @return the response
|
* @return the response
|
||||||
* @see <a href="https://www.hl7.org/fhir/http.html#delete">https://www.hl7.org/fhir/http.html#delete</a>
|
* @see <a href="https://www.hl7.org/fhir/http.html#delete">https://www.hl7.org/fhir/http.html#delete</a>
|
||||||
*/
|
*/
|
||||||
@DELETE
|
@DELETE
|
||||||
@Path("/{id}")
|
@Path("/{id}")
|
||||||
public Response delete(@PathParam("id") final String id) throws IOException {
|
public Response delete(@PathParam("id") final String id)
|
||||||
return execute(getResourceRequest(RequestTypeEnum.DELETE, RestOperationTypeEnum.DELETE).id(id));
|
throws IOException {
|
||||||
}
|
return execute(getResourceRequest(RequestTypeEnum.DELETE, RestOperationTypeEnum.DELETE).id(id));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read the current state of the resource
|
* Read the current state of the resource
|
||||||
*
|
*
|
||||||
* @param id the id of the resource to read
|
* @param id the id of the resource to read
|
||||||
* @return the response
|
* @return the response
|
||||||
* @see <a href="https://www.hl7.org/fhir/http.html#read">https://www.hl7.org/fhir/http.html#read</a>
|
* @see <a href="https://www.hl7.org/fhir/http.html#read">https://www.hl7.org/fhir/http.html#read</a>
|
||||||
*/
|
*/
|
||||||
@GET
|
@GET
|
||||||
@Path("/{id}")
|
@Path("/{id}")
|
||||||
public Response find(@PathParam("id") final String id) throws IOException {
|
public Response find(@PathParam("id") final String id)
|
||||||
return execute(getResourceRequest(RequestTypeEnum.GET, RestOperationTypeEnum.READ).id(id));
|
throws IOException {
|
||||||
}
|
return execute(getResourceRequest(RequestTypeEnum.GET, RestOperationTypeEnum.READ).id(id));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute a custom operation
|
* Execute a custom operation
|
||||||
*
|
*
|
||||||
* @param resource the resource to create
|
* @param resource the resource to create
|
||||||
* @param requestType the type of request
|
* @param requestType the type of request
|
||||||
* @param id the id of the resource on which to perform the operation
|
* @param id the id of the resource on which to perform the operation
|
||||||
* @param operationName the name of the operation to execute
|
* @param operationName the name of the operation to execute
|
||||||
* @param operationType the rest operation type
|
* @param operationType the rest operation type
|
||||||
* @return the response
|
* @return the response
|
||||||
* @see <a href="https://www.hl7.org/fhir/operations.html">https://www.hl7.org/fhir/operations.html</a>
|
* @see <a href="https://www.hl7.org/fhir/operations.html">https://www.hl7.org/fhir/operations.html</a>
|
||||||
*/
|
*/
|
||||||
protected Response customOperation(final String resource, RequestTypeEnum requestType, String id,
|
protected Response customOperation(final String resource, final RequestTypeEnum requestType, final String id,
|
||||||
String operationName, RestOperationTypeEnum operationType) throws IOException {
|
final String operationName, final RestOperationTypeEnum operationType)
|
||||||
Builder request = getResourceRequest(requestType, operationType).resource(resource).id(id);
|
throws IOException {
|
||||||
return execute(request, operationName);
|
final Builder request = getResourceRequest(requestType, operationType).resource(resource).id(id);
|
||||||
}
|
return execute(request, operationName);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the update history for a particular resource
|
* Retrieve the update history for a particular resource
|
||||||
*
|
*
|
||||||
* @param id the id of the resource
|
* @param id the id of the resource
|
||||||
* @param version the version of the resource
|
* @param version the version of the resource
|
||||||
* @return the response
|
* @return the response
|
||||||
* @see <a href="https://www.hl7.org/fhir/http.html#history">https://www.hl7.org/fhir/http.html#history</a>
|
* @see <a href="https://www.hl7.org/fhir/http.html#history">https://www.hl7.org/fhir/http.html#history</a>
|
||||||
*/
|
*/
|
||||||
@GET
|
@GET
|
||||||
@Path("/{id}/_history/{version}")
|
@Path("/{id}/_history/{version}")
|
||||||
public Response findHistory(@PathParam("id") final String id, @PathParam("version") final String version)
|
public Response findHistory(@PathParam("id") final String id, @PathParam("version") final String version)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
Builder theRequest = getResourceRequest(RequestTypeEnum.GET, RestOperationTypeEnum.VREAD).id(id)
|
final Builder theRequest = getResourceRequest(RequestTypeEnum.GET, RestOperationTypeEnum.VREAD).id(id).version(version);
|
||||||
.version(version);
|
return execute(theRequest);
|
||||||
return execute(theRequest);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compartment Based Access
|
* Compartment Based Access
|
||||||
*
|
*
|
||||||
* @param id the resource to which the compartment belongs
|
* @param id the resource to which the compartment belongs
|
||||||
* @param compartment the compartment
|
* @param compartment the compartment
|
||||||
* @return the repsonse
|
* @return the repsonse
|
||||||
* @see <a href="https://www.hl7.org/fhir/http.html#search">https://www.hl7.org/fhir/http.html#search</a>
|
* @see <a href="https://www.hl7.org/fhir/http.html#search">https://www.hl7.org/fhir/http.html#search</a>
|
||||||
* @see <a href="https://www.hl7.org/fhir/compartments.html#compartment">https://www.hl7.org/fhir/compartments.html#compartment</a>
|
* @see <a href="https://www.hl7.org/fhir/compartments.html#compartment">https://www.hl7.org/fhir/compartments.html#compartment</a>
|
||||||
*/
|
*/
|
||||||
@GET
|
@GET
|
||||||
@Path("/{id}/{compartment}")
|
@Path("/{id}/{compartment}")
|
||||||
public Response findCompartment(@PathParam("id") final String id,
|
public Response findCompartment(@PathParam("id") final String id, @PathParam("compartment") final String compartment)
|
||||||
@PathParam("compartment") final String compartment) throws IOException {
|
throws IOException {
|
||||||
Builder theRequest = getResourceRequest(RequestTypeEnum.GET, RestOperationTypeEnum.SEARCH_TYPE).id(id)
|
final Builder theRequest = getResourceRequest(RequestTypeEnum.GET, RestOperationTypeEnum.SEARCH_TYPE).id(id).compartment(
|
||||||
.compartment(compartment);
|
compartment);
|
||||||
return execute(theRequest, compartment);
|
return execute(theRequest, compartment);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the method described by the requestBuilder and methodKey
|
* Execute the method described by the requestBuilder and methodKey
|
||||||
*
|
*
|
||||||
* @param theRequestBuilder the requestBuilder that contains the information about the request
|
* @param theRequestBuilder the requestBuilder that contains the information about the request
|
||||||
* @param methodKey the key determining the method to be executed
|
* @param methodKey the key determining the method to be executed
|
||||||
* @return the response
|
* @return the response
|
||||||
*/
|
*/
|
||||||
private Response execute(Builder theRequestBuilder, String methodKey) throws IOException {
|
private Response execute(final Builder theRequestBuilder, final String methodKey)
|
||||||
JaxRsRequest theRequest = theRequestBuilder.build();
|
throws IOException {
|
||||||
BaseMethodBinding<?> method = getBinding(theRequest.getRestOperationType(), methodKey);
|
final JaxRsRequest theRequest = theRequestBuilder.build();
|
||||||
try {
|
final BaseMethodBinding<?> method = getBinding(theRequest.getRestOperationType(), methodKey);
|
||||||
return (Response) method.invokeServer(this, theRequest);
|
try {
|
||||||
} catch (JaxRsResponseException theException) {
|
return (Response) method.invokeServer(this, theRequest);
|
||||||
return new JaxRsExceptionInterceptor().convertExceptionIntoResponse(theRequest, theException);
|
}
|
||||||
}
|
catch (final Throwable theException) {
|
||||||
}
|
return handleException(theRequest, theException);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the method described by the requestBuilder
|
* Execute the method described by the requestBuilder
|
||||||
*
|
*
|
||||||
* @param theRequestBuilder the requestBuilder that contains the information about the request
|
* @param theRequestBuilder the requestBuilder that contains the information about the request
|
||||||
* @return the response
|
* @return the response
|
||||||
*/
|
*/
|
||||||
private Response execute(Builder theRequestBuilder) throws IOException {
|
private Response execute(final Builder theRequestBuilder)
|
||||||
return execute(theRequestBuilder, JaxRsMethodBindings.DEFAULT_METHOD_KEY);
|
throws IOException {
|
||||||
}
|
return execute(theRequestBuilder, JaxRsMethodBindings.DEFAULT_METHOD_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the method binding for the given rest operation
|
* Return the method binding for the given rest operation
|
||||||
*
|
*
|
||||||
* @param restOperation the rest operation to retrieve
|
* @param restOperation the rest operation to retrieve
|
||||||
* @param theBindingKey the key determining the method to be executed (needed for e.g. custom operation)
|
* @param theBindingKey the key determining the method to be executed (needed for e.g. custom operation)
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected BaseMethodBinding<?> getBinding(RestOperationTypeEnum restOperation, String theBindingKey) {
|
protected BaseMethodBinding<?> getBinding(final RestOperationTypeEnum restOperation, final String theBindingKey) {
|
||||||
return getBindings().getBinding(restOperation, theBindingKey);
|
return getBindings().getBinding(restOperation, theBindingKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default: no paging provider
|
* Default: no paging provider
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public IPagingProvider getPagingProvider() {
|
public IPagingProvider getPagingProvider() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default: BundleInclusionRule.BASED_ON_INCLUDES
|
* Default: BundleInclusionRule.BASED_ON_INCLUDES
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public BundleInclusionRule getBundleInclusionRule() {
|
public BundleInclusionRule getBundleInclusionRule() {
|
||||||
return BundleInclusionRule.BASED_ON_INCLUDES;
|
return BundleInclusionRule.BASED_ON_INCLUDES;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The resource type should return conform to the generic resource included
|
* The resource type should return conform to the generic resource included
|
||||||
* in the topic
|
* in the topic
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public abstract Class<R> getResourceType();
|
public abstract Class<R> getResourceType();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the bindings defined in this resource provider
|
* Return the bindings defined in this resource provider
|
||||||
*
|
*
|
||||||
* @return the jax-rs method bindings
|
* @return the jax-rs method bindings
|
||||||
*/
|
*/
|
||||||
public JaxRsMethodBindings getBindings() {
|
public JaxRsMethodBindings getBindings() {
|
||||||
return theBindings;
|
return theBindings;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the request builder based on the resource name for the server
|
* Return the request builder based on the resource name for the server
|
||||||
|
|
|
@ -10,7 +10,7 @@ package ca.uhn.fhir.jaxrs.server.interceptor;
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -41,36 +41,38 @@ import ca.uhn.fhir.rest.server.interceptor.ExceptionHandlingInterceptor;
|
||||||
public class JaxRsExceptionInterceptor {
|
public class JaxRsExceptionInterceptor {
|
||||||
|
|
||||||
/** the existing exception handler which is able to convert exception into responses*/
|
/** the existing exception handler which is able to convert exception into responses*/
|
||||||
private ExceptionHandlingInterceptor exceptionHandler;
|
private final ExceptionHandlingInterceptor exceptionHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default constructor
|
* The default constructor
|
||||||
*/
|
*/
|
||||||
public JaxRsExceptionInterceptor() {
|
public JaxRsExceptionInterceptor() {
|
||||||
this.exceptionHandler = new ExceptionHandlingInterceptor();
|
this.exceptionHandler = new ExceptionHandlingInterceptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A utility constructor for unit testing
|
* A utility constructor for unit testing
|
||||||
* @param exceptionHandler the handler for the exception conversion
|
* @param exceptionHandler the handler for the exception conversion
|
||||||
*/
|
*/
|
||||||
JaxRsExceptionInterceptor(ExceptionHandlingInterceptor exceptionHandler) {
|
JaxRsExceptionInterceptor(final ExceptionHandlingInterceptor exceptionHandler) {
|
||||||
this.exceptionHandler = exceptionHandler;
|
this.exceptionHandler = exceptionHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This interceptor will catch all exception and convert them using the exceptionhandler
|
* This interceptor will catch all exception and convert them using the exceptionhandler
|
||||||
* @param ctx the invocation context
|
* @param ctx the invocation context
|
||||||
* @return the result
|
* @return the result
|
||||||
* @throws JaxRsResponseException an exception that can be handled by a jee container
|
* @throws JaxRsResponseException an exception that can be handled by a jee container
|
||||||
*/
|
*/
|
||||||
@AroundInvoke
|
@AroundInvoke
|
||||||
public Object intercept(final InvocationContext ctx) throws JaxRsResponseException {
|
public Object intercept(final InvocationContext ctx)
|
||||||
|
throws JaxRsResponseException {
|
||||||
try {
|
try {
|
||||||
return ctx.proceed();
|
return ctx.proceed();
|
||||||
} catch(final Exception theException) {
|
}
|
||||||
AbstractJaxRsProvider theServer = (AbstractJaxRsProvider) ctx.getTarget();
|
catch (final Exception theException) {
|
||||||
throw convertException(theServer, theException);
|
final AbstractJaxRsProvider theServer = (AbstractJaxRsProvider) ctx.getTarget();
|
||||||
|
throw convertException(theServer, theException);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,41 +82,48 @@ public class JaxRsExceptionInterceptor {
|
||||||
* @param theException the exception to convert
|
* @param theException the exception to convert
|
||||||
* @return JaxRsResponseException
|
* @return JaxRsResponseException
|
||||||
*/
|
*/
|
||||||
public JaxRsResponseException convertException(final AbstractJaxRsProvider theServer, final Throwable theException) {
|
public JaxRsResponseException convertException(final AbstractJaxRsProvider theServer, final Throwable theException) {
|
||||||
if (theServer.withStackTrace()) {
|
if (theServer.withStackTrace()) {
|
||||||
exceptionHandler.setReturnStackTracesForExceptionTypes(Throwable.class);
|
exceptionHandler.setReturnStackTracesForExceptionTypes(Throwable.class);
|
||||||
}
|
}
|
||||||
JaxRsRequest requestDetails = theServer.getRequest(null, null).build();
|
final JaxRsRequest requestDetails = theServer.getRequest(null, null).build();
|
||||||
BaseServerResponseException convertedException = preprocessException(theException, requestDetails);
|
final BaseServerResponseException convertedException = preprocessException(theException, requestDetails);
|
||||||
return new JaxRsResponseException(convertedException);
|
return new JaxRsResponseException(convertedException);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method converts an exception into a response
|
* This method converts an exception into a response
|
||||||
* @param theRequest the request
|
* @param theRequest the request
|
||||||
* @param theException the thrown exception
|
* @param theException the thrown exception
|
||||||
* @return the response describing the error
|
* @return the response describing the error
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public Response convertExceptionIntoResponse(JaxRsRequest theRequest, JaxRsResponseException theException)
|
public Response convertExceptionIntoResponse(final JaxRsRequest theRequest, final JaxRsResponseException theException)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
return handleExceptionWithoutServletError(theRequest, theException);
|
return handleExceptionWithoutServletError(theRequest, theException);
|
||||||
}
|
}
|
||||||
|
|
||||||
private BaseServerResponseException preprocessException(final Throwable theException, JaxRsRequest requestDetails) {
|
private BaseServerResponseException preprocessException(final Throwable theException, final JaxRsRequest requestDetails) {
|
||||||
try {
|
try {
|
||||||
return exceptionHandler.preProcessOutgoingException(requestDetails, theException, null);
|
Throwable theExceptionToConvert = theException;
|
||||||
} catch(ServletException e) {
|
if (!(theException instanceof BaseServerResponseException) && (theException.getCause() instanceof BaseServerResponseException)) {
|
||||||
return new InternalErrorException(e);
|
theExceptionToConvert = theException.getCause();
|
||||||
}
|
}
|
||||||
}
|
return exceptionHandler.preProcessOutgoingException(requestDetails, theExceptionToConvert, null);
|
||||||
|
}
|
||||||
|
catch (final ServletException e) {
|
||||||
|
return new InternalErrorException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Response handleExceptionWithoutServletError(JaxRsRequest theRequest, BaseServerResponseException theException) throws IOException {
|
private Response handleExceptionWithoutServletError(final JaxRsRequest theRequest, final BaseServerResponseException theException)
|
||||||
try {
|
throws IOException {
|
||||||
return (Response) exceptionHandler.handleException(theRequest, theException);
|
try {
|
||||||
} catch (ServletException e) {
|
return (Response) exceptionHandler.handleException(theRequest, theException);
|
||||||
BaseServerResponseException newException = preprocessException(new InternalErrorException(e), theRequest);
|
}
|
||||||
return handleExceptionWithoutServletError(theRequest, newException);
|
catch (final ServletException e) {
|
||||||
}
|
final BaseServerResponseException newException = preprocessException(new InternalErrorException(e), theRequest);
|
||||||
}
|
return handleExceptionWithoutServletError(theRequest, newException);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue