
com.yahoo.parsec.clients.ParsecHttpRequestRetryCallable Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of parsec-clients Show documentation
Show all versions of parsec-clients Show documentation
The Parsec Java Libraries.
// Copyright 2016 Yahoo Inc.
// Licensed under the terms of the Apache license. Please see LICENSE.md file distributed with this work for terms.
package com.yahoo.parsec.clients;
import com.ning.http.client.AsyncHandler;
import com.ning.http.client.AsyncHttpClient;
import com.ning.http.client.Request;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
/**
* {@link Callable} implementation that handles HTTP request retry based on response status code.
*/
class ParsecHttpRequestRetryCallable implements Callable {
/**
* Logger.
*/
private static final Logger LOGGER = LoggerFactory.getLogger(ParsecHttpRequestRetryCallable.class);
/**
* Async handler.
*/
private final AsyncHandler asyncHandler;
/**
* Ning client.
*/
private final AsyncHttpClient client;
/**
* Request.
*/
private final ParsecAsyncHttpRequest request;
/**
* Response list.
*/
private List responses;
/**
* Constructor.
*
* @param client client
* @param request request
*/
public ParsecHttpRequestRetryCallable(final AsyncHttpClient client, final ParsecAsyncHttpRequest request) {
this(client, request, null);
}
/**
* Constructor.
*
* @param client client
* @param request request
* @param asyncHandler async handler
*/
public ParsecHttpRequestRetryCallable(
final AsyncHttpClient client, final ParsecAsyncHttpRequest request, final AsyncHandler asyncHandler) {
this.client = client;
this.request = request;
this.asyncHandler = asyncHandler;
responses = new ArrayList<>();
}
/**
* Check status code and handles retry if T is type {@link Response} or Ning {@link com.ning.http.client.Response}.
*
* @return T
* @throws Exception exception
*/
@Override
public T call() throws Exception {
responses.clear();
final Request ningRequest = request.getNingRequest();
final List retryStatusCodes = request.getRetryStatusCodes();
final List> retryExceptions = request.getRetryExceptions();
final int maxRetries = request.getMaxRetries();
T response;
Exception exception;
int retries = 0;
for (; ; ) {
response = null;
exception = null;
try {
response = executeRequest(ningRequest);
responses.add(response);
int statusCode = getStatusCode(response);
if (statusCode == -1 || !retryStatusCodes.contains(statusCode)) {
break;
}
} catch (Exception e) {
Throwable root = ExceptionUtils.getRootCause(e);
if (!retryExceptions.contains(root.getClass())) {
throw e;
}
exception = e;
}
if (retries == maxRetries) {
LOGGER.debug("Max retries reached: " + retries + " (max: " + maxRetries + ")");
break;
}
retries++;
LOGGER.debug("Retry number: " + retries + " (max: " + maxRetries + ")");
}
if (exception != null) {
throw exception;
}
return response;
}
/**
* Execute Request.
*
* @param ningRequest Ning request
* @return T
* @throws InterruptedException Interrupted exception
* @throws ExecutionException Execution exception
*/
@SuppressWarnings("unchecked")
private T executeRequest(Request ningRequest) throws InterruptedException, ExecutionException {
if (asyncHandler != null) {
return client.executeRequest(ningRequest, asyncHandler).get();
} else {
return (T) client.executeRequest(ningRequest).get();
}
}
/**
* Get Responses.
*
* @return {@literal List}
*/
public List getResponses() {
return responses;
}
/**
* Gets Status Code from {@link Response} or Ning {@link com.ning.http.client.Response}.
*
* @param response T
* @return status code or -1 if T is not type of {@link Response} or Ning {@link com.ning.http.client.Response}
*/
private int getStatusCode(T response) {
if (response instanceof Response) {
return ((Response) response).getStatus();
} else if (response instanceof com.ning.http.client.Response) {
return ((com.ning.http.client.Response) response).getStatusCode();
} else {
return -1;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy