> +   
> @Payload("<ws:getDataCenter><dataCenterId>{id}</dataCenterId></ws:getDataCenter>")
> +   @XMLResponseParser(GetVDCResponseHandler.class)
> +   @Fallback(NullOnNotFoundOr404.class)
> +   VirtualDataCenter getDataCenter(@PayloadParam("id") String identifier);
> +
> +   /**
> +    * Creates and saves a new, empty Virtual Data Center. Returns its 
> identifier for further reference.
> +    *
> +    * @param vdc VDC payload containing dataCenterName, region (both 
> optional)
> +    * @return Version response
> +    */
> +   @POST
> +   @Named("CreateDataCenter")
> +   @MapBinder(CreateDataCenterRequestBinder.class)
> +   @XMLResponseParser(VersionResponseHandler.class)
> +   @Fallback(NullOnNotFoundOr404.class)

So this seems to be YAATS (Yet Another Api That Sucks :D). This is something 
that needs to be configured a bit different.

jclouds by default tries to retry failed requests using a customizable 
strategy. It first [sends the 
request](https://github.com/jclouds/jclouds/blob/master/core/src/main/java/org/jclouds/http/internal/BaseHttpCommandExecutorService.java#L96)
 and decides if it must be retried [based on the response 
code](https://github.com/jclouds/jclouds/blob/master/core/src/main/java/org/jclouds/http/internal/BaseHttpCommandExecutorService.java#L104-L111).
 If the response is a 2xx, then the operation just returns and the 
`ResponseParsers` (such as the `XMLResponseParser`) are invoked to transform 
the request in the right Java entity returned by the API.

However, if after the configured retries, the response is still a failure, then 
the configured `ErrorHandler` (the PB error handler in this case) [will be 
invoked](https://github.com/jclouds/jclouds/blob/master/core/src/main/java/org/jclouds/http/internal/BaseHttpCommandExecutorService.java#L135)
 to populate the right exception. That exception is [thrown 
later](https://github.com/jclouds/jclouds/blob/master/core/src/main/java/org/jclouds/http/internal/BaseHttpCommandExecutorService.java#L125-L126)
 and [captured and 
transformed](https://github.com/jclouds/jclouds/blob/master/core/src/main/java/org/jclouds/rest/internal/InvokeHttpMethod.java#L94)
 if the API method defines a `Fallback`, so the right result is returned.

With this bit of context in mind, the `XMLResponseParser` won't be invoked if 
the response is a 500, as an exception will be propagated before. The problem 
here is that you need to read the response body to actually know if the request 
failed (YAATS!). The current code only checks the response status, so you'll 
have to override a bit of code to populate the proper response code.

The DigitalOcean API v1 has the same problem, and you can copy how it fixes it. 
It defines a [subclass of the 
JavaUrlHttpCommandExecutorService](https://github.com/jclouds/jclouds-labs/blob/master/digitalocean/src/main/java/org/jclouds/digitalocean/http/ResponseStatusFromPayloadHttpCommandExecutorService.java)
 that inspects the body of the response and populates the right response code. 
The configuration is done 
[here](https://github.com/jclouds/jclouds-labs/blob/master/digitalocean/src/main/java/org/jclouds/digitalocean/config/DigitalOceanHttpApiModule.java#L48-L56)
 and 
[here](https://github.com/jclouds/jclouds-labs/blob/master/digitalocean/src/main/java/org/jclouds/digitalocean/DigitalOceanApiMetadata.java#L70),
 so it is properly bound to the Guice context. With that in place, the response 
body is read and the response code set accordingly, so the default jclouds 
mechanisms to retry or fail the requests (and the subsequent invocations of the 
response parsers, only when the 
 request 
 really suceeds, or the fallbacks) work as expected.

It is not optimal, because when the response is a 2xx you'll read the body 
twice (one to determine if there is an error, and a second one in the response 
parser) and often that means that the response body must be buffered, if the 
InputSteram for the body is not repeatable, but it is the less intrusive 
solution you have with APIs like this.

---
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/72/files#r17465022

Reply via email to