001package org.apache.maven.wagon.shared.http; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import org.apache.http.HttpResponse; 023import org.apache.http.HttpStatus; 024import org.apache.http.annotation.Contract; 025import org.apache.http.annotation.ThreadingBehavior; 026import org.apache.http.client.ServiceUnavailableRetryStrategy; 027import org.apache.http.protocol.HttpContext; 028import org.apache.http.util.Args; 029 030/** 031 * An implementation of the {@link ServiceUnavailableRetryStrategy} interface. 032 * that retries {@code 408} (Request Timeout), {@code 429} (Too Many Requests), 033 * and {@code 500} (Server side error) responses for a fixed number of times at a fixed interval. 034 */ 035@Contract( threading = ThreadingBehavior.IMMUTABLE ) 036public class StandardServiceUnavailableRetryStrategy implements ServiceUnavailableRetryStrategy 037{ 038 /** 039 * Maximum number of allowed retries if the server responds with a HTTP code 040 * in our retry code list. 041 */ 042 private final int maxRetries; 043 044 /** 045 * Retry interval between subsequent requests, in milliseconds. 046 */ 047 private final long retryInterval; 048 049 public StandardServiceUnavailableRetryStrategy( final int maxRetries, final int retryInterval ) 050 { 051 super(); 052 Args.positive( maxRetries, "Max retries" ); 053 Args.positive( retryInterval, "Retry interval" ); 054 this.maxRetries = maxRetries; 055 this.retryInterval = retryInterval; 056 } 057 058 @Override 059 public boolean retryRequest( final HttpResponse response, final int executionCount, final HttpContext context ) 060 { 061 int statusCode = response.getStatusLine().getStatusCode(); 062 boolean retryableStatusCode = statusCode == HttpStatus.SC_REQUEST_TIMEOUT 063 // Too Many Requests ("standard" rate-limiting) 064 || statusCode == AbstractHttpClientWagon.SC_TOO_MANY_REQUESTS 065 // Assume server errors are momentary hiccups 066 || statusCode == HttpStatus.SC_INTERNAL_SERVER_ERROR 067 || statusCode == HttpStatus.SC_BAD_GATEWAY 068 || statusCode == HttpStatus.SC_SERVICE_UNAVAILABLE 069 || statusCode == HttpStatus.SC_GATEWAY_TIMEOUT; 070 return executionCount <= maxRetries && retryableStatusCode; 071 } 072 073 @Override 074 public long getRetryInterval() 075 { 076 return retryInterval; 077 } 078 079}