test in weblogic: fix interceptor + stateless on abstract
This commit is contained in:
parent
0aafd37397
commit
63db1b646f
|
@ -36,6 +36,7 @@ import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
|||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.rest.api.SummaryEnum;
|
||||
import ca.uhn.fhir.rest.method.RequestDetails;
|
||||
import ca.uhn.fhir.rest.server.IRestfulResponse;
|
||||
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.util.OperationOutcomeUtil;
|
||||
|
@ -47,6 +48,13 @@ public class ExceptionHandlingInterceptor extends InterceptorAdapter {
|
|||
|
||||
@Override
|
||||
public boolean handleException(RequestDetails theRequestDetails, BaseServerResponseException theException, HttpServletRequest theRequest, HttpServletResponse theResponse) throws ServletException, IOException {
|
||||
handleException(theRequestDetails, theException);
|
||||
return false;
|
||||
}
|
||||
|
||||
public Object handleException(RequestDetails theRequestDetails, BaseServerResponseException theException)
|
||||
throws ServletException, IOException {
|
||||
IRestfulResponse response = theRequestDetails.getResponse();
|
||||
|
||||
FhirContext ctx = theRequestDetails.getServer().getFhirContext();
|
||||
|
||||
|
@ -64,22 +72,19 @@ public class ExceptionHandlingInterceptor extends InterceptorAdapter {
|
|||
if (isNotBlank(next.getKey()) && next.getValue() != null) {
|
||||
String nextKey = next.getKey();
|
||||
for (String nextValue : next.getValue()) {
|
||||
theResponse.addHeader(nextKey, nextValue);
|
||||
response.addHeader(nextKey, nextValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
theRequestDetails.getResponse().streamResponseAsResource(oo, true, Collections.singleton(SummaryEnum.FALSE), statusCode, false, false);
|
||||
|
||||
return response.streamResponseAsResource(oo, true, Collections.singleton(SummaryEnum.FALSE), statusCode, false, false);
|
||||
// theResponse.setStatus(statusCode);
|
||||
// theRequestDetails.getServer().addHeadersToResponse(theResponse);
|
||||
// theResponse.setContentType("text/plain");
|
||||
// theResponse.setCharacterEncoding("UTF-8");
|
||||
// theResponse.getWriter().append(theException.getMessage());
|
||||
// theResponse.getWriter().close();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -64,7 +64,7 @@ public class ServletRestfulResponse extends RestfulResponse<ServletRequestDetail
|
|||
}
|
||||
}
|
||||
|
||||
public final Object sendWriterResponse(int status, String contentType, String charset, Writer writer) throws IOException {
|
||||
public final Object sendWriterResponse(int status, String contentType, String charset, Writer writer) throws IOException {
|
||||
writer.close();
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -11,8 +11,6 @@ import java.util.Map.Entry;
|
|||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.ejb.Local;
|
||||
import javax.ejb.Stateless;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.OPTIONS;
|
||||
import javax.ws.rs.Path;
|
||||
|
@ -44,9 +42,6 @@ import ca.uhn.fhir.util.ReflectionUtil;
|
|||
* Conformance Rest Service
|
||||
* @author Peter Van Houte
|
||||
*/
|
||||
@Local
|
||||
@Path("")
|
||||
@Stateless
|
||||
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
||||
public abstract class AbstractJaxRsConformanceProvider extends AbstractJaxRsProvider {
|
||||
|
||||
|
@ -67,8 +62,7 @@ public abstract class AbstractJaxRsConformanceProvider extends AbstractJaxRsProv
|
|||
}
|
||||
|
||||
@PostConstruct
|
||||
protected void setUpPostConstruct()
|
||||
throws Exception {
|
||||
protected void setUpPostConstruct() {
|
||||
for (Entry<Class<? extends IResourceProvider>, IResourceProvider> provider : getProviders().entrySet()) {
|
||||
addProvider(provider.getValue(), provider.getKey());
|
||||
}
|
||||
|
@ -86,7 +80,7 @@ public abstract class AbstractJaxRsConformanceProvider extends AbstractJaxRsProv
|
|||
myConformance = serverConformanceProvider.getServerConformance(null);
|
||||
}
|
||||
|
||||
protected abstract ConcurrentHashMap<Class<? extends IResourceProvider>, IResourceProvider> getProviders() throws Exception;
|
||||
protected abstract ConcurrentHashMap<Class<? extends IResourceProvider>, IResourceProvider> getProviders();
|
||||
|
||||
@OPTIONS
|
||||
@Path("/metadata")
|
||||
|
|
|
@ -66,9 +66,6 @@ public abstract class AbstractJaxRsProvider implements IRestfulServerDefaults, I
|
|||
return getBaseForServer();
|
||||
}
|
||||
|
||||
/**
|
||||
* PARSING METHODS
|
||||
*/
|
||||
protected JaxRsRequest createRequestDetails(final String resourceString, RequestTypeEnum requestType, RestOperationTypeEnum restOperation) {
|
||||
return new JaxRsRequest(this, resourceString, requestType, restOperation);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import javax.ws.rs.core.Response;
|
|||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
import ca.uhn.fhir.jaxrs.server.interceptor.BaseServerRuntimeResponseException;
|
||||
import ca.uhn.fhir.jaxrs.server.interceptor.JaxRsExceptionInterceptor;
|
||||
import ca.uhn.fhir.jaxrs.server.util.JaxRsRequest;
|
||||
import ca.uhn.fhir.jaxrs.server.util.MethodBindings;
|
||||
|
@ -35,6 +36,7 @@ import ca.uhn.fhir.rest.server.IPagingProvider;
|
|||
import ca.uhn.fhir.rest.server.IRestfulServer;
|
||||
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.rest.server.interceptor.ExceptionHandlingInterceptor;
|
||||
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
||||
import ca.uhn.fhir.util.UrlUtil;
|
||||
|
||||
|
@ -45,8 +47,10 @@ import ca.uhn.fhir.util.UrlUtil;
|
|||
*/
|
||||
@Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN})
|
||||
@Consumes({MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_JSON, Constants.CT_FHIR_JSON, Constants.CT_FHIR_XML})
|
||||
@Interceptors(JaxRsExceptionInterceptor.class)
|
||||
public abstract class AbstractJaxRsResourceProvider<R extends IResource> extends AbstractJaxRsProvider implements IRestfulServer<JaxRsRequest> {
|
||||
|
||||
private static final ExceptionHandlingInterceptor EXCEPTION_HANDLING_INTERCEPTOR = new ExceptionHandlingInterceptor();
|
||||
private final MethodBindings bindings;
|
||||
|
||||
protected AbstractJaxRsResourceProvider() {
|
||||
|
@ -153,8 +157,12 @@ public abstract class AbstractJaxRsResourceProvider<R extends IResource> extends
|
|||
private Response executeMethod(final String resourceString, RequestTypeEnum requestType, RestOperationTypeEnum restOperation, String id,
|
||||
BaseMethodBinding<?> method)
|
||||
throws IOException {
|
||||
final RequestDetails theRequest = createRequestDetails(resourceString, requestType, restOperation, id);
|
||||
return (Response) method.invokeServer(this, theRequest);
|
||||
final JaxRsRequest theRequest = createRequestDetails(resourceString, requestType, restOperation, id);
|
||||
try {
|
||||
return (Response) method.invokeServer(this, theRequest);
|
||||
} catch(BaseServerRuntimeResponseException theException) {
|
||||
return new JaxRsExceptionInterceptor().handleException(theRequest, theException);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package ca.uhn.fhir.jaxrs.server.interceptor;
|
||||
|
||||
import javax.ejb.ApplicationException;
|
||||
|
||||
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
||||
|
||||
@ApplicationException(rollback=false)
|
||||
public class BaseServerRuntimeResponseException extends BaseServerResponseException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public BaseServerRuntimeResponseException(BaseServerResponseException base) {
|
||||
super(base.getStatusCode(), base.getMessage(), base.getCause(), base.getOperationOutcome());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,169 +1,77 @@
|
|||
package ca.uhn.fhir.jaxrs.server.interceptor;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.interceptor.AroundInvoke;
|
||||
import javax.interceptor.InvocationContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.Response.ResponseBuilder;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
import ca.uhn.fhir.jaxrs.server.AbstractJaxRsProvider;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.jaxrs.server.util.JaxRsRequest;
|
||||
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.util.OperationOutcomeUtil;
|
||||
import ca.uhn.fhir.rest.server.interceptor.ExceptionHandlingInterceptor;
|
||||
|
||||
public class JaxRsExceptionInterceptor {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = LoggerFactory.getLogger(JaxRsExceptionInterceptor.class);
|
||||
private Class<?>[] myReturnStackTracesForExceptionTypes;
|
||||
|
||||
private ExceptionHandlingInterceptor exceptionHandler;
|
||||
@Context
|
||||
private UriInfo info;
|
||||
@Context
|
||||
private HttpHeaders headers;
|
||||
|
||||
AbstractJaxRsProvider theServer;
|
||||
|
||||
FhirContext fhirContext = AbstractJaxRsProvider.CTX;
|
||||
|
||||
@AroundInvoke
|
||||
public Object intercept(final InvocationContext ctx) throws Exception {
|
||||
try {
|
||||
if(!ourLog.isDebugEnabled() || ctx.getMethod().getName().contains("getResourceType")) {
|
||||
return ctx.proceed();
|
||||
} else {
|
||||
ourLog.debug("METHOD_CALL : " + ctx.getMethod().getName() + " [ " + Arrays.asList(ctx.getParameters()) + "] ");
|
||||
Object proceed = ctx.proceed();
|
||||
ourLog.debug("RESULT : " + proceed.toString());
|
||||
return proceed;
|
||||
}
|
||||
} catch(final Exception theException) {
|
||||
return handleException(theException);
|
||||
}
|
||||
}
|
||||
|
||||
public Response handleException(final Throwable theException)
|
||||
{
|
||||
IBaseOperationOutcome oo = null;
|
||||
int statusCode = Constants.STATUS_HTTP_500_INTERNAL_ERROR;
|
||||
|
||||
if (theException instanceof BaseServerResponseException) {
|
||||
oo = ((BaseServerResponseException) theException).getOperationOutcome();
|
||||
statusCode = ((BaseServerResponseException) theException).getStatusCode();
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate an OperationOutcome to return, unless the exception throw by the resource provider had one
|
||||
*/
|
||||
if (oo == null) {
|
||||
try {
|
||||
final RuntimeResourceDefinition ooDef = fhirContext.getResourceDefinition("OperationOutcome");
|
||||
oo = (IBaseOperationOutcome) ooDef.getImplementingClass().newInstance();
|
||||
|
||||
if (theException instanceof InternalErrorException) {
|
||||
ourLog.error("Failure during REST processing", theException);
|
||||
populateDetails(fhirContext, theException, oo);
|
||||
} else if (theException instanceof BaseServerResponseException) {
|
||||
ourLog.warn("Failure during REST processing: {}", theException);
|
||||
final BaseServerResponseException baseServerResponseException = (BaseServerResponseException) theException;
|
||||
statusCode = baseServerResponseException.getStatusCode();
|
||||
populateDetails(fhirContext, theException, oo);
|
||||
if (baseServerResponseException.getAdditionalMessages() != null) {
|
||||
for (final String next : baseServerResponseException.getAdditionalMessages()) {
|
||||
OperationOutcomeUtil.addIssue(fhirContext, oo, "error", next);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ourLog.error("Failure during REST processing: " + theException.toString(), theException);
|
||||
populateDetails(fhirContext, theException, oo);
|
||||
statusCode = Constants.STATUS_HTTP_500_INTERNAL_ERROR;
|
||||
}
|
||||
} catch (final Exception e1) {
|
||||
ourLog.error("Failed to instantiate OperationOutcome resource instance", e1);
|
||||
final ResponseBuilder result = Response.status(Constants.STATUS_HTTP_500_INTERNAL_ERROR);
|
||||
result.header(Constants.HEADER_CONTENT_TYPE, Constants.CT_TEXT_WITH_UTF8);
|
||||
result.header(Constants.HEADER_CONTENT_ENCODING, Constants.CHARSET_NAME_UTF8);
|
||||
result.entity(theException.getMessage());
|
||||
return result.build();
|
||||
}
|
||||
} else {
|
||||
ourLog.error("Unknown error during processing", theException);
|
||||
}
|
||||
|
||||
// Add headers associated with the specific error code
|
||||
if (theException instanceof BaseServerResponseException) {
|
||||
final Map<String, String[]> additional = ((BaseServerResponseException) theException).getAssociatedHeaders();
|
||||
if (additional != null) {
|
||||
for (final Entry<String, String[]> next : additional.entrySet()) {
|
||||
if (isNotBlank(next.getKey()) && next.getValue() != null) {
|
||||
final String nextKey = next.getKey();
|
||||
for (final String nextValue : next.getValue()) {
|
||||
addHeader(nextKey, nextValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final boolean requestIsBrowser = false; // RestfulServer.requestIsBrowser(theRequest);
|
||||
final String fhirServerBase = ""; // theRequestDetails.getFhirServerBase();
|
||||
|
||||
// theResponse.setStatus(statusCode);
|
||||
// theRequestDetails.getServer().addHeadersToResponse(theResponse);
|
||||
// theResponse.setContentType("text/plain");
|
||||
// theResponse.setCharacterEncoding("UTF-8");
|
||||
// theResponse.getWriter().append(theException.getMessage());
|
||||
// theResponse.getWriter().close();
|
||||
|
||||
final ResponseBuilder result = Response.status(statusCode);
|
||||
//final String resName = ctx.getResourceDefinition(oo).getName();
|
||||
result.header(Constants.HEADER_CONTENT_TYPE, Constants.CT_TEXT_WITH_UTF8);
|
||||
result.entity(theException.getMessage());
|
||||
return result.build();
|
||||
}
|
||||
|
||||
private void addHeader(final String nextKey, final String nextValue) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
private void populateDetails(final FhirContext theCtx, final Throwable theException, final IBaseOperationOutcome theOo) {
|
||||
if (myReturnStackTracesForExceptionTypes != null) {
|
||||
for (final Class<?> next : myReturnStackTracesForExceptionTypes) {
|
||||
if (next.isAssignableFrom(theException.getClass())) {
|
||||
final String detailsValue = theException.getMessage() + "\n\n" + ExceptionUtils.getStackTrace(theException);
|
||||
OperationOutcomeUtil.addIssue(theCtx, theOo, "error", detailsValue);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OperationOutcomeUtil.addIssue(theCtx, theOo, "error", theException.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* If any server methods throw an exception which extends any of the given exception types, the exception stack trace
|
||||
* will be returned to the user. This can be useful for helping to diagnose issues, but may not be desirable for
|
||||
* production situations.
|
||||
*
|
||||
* @param theExceptionTypes
|
||||
* The exception types for which to return the stack trace to the user.
|
||||
* @return Returns an instance of this interceptor, to allow for easy method chaining.
|
||||
*/
|
||||
public JaxRsExceptionInterceptor setReturnStackTracesForExceptionTypes(final Class<?>... theExceptionTypes) {
|
||||
myReturnStackTracesForExceptionTypes = theExceptionTypes;
|
||||
return this;
|
||||
}
|
||||
public JaxRsExceptionInterceptor() {
|
||||
this.exceptionHandler = new ExceptionHandlingInterceptor();
|
||||
}
|
||||
|
||||
public JaxRsExceptionInterceptor(ExceptionHandlingInterceptor exceptionHandler) {
|
||||
this.exceptionHandler = exceptionHandler;
|
||||
}
|
||||
|
||||
@AroundInvoke
|
||||
public Object intercept(final InvocationContext ctx) throws Throwable {
|
||||
try {
|
||||
return ctx.proceed();
|
||||
} catch(final Exception theException) {
|
||||
theServer = (AbstractJaxRsProvider) ctx.getTarget();
|
||||
throw convertException(theServer, theException);
|
||||
}
|
||||
}
|
||||
|
||||
public BaseServerRuntimeResponseException convertException(final AbstractJaxRsProvider theServer, final Exception theException) {
|
||||
JaxRsRequest requestDetails = new JaxRsRequest(theServer, null, null, null);
|
||||
BaseServerResponseException convertedException = preprocessException(theException, requestDetails);
|
||||
return new BaseServerRuntimeResponseException(convertedException);
|
||||
}
|
||||
|
||||
public Response handleException(JaxRsRequest theRequest, BaseServerRuntimeResponseException theException)
|
||||
throws IOException {
|
||||
return handleExceptionWithoutServletError(theRequest, theException);
|
||||
}
|
||||
|
||||
private BaseServerResponseException preprocessException(final Exception theException, JaxRsRequest requestDetails) {
|
||||
try {
|
||||
return exceptionHandler.preProcessOutgoingException(requestDetails, theException, null);
|
||||
} catch(ServletException e) {
|
||||
return new InternalErrorException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private Response handleExceptionWithoutServletError(JaxRsRequest theRequest, BaseServerResponseException theException) throws IOException {
|
||||
try {
|
||||
return (Response) exceptionHandler.handleException(theRequest, theException);
|
||||
} catch (ServletException e) {
|
||||
BaseServerResponseException newException = preprocessException(new InternalErrorException(e), theRequest);
|
||||
return handleExceptionWithoutServletError(theRequest, newException);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
|||
import ca.uhn.fhir.rest.method.BaseMethodBinding;
|
||||
import ca.uhn.fhir.rest.method.OperationMethodBinding;
|
||||
import ca.uhn.fhir.rest.method.SearchMethodBinding;
|
||||
import ca.uhn.fhir.rest.server.exceptions.NotImplementedOperationException;
|
||||
import ca.uhn.fhir.util.ReflectionUtil;
|
||||
|
||||
/**
|
||||
|
@ -63,7 +64,7 @@ public class MethodBindings {
|
|||
String nonEmptyQualifier = StringUtils.defaultIfBlank(qualifier, "");
|
||||
ConcurrentHashMap<String, BaseMethodBinding<?>> map = operationBindings.get(operationType);
|
||||
if(map == null || !map.containsKey(nonEmptyQualifier)) {
|
||||
throw new UnsupportedOperationException();
|
||||
throw new NotImplementedOperationException("Operation not implemented");
|
||||
} else {
|
||||
return map.get(nonEmptyQualifier);
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package ca.uhn.fhir.jaxrs.server;
|
|||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.argThat;
|
||||
|
@ -35,6 +36,7 @@ import ca.uhn.fhir.context.FhirContext;
|
|||
import ca.uhn.fhir.jaxrs.server.example.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.jaxrs.server.example.TestJaxRsConformanceRestProvider;
|
||||
import ca.uhn.fhir.jaxrs.server.example.TestJaxRsMockPatientRestProvider;
|
||||
import ca.uhn.fhir.jaxrs.server.interceptor.BaseServerRuntimeResponseException;
|
||||
import ca.uhn.fhir.jaxrs.server.interceptor.JaxRsExceptionInterceptor;
|
||||
import ca.uhn.fhir.model.api.BundleEntry;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
|
@ -351,15 +353,16 @@ public class AbstractJaxRsResourceProviderTest {
|
|||
@Test
|
||||
public void testXFindUnknownPatient() {
|
||||
try {
|
||||
when(mock.find(idCaptor.capture())).thenThrow(new ResourceNotFoundException(new IdDt("999955541264")));
|
||||
final Patient existing = client.read(Patient.class, "999955541264");
|
||||
BaseServerRuntimeResponseException notFoundException = new BaseServerRuntimeResponseException(new ResourceNotFoundException(new IdDt("999955541264")));
|
||||
when(mock.find(idCaptor.capture())).thenThrow(notFoundException);
|
||||
client.read(Patient.class, "999955541264");
|
||||
fail();
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
// assertEquals(e.getStatusCode(), 404);
|
||||
} catch (final ResourceNotFoundException e) {
|
||||
assertEquals(ResourceNotFoundException.STATUS_CODE, e.getStatusCode());
|
||||
assertTrue(e.getMessage().contains("999955541264"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Bundle getPatientBundle(int size) {
|
||||
Bundle result = new Bundle();
|
||||
for (long i = 0; i < size; i++) {
|
||||
|
|
|
@ -27,7 +27,7 @@ public class TestJaxRsConformanceRestProvider extends AbstractJaxRsConformancePr
|
|||
}
|
||||
|
||||
@Override
|
||||
protected ConcurrentHashMap<Class<? extends IResourceProvider>, IResourceProvider> getProviders() throws Exception {
|
||||
protected ConcurrentHashMap<Class<? extends IResourceProvider>, IResourceProvider> getProviders() {
|
||||
ConcurrentHashMap<Class<? extends IResourceProvider>, IResourceProvider> map = new ConcurrentHashMap<Class<? extends IResourceProvider>, IResourceProvider>();
|
||||
map.put(TestJaxRsMockPatientRestProvider.class, new TestJaxRsMockPatientRestProvider());
|
||||
map.put(TestJaxRsConformanceRestProvider.class, new TestJaxRsConformanceRestProvider());
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
package ca.uhn.fhir.jaxrs.server.interceptor;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.isNull;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import javax.interceptor.InvocationContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.jaxrs.server.AbstractJaxRsProvider;
|
||||
import ca.uhn.fhir.jaxrs.server.example.TestDummyPatientProvider;
|
||||
import ca.uhn.fhir.jaxrs.server.util.JaxRsRequest;
|
||||
import ca.uhn.fhir.rest.method.RequestDetails;
|
||||
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.NotImplementedOperationException;
|
||||
import ca.uhn.fhir.rest.server.interceptor.ExceptionHandlingInterceptor;
|
||||
|
||||
public class JaxRsExceptionInterceptorTest {
|
||||
|
||||
JaxRsExceptionInterceptor interceptor = new JaxRsExceptionInterceptor();
|
||||
private InvocationContext context;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
interceptor = new JaxRsExceptionInterceptor();
|
||||
context = mock(InvocationContext.class);
|
||||
TestDummyPatientProvider provider = spy(TestDummyPatientProvider.class);
|
||||
when(context.getTarget()).thenReturn(provider);
|
||||
doReturn("http://baseUri").when(provider).getBaseForServer();
|
||||
doReturn(new HashMap<String, String[]>()).when(provider).getQueryMap();
|
||||
doReturn(mock(HttpHeaders.class)).when(provider).getHeaders();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInterceptWithBaseServerError() throws Throwable {
|
||||
NotImplementedOperationException thrownException = new NotImplementedOperationException("not implemented");
|
||||
when(context.proceed()).thenThrow(thrownException);
|
||||
try {
|
||||
interceptor.intercept(context);
|
||||
fail();
|
||||
} catch (BaseServerResponseException e) {
|
||||
assertEquals(e.getMessage(), thrownException.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntercepWithServletError() throws Throwable {
|
||||
ExceptionHandlingInterceptor exceptionHandler = mock(ExceptionHandlingInterceptor.class);
|
||||
when(exceptionHandler.preProcessOutgoingException(any(RequestDetails.class), any(Throwable.class),
|
||||
isNull(HttpServletRequest.class))).thenThrow(new ServletException("someMessage"));
|
||||
interceptor = new JaxRsExceptionInterceptor(exceptionHandler);
|
||||
when(context.proceed()).thenThrow(new ServletException());
|
||||
try {
|
||||
interceptor.intercept(context);
|
||||
fail();
|
||||
} catch (BaseServerResponseException e) {
|
||||
assertTrue(e.getMessage().contains("someMessage"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInterceptServletWithoutError() throws Throwable {
|
||||
Object expected = new Object();
|
||||
when(context.proceed()).thenReturn(expected);
|
||||
Object result = interceptor.intercept(context);
|
||||
assertSame(expected, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleExceptionWithServletError() throws Throwable {
|
||||
JaxRsRequest request = new JaxRsRequest((AbstractJaxRsProvider) context.getTarget(), null, null, null);
|
||||
|
||||
ExceptionHandlingInterceptor exceptionHandler = spy(ExceptionHandlingInterceptor.class);
|
||||
doThrow(new ServletException("someMessage")).when(exceptionHandler).preProcessOutgoingException(any(RequestDetails.class), any(Throwable.class),
|
||||
isNull(HttpServletRequest.class));
|
||||
|
||||
interceptor = new JaxRsExceptionInterceptor(exceptionHandler);
|
||||
|
||||
when(context.proceed()).thenThrow(new ServletException());
|
||||
|
||||
BaseServerRuntimeResponseException thrownException = new BaseServerRuntimeResponseException(new NotImplementedOperationException("not implemented"));
|
||||
doThrow(new javax.servlet.ServletException("someMessage")).when(exceptionHandler).handleException(request, thrownException);
|
||||
BaseServerRuntimeResponseException internalException = thrownException;
|
||||
Response result = interceptor.handleException(request, internalException);
|
||||
assertEquals(InternalErrorException.STATUS_CODE, result.getStatus());
|
||||
}
|
||||
|
||||
}
|
|
@ -26,6 +26,7 @@ import ca.uhn.fhir.rest.annotation.Update;
|
|||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.rest.server.exceptions.NotImplementedOperationException;
|
||||
|
||||
@FixMethodOrder(MethodSorters.DEFAULT)
|
||||
public class MethodBindingsTest {
|
||||
|
@ -35,7 +36,7 @@ public class MethodBindingsTest {
|
|||
MethodBindings.getClassBindings().clear();
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
@Test(expected = NotImplementedOperationException.class)
|
||||
public void testFindMethodsForProviderNotDefinedMappingMethods() {
|
||||
new TestDummyPatientProvider().getBindings().getBinding(RestOperationTypeEnum.UPDATE, "");
|
||||
}
|
||||
|
@ -120,7 +121,7 @@ public class MethodBindingsTest {
|
|||
try {
|
||||
bindings.getBinding(RestOperationTypeEnum.EXTENDED_OPERATION_TYPE, "$thirdMethod");
|
||||
fail();
|
||||
} catch(UnsupportedOperationException e){
|
||||
} catch(NotImplementedOperationException e){
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ public class JaxRsConformanceProvider extends AbstractJaxRsConformanceProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected ConcurrentHashMap<Class<? extends IResourceProvider>, IResourceProvider> getProviders() throws Exception {
|
||||
protected ConcurrentHashMap<Class<? extends IResourceProvider>, IResourceProvider> getProviders() {
|
||||
ConcurrentHashMap<Class<? extends IResourceProvider>, IResourceProvider> map = new ConcurrentHashMap<Class<? extends IResourceProvider>, IResourceProvider>();
|
||||
map.put(JaxRsConformanceProvider.class, new JaxRsConformanceProvider());
|
||||
map.put(JaxRsPatientRestProvider.class, new JaxRsPatientRestProvider());
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package ca.uhn.fhir.jaxrs.server.example;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
|
@ -66,7 +67,7 @@ public class JaxRsPatientRestProvider extends AbstractJaxRsResourceProvider<Pati
|
|||
private static Long counter = 1L;
|
||||
private static final ConcurrentHashMap<String, List<Patient>> patients = new ConcurrentHashMap<String, List<Patient>>();
|
||||
|
||||
public JaxRsPatientRestProvider() throws Exception {
|
||||
public JaxRsPatientRestProvider() {
|
||||
super(JaxRsPatientRestProvider.class);
|
||||
}
|
||||
|
||||
|
@ -132,7 +133,8 @@ public class JaxRsPatientRestProvider extends AbstractJaxRsResourceProvider<Pati
|
|||
}
|
||||
|
||||
@Read
|
||||
public Patient find(@IdParam final IdDt theId) {
|
||||
@Interceptors(JaxRsExceptionInterceptor.class)
|
||||
public Patient find(@IdParam final IdDt theId) throws InvocationTargetException {
|
||||
if (patients.containsKey(theId.getIdPart())) {
|
||||
return getLast(patients.get(theId.getIdPart()));
|
||||
} else {
|
||||
|
@ -168,7 +170,7 @@ public class JaxRsPatientRestProvider extends AbstractJaxRsResourceProvider<Pati
|
|||
}
|
||||
|
||||
@Delete
|
||||
public MethodOutcome delete(@IdParam final IdDt theId) {
|
||||
public MethodOutcome delete(@IdParam final IdDt theId) throws InvocationTargetException {
|
||||
final Patient deletedPatient = find(theId);
|
||||
patients.remove(deletedPatient.getId().getIdPart());
|
||||
final MethodOutcome result = new MethodOutcome().setCreated(true);
|
||||
|
@ -203,7 +205,7 @@ public class JaxRsPatientRestProvider extends AbstractJaxRsResourceProvider<Pati
|
|||
|
||||
@Operation(name = "last", idempotent = true, returnParameters = {
|
||||
@OperationParam(name = "return", type = StringDt.class) })
|
||||
public Parameters last(@OperationParam(name = "dummy") StringDt dummyInput) {
|
||||
public Parameters last(@OperationParam(name = "dummy") StringDt dummyInput) throws InvocationTargetException {
|
||||
System.out.println("inputparameter");
|
||||
Parameters parameters = new Parameters();
|
||||
Patient patient = find(new IdDt(counter.intValue() - 1));
|
||||
|
|
|
@ -63,7 +63,8 @@ public class JaxRsPatientProviderTest {
|
|||
|
||||
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
||||
ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
|
||||
client = ourCtx.newRestfulGenericClient("http://localhost:" + ourPort + "/");
|
||||
//client = ourCtx.newRestfulGenericClient("http://localhost:" + ourPort + "/");
|
||||
client = ourCtx.newRestfulGenericClient("http://localhost:8580/hapi-fhir-jaxrsserver-example/jaxrs-demo/");
|
||||
client.setEncoding(EncodingEnum.JSON);
|
||||
client.registerInterceptor(new LoggingInterceptor(true));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue