jclouds/jclouds — pull request #1005 by steveloughran (2012-11-26 20:16:19+00:00)
Title: Jclouds 549 retry after -second revision

Revision of the patch

* Renamed RetryAfter exception to RetryLater, which contains the delta in time before retrying (and the original JSON).
* Constructor takes a delay or a date pair (retry time, current time) to calculate the offset.
* Error handler to look first for a retryAfter field in the JSON response, falling back to look for a "retryAt" before falling back to an InsufficientResourcesException
* The parsing does a lot of returning null rather than raising exceptions on failures. That was a choice on the basis that the nested try/catch logic may actually be messier. That decisions could be revisited.
* Any exception raised during the parse process is considered an error- logged at error and included in the nested exception. I'm not 100% sure that including that trace is the right approach, but it is the only way to make the reason for downgrading the exception to be visible.
* Unit tests that work with the Rackspace UK and Folsom samples; there are also tests that look for the "both fields in JSON" situation -the retryAt field is picked up first.
* Time formatting was set up to be handed off to a DateService implementation -manually set up in the test runner, injected in the live system. However, because of issue 1127, the injection is being ignored and the SimpleDateService used.
* Functional testing against rackspace UK (but not a Folsom instance)

With this patch, a stack trace against Rackspace UK becomes (via Whirr/Log4J):

```
2012-11-26 19:52:10,087 ERROR [jclouds.compute] (user thread 2) << problem customizing node(LON/e82676b9-585f-4979-b95a-f62ed21188e7):
org.jclouds.openstack.nova.v2_0.handlers.RetryLaterException: GET https://lon.servers.api.rackspacecloud.com/v2/10025232/servers/e82676b9-585f-4979-b95a-f62ed21188e7 HTTP/1.1 failed - retry at Mon Nov 26 19:52:20 GMT 2012 --retry after 10s
{
"overLimit" : {
"code" : 413,
"message" : "OverLimit Retry...",
"details" : "Error Details...",
"retryAt" : "2012-11-26T19:52:20UTC"
}
}
at org.jclouds.openstack.nova.v2_0.handlers.NovaErrorHandler.buildRetryException(NovaErrorHandler.java:147)
at org.jclouds.openstack.nova.v2_0.handlers.NovaErrorHandler.handleError(NovaErrorHandler.java:95)
at org.jclouds.http.handlers.DelegatingErrorHandler.handleError(DelegatingErrorHandler.java:69)
at org.jclouds.http.internal.BaseHttpCommandExecutorService$HttpResponseCallable.shouldContinue(BaseHttpCommandExecutorService.java:197)
at org.jclouds.http.internal.BaseHttpCommandExecutorService$HttpResponseCallable.call(BaseHttpCommandExecutorService.java:167)
at org.jclouds.http.internal.BaseHttpCommandExecutorService$HttpResponseCallable.call(BaseHttpCommandExecutorService.java:135)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:680)
at org.jclouds.concurrent.config.DescribingExecutorService.submit(
```