001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.eclipse.aether.spi.connector.transport.http;
020
021import java.net.URI;
022
023import org.eclipse.aether.spi.connector.transport.Transporter;
024import org.slf4j.Logger;
025
026/**
027 * A transporter using HTTP protocol.
028 *
029 * @since 2.0.0
030 */
031public interface HttpTransporter extends Transporter {
032    @Override
033    default int classify(Throwable error) {
034        if (error instanceof HttpTransporterException) {
035            int statusCode = ((HttpTransporterException) error).getStatusCode();
036            if (statusCode == HttpConstants.NOT_FOUND || statusCode == HttpConstants.GONE) {
037                return ERROR_NOT_FOUND;
038            }
039        }
040        return ERROR_OTHER;
041    }
042
043    /**
044     * Log a retry message for an immediate retry.
045     * @param logger the logger to log the retry message
046     * @param method the HTTP method of the request (e.g. GET, PUT, etc.)
047     * @param uri the URI of the request
048     * @param requestAttempt the 0-based counter of the previous request attempt (0 for the first attempt, 1 for the first retry, etc.)
049     * @param maxRequestAttempt the maximum number of request attempts (this is including this original request)
050     * @param exception the exception that caused the immediate retry
051     */
052    static void logImmediateRetry(
053            Logger logger, String method, URI uri, int requestAttempt, int maxRequestAttempt, Throwable exception) {
054        String reason = String.format("%s: %s", exception.getClass().getName(), exception.getMessage());
055        logRetry(logger, method, uri, requestAttempt, maxRequestAttempt, reason, 0L, null);
056    }
057
058    /**
059     * Log a retry message for a delayed retry.
060     * @param logger the logger to log the retry message
061     * @param method the HTTP method of the request (e.g. GET, PUT, etc.)
062     * @param uri the URI of the request
063     * @param requestAttempt the 0-based counter of the previous request attempt (0 for the first attempt, 1 for the first retry, etc.)
064     * @param maxRequestAttempt the maximum number of request attempts (this is including this original request)
065     * @param reason the reason for the retry (usually a status code or an exception)
066     * @param retryDelay the interval in milliseconds before the next retry (0 or negative for immediate retry)
067     * @param retryDelayReason the reason for the retry interval (may be empty if unknown)
068     */
069    @SuppressWarnings("checkstyle:parameternumber")
070    static void logRetry(
071            Logger logger,
072            String method,
073            URI uri,
074            int requestAttempt,
075            int maxRequestAttempt,
076            String reason,
077            long retryDelay,
078            String retryDelayReason) {
079
080        final String retryingDelayMessage;
081        if (retryDelay > 0L) {
082            if (retryDelayReason != null && !retryDelayReason.isEmpty()) {
083                retryingDelayMessage = "Retrying in " + retryDelay + " ms (due to " + retryDelayReason + ")";
084            } else {
085                retryingDelayMessage = "Retrying in " + retryDelay + " ms";
086            }
087        } else {
088            retryingDelayMessage = "Retrying immediately";
089        }
090        logger.warn(
091                "{} request to {} failed (attempt {} of {}) due to {}. {}...",
092                method,
093                uri,
094                requestAttempt + 1,
095                maxRequestAttempt,
096                reason,
097                retryingDelayMessage);
098    }
099}