From 86129df416049c3808e647e48353aa34fa1e80e3 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Wed, 1 Jun 2011 20:30:30 -0700 Subject: [PATCH] stabilized bluelock --- .../strategy/VCloudDestroyNodeStrategy.java | 53 +++++++++---------- .../features/VAppTemplateClientLiveTest.java | 21 ++++---- .../vcloud/features/VmClientLiveTest.java | 2 +- .../ParseVCloudErrorFromHttpResponse.java | 5 +- .../ParseVCloudErrorFromHttpResponseTest.java | 26 ++++++--- .../compute/BaseComputeServiceLiveTest.java | 8 +-- .../http/BaseHttpErrorHandlerTest.java | 12 +++-- ...kVCloudDirectorComputeServiceLiveTest.java | 2 +- 8 files changed, 71 insertions(+), 58 deletions(-) diff --git a/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/strategy/VCloudDestroyNodeStrategy.java b/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/strategy/VCloudDestroyNodeStrategy.java index a11e4b0052..119af79829 100644 --- a/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/strategy/VCloudDestroyNodeStrategy.java +++ b/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/strategy/VCloudDestroyNodeStrategy.java @@ -67,50 +67,47 @@ public class VCloudDestroyNodeStrategy implements DestroyNodeStrategy { VApp vApp = client.getVAppClient().getVApp(vappId); if (vApp == null) return null; - vApp = powerOffVAppIfDeployed(vApp); + + waitForPendingTasksToComplete(vApp); + vApp = undeployVAppIfDeployed(vApp); - deleteVApp(vappId); + deleteVApp(vApp); try { return getNode.getNode(id); } catch (AuthorizationException e) { + // vcloud bug will sometimes throw an exception getting the vapp right after deleting it. logger.trace("authorization error getting %s after deletion: %s", id, e.getMessage()); return null; } } - void deleteVApp(URI vappId) { - logger.debug(">> deleting vApp(%s)", vappId); - Task task = client.getVAppClient().deleteVApp(vappId); + void waitForPendingTasksToComplete(VApp vApp) { + for (Task task : vApp.getTasks()) + waitForTask(task, vApp); + } + + public void waitForTask(Task task, VApp vAppResponse) { if (!successTester.apply(task.getHref())) { - throw new RuntimeException(String.format("failed to %s %s: %s", "delete", vappId, task)); + throw new RuntimeException(String.format("failed to %s %s: %s", task.getName(), vAppResponse.getName(), task)); } - logger.debug("<< deleted vApp(%s)", vappId); + } + + void deleteVApp(VApp vApp) { + logger.debug(">> deleting vApp(%s)", vApp.getHref()); + waitForTask(client.getVAppClient().deleteVApp(vApp.getHref()), vApp); + logger.debug("<< deleted vApp(%s)", vApp.getHref()); } VApp undeployVAppIfDeployed(VApp vApp) { - if (vApp.getStatus().compareTo(Status.RESOLVED) > 0) { + if (vApp.getStatus() != Status.OFF) { logger.debug(">> undeploying vApp(%s), current status: %s", vApp.getName(), vApp.getStatus()); - Task task = client.getVAppClient().undeployVApp(vApp.getHref()); - if (!successTester.apply(task.getHref())) { - // TODO timeout - throw new RuntimeException(String.format("failed to %s %s: %s", "undeploy", vApp.getName(), task)); + try { + waitForTask(client.getVAppClient().undeployVApp(vApp.getHref()), vApp); + vApp = client.getVAppClient().getVApp(vApp.getHref()); + logger.debug("<< %s vApp(%s)", vApp.getStatus(), vApp.getName()); + } catch (IllegalStateException e) { + logger.warn(e, "<< %s vApp(%s)", vApp.getStatus(), vApp.getName()); } - vApp = client.getVAppClient().getVApp(vApp.getHref()); - logger.debug("<< %s vApp(%s)", vApp.getStatus(), vApp.getName()); - } - return vApp; - } - - VApp powerOffVAppIfDeployed(VApp vApp) { - if (vApp.getStatus().compareTo(Status.OFF) > 0) { - logger.debug(">> powering off vApp(%s), current status: %s", vApp.getName(), vApp.getStatus()); - Task task = client.getVAppClient().powerOffVApp(vApp.getHref()); - if (!successTester.apply(task.getHref())) { - // TODO timeout - throw new RuntimeException(String.format("failed to %s %s: %s", "powerOff", vApp.getName(), task)); - } - vApp = client.getVAppClient().getVApp(vApp.getHref()); - logger.debug("<< %s vApp(%s)", vApp.getStatus(), vApp.getName()); } return vApp; } diff --git a/apis/vcloud/src/test/java/org/jclouds/vcloud/features/VAppTemplateClientLiveTest.java b/apis/vcloud/src/test/java/org/jclouds/vcloud/features/VAppTemplateClientLiveTest.java index 8ba9754b1b..14f9fed1c9 100644 --- a/apis/vcloud/src/test/java/org/jclouds/vcloud/features/VAppTemplateClientLiveTest.java +++ b/apis/vcloud/src/test/java/org/jclouds/vcloud/features/VAppTemplateClientLiveTest.java @@ -34,7 +34,9 @@ import org.jclouds.vcloud.domain.Catalog; import org.jclouds.vcloud.domain.CatalogItem; import org.jclouds.vcloud.domain.Org; import org.jclouds.vcloud.domain.ReferenceType; +import org.jclouds.vcloud.domain.Status; import org.jclouds.vcloud.domain.Task; +import org.jclouds.vcloud.domain.VApp; import org.jclouds.vcloud.domain.VAppTemplate; import org.jclouds.vcloud.options.CatalogItemOptions; import org.jclouds.vcloud.predicates.TaskSuccess; @@ -125,20 +127,17 @@ public class VAppTemplateClientLiveTest extends BaseVCloudClientLiveTest { Predicate taskTester = new RetryablePredicate(new TaskSuccess(getVCloudApi()), 600, 5, TimeUnit.SECONDS); - // I have to powerOff first - Task task = getVCloudApi().getVAppClient().powerOffVApp(URI.create(node.getId())); - - // wait up to ten minutes per above - assert taskTester.apply(task.getHref()) : node; - - // having a problem where the api is returning an error telling us to stop! - // I have to undeploy first - task = getVCloudApi().getVAppClient().undeployVApp(URI.create(node.getId())); + Task task = getVCloudApi().getVAppClient().undeployVApp(URI.create(node.getId())); // wait up to ten minutes per above assert taskTester.apply(task.getHref()) : node; + VApp vApp = getVCloudApi().getVAppClient().getVApp(URI.create(node.getId())); + + // wait up to ten minutes per above + assertEquals(vApp.getStatus(), Status.OFF); + // vdc is equiv to the node's location // vapp uri is the same as the node's id vappTemplate = getVCloudApi().getVAppTemplateClient().captureVAppAsTemplateInVDC(URI.create(node.getId()), @@ -155,11 +154,11 @@ public class VAppTemplateClientLiveTest extends BaseVCloudClientLiveTest { vappTemplate.getHref(), getVCloudApi().getCatalogClient().findCatalogInOrgNamed(null, null).getHref(), "fooname", CatalogItemOptions.Builder.description("description").properties(ImmutableMap.of("foo", "bar"))); - + assertEquals(item.getName(), "fooname"); assertEquals(item.getDescription(), "description"); assertEquals(item.getProperties(), ImmutableMap.of("foo", "bar")); - assertEquals(item.getEntity().getName(), vappTemplate.getName()); + assertEquals(item.getEntity().getName(), "fooname"); assertEquals(item.getEntity().getHref(), vappTemplate.getHref()); assertEquals(item.getEntity().getType(), vappTemplate.getType()); diff --git a/apis/vcloud/src/test/java/org/jclouds/vcloud/features/VmClientLiveTest.java b/apis/vcloud/src/test/java/org/jclouds/vcloud/features/VmClientLiveTest.java index 9153afab70..4c52b8b9b0 100644 --- a/apis/vcloud/src/test/java/org/jclouds/vcloud/features/VmClientLiveTest.java +++ b/apis/vcloud/src/test/java/org/jclouds/vcloud/features/VmClientLiveTest.java @@ -161,9 +161,9 @@ public class VmClientLiveTest extends BaseVCloudClientLiveTest { } protected void checkVmOutput(String fooTxtContentsMadeByVMwareTools, String decodedVMwareToolsOutput) { + assertEquals(decodedVMwareToolsOutput, script); // note that vmwaretools throws in \r characters when executing scripts assertEquals(fooTxtContentsMadeByVMwareTools, iLoveAscii + "\r\n"); - assertEquals(decodedVMwareToolsOutput, script); } protected IPSocket getSocket(NodeMetadata node) { diff --git a/common/vcloud/src/main/java/org/jclouds/vcloud/handlers/ParseVCloudErrorFromHttpResponse.java b/common/vcloud/src/main/java/org/jclouds/vcloud/handlers/ParseVCloudErrorFromHttpResponse.java index 59f35a2787..5082bcc342 100644 --- a/common/vcloud/src/main/java/org/jclouds/vcloud/handlers/ParseVCloudErrorFromHttpResponse.java +++ b/common/vcloud/src/main/java/org/jclouds/vcloud/handlers/ParseVCloudErrorFromHttpResponse.java @@ -88,8 +88,9 @@ public class ParseVCloudErrorFromHttpResponse implements HttpErrorHandler { switch (response.getStatusCode()) { case 400: - if (error != null && error.getMinorErrorCode() != null - && error.getMinorErrorCode() == MinorCode.BUSY_ENTITY) + if (error != null + && (error.getMinorErrorCode() != null && error.getMinorErrorCode() == MinorCode.BUSY_ENTITY) + || (error.getMessage() != null && error.getMessage().indexOf("is not running") != -1)) exception = new IllegalStateException(message, exception); else exception = new IllegalArgumentException(message, exception); diff --git a/common/vcloud/src/test/java/org/jclouds/vcloud/handlers/ParseVCloudErrorFromHttpResponseTest.java b/common/vcloud/src/test/java/org/jclouds/vcloud/handlers/ParseVCloudErrorFromHttpResponseTest.java index 210dc7e0c3..2aab97e85a 100644 --- a/common/vcloud/src/test/java/org/jclouds/vcloud/handlers/ParseVCloudErrorFromHttpResponseTest.java +++ b/common/vcloud/src/test/java/org/jclouds/vcloud/handlers/ParseVCloudErrorFromHttpResponseTest.java @@ -25,6 +25,7 @@ import org.jclouds.http.HttpErrorHandler; import org.jclouds.http.HttpResponseException; import org.jclouds.rest.AuthorizationException; import org.jclouds.rest.ResourceNotFoundException; +import org.jclouds.vcloud.VCloudMediaType; import org.testng.annotations.Test; /** @@ -36,23 +37,32 @@ public class ParseVCloudErrorFromHttpResponseTest extends BaseHttpErrorHandlerTe @Test public void testGet404SetsResourceNotFoundException() { - assertCodeMakes("GET", URI - .create("https://services.vcloudexpress.terremark.com/api/v0.8a-ext1.6/vdc/32"), - 404, "", "", ResourceNotFoundException.class); + assertCodeMakes("GET", URI.create("https://services.vcloudexpress.terremark.com/api/v0.8a-ext1.6/vdc/32"), 404, + "", "", ResourceNotFoundException.class); } @Test public void testDelete404SetsHttpResponseException() { - assertCodeMakes("DELETE", URI - .create("https://services.vcloudexpress.terremark.com/api/v0.8a-ext1.6/vdc/32"), + assertCodeMakes("DELETE", URI.create("https://services.vcloudexpress.terremark.com/api/v0.8a-ext1.6/vdc/32"), 404, "", "", HttpResponseException.class); } + @Test + public void testPOSTNotRunningSetsIllegalStateException() { + assertCodeMakes( + "POST", + URI.create("https://vcenterprise.bluelock.com/api/v1.0/vApp/vapp-138351019/action/undeploy"), + 400, + "HTTP/1.1 400 Bad Request", + VCloudMediaType.ERROR_XML, + "\n", + IllegalStateException.class); + } + @Test public void test401SetsAuthorizationException() { - assertCodeMakes("GET", URI - .create("https://services.vcloudexpress.terremark.com/api/v0.8a-ext1.6/vdc/32"), - 401, "", "", AuthorizationException.class); + assertCodeMakes("GET", URI.create("https://services.vcloudexpress.terremark.com/api/v0.8a-ext1.6/vdc/32"), 401, + "", "", AuthorizationException.class); } @Override diff --git a/compute/src/test/java/org/jclouds/compute/BaseComputeServiceLiveTest.java b/compute/src/test/java/org/jclouds/compute/BaseComputeServiceLiveTest.java index 277bbd0a25..c65d49e8bf 100755 --- a/compute/src/test/java/org/jclouds/compute/BaseComputeServiceLiveTest.java +++ b/compute/src/test/java/org/jclouds/compute/BaseComputeServiceLiveTest.java @@ -561,7 +561,7 @@ public abstract class BaseComputeServiceLiveTest { } } - protected int nonBlockDuration = 30 * 1000; + protected int nonBlockDurationSeconds = 30; public void testOptionToNotBlock() throws Exception { String group = this.group + "block"; @@ -577,9 +577,9 @@ public abstract class BaseComputeServiceLiveTest { Set nodes = client.createNodesInGroup(group, 1, options); NodeMetadata node = getOnlyElement(nodes); assert node.getState() != NodeState.RUNNING; - long duration = System.currentTimeMillis() - time; - assert duration < nonBlockDuration : String.format("duration(%d) longer than expected(%d) seconds! ", - duration / 1000, nonBlockDuration); + long duration = (System.currentTimeMillis() - time) / 1000; + assert duration < nonBlockDurationSeconds : String.format("duration(%d) longer than expected(%d) seconds! ", + duration, nonBlockDurationSeconds); } finally { client.destroyNodesMatching(inGroup(group)); } diff --git a/core/src/test/java/org/jclouds/http/BaseHttpErrorHandlerTest.java b/core/src/test/java/org/jclouds/http/BaseHttpErrorHandlerTest.java index 20940e9a01..d1fc7c578e 100644 --- a/core/src/test/java/org/jclouds/http/BaseHttpErrorHandlerTest.java +++ b/core/src/test/java/org/jclouds/http/BaseHttpErrorHandlerTest.java @@ -59,15 +59,21 @@ public abstract class BaseHttpErrorHandlerTest { protected abstract Class getHandlerClass(); - protected void assertCodeMakes(String method, URI uri, int statusCode, String message, + protected void assertCodeMakes(String method, URI uri, int statusCode, String message, String content, + Class expected) { + assertCodeMakes(method, uri, statusCode, message, null, content, expected); + } + + protected void assertCodeMakes(String method, URI uri, int statusCode, String message, String contentType, String content, Class expected) { - HttpErrorHandler function = Guice.createInjector(new SaxParserModule()).getInstance( - getHandlerClass()); + HttpErrorHandler function = Guice.createInjector(new SaxParserModule()).getInstance(getHandlerClass()); HttpCommand command = createMock(HttpCommand.class); HttpRequest request = new HttpRequest(method, uri); HttpResponse response = new HttpResponse(statusCode, message, Payloads.newStringPayload(content)); + if (contentType != null) + response.getPayload().getContentMetadata().setContentType(contentType); expect(command.getCurrentRequest()).andReturn(request).atLeastOnce(); command.setException(classEq(expected)); diff --git a/providers/bluelock-vcdirector/src/test/java/org/jclouds/vcloud/bluelock/compute/BluelockVCloudDirectorComputeServiceLiveTest.java b/providers/bluelock-vcdirector/src/test/java/org/jclouds/vcloud/bluelock/compute/BluelockVCloudDirectorComputeServiceLiveTest.java index 0cf76f581c..00dc577a1a 100644 --- a/providers/bluelock-vcdirector/src/test/java/org/jclouds/vcloud/bluelock/compute/BluelockVCloudDirectorComputeServiceLiveTest.java +++ b/providers/bluelock-vcdirector/src/test/java/org/jclouds/vcloud/bluelock/compute/BluelockVCloudDirectorComputeServiceLiveTest.java @@ -39,7 +39,7 @@ public class BluelockVCloudDirectorComputeServiceLiveTest extends VCloudComputeS public BluelockVCloudDirectorComputeServiceLiveTest() { provider = "bluelock-vcdirector"; // vcloud requires instantiate before deploy, which takes longer than 30 seconds - nonBlockDuration = 300; + nonBlockDurationSeconds = 300; } @Override