You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2011/06/29 14:56:38 UTC
svn commit: r1141078 - in /httpcomponents/httpclient/trunk/httpclient/src:
main/java/org/apache/http/client/ main/java/org/apache/http/impl/client/
test/java/org/apache/http/impl/client/
Author: olegk
Date: Wed Jun 29 12:56:38 2011
New Revision: 1141078
URL: http://svn.apache.org/viewvc?rev=1141078&view=rev
Log:
HTTPCLIENT-1105: Built-in way to do auto-retry for certain status codes
Contributed by Dan Checkoway <dcheckoway at gmail.com>
Added:
httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/ServiceUnavailableRetryStrategy.java (with props)
httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/AutoRetryHttpClient.java (with props)
httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/DefaultServiceUnavailableRetryStrategy.java (with props)
httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/client/TestAutoRetryHttpClient.java (with props)
Added: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/ServiceUnavailableRetryStrategy.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/ServiceUnavailableRetryStrategy.java?rev=1141078&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/ServiceUnavailableRetryStrategy.java (added)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/ServiceUnavailableRetryStrategy.java Wed Jun 29 12:56:38 2011
@@ -0,0 +1,66 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.client;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.protocol.HttpContext;
+
+/**
+ * Strategy interface that allows API users to plug in their own logic to
+ * control whether or not a retry should automatically be done, how many times
+ * it should be retried and so on.
+ *
+ */
+public interface ServiceUnavailableRetryStrategy {
+
+ /**
+ * Determines if a method should be retried given the response from the target server.
+ *
+ * @param response the response from the target server
+ * @param executionCount the number of times this method has been
+ * unsuccessfully executed
+ * @param context the context for the request execution
+
+ * @return <code>true</code> if the method should be retried, <code>false</code>
+ * otherwise
+ */
+ boolean retryRequest(HttpResponse response, int executionCount, HttpContext context);
+
+ /**
+ * @return The interval between the subsequent auto-retries.
+ */
+ long getRetryInterval();
+
+ /**
+ * @return the multiplying factor for continuous errors situations returned
+ * by the server-side. Each retry attempt will multiply this factor
+ * with the retry interval.
+ */
+ int getRetryFactor();
+
+}
\ No newline at end of file
Propchange: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/ServiceUnavailableRetryStrategy.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/ServiceUnavailableRetryStrategy.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/ServiceUnavailableRetryStrategy.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/AutoRetryHttpClient.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/AutoRetryHttpClient.java?rev=1141078&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/AutoRetryHttpClient.java (added)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/AutoRetryHttpClient.java Wed Jun 29 12:56:38 2011
@@ -0,0 +1,171 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.impl.client;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.net.URI;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.annotation.ThreadSafe;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.params.HttpParams;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.client.*;
+
+@ThreadSafe
+public class AutoRetryHttpClient implements HttpClient {
+
+ private final HttpClient backend;
+
+ private final ServiceUnavailableRetryStrategy retryStrategy;
+
+ private final Log log = LogFactory.getLog(getClass());
+
+ public AutoRetryHttpClient(
+ final HttpClient client, final ServiceUnavailableRetryStrategy retryStrategy) {
+ super();
+ if (client == null) {
+ throw new IllegalArgumentException("HttpClient may not be null");
+ }
+ if (retryStrategy == null) {
+ throw new IllegalArgumentException(
+ "ServiceUnavailableRetryStrategy may not be null");
+ }
+ this.backend = client;
+ this.retryStrategy = retryStrategy;
+ }
+
+ /**
+ * Constructs a {@code AutoRetryHttpClient} with default caching settings that
+ * stores cache entries in memory and uses a vanilla
+ * {@link DefaultHttpClient} for backend requests.
+ */
+ public AutoRetryHttpClient() {
+ this(new DefaultHttpClient(), new DefaultServiceUnavailableRetryStrategy());
+ }
+
+ /**
+ * Constructs a {@code AutoRetryHttpClient} with the given caching options that
+ * stores cache entries in memory and uses a vanilla
+ * {@link DefaultHttpClient} for backend requests.
+ *
+ * @param config
+ * retry configuration module options
+ */
+ public AutoRetryHttpClient(ServiceUnavailableRetryStrategy config) {
+ this(new DefaultHttpClient(), config);
+ }
+
+ /**
+ * Constructs a {@code AutoRetryHttpClient} with default caching settings that
+ * stores cache entries in memory and uses the given {@link HttpClient} for
+ * backend requests.
+ *
+ * @param client
+ * used to make origin requests
+ */
+ public AutoRetryHttpClient(HttpClient client) {
+ this(client, new DefaultServiceUnavailableRetryStrategy());
+ }
+
+ public HttpResponse execute(HttpHost target, HttpRequest request)
+ throws IOException {
+ HttpContext defaultContext = null;
+ return execute(target, request, defaultContext);
+ }
+
+ public <T> T execute(HttpHost target, HttpRequest request,
+ ResponseHandler<? extends T> responseHandler) throws IOException {
+ return execute(target, request, responseHandler, null);
+ }
+
+ public <T> T execute(HttpHost target, HttpRequest request,
+ ResponseHandler<? extends T> responseHandler, HttpContext context)
+ throws IOException {
+ HttpResponse resp = execute(target, request, context);
+ return responseHandler.handleResponse(resp);
+ }
+
+ public HttpResponse execute(HttpUriRequest request) throws IOException {
+ HttpContext context = null;
+ return execute(request, context);
+ }
+
+ public HttpResponse execute(HttpUriRequest request, HttpContext context)
+ throws IOException {
+ URI uri = request.getURI();
+ HttpHost httpHost = new HttpHost(uri.getHost(), uri.getPort(),
+ uri.getScheme());
+ return execute(httpHost, request, context);
+ }
+
+ public <T> T execute(HttpUriRequest request,
+ ResponseHandler<? extends T> responseHandler) throws IOException {
+ return execute(request, responseHandler, null);
+ }
+
+ public <T> T execute(HttpUriRequest request,
+ ResponseHandler<? extends T> responseHandler, HttpContext context)
+ throws IOException {
+ HttpResponse resp = execute(request, context);
+ return responseHandler.handleResponse(resp);
+ }
+
+ public HttpResponse execute(HttpHost target, HttpRequest request,
+ HttpContext context) throws IOException {
+ for (int c = 1;; c++) {
+ HttpResponse response = backend.execute(target, request, context);
+ if (retryStrategy.retryRequest(response, c, context)) {
+ long nextInterval = retryStrategy.getRetryInterval() * retryStrategy.getRetryFactor();
+ try {
+ log.trace("Wait for " + nextInterval);
+ Thread.sleep(nextInterval);
+ } catch (InterruptedException e) {
+ throw new InterruptedIOException(e.getMessage());
+ }
+ } else {
+ return response;
+ }
+ }
+ }
+
+ public ClientConnectionManager getConnectionManager() {
+ return backend.getConnectionManager();
+ }
+
+ public HttpParams getParams() {
+ return backend.getParams();
+ }
+
+}
\ No newline at end of file
Propchange: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/AutoRetryHttpClient.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/AutoRetryHttpClient.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/AutoRetryHttpClient.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/DefaultServiceUnavailableRetryStrategy.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/DefaultServiceUnavailableRetryStrategy.java?rev=1141078&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/DefaultServiceUnavailableRetryStrategy.java (added)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/DefaultServiceUnavailableRetryStrategy.java Wed Jun 29 12:56:38 2011
@@ -0,0 +1,129 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.impl.client;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.client.ServiceUnavailableRetryStrategy;
+import org.apache.http.protocol.HttpContext;
+
+/**
+ * Default implementation for the <code>ServiceUnavailableRetryStrategy</code>
+ * interface.
+ *
+ */
+public class DefaultServiceUnavailableRetryStrategy implements ServiceUnavailableRetryStrategy {
+
+ private List<Integer> retryResponseCodes = new ArrayList<Integer>();
+
+ /**
+ * Maximum number of allowed retries if the server responds with a HTTP code
+ * in our retry code list. Default value is 1.
+ */
+ private int maxRetries = 1;
+
+ /**
+ * Retry interval between subsequent requests, in milliseconds. Default
+ * value is 1 second.
+ */
+ private long retryInterval = 1000;
+
+ /**
+ * Multiplying factor for continuous errors situations returned by the
+ * server-side. Each retry attempt will multiply this factor with the retry
+ * interval. Default value is 1, which means each retry interval will be
+ * constant.
+ */
+ private int retryFactor = 1;
+
+ public void addResponseCodeForRetry(int responseCode) {
+ retryResponseCodes.add(responseCode);
+ }
+
+ public boolean retryRequest(final HttpResponse response, int executionCount, final HttpContext context) {
+ return executionCount <= maxRetries && retryResponseCodes.contains(
+ response.getStatusLine().getStatusCode());
+ }
+
+ /**
+ * @return The maximum number of allowed auto-retries in case the server
+ * response code is contained in this retry strategy. Default value
+ * is 1, meaning no-retry.
+ */
+ public int getMaxRetries() {
+ return maxRetries;
+ }
+
+ public void setMaxRetries(int maxRetries) {
+ if (maxRetries < 1) {
+ throw new IllegalArgumentException(
+ "MaxRetries should be greater than 1");
+ }
+ this.maxRetries = maxRetries;
+ }
+
+ /**
+ * @return The interval between the subsequent auto-retries. Default value
+ * is 1000 ms, meaning there is 1 second X
+ * <code>getRetryFactor()</code> between the subsequent auto
+ * retries.
+ *
+ */
+ public long getRetryInterval() {
+ return retryInterval;
+ }
+
+ public void setRetryInterval(long retryInterval) {
+ if (retryInterval < 1) {
+ throw new IllegalArgumentException(
+ "Retry interval should be greater than 1");
+ }
+ this.retryInterval = retryInterval;
+ }
+
+ /**
+ * @return the multiplying factor for continuous errors situations returned
+ * by the server-side. Each retry attempt will multiply this factor
+ * with the retry interval. default value is 1, meaning the retry
+ * intervals are constant.
+ */
+ public int getRetryFactor() {
+ return retryFactor;
+ }
+
+ public void setRetryFactor(int factor) {
+ if (factor < 1) {
+ throw new IllegalArgumentException(
+ "Retry factor should be greater than 1");
+ }
+ this.retryFactor = factor;
+ }
+
+}
Propchange: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/DefaultServiceUnavailableRetryStrategy.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/DefaultServiceUnavailableRetryStrategy.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/DefaultServiceUnavailableRetryStrategy.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/client/TestAutoRetryHttpClient.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/client/TestAutoRetryHttpClient.java?rev=1141078&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/client/TestAutoRetryHttpClient.java (added)
+++ httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/client/TestAutoRetryHttpClient.java Wed Jun 29 12:56:38 2011
@@ -0,0 +1,241 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.impl.client;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Date;
+import java.util.Random;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.HttpVersion;
+import org.apache.http.client.HttpClient;
+import org.apache.http.entity.ByteArrayEntity;
+import org.apache.http.impl.client.AutoRetryHttpClient;
+import org.apache.http.impl.client.DefaultServiceUnavailableRetryStrategy;
+import org.apache.http.impl.cookie.DateUtils;
+import org.apache.http.message.BasicHttpRequest;
+import org.apache.http.message.BasicHttpResponse;
+import org.apache.http.protocol.BasicHttpContext;
+import org.apache.http.protocol.HttpContext;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestAutoRetryHttpClient{
+
+ private AutoRetryHttpClient impl;
+
+ private HttpClient mockBackend;
+
+ private HttpHost host;
+
+ @Before
+ public void setUp() {
+ mockBackend = mock(HttpClient.class);
+ host = new HttpHost("foo.example.com");
+ }
+
+ static HttpResponse make200Response() {
+ HttpResponse out = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
+ out.setHeader("Date", DateUtils.formatDate(new Date()));
+ out.setHeader("Server", "MockOrigin/1.0");
+ out.setHeader("Content-Length", "128");
+ out.setEntity(makeBody(128));
+ return out;
+ }
+
+
+ static HttpRequest makeDefaultRequest() {
+ return new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1);
+ }
+
+ static HttpResponse make500Response() {
+ return new BasicHttpResponse(HttpVersion.HTTP_1_1,
+ HttpStatus.SC_INTERNAL_SERVER_ERROR, "Internal Server Error");
+ }
+
+ static HttpResponse make503Response() {
+ return new BasicHttpResponse(HttpVersion.HTTP_1_1,
+ HttpStatus.SC_SERVICE_UNAVAILABLE, "Service Unavailable");
+ }
+
+ static HttpResponse make502Response() {
+ return new BasicHttpResponse(HttpVersion.HTTP_1_1,
+ HttpStatus.SC_BAD_GATEWAY, "Bad Gateway");
+ }
+
+ /** Generates a response body with random content.
+ * @param nbytes length of the desired response body
+ * @return an {@link HttpEntity}
+ */
+ static HttpEntity makeBody(int nbytes) {
+ return new ByteArrayEntity(getRandomBytes(nbytes));
+ }
+
+ static byte[] getRandomBytes(int nbytes) {
+ byte[] bytes = new byte[nbytes];
+ (new Random()).nextBytes(bytes);
+ return bytes;
+ }
+
+ @Test
+ public void testAddOneStatusInRetryConfig(){
+ DefaultServiceUnavailableRetryStrategy retryStrategy = new DefaultServiceUnavailableRetryStrategy();
+ retryStrategy.addResponseCodeForRetry(503);
+ HttpContext context = new BasicHttpContext();
+ HttpResponse response1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, 503, "Oppsie");
+ assertTrue(retryStrategy.retryRequest(response1, 1, context));
+ HttpResponse response2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, 502, "Oppsie");
+ assertFalse(retryStrategy.retryRequest(response2, 1, context));
+ }
+
+ @Test
+ public void testAddMultipleStatusesInRetryConfig(){
+ DefaultServiceUnavailableRetryStrategy retryStrategy = new DefaultServiceUnavailableRetryStrategy();
+ retryStrategy.addResponseCodeForRetry(503);
+ retryStrategy.addResponseCodeForRetry(502);
+ HttpContext context = new BasicHttpContext();
+ HttpResponse response1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, 503, "Oppsie");
+ assertTrue(retryStrategy.retryRequest(response1, 1, context));
+ HttpResponse response2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, 502, "Oppsie");
+ assertTrue(retryStrategy.retryRequest(response2, 1, context));
+ HttpResponse response3 = new BasicHttpResponse(HttpVersion.HTTP_1_1, 500, "Oppsie");
+ assertFalse(retryStrategy.retryRequest(response3, 1, context));
+ }
+
+ @Test
+ public void testNoAutoRetry() throws java.io.IOException{
+ DefaultServiceUnavailableRetryStrategy retryStrategy = new DefaultServiceUnavailableRetryStrategy();
+ retryStrategy.setMaxRetries(2);
+ retryStrategy.setRetryInterval(100);
+
+ impl = new AutoRetryHttpClient(mockBackend,retryStrategy);
+
+ HttpRequest req1 = makeDefaultRequest();
+ HttpResponse resp1 = make500Response();
+ HttpResponse resp2 = make200Response();
+
+ when(mockBackend.execute(host, req1,(HttpContext)null)).thenReturn(resp1).thenReturn(resp2);
+
+ HttpResponse result = impl.execute(host, req1);
+
+ verify(mockBackend,times(1)).execute(host, req1,(HttpContext)null);
+
+ assertEquals(resp1,result);
+ assertEquals(500,result.getStatusLine().getStatusCode());
+ }
+
+ @Test
+ public void testMultipleAutoRetry() throws java.io.IOException{
+ DefaultServiceUnavailableRetryStrategy retryStrategy = new DefaultServiceUnavailableRetryStrategy();
+ retryStrategy.addResponseCodeForRetry(503);
+ retryStrategy.addResponseCodeForRetry(502);
+ retryStrategy.setMaxRetries(5);
+ retryStrategy.setRetryInterval(100);
+
+ impl = new AutoRetryHttpClient(mockBackend,retryStrategy);
+
+ HttpRequest req1 = makeDefaultRequest();
+ HttpResponse resp1 = make503Response();
+ HttpResponse resp2 = make502Response();
+ HttpResponse resp3 = make200Response();
+
+ when(mockBackend.execute(host, req1,(HttpContext)null)).thenReturn(resp1).thenReturn(resp2).thenReturn(resp3);
+
+ HttpResponse result = impl.execute(host, req1);
+
+ verify(mockBackend,times(3)).execute(host, req1,(HttpContext)null);
+
+ assertEquals(resp3,result);
+ assertEquals(200,result.getStatusLine().getStatusCode());
+ }
+
+ @Test
+ public void test503SingleAutoRetry() throws java.io.IOException{
+ DefaultServiceUnavailableRetryStrategy retryStrategy = new DefaultServiceUnavailableRetryStrategy();
+ retryStrategy.addResponseCodeForRetry(503);
+ retryStrategy.setMaxRetries(5);
+ retryStrategy.setRetryInterval(100);
+
+ impl = new AutoRetryHttpClient(mockBackend,retryStrategy);
+
+ HttpRequest req1 = makeDefaultRequest();
+ HttpResponse resp1 = make503Response();
+ HttpResponse resp2 = make200Response();
+
+ when(mockBackend.execute(host, req1,(HttpContext)null)).thenReturn(resp1).thenReturn(resp2);
+
+ HttpResponse result = impl.execute(host, req1);
+
+ verify(mockBackend,times(2)).execute(host, req1,(HttpContext)null);
+
+ assertEquals(resp2,result);
+ assertEquals(200,result.getStatusLine().getStatusCode());
+ }
+
+ @Test
+ public void testRetryInterval() throws java.io.IOException{
+ DefaultServiceUnavailableRetryStrategy retryStrategy = new DefaultServiceUnavailableRetryStrategy();
+ retryStrategy.addResponseCodeForRetry(503);
+ retryStrategy.setMaxRetries(5);
+ retryStrategy.setRetryFactor(2);
+ retryStrategy.setRetryInterval(100); // 0.1 seconds
+
+ impl = new AutoRetryHttpClient(mockBackend,retryStrategy);
+
+ HttpRequest req1 = makeDefaultRequest();
+ HttpResponse resp1 = make503Response();
+ HttpResponse resp2 = make200Response();
+
+ when(mockBackend.execute(host, req1,(HttpContext)null)).thenReturn(resp1).thenReturn(resp2);
+
+ long currentTime = System.currentTimeMillis();
+ HttpResponse result = impl.execute(host, req1);
+
+ long elapsedTime = System.currentTimeMillis();
+
+ verify(mockBackend,times(2)).execute(host, req1,(HttpContext)null);
+
+ assertEquals(resp2,result);
+ assertEquals(200,result.getStatusLine().getStatusCode());
+ assertTrue((elapsedTime - currentTime) > 100);
+ }
+
+
+
+}
Propchange: httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/client/TestAutoRetryHttpClient.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/client/TestAutoRetryHttpClient.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/client/TestAutoRetryHttpClient.java
------------------------------------------------------------------------------
svn:mime-type = text/plain