diff --git a/config/alfresco/public-rest-context.xml b/config/alfresco/public-rest-context.xml index ca49b16bb9..98eb973ec9 100644 --- a/config/alfresco/public-rest-context.xml +++ b/config/alfresco/public-rest-context.xml @@ -145,6 +145,7 @@ + diff --git a/source/java/org/alfresco/rest/framework/webscripts/AbstractResourceWebScript.java b/source/java/org/alfresco/rest/framework/webscripts/AbstractResourceWebScript.java index 8888529cd2..fef49a9ee2 100644 --- a/source/java/org/alfresco/rest/framework/webscripts/AbstractResourceWebScript.java +++ b/source/java/org/alfresco/rest/framework/webscripts/AbstractResourceWebScript.java @@ -25,6 +25,7 @@ import java.util.List; import java.util.ListIterator; import java.util.Map; +import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.repo.node.integrity.IntegrityException; import org.alfresco.repo.tenant.TenantUtil; import org.alfresco.repo.transaction.RetryingTransactionHelper; @@ -146,17 +147,9 @@ public abstract class AbstractResourceWebScript extends ApiWebScript implements } } - catch (IntegrityException intException) + catch (AlfrescoRuntimeException | ApiException | WebScriptException xception ) { - renderErrorResponse(resolveException(intException), res); - } - catch (ApiException apiException) - { - renderErrorResponse(resolveException(apiException), res); - } - catch (WebScriptException webException) - { - renderErrorResponse(resolveException(webException), res); + renderErrorResponse(resolveException(xception), res); } catch (RuntimeException runtimeException) { diff --git a/source/java/org/alfresco/rest/framework/webscripts/ApiWebScript.java b/source/java/org/alfresco/rest/framework/webscripts/ApiWebScript.java index 2ddad57430..7aa3324e0e 100644 --- a/source/java/org/alfresco/rest/framework/webscripts/ApiWebScript.java +++ b/source/java/org/alfresco/rest/framework/webscripts/ApiWebScript.java @@ -161,7 +161,7 @@ public abstract class ApiWebScript extends AbstractWebScript } } - private Api determineApi(Map templateVars) + public Api determineApi(Map templateVars) { String apiScope = templateVars.get("apiScope"); String apiVersion = templateVars.get("apiVersion"); diff --git a/source/test-java/org/alfresco/rest/framework/tests/api/mocks/BadEntityResource.java b/source/test-java/org/alfresco/rest/framework/tests/api/mocks/BadEntityResource.java new file mode 100644 index 0000000000..da7d871ff3 --- /dev/null +++ b/source/test-java/org/alfresco/rest/framework/tests/api/mocks/BadEntityResource.java @@ -0,0 +1,33 @@ +package org.alfresco.rest.framework.tests.api.mocks; + +import org.alfresco.repo.node.integrity.IntegrityException; +import org.alfresco.rest.framework.WebApiDescription; +import org.alfresco.rest.framework.WebApiParam; +import org.alfresco.rest.framework.WebApiParameters; +import org.alfresco.rest.framework.core.ResourceParameter; +import org.alfresco.rest.framework.resource.EntityResource; +import org.alfresco.rest.framework.resource.actions.interfaces.EntityResourceAction; +import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo; +import org.alfresco.rest.framework.resource.parameters.Parameters; +import org.springframework.extensions.webscripts.Status; + +@EntityResource(name= BadEntityResource.ENTITY_KEY,title="bad resource that does bad things") +public class BadEntityResource implements EntityResourceAction.Read,EntityResourceAction.ReadById +{ + public static final String ENTITY_KEY = "bad"; + + + @Override + public Sheep readById(String id, Parameters parameters) + { + throw new IntegrityException("bad integrity", null); + } + + @Override + @WebApiDescription(title = "Gets all the Sheep", successStatus = Status.STATUS_ACCEPTED) + public CollectionWithPagingInfo readAll(Parameters params) + { + throw new RuntimeException("read all"); + } + +} diff --git a/source/test-java/org/alfresco/rest/framework/tests/core/AllRestFrameworkTest.java b/source/test-java/org/alfresco/rest/framework/tests/core/AllRestFrameworkTest.java index f02260abde..0faddfc3e8 100644 --- a/source/test-java/org/alfresco/rest/framework/tests/core/AllRestFrameworkTest.java +++ b/source/test-java/org/alfresco/rest/framework/tests/core/AllRestFrameworkTest.java @@ -11,7 +11,8 @@ import org.junit.runners.Suite.SuiteClasses; @RunWith(Suite.class) @SuiteClasses({ InspectorTests.class, JsonJacksonTests.class, ParamsExtractorTests.class, ResourceLocatorTests.class, ResourceWebScriptHelperTests.class, SerializeTests.class, - WhereTests.class, ExecutionTests.class, WithResponseTest.class }) + WhereTests.class, ExecutionTests.class, WithResponseTest.class, + ExceptionResolverTests.class }) public class AllRestFrameworkTest { diff --git a/source/test-java/org/alfresco/rest/framework/tests/core/ExceptionResolverTests.java b/source/test-java/org/alfresco/rest/framework/tests/core/ExceptionResolverTests.java index 8b004f62f1..cbf3f6329d 100644 --- a/source/test-java/org/alfresco/rest/framework/tests/core/ExceptionResolverTests.java +++ b/source/test-java/org/alfresco/rest/framework/tests/core/ExceptionResolverTests.java @@ -5,11 +5,13 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import org.alfresco.repo.forms.FormNotFoundException; +import org.alfresco.repo.node.integrity.IntegrityException; import org.alfresco.rest.framework.core.exceptions.ApiException; import org.alfresco.rest.framework.core.exceptions.ConstraintViolatedException; import org.alfresco.rest.framework.core.exceptions.DeletedResourceException; import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException; import org.alfresco.rest.framework.core.exceptions.ErrorResponse; +import org.alfresco.rest.framework.core.exceptions.InsufficientStorageException; import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException; import org.alfresco.rest.framework.core.exceptions.NotFoundException; import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException; @@ -77,6 +79,12 @@ public class ExceptionResolverTests //Try a random exception response = simpleMappingExceptionResolver.resolveException(new FormNotFoundException(null)); assertNull(response); + + response = simpleMappingExceptionResolver.resolveException(new InsufficientStorageException(null)); + assertEquals(507, response.getStatusCode()); + + response = simpleMappingExceptionResolver.resolveException(new IntegrityException(null)); + assertEquals(422, response.getStatusCode()); } } diff --git a/source/test-java/org/alfresco/rest/framework/tests/core/ExecutionTests.java b/source/test-java/org/alfresco/rest/framework/tests/core/ExecutionTests.java index 17d5b60427..da20c068d9 100644 --- a/source/test-java/org/alfresco/rest/framework/tests/core/ExecutionTests.java +++ b/source/test-java/org/alfresco/rest/framework/tests/core/ExecutionTests.java @@ -5,14 +5,17 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import org.alfresco.rest.framework.Api; import org.alfresco.rest.framework.core.ResourceLocator; import org.alfresco.rest.framework.core.ResourceLookupDictionary; import org.alfresco.rest.framework.core.ResourceWithMetadata; +import org.alfresco.rest.framework.core.exceptions.SimpleMappingExceptionResolver; import org.alfresco.rest.framework.jacksonextensions.ExecutionResult; import org.alfresco.rest.framework.resource.actions.ActionExecutor; import org.alfresco.rest.framework.resource.content.ContentInfo; @@ -27,9 +30,12 @@ import org.alfresco.rest.framework.webscripts.AbstractResourceWebScript; import org.alfresco.rest.framework.webscripts.ApiWebScript; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.extensions.webscripts.Cache; +import org.springframework.extensions.webscripts.Match; import org.springframework.extensions.webscripts.Status; import org.springframework.extensions.webscripts.WebScriptRequest; import org.springframework.extensions.webscripts.WebScriptResponse; @@ -37,9 +43,12 @@ import org.springframework.http.HttpMethod; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import javax.servlet.http.HttpServletResponse; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -50,6 +59,9 @@ public class ExecutionTests extends AbstractContextTest { static final Api api3 = Api.valueOf("alfrescomock", "private", "3"); + @Autowired + SimpleMappingExceptionResolver simpleMappingExceptionResolver; + @Test public void testInvokeGet() throws IOException { @@ -218,4 +230,55 @@ public class ExecutionTests extends AbstractContextTest result = executor.execute(calf, Params.valueOf("4", "56", mock(WebScriptRequest.class)), mock(WebScriptResponse.class), false); assertNull(result); } + + @Test + public void testInvokeAbstract() throws IOException + { + AbstractResourceWebScript executor = (AbstractResourceWebScript) applicationContext.getBean("executorOfGets"); + executor.setLocator(locator); + executor.setResolver(simpleMappingExceptionResolver); + executor.setJsonHelper(jsonHelper); + Map templateVars = new HashMap(); + templateVars.put("apiScope", "private"); + templateVars.put("apiVersion", "1"); + templateVars.put("apiName", "alfrescomock"); + templateVars.put(ResourceLocator.COLLECTION_RESOURCE, "sheep"); + executor.execute(executor.determineApi(templateVars), mockRequest(templateVars,new HashMap>(1)), mock(WebScriptResponse.class)); + + WebScriptResponse response = mockResponse(); + templateVars.put(ResourceLocator.COLLECTION_RESOURCE, "bad"); + executor.execute(api, mockRequest(templateVars,new HashMap>(1)), response); + //throws a runtime exception so INTERNAL_SERVER_ERROR + verify(response, times(1)).setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + + response = mockResponse(); + templateVars.put(ResourceLocator.ENTITY_ID, "badId"); + executor.execute(api, mockRequest(templateVars,new HashMap>(1)), response); + //throws a IntegrityException so 422 + verify(response, times(1)).setStatus(422); + + } + + private WebScriptResponse mockResponse() throws IOException + { + WebScriptResponse res = mock(WebScriptResponse.class); + when(res.getOutputStream()).thenReturn(new ByteArrayOutputStream()); + return res; + } + + private WebScriptRequest mockRequest(Map templateVars, final Map> params) + { + final String[] paramNames = params.keySet().toArray(new String[]{}); + WebScriptRequest request = mock(WebScriptRequest.class); + when(request.getServiceMatch()).thenReturn(new Match(null, templateVars,null)); + when(request.getParameterNames()).thenReturn(paramNames); + when(request.getParameterValues(anyString())).thenAnswer(new Answer() { + @Override + public String[] answer(InvocationOnMock invocation) throws Throwable { + Object[] args = invocation.getArguments(); + return params.get((String) args[0]).toArray(new String[]{}); + } + }); + return request; + } } diff --git a/source/test-resources/test-rest-context.xml b/source/test-resources/test-rest-context.xml index c35e3f77ac..6613c27ff6 100644 --- a/source/test-resources/test-rest-context.xml +++ b/source/test-resources/test-rest-context.xml @@ -34,15 +34,21 @@ - - - - - - - - - + + + + + + + + + + + + + + +