protected List<Server> pollForServers() {
try {
List<Server> activeNodeList = getNodeList();
int activeNodeCount = activeNodeList.size();
Server server = null;
List<String> hosts = null;
String path = "/?endpoint";
// we want to try a different node on failure until we try every active node (HttpClient will auto-retry
// 500s and some IOEs), but we don't want to start with the same node each time.
for (int i = 0; i < activeNodeCount; i++) {
try {
// get next server in the list (trying to distribute this call among active nodes)
// note: the extra modulus logic is there just in case requestCounter wraps around to a negative value
server = activeNodeList.get((requestCounter++ % activeNodeCount + activeNodeCount) % activeNodeCount);
HttpGet request = new HttpGet(protocol + "://" + server + path);
logger.debug("endpoint query attempt #" + (i + 1) + ": trying " + server);
// format date
String rfcDate;
synchronized (rfc822DateFormat) {
rfcDate = rfc822DateFormat.format(new Date());
}
// generate signature
String canonicalString = "GET\n\n\n" + rfcDate + "\n" + path;
String signature = getSignature(canonicalString, secret);
// add date and auth headers
request.addHeader("Date", rfcDate);
request.addHeader("Authorization", "AWS " + user + ":" + signature);
// send request
HttpResponse response = httpClient.execute(request);
if (response.getStatusLine().getStatusCode() > 299) {
EntityUtils.consumeQuietly(response.getEntity());
throw new RuntimeException("received error response: " + response.getStatusLine());
}
logger.debug("received success response: " + response.getStatusLine());
hosts = parseResponse(response);
break;
} catch (Exception e) {
logger.warn("error polling for endpoints on " + server, e);
}
}
if (hosts == null)
throw new RuntimeException("Exhausted all nodes; no response available");
List<Server> updatedNodeList = new ArrayList<Server>();
for (String host : hosts) {
updatedNodeList.add(new Server(host, port));
}
setNodeList(updatedNodeList);
} catch (Exception e) {
logger.warn("Unable to poll for servers", e);
}