use of com.okta.sdk.impl.http.RestException in project okta-sdk-java by okta.
the class HttpClientRequestExecutor method executeRequest.
@Override
public Response executeRequest(Request request) throws RestException {
Assert.notNull(request, "Request argument cannot be null.");
int retryCount = 0;
URI redirectUri = null;
HttpEntity entity = null;
RestException exception = null;
// Make a copy of the original request params and headers so that we can
// permute them in the loop and start over with the original every time.
QueryString originalQuery = new QueryString();
originalQuery.putAll(request.getQueryString());
HttpHeaders originalHeaders = new HttpHeaders();
originalHeaders.putAll(request.getHeaders());
while (true) {
if (redirectUri != null) {
request = new DefaultRequest(request.getMethod(), redirectUri.toString(), null, null, request.getBody(), request.getHeaders().getContentLength());
}
if (retryCount > 0) {
request.setQueryString(originalQuery);
request.setHeaders(originalHeaders);
}
// Sign the request
this.requestAuthenticator.authenticate(request);
HttpRequestBase httpRequest = this.httpClientRequestFactory.createHttpClientRequest(request, entity);
if (httpRequest instanceof HttpEntityEnclosingRequest) {
entity = ((HttpEntityEnclosingRequest) httpRequest).getEntity();
}
HttpResponse httpResponse = null;
try {
// before executing the request below.
if (retryCount > 0 && redirectUri == null) {
pauseExponentially(retryCount, exception);
if (entity != null) {
InputStream content = entity.getContent();
if (content.markSupported()) {
content.reset();
}
}
}
// reset redirectUri so that if there is an exception, we will pause on retry
redirectUri = null;
exception = null;
retryCount++;
httpResponse = httpClient.execute(httpRequest);
if (isRedirect(httpResponse)) {
Header[] locationHeaders = httpResponse.getHeaders("Location");
String location = locationHeaders[0].getValue();
log.debug("Redirecting to: {}", location);
redirectUri = URI.create(location);
httpRequest.setURI(redirectUri);
} else {
Response response = toSdkResponse(httpResponse);
int httpStatus = response.getHttpStatus();
if (httpStatus == 429) {
throw new RestException("HTTP 429: Too Many Requests. Exceeded request rate limit in the allotted amount of time.");
}
if ((httpStatus == 503 || httpStatus == 504) && retryCount <= this.numRetries) {
// allow the loop to continue to execute a retry request
continue;
}
return response;
}
} catch (Throwable t) {
log.warn("Unable to execute HTTP request: ", t.getMessage(), t);
if (t instanceof RestException) {
exception = (RestException) t;
}
if (!shouldRetry(httpRequest, t, retryCount)) {
throw new RestException("Unable to execute HTTP request: " + t.getMessage(), t);
}
} finally {
try {
httpResponse.getEntity().getContent().close();
} catch (Throwable ignored) {
// NOPMD
}
}
}
}
use of com.okta.sdk.impl.http.RestException in project okta-sdk-java by okta.
the class HttpClientRequestExecutor method pauseExponentially.
/**
* Exponential sleep on failed request to avoid flooding a service with
* retries.
*
* @param retries Current retry count.
* @param previousException Exception information for the previous attempt, if any.
*/
private void pauseExponentially(int retries, RestException previousException) {
long delay;
if (backoffStrategy != null) {
delay = this.backoffStrategy.getDelayMillis(retries);
} else {
long scaleFactor = 300;
if (previousException != null && isThrottlingException(previousException)) {
scaleFactor = 500 + random.nextInt(100);
}
delay = (long) (Math.pow(2, retries) * scaleFactor);
}
delay = Math.min(delay, MAX_BACKOFF_IN_MILLISECONDS);
log.debug("Retryable condition detected, will retry in {}ms, attempt number: {}", delay, retries);
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RestException(e.getMessage(), e);
}
}
Aggregations