com.microsoft.graph.httpcore.RetryHandler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of com.liferay.document.library.opener.onedrive.web
Show all versions of com.liferay.document.library.opener.onedrive.web
Liferay Document Library Opener OneDrive Web
package com.microsoft.graph.httpcore;
import java.io.IOException;
import com.microsoft.graph.httpcore.middlewareoption.IShouldRetry;
import com.microsoft.graph.httpcore.middlewareoption.MiddlewareType;
import com.microsoft.graph.httpcore.middlewareoption.RetryOptions;
import com.microsoft.graph.httpcore.middlewareoption.TelemetryOptions;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
public class RetryHandler implements Interceptor{
public final MiddlewareType MIDDLEWARE_TYPE = MiddlewareType.RETRY;
private RetryOptions mRetryOption;
/*
* constant string being used
*/
private final String RETRY_ATTEMPT_HEADER = "Retry-Attempt";
private final String RETRY_AFTER = "Retry-After";
/** Content length request header value */
private final String CONTENT_LENGTH = "Content-Length";
public static final int MSClientErrorCodeTooManyRequests = 429;
public static final int MSClientErrorCodeServiceUnavailable = 503;
public static final int MSClientErrorCodeGatewayTimeout = 504;
private final long DELAY_MILLISECONDS = 1000;
/*
* @retryOption Create Retry handler using retry option
*/
public RetryHandler(RetryOptions retryOption) {
this.mRetryOption = retryOption;
if(this.mRetryOption == null) {
this.mRetryOption = new RetryOptions();
}
}
/*
* Initialize retry handler with default retry option
*/
public RetryHandler() {
this(null);
}
boolean retryRequest(Response response, int executionCount, Request request, RetryOptions retryOptions) {
// Should retry option
// Use should retry common for all requests
IShouldRetry shouldRetryCallback = null;
if(retryOptions != null) {
shouldRetryCallback = retryOptions.shouldRetry();
}
boolean shouldRetry = false;
// Status codes 429 503 504
int statusCode = response.code();
// Only requests with payloads that are buffered/rewindable are supported.
// Payloads with forward only streams will be have the responses returned
// without any retry attempt.
shouldRetry =
(executionCount <= retryOptions.maxRetries())
&& checkStatus(statusCode) && isBuffered(request)
&& shouldRetryCallback != null
&& shouldRetryCallback.shouldRetry(retryOptions.delay(), executionCount, request, response);
if(shouldRetry) {
long retryInterval = getRetryAfter(response, retryOptions.delay(), executionCount);
try {
Thread.sleep(retryInterval);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return shouldRetry;
}
/**
* Get retry after in milliseconds
* @param response Response
* @param delay Delay in seconds
* @param executionCount Execution count of retries
* @return Retry interval in milliseconds
*/
long getRetryAfter(Response response, long delay, int executionCount) {
String retryAfterHeader = response.header(RETRY_AFTER);
double retryDelay = RetryOptions.DEFAULT_DELAY * DELAY_MILLISECONDS;
if(retryAfterHeader != null) {
retryDelay = Long.parseLong(retryAfterHeader) * DELAY_MILLISECONDS;
} else {
retryDelay = (double)((Math.pow(2.0, (double)executionCount)-1)*0.5);
retryDelay = (executionCount < 2 ? delay : retryDelay + delay) + (double)Math.random();
retryDelay *= DELAY_MILLISECONDS;
}
return (long)Math.min(retryDelay, RetryOptions.MAX_DELAY * DELAY_MILLISECONDS);
}
boolean checkStatus(int statusCode) {
return (statusCode == MSClientErrorCodeTooManyRequests || statusCode == MSClientErrorCodeServiceUnavailable
|| statusCode == MSClientErrorCodeGatewayTimeout);
}
boolean isBuffered(Request request) {
final String methodName = request.method();
final boolean isHTTPMethodPutPatchOrPost = methodName.equalsIgnoreCase("POST") ||
methodName.equalsIgnoreCase("PUT") ||
methodName.equalsIgnoreCase("PATCH");
if(isHTTPMethodPutPatchOrPost && request.body() != null) {
try {
return request.body().contentLength() != -1L;
} catch (IOException ex) {
// expected
return false;
}
}
return true;
}
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if(request.tag(TelemetryOptions.class) == null)
request = request.newBuilder().tag(TelemetryOptions.class, new TelemetryOptions()).build();
request.tag(TelemetryOptions.class).setFeatureUsage(TelemetryOptions.RETRY_HANDLER_ENABLED_FLAG);
Response response = chain.proceed(request);
// Use should retry pass along with this request
RetryOptions retryOption = request.tag(RetryOptions.class);
retryOption = retryOption != null ? retryOption : mRetryOption;
int executionCount = 1;
while(retryRequest(response, executionCount, request, retryOption)) {
request = request.newBuilder().addHeader(RETRY_ATTEMPT_HEADER, String.valueOf(executionCount)).build();
executionCount++;
if(response != null) {
if(response.body() != null)
response.body().close();
response.close();
}
response = chain.proceed(request);
}
return response;
}
}