Repository: jclouds-labs Updated Branches: refs/heads/master 4a9536b8c -> 2d9cb407e
JCLOUDS-1432 - handle RESOURCE_NOT_FOUND, do not expect 404 when assets not found Project: http://git-wip-us.apache.org/repos/asf/jclouds-labs/repo Commit: http://git-wip-us.apache.org/repos/asf/jclouds-labs/commit/2d9cb407 Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs/tree/2d9cb407 Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs/diff/2d9cb407 Branch: refs/heads/master Commit: 2d9cb407e61b1568e2ce9a118bf8bc2c8a2c9855 Parents: 4a9536b Author: FileIOUtility <[email protected]> Authored: Tue Jul 17 14:28:37 2018 +0100 Committer: Ignasi Barrera <[email protected]> Committed: Tue Jul 17 10:47:39 2018 -0700 ---------------------------------------------------------------------- .../cloudcontrol/features/ServerApi.java | 2 -- .../DimensionDataCloudControlErrorHandler.java | 26 +++++++++++------- .../features/ServerApiMockTest.java | 28 +++++++++----------- .../BaseDimensionDataCloudControlMockTest.java | 12 +++++++-- 4 files changed, 40 insertions(+), 28 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2d9cb407/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerApi.java ---------------------------------------------------------------------- diff --git a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerApi.java b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerApi.java index 6338258..f6ba5c5 100644 --- a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerApi.java +++ b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerApi.java @@ -68,7 +68,6 @@ public interface ServerApi { @GET @Path("/server") @ResponseParser(ParseServers.class) - @Fallback(Fallbacks.EmptyIterableWithMarkerOnNotFoundOr404.class) PaginatedCollection<Server> listServers(DatacenterIdListFilters datacenterIdListFilters); @Named("server:list") @@ -76,7 +75,6 @@ public interface ServerApi { @Path("/server") @Transform(ParseServers.ToPagedIterable.class) @ResponseParser(ParseServers.class) - @Fallback(Fallbacks.EmptyPagedIterableOnNotFoundOr404.class) PagedIterable<Server> listServers(); @Named("server:get") http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2d9cb407/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/handlers/DimensionDataCloudControlErrorHandler.java ---------------------------------------------------------------------- diff --git a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/handlers/DimensionDataCloudControlErrorHandler.java b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/handlers/DimensionDataCloudControlErrorHandler.java index 1d65315..896d8be 100644 --- a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/handlers/DimensionDataCloudControlErrorHandler.java +++ b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/handlers/DimensionDataCloudControlErrorHandler.java @@ -26,6 +26,8 @@ import org.jclouds.rest.ResourceNotFoundException; import javax.inject.Singleton; +import java.util.ConcurrentModificationException; + import static org.jclouds.http.HttpUtils.closeClientButKeepContentStream; /** @@ -47,16 +49,22 @@ public class DimensionDataCloudControlErrorHandler implements HttpErrorHandler { String.format("%s -> %s", command.getCurrentRequest().getRequestLine(), response.getStatusLine()); switch (response.getStatusCode()) { case 400: - if (message.contains("RESOURCE_NOT_FOUND") || message.contains("OPERATION_NOT_SUPPORTED")) { + if (message.contains("RESOURCE_NOT_FOUND")) { exception = new ResourceNotFoundException(message, exception); - } else if (message.contains("INVALID_INPUT_DATA") || message.contains("ORGANIZATION_NOT_VERIFIED") - || (message.contains("SYSTEM_ERROR") && !message.contains("RETRYABLE_SYSTEM_ERROR")) || message - .contains("CPU_SPEED_NOT_AVAILABLE") || message.contains("CONFIGURATION_NOT_SUPPORTED")) { + } else if (message.contains("OPERATION_NOT_SUPPORTED")) { + exception = new UnsupportedOperationException(message, exception); + } else if (message.contains("RESOURCE_BUSY")) { + exception = new ConcurrentModificationException(message, exception); + } else if (message.contains("RESOURCE_LOCKED")) { exception = new IllegalStateException(message, exception); - } else if (message.contains("RESOURCE_BUSY") || message.contains("UNEXPECTED_ERROR")) { - exception = new ResourceNotFoundException(message, exception); } else if (message.contains("NAME_NOT_UNIQUE")) { exception = new ResourceAlreadyExistsException(message, exception); + } else if (message.contains("UNEXPECTED_ERROR") + || message.contains("RETRYABLE_SYSTEM_ERROR") + || message.contains("SYSTEM_ERROR")) { + break; + } else { + exception = new IllegalArgumentException(message, exception); } break; case 401: @@ -66,9 +74,9 @@ public class DimensionDataCloudControlErrorHandler implements HttpErrorHandler { exception = new AuthorizationException(message, exception); break; case 404: - if (!command.getCurrentRequest().getMethod().equals("DELETE")) { - exception = new ResourceNotFoundException(message, exception); - } + // CloudControl uses error code 400 with RESOURCE_NOT_FOUND to report missing assets + // 404 means malformed URI only + exception = new IllegalArgumentException(message, exception); break; } command.setException(exception); http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2d9cb407/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerApiMockTest.java ---------------------------------------------------------------------- diff --git a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerApiMockTest.java b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerApiMockTest.java index e396139..c8cd46d 100644 --- a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerApiMockTest.java +++ b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerApiMockTest.java @@ -26,11 +26,10 @@ import org.jclouds.dimensiondata.cloudcontrol.domain.Server; import org.jclouds.dimensiondata.cloudcontrol.domain.options.CloneServerOptions; import org.jclouds.dimensiondata.cloudcontrol.domain.options.CreateServerOptions; import org.jclouds.dimensiondata.cloudcontrol.internal.BaseAccountAwareCloudControlMockTest; +import org.jclouds.http.HttpResponseException; import org.jclouds.http.Uris; -import org.jclouds.rest.ResourceNotFoundException; import org.testng.annotations.Test; -import javax.ws.rs.HttpMethod; import java.util.List; import static javax.ws.rs.HttpMethod.GET; @@ -39,6 +38,7 @@ import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown; import static org.jclouds.dimensiondata.cloudcontrol.options.DatacenterIdListFilters.Builder.datacenterId; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertNull; import static org.testng.Assert.assertTrue; /** @@ -55,8 +55,8 @@ public class ServerApiMockTest extends BaseAccountAwareCloudControlMockTest { try { serverApi().deployServer(ServerApiMockTest.class.getSimpleName(), "imageId", true, networkInfo, "administratorPassword"); - failBecauseExceptionWasNotThrown(ResourceNotFoundException.class); - } catch (ResourceNotFoundException e) { + failBecauseExceptionWasNotThrown(HttpResponseException.class); + } catch (HttpResponseException e) { assertNotNull(e); assertSent(POST, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/server/deployServer"); } @@ -121,10 +121,9 @@ public class ServerApiMockTest extends BaseAccountAwareCloudControlMockTest { return Uris.uriBuilder("/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/server/server"); } - public void testListServers_404() throws Exception { - server.enqueue(response404()); - assertTrue(serverApi().listServers().concat().isEmpty()); - assertSent(HttpMethod.GET, getListServerUriBuilder().toString()); + public void testListServers_NoServersFound() { + server.enqueue(emptyListResponse("server")); + assertTrue(serverApi().listServers().concat().isEmpty(), "should return empty list when no Servers found"); } public void testGetServer() throws Exception { @@ -135,10 +134,10 @@ public class ServerApiMockTest extends BaseAccountAwareCloudControlMockTest { assertNotNull(found.guest().vmTools()); } - public void testGetServer_404() throws Exception { - server.enqueue(response404()); - serverApi().getServer("12345"); - assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/server/server/12345"); + public void testGetServer_NotFound() { + server.enqueue(responseResourceNotFound()); + Server foundServer = serverApi().getServer("12345"); + assertNull(foundServer, "should return null when Server was not found"); } public void testDeleteServer() throws Exception { @@ -149,10 +148,9 @@ public class ServerApiMockTest extends BaseAccountAwareCloudControlMockTest { assertBodyContains(recordedRequest, "{\"id\":\"12345\"}"); } - public void testDeleteServer_404() throws Exception { - server.enqueue(response404()); + public void testDeleteServer_NotFound() { + server.enqueue(responseResourceNotFound()); serverApi().deleteServer("12345"); - assertSent(POST, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/server/deleteServer"); } public void testPowerOffServer() throws Exception { http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2d9cb407/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/internal/BaseDimensionDataCloudControlMockTest.java ---------------------------------------------------------------------- diff --git a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/internal/BaseDimensionDataCloudControlMockTest.java b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/internal/BaseDimensionDataCloudControlMockTest.java index 72dfd2c..7ddba51 100644 --- a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/internal/BaseDimensionDataCloudControlMockTest.java +++ b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/internal/BaseDimensionDataCloudControlMockTest.java @@ -149,7 +149,7 @@ public class BaseDimensionDataCloudControlMockTest implements IHookable { */ protected MockResponse responseUnexpectedError() { return new MockResponse().setResponseCode(400).setStatus("HTTP/1.1 400 Bad Request") - .setBody("content: [{\"operation\":\"OPERATION\",\"responseCode\":\"UNEXPECTED_ERROR\"}]"); + .setBody("{\"operation\":\"OPERATION\",\"responseCode\":\"UNEXPECTED_ERROR\"}"); } /** @@ -159,13 +159,21 @@ public class BaseDimensionDataCloudControlMockTest implements IHookable { */ protected MockResponse responseResourceNotFound() { return new MockResponse().setResponseCode(400).setStatus("HTTP/1.1 400 Bad Request") - .setBody("content: [{\"operation\":\"OPERATION\",\"responseCode\":\"RESOURCE_NOT_FOUND\"}]"); + .setBody("{\"operation\":\"OPERATION\",\"responseCode\":\"RESOURCE_NOT_FOUND\"}"); } protected MockResponse response404() { return new MockResponse().setStatus("HTTP/1.1 404 Not Found"); } + protected MockResponse emptyListResponse(String assetName) { + return new MockResponse().setBody("{ \"" + assetName + "\": []," + + " \"pageNumber\": 1,\n" + + " \"pageCount\": 0,\n" + + " \"totalCount\": 0,\n" + + " \"pageSize\": 250}"); + } + /** * Mocked OK 200 Response *
