1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.http.impl.execchain;
29
30 import java.io.IOException;
31 import java.io.InterruptedIOException;
32
33 import org.apache.commons.logging.Log;
34 import org.apache.commons.logging.LogFactory;
35 import org.apache.http.Header;
36 import org.apache.http.HttpException;
37 import org.apache.http.annotation.Contract;
38 import org.apache.http.annotation.ThreadingBehavior;
39 import org.apache.http.client.ServiceUnavailableRetryStrategy;
40 import org.apache.http.client.methods.CloseableHttpResponse;
41 import org.apache.http.client.methods.HttpExecutionAware;
42 import org.apache.http.client.methods.HttpRequestWrapper;
43 import org.apache.http.client.protocol.HttpClientContext;
44 import org.apache.http.conn.routing.HttpRoute;
45 import org.apache.http.util.Args;
46
47
48
49
50
51
52
53
54
55
56
57
58
59 @Contract(threading = ThreadingBehavior.IMMUTABLE_CONDITIONAL)
60 public class ServiceUnavailableRetryExec implements ClientExecChain {
61
62 private final Log log = LogFactory.getLog(getClass());
63
64 private final ClientExecChain requestExecutor;
65 private final ServiceUnavailableRetryStrategy retryStrategy;
66
67 public ServiceUnavailableRetryExec(
68 final ClientExecChain requestExecutor,
69 final ServiceUnavailableRetryStrategy retryStrategy) {
70 super();
71 Args.notNull(requestExecutor, "HTTP request executor");
72 Args.notNull(retryStrategy, "Retry strategy");
73 this.requestExecutor = requestExecutor;
74 this.retryStrategy = retryStrategy;
75 }
76
77 @Override
78 public CloseableHttpResponse execute(
79 final HttpRoute route,
80 final HttpRequestWrapper request,
81 final HttpClientContext context,
82 final HttpExecutionAware execAware) throws IOException, HttpException {
83 final Header[] origheaders = request.getAllHeaders();
84 for (int c = 1;; c++) {
85 final CloseableHttpResponse response = this.requestExecutor.execute(
86 route, request, context, execAware);
87 try {
88 if (this.retryStrategy.retryRequest(response, c, context)
89 && RequestEntityProxy.isRepeatable(request)) {
90 response.close();
91 final long nextInterval = this.retryStrategy.getRetryInterval();
92 if (nextInterval > 0) {
93 try {
94 this.log.trace("Wait for " + nextInterval);
95 Thread.sleep(nextInterval);
96 } catch (final InterruptedException e) {
97 Thread.currentThread().interrupt();
98 throw new InterruptedIOException();
99 }
100 }
101 request.setHeaders(origheaders);
102 } else {
103 return response;
104 }
105 } catch (final RuntimeException ex) {
106 response.close();
107 throw ex;
108 }
109 }
110 }
111
112 }