1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.jclouds.azure.storage.handlers;
20
21 import java.io.ByteArrayInputStream;
22
23 import javax.annotation.Resource;
24 import javax.inject.Named;
25
26 import org.jclouds.Constants;
27 import org.jclouds.azure.storage.domain.AzureStorageError;
28 import org.jclouds.azure.storage.util.AzureStorageUtils;
29 import org.jclouds.http.HttpCommand;
30 import org.jclouds.http.HttpException;
31 import org.jclouds.http.HttpResponse;
32 import org.jclouds.http.HttpRetryHandler;
33 import org.jclouds.http.HttpUtils;
34 import org.jclouds.http.handlers.BackoffLimitedRetryHandler;
35 import org.jclouds.logging.Logger;
36
37 import com.google.inject.Inject;
38
39
40
41
42
43
44 public class AzureStorageClientErrorRetryHandler implements HttpRetryHandler {
45
46 @Inject(optional = true)
47 @Named(Constants.PROPERTY_MAX_RETRIES)
48 private int retryCountLimit = 5;
49
50 private final AzureStorageUtils utils;
51 private final BackoffLimitedRetryHandler backoffHandler;
52
53 @Resource
54 protected Logger logger = Logger.NULL;
55
56 @Inject
57 public AzureStorageClientErrorRetryHandler(BackoffLimitedRetryHandler backoffHandler,
58 AzureStorageUtils utils) {
59 this.backoffHandler = backoffHandler;
60 this.utils = utils;
61 }
62
63 public boolean shouldRetryRequest(HttpCommand command, HttpResponse response) {
64 byte[] content = HttpUtils.closeClientButKeepContentStream(response);
65 command.incrementFailureCount();
66 if (!command.isReplayable()) {
67 logger.warn("Cannot retry after server error, command is not replayable: %1$s", command);
68 return false;
69 } else if (command.getFailureCount() > retryCountLimit) {
70 logger.warn(
71 "Cannot retry after server error, command has exceeded retry limit %1$d: %2$s",
72 retryCountLimit, command);
73 return false;
74 } else if (response.getStatusCode() == 409) {
75
76 if (content != null) {
77 try {
78 AzureStorageError error = utils.parseAzureStorageErrorFromContent(command, response,
79 new ByteArrayInputStream(content));
80 if ("ContainerBeingDeleted".equals(error.getCode())) {
81 backoffHandler.imposeBackoffExponentialDelay(100L, 3, retryCountLimit, command
82 .getFailureCount(), command.toString());
83 return true;
84 }
85 } catch (HttpException e) {
86 logger.warn(e, "error parsing response: %s", new String(content));
87 }
88 }
89 }
90 return false;
91 }
92
93 }