Make Monasca-API recover from Keystone failures
Fixes JAH-1987. Fixes "API is failing keystone authentication and never recovering". Make Monasca-API release HTTP connection in finally clause for Keystone requests. Change-Id: Ia4c9899a311794cad8f2fa538fce11bcc265a7e2
This commit is contained in:
parent
de87b63c9b
commit
908bd87609
|
@ -50,6 +50,7 @@ public class HttpAuthClient implements AuthClient {
|
||||||
private static final Logger logger = LoggerFactory.getLogger(HttpAuthClient.class);
|
private static final Logger logger = LoggerFactory.getLogger(HttpAuthClient.class);
|
||||||
|
|
||||||
private static final int DELTA_TIME_IN_SEC = 30;
|
private static final int DELTA_TIME_IN_SEC = 30;
|
||||||
|
private static final String APPLICATION_JSON = "application/json";
|
||||||
private static SimpleDateFormat expiryFormat;
|
private static SimpleDateFormat expiryFormat;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
@ -72,53 +73,67 @@ public class HttpAuthClient implements AuthClient {
|
||||||
@Override
|
@Override
|
||||||
public String validateTokenForServiceEndpointV3(String token) throws ClientProtocolException {
|
public String validateTokenForServiceEndpointV3(String token) throws ClientProtocolException {
|
||||||
String newUri = uri.toString() + "/v3/auth/tokens/";
|
String newUri = uri.toString() + "/v3/auth/tokens/";
|
||||||
Header[] header = new Header[1];
|
Header[] header = new Header[]{new BasicHeader(AUTH_SUBJECT_TOKEN, token)};
|
||||||
header[0] = new BasicHeader(AUTH_SUBJECT_TOKEN, token);
|
|
||||||
return verifyUUIDToken(token, newUri, header);
|
return verifyUUIDToken(token, newUri, header);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String verifyUUIDToken(String token, String newUri,
|
private String verifyUUIDToken(String token, String newUri,
|
||||||
Header[] header)
|
Header[] headers)
|
||||||
throws ClientProtocolException {
|
throws ClientProtocolException {
|
||||||
HttpResponse response = sendGet(newUri, header);
|
|
||||||
|
|
||||||
HttpEntity entity = response.getEntity();
|
HttpGet httpGet = new HttpGet(newUri);
|
||||||
int code = response.getStatusLine().getStatusCode();
|
|
||||||
|
|
||||||
InputStream instream = null;
|
|
||||||
try {
|
try {
|
||||||
if (code == 404) {
|
|
||||||
instream = entity.getContent();
|
httpGet.setHeader("Accept", APPLICATION_JSON);
|
||||||
instream.close();
|
httpGet.setHeader("Content-Type", APPLICATION_JSON);
|
||||||
throw new AuthException("Authorization failed for user token: " + token);
|
|
||||||
|
if (headers != null) {
|
||||||
|
for (Header header : headers) {
|
||||||
|
httpGet.setHeader(header);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code != 200) {
|
HttpResponse response = sendGet(httpGet);
|
||||||
adminToken = null;
|
|
||||||
instream = entity.getContent();
|
|
||||||
instream.close();
|
|
||||||
String reasonPhrase = response.getStatusLine().getReasonPhrase();
|
|
||||||
|
|
||||||
throw new AuthException("Failed to validate via HTTP " + code
|
HttpEntity entity = response.getEntity();
|
||||||
+ " " + reasonPhrase);
|
int code = response.getStatusLine().getStatusCode();
|
||||||
|
|
||||||
|
InputStream instream;
|
||||||
|
try {
|
||||||
|
if (code == 404) {
|
||||||
|
instream = entity.getContent();
|
||||||
|
instream.close();
|
||||||
|
throw new AuthException("Authorization failed for user token: " + token);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code != 200) {
|
||||||
|
adminToken = null;
|
||||||
|
instream = entity.getContent();
|
||||||
|
instream.close();
|
||||||
|
String reasonPhrase = response.getStatusLine().getReasonPhrase();
|
||||||
|
|
||||||
|
throw new AuthException("Failed to validate via HTTP " + code + " " + reasonPhrase);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new ClientProtocolException("IO Exception: problem closing stream ", e);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
|
||||||
throw new ClientProtocolException(
|
return parseResponse(response);
|
||||||
"IO Exception: problem closing stream ", e);
|
|
||||||
|
} finally {
|
||||||
|
|
||||||
|
httpGet.releaseConnection();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return parseResponse(response);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private HttpResponse sendPost(String uri, StringEntity body)
|
private HttpResponse sendPost(HttpPost httpPost)
|
||||||
throws ClientProtocolException {
|
throws ClientProtocolException {
|
||||||
HttpResponse response = null;
|
HttpResponse response;
|
||||||
HttpPost post = new HttpPost(uri);
|
|
||||||
post.setHeader("Accept", "application/json");
|
|
||||||
post.setHeader("Content-Type", "application/json");
|
|
||||||
try {
|
try {
|
||||||
post.setEntity(body);
|
response = client.execute(httpPost);
|
||||||
response = client.execute(post);
|
|
||||||
int code = response.getStatusLine().getStatusCode();
|
int code = response.getStatusLine().getStatusCode();
|
||||||
if (!(code == 201 || code == 200 || code == 203)) {
|
if (!(code == 201 || code == 200 || code == 203)) {
|
||||||
adminToken = null;
|
adminToken = null;
|
||||||
|
@ -134,41 +149,32 @@ public class HttpAuthClient implements AuthClient {
|
||||||
message = e.getMessage();
|
message = e.getMessage();
|
||||||
}
|
}
|
||||||
logger.error("Failure authenticating adminUser: {}", message);
|
logger.error("Failure authenticating adminUser: {}", message);
|
||||||
post.abort();
|
httpPost.abort();
|
||||||
throw new AdminAuthException(
|
throw new AdminAuthException(
|
||||||
"Failure authenticating adminUser :" + message, e);
|
"Failure authenticating adminUser :" + message, e);
|
||||||
}
|
}
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
private HttpResponse sendGet(String newUri, Header[] headers)
|
private HttpResponse sendGet(HttpGet httpGet)
|
||||||
throws ClientProtocolException {
|
throws ClientProtocolException {
|
||||||
HttpResponse response = null;
|
HttpResponse response;
|
||||||
HttpGet get = null;
|
|
||||||
|
|
||||||
get = new HttpGet(newUri);
|
|
||||||
get.setHeader("Accept", "application/json");
|
|
||||||
get.setHeader("Content-Type", "application/json");
|
|
||||||
if (headers != null) {
|
|
||||||
for (Header header : headers) {
|
|
||||||
get.setHeader(header);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (appConfig.getAdminAuthMethod().equalsIgnoreCase(Config.TOKEN)) {
|
if (appConfig.getAdminAuthMethod().equalsIgnoreCase(Config.TOKEN)) {
|
||||||
get.setHeader(new BasicHeader(TOKEN, appConfig.getAdminToken()));
|
httpGet.setHeader(new BasicHeader(TOKEN, appConfig.getAdminToken()));
|
||||||
} else {
|
} else {
|
||||||
get.setHeader(new BasicHeader(TOKEN, getAdminToken()));
|
httpGet.setHeader(new BasicHeader(TOKEN, getAdminToken()));
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
response = client.execute(get);
|
|
||||||
|
response = client.execute(httpGet);
|
||||||
|
|
||||||
} catch (ConnectException c) {
|
} catch (ConnectException c) {
|
||||||
get.abort();
|
httpGet.abort();
|
||||||
throw new ServiceUnavailableException(c.getMessage());
|
throw new ServiceUnavailableException(c.getMessage());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
get.abort();
|
httpGet.abort();
|
||||||
|
|
||||||
throw new ClientProtocolException(
|
throw new ClientProtocolException(
|
||||||
"IO Exception during GET request ", e);
|
"IO Exception during GET request ", e);
|
||||||
|
@ -202,23 +208,37 @@ public class HttpAuthClient implements AuthClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getAdminToken() throws ClientProtocolException {
|
private String getAdminToken() throws ClientProtocolException {
|
||||||
HttpResponse response;
|
|
||||||
String json;
|
|
||||||
JsonParser jp = new JsonParser();
|
|
||||||
|
|
||||||
if (adminTokenExpiry != null) {
|
if (adminTokenExpiry != null) {
|
||||||
if (isExpired(adminTokenExpiry)) {
|
if (isExpired(adminTokenExpiry)) {
|
||||||
adminToken = null;
|
adminToken = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (adminToken == null) {
|
if (adminToken == null) {
|
||||||
StringEntity params = getUnscopedV3AdminTokenRequest();
|
|
||||||
String authUri = uri + "/v3/auth/tokens";
|
String authUri = uri + "/v3/auth/tokens";
|
||||||
response = sendPost(authUri, params);
|
HttpPost httpPost = new HttpPost(authUri);
|
||||||
adminToken = response.getFirstHeader(AUTH_SUBJECT_TOKEN).getValue();
|
|
||||||
json = parseResponse(response);
|
try {
|
||||||
JsonObject token = jp.parse(json).getAsJsonObject().get("token").getAsJsonObject();
|
|
||||||
adminTokenExpiry = token.get("expires_at").getAsString();
|
StringEntity params = getUnscopedV3AdminTokenRequest();
|
||||||
|
httpPost.setHeader("Accept", APPLICATION_JSON);
|
||||||
|
httpPost.setHeader("Content-Type", APPLICATION_JSON);
|
||||||
|
httpPost.setEntity(params);
|
||||||
|
HttpResponse response = sendPost(httpPost);
|
||||||
|
adminToken = response.getFirstHeader(AUTH_SUBJECT_TOKEN).getValue();
|
||||||
|
String json = parseResponse(response);
|
||||||
|
JsonObject
|
||||||
|
token =
|
||||||
|
new JsonParser().parse(json).getAsJsonObject().get("token").getAsJsonObject();
|
||||||
|
adminTokenExpiry = token.get("expires_at").getAsString();
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
|
||||||
|
httpPost.releaseConnection();
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return adminToken;
|
return adminToken;
|
||||||
}
|
}
|
||||||
|
@ -289,7 +309,7 @@ public class HttpAuthClient implements AuthClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isExpired(String expires) {
|
private boolean isExpired(String expires) {
|
||||||
Date tokenExpiryDate = null;
|
Date tokenExpiryDate;
|
||||||
try {
|
try {
|
||||||
// The date looks like: 2014-11-13T02:34:59.953729Z
|
// The date looks like: 2014-11-13T02:34:59.953729Z
|
||||||
// SimpleDateFormat can't handle the microseconds so take them off
|
// SimpleDateFormat can't handle the microseconds so take them off
|
||||||
|
|
Loading…
Reference in New Issue