/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.streams.twitter.api;
import org.apache.streams.util.api.requests.backoff.AbstractBackOffStrategy;
import org.apache.streams.util.api.requests.backoff.BackOffException;
import org.apache.streams.util.api.requests.backoff.impl.LinearTimeBackOffStrategy;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.protocol.HttpContext;
import org.apache.juneau.rest.client.RetryOn;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Handle expected and unexpected exceptions.
*/
public class TwitterRetryHandler implements RetryOn {
private static final Logger LOGGER = LoggerFactory.getLogger(TwitterRetryHandler.class);
private static AbstractBackOffStrategy backoff_strategy;
// TODO: once request context is available, we can maintain multiple BackoffStrategy one per request path / params
// private static Map<String, AbstractBackOffStrategy> backoffs = new ConcurrentHashMap<>();
// This is everything we used to check via twitter4j to decide whether to retry.
//
// @Deprecated
// public static int handleTwitterError(Twitter twitter, Exception exception) {
// return handleTwitterError( twitter, null, exception);
// }
//
//
// public static int handleTwitterError(Twitter twitter, Long id, Exception exception) {
//
// if (exception instanceof TwitterException) {
// TwitterException twitterException = (TwitterException)exception;
//
// if (twitterException.exceededRateLimitation()) {
//
// long millisUntilReset = retry;
//
// final RateLimitStatus rateLimitStatus = twitterException.getRateLimitStatus();
// if (rateLimitStatus != null) {
// millisUntilReset = rateLimitStatus.getSecondsUntilReset() * 1000;
// }
//
// LOGGER.warn("Rate Limit Exceeded. Will retry in {} seconds...", millisUntilReset / 1000);
//
// try {
// Thread.sleep(millisUntilReset);
// } catch (InterruptedException e1) {
// Thread.currentThread().interrupt();
// }
//
// return 1;
// } else if (twitterException.isCausedByNetworkIssue()) {
// LOGGER.info("Twitter Network Issues Detected. Backing off...");
// LOGGER.info("{} - {}", twitterException.getExceptionCode(), twitterException.getLocalizedMessage());
// try {
// Thread.sleep(retry);
// } catch (InterruptedException e1) {
// Thread.currentThread().interrupt();
// }
// return 1;
// } else if (twitterException.isErrorMessageAvailable()) {
// if (twitterException.getMessage().toLowerCase().contains("does not exist")) {
// if ( id != null ) {
// LOGGER.warn("User does not exist: {}", id);
// } else {
// LOGGER.warn("User does not exist");
// }
// return (int)retryMax;
// } else {
// return (int)retryMax / 3;
// }
// } else {
// if (twitterException.getExceptionCode().equals("ced778ef-0c669ac0")) {
// // This is a known weird issue, not exactly sure the cause, but you'll never be able to get the data.
// return (int)retryMax / 3;
// } else if (twitterException.getExceptionCode().equals("4be80492-0a7bf7c7")) {
// // This is a 401 reflecting credentials don't have access to the requested resource.
// if ( id != null ) {
// LOGGER.warn("Authentication Exception accessing id: {}", id);
// } else {
// LOGGER.warn("Authentication Exception");
// }
// return (int)retryMax;
// } else {
// LOGGER.warn("Unknown Twitter Exception...");
// LOGGER.warn(" Access: {}", twitterException.getAccessLevel());
// LOGGER.warn(" Code: {}", twitterException.getExceptionCode());
// LOGGER.warn(" Message: {}", twitterException.getLocalizedMessage());
// return (int)retryMax / 10;
// }
// }
// } else if (exception instanceof RuntimeException) {
// LOGGER.warn("TwitterGrabber: Unknown Runtime Error", exception.getMessage());
// return (int)retryMax / 3;
// } else {
// LOGGER.info("Completely Unknown Exception: {}", exception);
// return (int)retryMax / 3;
// }
// }
// TODO: juneau 6.3.x-incubating
// @Override
// public boolean onCode(int httpResponseCode) {
//
// LOGGER.warn("TwitterRetryHandler: {}", httpResponseCode);
//
// if( httpResponseCode > 400 ) {
// return true;
// } else {
// return false;
// }
//
// }
@Override
public boolean onCode(int httpResponseCode) {
// if( backoff_strategy == null ) {
// backoff_strategy = new LinearTimeBackOffStrategy(retrySleepMs / 1000, retryMax);
// }
// if( httpResponseCode > 400 ) {
// try {
// backoff_strategy.backOff();
// return true;
// } catch (BackOffException boe) {
// backoff_strategy.reset();
// return false;
// }
// } else {
// return false;
// }
if( httpResponseCode > 400 ) {
return true;
} else {
return false;
}
}
}