com.sap.hana.datalake.files.utils.http.RequestRetryHandler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sap-hdlfs Show documentation
Show all versions of sap-hdlfs Show documentation
An implementation of org.apache.hadoop.fs.FileSystem targeting SAP HANA Data Lake Files.
// © 2024 SAP SE or an SAP affiliate company. All rights reserved.
package com.sap.hana.datalake.files.utils.http;
import com.sap.hana.datalake.files.classification.InterfaceAudience;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.client.RequestWrapper;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.Args;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.Set;
@InterfaceAudience.Private
public class RequestRetryHandler implements HttpRequestRetryHandler {
private static final Logger LOG = LoggerFactory.getLogger(RequestRetryHandler.class);
private final int maxRetries;
private final boolean retrySentRequests;
private final Set> nonRetriableExceptions;
public RequestRetryHandler(final int maxRetries, final boolean retrySentRequests, final Set> nonRetriableExceptions) {
this.maxRetries = maxRetries;
this.retrySentRequests = retrySentRequests;
this.nonRetriableExceptions = nonRetriableExceptions;
}
@Override
public boolean retryRequest(final IOException exception, final int executionCount, final HttpContext httpContext) {
Args.notNull(exception, "exception");
Args.notNull(httpContext, "httpContext");
if (executionCount > this.maxRetries) {
LOG.debug("Exception [{}] will not be retried; reason: max retries [{}] reached", exception.getClass(), this.maxRetries);
return false;
}
if (!this.shouldRetryException(exception)) {
LOG.debug("Exception [{}] will not be retried; reason: non retriable exception", exception.getClass());
return false;
}
final HttpClientContext clientContext = HttpClientContext.adapt(httpContext);
final HttpRequest request = clientContext.getRequest();
if (this.requestIsAborted(request)) {
LOG.debug("Exception [{}] will not be retried; reason: request aborted", exception.getClass());
return false;
}
if (this.handleRequestAsIdempotent(request)) {
LOG.debug("Exception [{}] will be retried; reason: request is idempotent", exception.getClass());
return true;
}
// Retry if the request has not been sent fully or if it's OK to retry methods that have been sent
if (!this.retrySentRequests && clientContext.isRequestSent()) {
LOG.debug("Exception [{}] will not be retried; reason: request already sent", exception.getClass());
return false;
}
LOG.debug("Exception [{}] will be retried", exception.getClass());
return true;
}
private boolean shouldRetryException(final IOException exception) {
if (this.nonRetriableExceptions.contains(exception.getClass())) {
return false;
}
for (final Class extends IOException> rejectException : this.nonRetriableExceptions) {
if (rejectException.isInstance(exception)) {
return false;
}
}
return true;
}
private boolean requestIsAborted(final HttpRequest request) {
final HttpRequest effectiveRequest = request instanceof RequestWrapper ?
((RequestWrapper) request).getOriginal() :
request;
return effectiveRequest instanceof HttpUriRequest &&
((HttpUriRequest) effectiveRequest).isAborted();
}
private boolean handleRequestAsIdempotent(final HttpRequest request) {
return !(request instanceof HttpEntityEnclosingRequest);
}
}
// © 2024 SAP SE or an SAP affiliate company. All rights reserved.
© 2015 - 2025 Weber Informatics LLC | Privacy Policy