下面列出了org.apache.http.HttpStatus#SC_SERVICE_UNAVAILABLE 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public boolean shouldRetry(Exception ex, RequestMessage request,
ResponseMessage response, int retries) {
if (ex instanceof ClientException) {
String errorCode = ((ClientException) ex).getErrorCode();
if (errorCode.equals(ClientErrorCode.CONNECTION_TIMEOUT)
|| errorCode.equals(ClientErrorCode.SOCKET_TIMEOUT)) {
return true;
}
}
if (response != null) {
int statusCode = response.getStatusCode();
if (statusCode == HttpStatus.SC_INTERNAL_SERVER_ERROR
|| statusCode == HttpStatus.SC_SERVICE_UNAVAILABLE) {
return true;
}
}
return false;
}
@Override
public boolean shouldRetry(Exception ex, RequestMessage request,
ResponseMessage response, int retries) {
if (ex instanceof ClientException) {
String errorCode = ((ClientException) ex).getErrorCode();
if (errorCode.equals(ClientErrorCode.CONNECTION_TIMEOUT)
|| errorCode.equals(ClientErrorCode.SOCKET_TIMEOUT)) {
return true;
}
}
if (response != null) {
int statusCode = response.getStatusCode();
if (statusCode == HttpStatus.SC_INTERNAL_SERVER_ERROR
|| statusCode == HttpStatus.SC_SERVICE_UNAVAILABLE) {
return true;
}
}
return false;
}
/**
* handleExceptionStatusCode - throws the correct error for a status
*
* @param statusLine the status line we want to check
* @throws BackOffException -- if we have a 503 exception
* @throws IOException - if we don't know what it is
*/
private static void handleExceptionalStatus(StatusLine statusLine,
HttpResponse response)
throws IOException, IngestResponseException
{
//if we have a 503 exception throw a backoff
switch (statusLine.getStatusCode())
{
//If we have a 503, BACKOFF
case HttpStatus.SC_SERVICE_UNAVAILABLE:
LOGGER.warn("503 Status hit, backoff");
throw new BackOffException();
//We don't know how to respond now...
default:
LOGGER.error("Status code {} found in response from service",
statusLine.getStatusCode());
String blob = EntityUtils.toString(response.getEntity());
throw new IngestResponseException(statusLine.getStatusCode(),
IngestResponseException
.IngestExceptionBody.parseBody(blob));
}
}
@Override
public boolean retryRequest(HttpResponse response, int executionCount, HttpContext context) {
// Note that a 404 can happen during service startup, so we want to retry.
boolean shouldRetry = executionCount <= maxRetries
&& (response.getStatusLine().getStatusCode() == HttpStatus.SC_SERVICE_UNAVAILABLE || response.getStatusLine().getStatusCode() == HttpStatus.SC_NOT_FOUND);
if (shouldRetry) {
retryCounter.inc();
}
return shouldRetry;
}
private boolean isRequestRateExceededException(Throwable t) {
if (t instanceof AmazonS3Exception) {
AmazonS3Exception e = (AmazonS3Exception) t;
// Several ways AWS communicates rate limit exceeded: 503 status codes and "SlowDown" error codes.
// Check for either.
return e.getStatusCode() == HttpStatus.SC_SERVICE_UNAVAILABLE ||
(e.getErrorCode() != null && e.getErrorCode().toLowerCase().contains("slowdown"));
}
return false;
}
/**
* Returns whether a failed request should be retried according to the given request context. In the following
* circumstances, the request will fail directly without consulting this method:
* <ul>
* <li>if it has already reached the max retry limit,
* <li>if the request contains non-repeatable content,
* <li>if any RuntimeException or Error is thrown when executing the request.
* </ul>
*
* @param exception the exception from the failed request, represented as a BceClientException object.
* @param retriesAttempted the number of times the current request has been attempted.
* @return true if the failed request should be retried.
*/
protected boolean shouldRetry(BceClientException exception, int retriesAttempted) {
// Always retry on client exceptions caused by IOException
if (exception.getCause() instanceof IOException) {
logger.debug("Retry for IOException.");
return true;
}
// Only retry on a subset of service exceptions
if (exception instanceof BceServiceException) {
BceServiceException e = (BceServiceException) exception;
/*
* For 500 internal server errors and 503 service unavailable errors and 502 service bad gateway, we want to retry, but we need to use
* an exponential back-off strategy so that we don't overload a server with a flood of retries.
*/
if (e.getStatusCode() == HttpStatus.SC_INTERNAL_SERVER_ERROR) {
logger.debug("Retry for internal server error.");
return true;
}
if (e.getStatusCode() == HttpStatus.SC_BAD_GATEWAY) {
logger.debug("Retry for bad gateway.");
return true;
}
if (e.getStatusCode() == HttpStatus.SC_SERVICE_UNAVAILABLE) {
logger.debug("Retry for service unavailable.");
return true;
}
String errorCode = e.getErrorCode();
if (ErrorCode.REQUEST_EXPIRED.equals(errorCode)) {
logger.debug("Retry for request expired.");
return true;
}
}
return false;
}
public BackgroundException map(final Throwable failure, final StringBuilder buffer, final int statusCode) {
switch(statusCode) {
case HttpStatus.SC_UNAUTHORIZED:
return new LoginFailureException(buffer.toString(), failure);
case HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED:
return new ProxyLoginFailureException(buffer.toString(), failure);
case HttpStatus.SC_FORBIDDEN:
case HttpStatus.SC_NOT_ACCEPTABLE:
return new AccessDeniedException(buffer.toString(), failure);
case HttpStatus.SC_CONFLICT:
return new ConflictException(buffer.toString(), failure);
case HttpStatus.SC_NOT_FOUND:
case HttpStatus.SC_GONE:
case HttpStatus.SC_REQUESTED_RANGE_NOT_SATISFIABLE:
return new NotfoundException(buffer.toString(), failure);
case HttpStatus.SC_INSUFFICIENT_SPACE_ON_RESOURCE:
case HttpStatus.SC_INSUFFICIENT_STORAGE:
case HttpStatus.SC_PAYMENT_REQUIRED:
return new QuotaException(buffer.toString(), failure);
case HttpStatus.SC_UNPROCESSABLE_ENTITY:
case HttpStatus.SC_BAD_REQUEST:
case HttpStatus.SC_REQUEST_URI_TOO_LONG:
case HttpStatus.SC_METHOD_NOT_ALLOWED:
case HttpStatus.SC_NOT_IMPLEMENTED:
return new InteroperabilityException(buffer.toString(), failure);
case HttpStatus.SC_REQUEST_TIMEOUT:
case HttpStatus.SC_GATEWAY_TIMEOUT:
return new ConnectionTimeoutException(buffer.toString(), failure);
case HttpStatus.SC_LOCKED:
return new LockedException(buffer.toString(), failure);
case HttpStatus.SC_BAD_GATEWAY:
case HttpStatus.SC_INTERNAL_SERVER_ERROR:
case HttpStatus.SC_SERVICE_UNAVAILABLE:
case 429:
// Too Many Requests. Rate limiting
case 509:
// Bandwidth Limit Exceeded
return new RetriableAccessDeniedException(buffer.toString(), failure);
default:
return new InteroperabilityException(buffer.toString(), failure);
}
}
public RemoteIdentityServerException(String error) {
super(HttpStatus.SC_SERVICE_UNAVAILABLE, "M_REMOTE_IS_ERROR", "Error from remote server: " + error);
}
public RemoteHomeServerException(String error) {
super(HttpStatus.SC_SERVICE_UNAVAILABLE, "M_REMOTE_HS_ERROR", "Error from remote server: " + error);
}
private <T> RestResult<T> execute( String httpMethod, String url, Object body, Class<T> clazz, boolean encrypt )
{
log.info( "{} {}", httpMethod, url );
WebClient webClient = null;
Response response = null;
RestResult<T> restResult = new RestResult<>( HttpStatus.SC_INTERNAL_SERVER_ERROR );
try
{
webClient = configManager.getTrustedWebClientWithAuth( url, configManager.getBazaarIp() );
Object requestBody = encrypt ? encryptBody( body ) : body;
response = webClient.invoke( httpMethod, requestBody );
// retry on 503 http code >>>
int attemptNo = 1;
while ( response.getStatus() == HttpStatus.SC_SERVICE_UNAVAILABLE && attemptNo < MAX_ATTEMPTS )
{
attemptNo++;
response = webClient.invoke( httpMethod, requestBody );
TaskUtil.sleep( 500 );
}
// <<< retry on 503 http code
log.info( "response.status: {} - {}", response.getStatus(), response.getStatusInfo().getReasonPhrase() );
restResult = handleResponse( response, clazz, encrypt );
}
catch ( Exception e )
{
if ( response != null )
{
restResult.setReasonPhrase( response.getStatusInfo().getReasonPhrase() );
}
Throwable rootCause = ExceptionUtil.getRootCauze( e );
if ( rootCause instanceof ConnectException || rootCause instanceof UnknownHostException
|| rootCause instanceof BindException || rootCause instanceof NoRouteToHostException
|| rootCause instanceof PortUnreachableException || rootCause instanceof SocketTimeoutException )
{
restResult.setError( CONNECTION_EXCEPTION_MARKER );
}
else
{
restResult.setError( ERROR + e.getMessage() );
}
log.error( ERROR + e.getMessage() );
}
finally
{
close( webClient, response );
}
return restResult;
}
private int computeStatus(int status) {
switch (status) {
case HttpStatus.SC_FORBIDDEN:
case HttpStatus.SC_METHOD_NOT_ALLOWED:
case HttpStatus.SC_BAD_REQUEST:
case HttpStatus.SC_UNAUTHORIZED:
case HttpStatus.SC_PAYMENT_REQUIRED:
case HttpStatus.SC_NOT_FOUND:
case HttpStatus.SC_NOT_ACCEPTABLE:
case HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED:
case HttpStatus.SC_REQUEST_TIMEOUT:
case HttpStatus.SC_CONFLICT:
case HttpStatus.SC_GONE:
case HttpStatus.SC_LENGTH_REQUIRED:
case HttpStatus.SC_PRECONDITION_FAILED:
case HttpStatus.SC_REQUEST_TOO_LONG:
case HttpStatus.SC_REQUEST_URI_TOO_LONG:
case HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE:
case HttpStatus.SC_REQUESTED_RANGE_NOT_SATISFIABLE:
case HttpStatus.SC_EXPECTATION_FAILED:
case HttpStatus.SC_INSUFFICIENT_SPACE_ON_RESOURCE:
case HttpStatus.SC_METHOD_FAILURE:
case HttpStatus.SC_UNPROCESSABLE_ENTITY:
case HttpStatus.SC_LOCKED:
case HttpStatus.SC_FAILED_DEPENDENCY:
case HttpStatus.SC_INTERNAL_SERVER_ERROR:
case HttpStatus.SC_NOT_IMPLEMENTED:
case HttpStatus.SC_BAD_GATEWAY:
case HttpStatus.SC_SERVICE_UNAVAILABLE:
case HttpStatus.SC_GATEWAY_TIMEOUT:
case HttpStatus.SC_HTTP_VERSION_NOT_SUPPORTED:
case HttpStatus.SC_INSUFFICIENT_STORAGE:
return 0;
case HttpStatus.SC_CONTINUE:
case HttpStatus.SC_SWITCHING_PROTOCOLS:
case HttpStatus.SC_PROCESSING:
case HttpStatus.SC_OK:
case HttpStatus.SC_CREATED:
case HttpStatus.SC_ACCEPTED:
case HttpStatus.SC_NON_AUTHORITATIVE_INFORMATION:
case HttpStatus.SC_NO_CONTENT:
case HttpStatus.SC_RESET_CONTENT:
case HttpStatus.SC_PARTIAL_CONTENT:
case HttpStatus.SC_MULTI_STATUS:
case HttpStatus.SC_MULTIPLE_CHOICES:
case HttpStatus.SC_MOVED_PERMANENTLY:
case HttpStatus.SC_MOVED_TEMPORARILY:
case HttpStatus.SC_SEE_OTHER:
case HttpStatus.SC_NOT_MODIFIED:
case HttpStatus.SC_USE_PROXY:
case HttpStatus.SC_TEMPORARY_REDIRECT:
return 1;
default :
return 1;
}
}
/**
* タイムアウト値のチェック.
* @throws DcEngineException DcEngine例外
*/
public final void checkTimeout() throws DcEngineException {
if (timeout < System.currentTimeMillis()) {
throw new DcEngineException("JavaScript Timeout", HttpStatus.SC_SERVICE_UNAVAILABLE);
}
}
private void handleThrottleOut(MessageContext messageContext) {
String errorMessage = null;
String errorDescription = null;
int errorCode = -1;
int httpErrorCode = -1;
if (APIThrottleConstants.HARD_LIMIT_EXCEEDED.equals(
messageContext.getProperty(APIThrottleConstants.THROTTLED_OUT_REASON))) {
errorCode = APIThrottleConstants.HARD_LIMIT_EXCEEDED_ERROR_CODE;
errorMessage = "API Limit Reached";
errorDescription = "API not accepting requests";
// It it's a hard limit exceeding, we tell it as service not being available.
httpErrorCode = HttpStatus.SC_SERVICE_UNAVAILABLE;
} else if (APIThrottleConstants.API_LIMIT_EXCEEDED
.equals(messageContext.getProperty(APIThrottleConstants.THROTTLED_OUT_REASON))) {
errorCode = APIThrottleConstants.API_THROTTLE_OUT_ERROR_CODE;
errorMessage = "Message throttled out";
// By default we send a 429 response back
httpErrorCode = APIThrottleConstants.SC_TOO_MANY_REQUESTS;
errorDescription = "You have exceeded your quota";
} else if (APIThrottleConstants.RESOURCE_LIMIT_EXCEEDED
.equals(messageContext.getProperty(APIThrottleConstants.THROTTLED_OUT_REASON))) {
errorCode = APIThrottleConstants.RESOURCE_THROTTLE_OUT_ERROR_CODE;
errorMessage = "Message throttled out";
// By default we send a 429 response back
httpErrorCode = APIThrottleConstants.SC_TOO_MANY_REQUESTS;
errorDescription = "You have exceeded your quota";
} else {
errorCode = APIThrottleConstants.APPLICATION_THROTTLE_OUT_ERROR_CODE;
errorMessage = "Message throttled out";
// By default we send a 429 response back
httpErrorCode = APIThrottleConstants.SC_TOO_MANY_REQUESTS;
errorDescription = "You have exceeded your quota";
}
messageContext.setProperty(SynapseConstants.ERROR_CODE, errorCode);
messageContext.setProperty(SynapseConstants.ERROR_MESSAGE, errorMessage);
Mediator sequence = messageContext.getSequence(APIThrottleConstants.API_THROTTLE_OUT_HANDLER);
// Invoke the custom error handler specified by the user
if (sequence != null && !sequence.mediate(messageContext)) {
// If needed user should be able to prevent the rest of the fault handling
// logic from getting executed
return;
}
org.apache.axis2.context.MessageContext axis2MC = ((Axis2MessageContext) messageContext).
getAxis2MessageContext();
// This property need to be set to avoid sending the content in pass-through pipe (request message)
// as the response.
axis2MC.setProperty(PassThroughConstants.MESSAGE_BUILDER_INVOKED, Boolean.TRUE);
try {
RelayUtils.consumeAndDiscardMessage(axis2MC);
} catch (AxisFault axisFault) {
//In case of an error it is logged and the process is continued because we're setting a fault message in the payload.
log.error("Error occurred while consuming and discarding the message", axisFault);
}
if (messageContext.isDoingPOX() || messageContext.isDoingGET()) {
Utils.setFaultPayload(messageContext, getFaultPayload(errorCode, errorMessage, errorDescription));
} else {
setSOAPFault(messageContext, errorMessage, errorDescription);
}
sendFault(messageContext, httpErrorCode);
}
/**
* Translate the versions.
* <pre>
* [
* {
* "groupId": "com.google.guava",
* "artifactId": "guava",
* "version": "13.0.1"
* }
* ]
* </pre>
* This equates to a List of ProjectVersionRef.
*
* <pre>
* {
* "productNames": [],
* "productVersionIds": [],
* "repositoryGroup": "",
* "gavs": [
* {
* "groupId": "com.google.guava",
* "artifactId": "guava",
* "version": "13.0.1"
* }
* ]
* }
* </pre>
* There may be a lot of them, possibly causing timeouts or other issues.
* This is mitigated by splitting them into smaller chunks when an error occurs and retrying.
*/
public Map<ProjectVersionRef, String> translateVersions( List<ProjectVersionRef> p ) throws RestException
{
final List<ProjectVersionRef> projects = p.stream().distinct().collect( Collectors.toList() );
if ( p.size() != projects.size() )
{
logger.debug( "Eliminating duplicates from {} resulting in {}", p, projects );
}
logger.info( "Calling REST client... (with {} GAVs)", projects.size() );
final Queue<Task> queue = new ArrayDeque<>();
final Map<ProjectVersionRef, String> result = new HashMap<>();
final long start = System.nanoTime();
boolean finishedSuccessfully = false;
try
{
partition( projects, queue );
while ( !queue.isEmpty() )
{
Task task = queue.remove();
task.executeTranslate();
if ( task.isSuccess() )
{
result.putAll( task.getResult() );
}
else
{
if ( task.canSplit() && isRecoverable( task.getStatus() ) )
{
if ( task.getStatus() == HttpStatus.SC_SERVICE_UNAVAILABLE )
{
logger.info( "The DA server is unavailable. Waiting {} before splitting the tasks and retrying",
retryDuration );
waitBeforeRetry( retryDuration );
}
List<Task> tasks = task.split();
logger.warn( "Failed to translate versions for task @{} due to {}, splitting and retrying. Chunk size was: {} and new chunk size {} in {} segments.",
task.hashCode(), task.getStatus(), task.getChunkSize(), tasks.get( 0 ).getChunkSize(),
tasks.size() );
queue.addAll( tasks );
}
else
{
if ( task.getStatus() < 0 )
{
logger.debug( "Caught exception calling server with message {}", task.getErrorMessage() );
}
else
{
logger.debug( "Did not get status {} but received {}", SC_OK, task.getStatus() );
}
throw new RestException( "Received response status {} with message: {}",
task.getStatus(), task.getErrorMessage() );
}
}
}
finishedSuccessfully = true;
}
finally
{
printFinishTime( logger, start, finishedSuccessfully);
}
return result;
}
private boolean isRecoverable(int httpErrorCode)
{
return httpErrorCode == HttpStatus.SC_GATEWAY_TIMEOUT || httpErrorCode == HttpStatus.SC_SERVICE_UNAVAILABLE;
}