diff --git a/api/src/main/java/org/commonjava/maven/galley/config/TransportManagerConfig.java b/api/src/main/java/org/commonjava/maven/galley/config/TransportManagerConfig.java index 322ad51e0..37d6b7e35 100644 --- a/api/src/main/java/org/commonjava/maven/galley/config/TransportManagerConfig.java +++ b/api/src/main/java/org/commonjava/maven/galley/config/TransportManagerConfig.java @@ -30,7 +30,8 @@ public class TransportManagerConfig final long DEFAULT_WAIT_RETRY_SCALING_INCREMENT = DEFAULT_THRESHOLD_WAIT_RETRY_SIZE; // how many times we retry depends on this. - final float DEFAULT_TIMEOUT_OVEREXTENSION_FACTOR = 1.25f; + final float DEFAULT_TIMEOUT_OVEREXTENSION_FACTOR = 2.25f; + // Use proxy retry will probably exceed one default request timeout, at least twice as much time to the first request timeout. private final long thresholdWaitRetrySize; diff --git a/transports/httpclient/src/main/java/org/commonjava/maven/galley/transport/htcli/Http.java b/transports/httpclient/src/main/java/org/commonjava/maven/galley/transport/htcli/Http.java index aba67bad6..2e6a2e74e 100644 --- a/transports/httpclient/src/main/java/org/commonjava/maven/galley/transport/htcli/Http.java +++ b/transports/httpclient/src/main/java/org/commonjava/maven/galley/transport/htcli/Http.java @@ -28,7 +28,7 @@ public interface Http extends Closeable { - CloseableHttpClient createClient( HttpLocation location, boolean isProxy ) + CloseableHttpClient createClient( HttpLocation location, boolean doProxy ) throws GalleyException; CloseableHttpClient createClient( HttpLocation location ) diff --git a/transports/httpclient/src/main/java/org/commonjava/maven/galley/transport/htcli/HttpImpl.java b/transports/httpclient/src/main/java/org/commonjava/maven/galley/transport/htcli/HttpImpl.java index 6f6e2a53f..2afc2bedc 100644 --- a/transports/httpclient/src/main/java/org/commonjava/maven/galley/transport/htcli/HttpImpl.java +++ b/transports/httpclient/src/main/java/org/commonjava/maven/galley/transport/htcli/HttpImpl.java @@ -93,7 +93,7 @@ public CloseableHttpClient createClient( final HttpLocation location ) } @Override - public CloseableHttpClient createClient( final HttpLocation location, final boolean isProxy ) + public CloseableHttpClient createClient( final HttpLocation location, final boolean doProxy ) throws GalleyException { try @@ -111,7 +111,7 @@ public CloseableHttpClient createClient( final HttpLocation location, final bool .withUser( location.getUser() ) .withIgnoreHostnameVerification( location.isIgnoreHostnameVerification() ) .withMaxConnections( maxConnections ); - if ( isProxy ) + if ( doProxy ) { logger.trace( "The location class: {}", location.getClass().getSimpleName() ); configBuilder.withProxyHost( location.getProxyHost() ) diff --git a/transports/httpclient/src/main/java/org/commonjava/maven/galley/transport/htcli/internal/AbstractHttpJob.java b/transports/httpclient/src/main/java/org/commonjava/maven/galley/transport/htcli/internal/AbstractHttpJob.java index 8e81f3f33..c39279ade 100644 --- a/transports/httpclient/src/main/java/org/commonjava/maven/galley/transport/htcli/internal/AbstractHttpJob.java +++ b/transports/httpclient/src/main/java/org/commonjava/maven/galley/transport/htcli/internal/AbstractHttpJob.java @@ -101,35 +101,80 @@ public long getTransferSize() protected boolean executeHttp() throws TransferException { - boolean result = true; + int tries = 1; + boolean doProxy = false; try { - result = doExecuteHttp(); - } - catch ( final NoHttpResponseException | ConnectTimeoutException | SocketTimeoutException e ) - { - // For those are not in the iad2 tenant egress rules, will throw timeout so use the configured proxy to retry - result = executeProxyHttp(); - } - catch ( final IOException e ) - { - addFieldToActiveSpan( "target-error-reason", "I/O" ); - addFieldToActiveSpan( "target-error", e.getClass().getSimpleName() ); - throw new TransferLocationException( location, "Repository remote request failed for: {}. Reason: {}", e, url, - e.getMessage() ); - } - catch ( TransferLocationException e ) - { - addFieldToActiveSpan( "target-error-reason", "no transport" ); - addFieldToActiveSpan( "target-error", e.getClass().getSimpleName() ); - throw e; - } - catch ( final GalleyException e ) - { - addFieldToActiveSpan( "target-error-reason", "unknown" ); - addFieldToActiveSpan( "target-error", e.getClass().getSimpleName() ); - throw new TransferException( "Repository remote request failed for: {}. Reason: {}", e, url, - e.getMessage() ); + while ( tries > 0 ) + { + tries--; + try + { + client = http.createClient( location, doProxy ); + response = client.execute( request, http.createContext( location ) ); + + final StatusLine line = response.getStatusLine(); + final int sc = line.getStatusCode(); + + logger.trace( "{} {} : {}", request.getMethod(), line, url ); + + if ( sc > 399 && sc != 404 && sc != 408 && sc != 502 && sc != 503 && sc != 504 ) + { + throw new TransferLocationException( location, + "Server misconfigured or not responding normally for url %s: '%s'", + url, line ); + } + else if ( !successStatuses.contains( sc ) ) + { + logger.trace( "Detected failure respon se: " + sc ); + success = TransferResponseUtils.handleUnsuccessfulResponse( request, response, location, url ); + logger.trace( "Returning non-error failure response for code: " + sc ); + return false; + } + } + catch ( final NoHttpResponseException | ConnectTimeoutException | SocketTimeoutException e ) + { + // For those are not in the iad2 tenant egress rules, will throw timeout so use the configured proxy to retry + if ( tries > 0 ) + { + } + else if ( !doProxy ) // never do with proxy, retry with proxy + { + tries = 1; + doProxy = true; + logger.debug( "Retry to execute with global proxy for {}", url ); + } + else // already did proxy, still timeout + { + addFieldToActiveSpan( "target-error-reason", "timeout" ); + addFieldToActiveSpan( "target-error", e.getClass().getSimpleName() ); + throw new TransferTimeoutException( location, url, + "Repository remote request failed for: {}. Reason: {}", e, + url, e.getMessage() ); + } + } + catch ( final IOException e ) + { + addFieldToActiveSpan( "target-error-reason", "I/O" ); + addFieldToActiveSpan( "target-error", e.getClass().getSimpleName() ); + throw new TransferLocationException( location, + "Repository remote request failed for: {}. Reason: {}", e, url, + e.getMessage() ); + } + catch ( TransferLocationException e ) + { + addFieldToActiveSpan( "target-error-reason", "no transport" ); + addFieldToActiveSpan( "target-error", e.getClass().getSimpleName() ); + throw e; + } + catch ( final GalleyException e ) + { + addFieldToActiveSpan( "target-error-reason", "unknown" ); + addFieldToActiveSpan( "target-error", e.getClass().getSimpleName() ); + throw new TransferException( "Repository remote request failed for: {}. Reason: {}", e, url, + e.getMessage() ); + } + } } finally { @@ -149,76 +194,6 @@ protected boolean executeHttp() } } } - - return result; - } - - protected boolean executeProxyHttp() - throws TransferException - { - try - { - return doExecuteHttp( true ); - } - catch ( final NoHttpResponseException | ConnectTimeoutException | SocketTimeoutException e ) - { - addFieldToActiveSpan( "target-error-reason", "timeout" ); - addFieldToActiveSpan( "target-error", e.getClass().getSimpleName() ); - throw new TransferTimeoutException( location, url, "Repository remote request failed for: {}. Reason: {}", - e, url, e.getMessage() ); - } - catch ( final IOException e ) - { - addFieldToActiveSpan( "target-error-reason", "I/O" ); - addFieldToActiveSpan( "target-error", e.getClass().getSimpleName() ); - throw new TransferLocationException( location, "Repository remote request failed for: {}. Reason: {}", e, - url, e.getMessage() ); - } - catch ( TransferLocationException e ) - { - addFieldToActiveSpan( "target-error-reason", "no transport" ); - addFieldToActiveSpan( "target-error", e.getClass().getSimpleName() ); - throw e; - } - catch ( final GalleyException e ) - { - addFieldToActiveSpan( "target-error-reason", "unknown" ); - addFieldToActiveSpan( "target-error", e.getClass().getSimpleName() ); - throw new TransferException( "Repository remote request failed for: {}. Reason: {}", e, url, - e.getMessage() ); - } - } - - private boolean doExecuteHttp() - throws GalleyException, IOException - { - return doExecuteHttp( false ); - } - - private boolean doExecuteHttp( boolean isProxy ) - throws GalleyException, IOException - { - client = http.createClient( location, isProxy ); - response = client.execute( request, http.createContext( location ) ); - - final StatusLine line = response.getStatusLine(); - final int sc = line.getStatusCode(); - - logger.trace( "{} {} : {}", request.getMethod(), line, url ); - - if ( sc > 399 && sc != 404 && sc != 408 && sc != 502 && sc != 503 && sc != 504 ) - { - throw new TransferLocationException( location, - "Server misconfigured or not responding normally for url %s: '%s'", - url, line ); - } - else if ( !successStatuses.contains( sc ) ) - { - logger.trace( "Detected failure respon se: " + sc ); - success = TransferResponseUtils.handleUnsuccessfulResponse( request, response, location, url ); - logger.trace( "Returning non-error failure response for code: " + sc ); - return false; - } return true; }