HADOOP-15809. ABFS: better exception handling when making getAccessToken call.
Contributed by Da Zhou
This commit is contained in:
parent
94d82f4162
commit
273cc2d4e9
@ -22,6 +22,7 @@
|
|||||||
import org.apache.hadoop.classification.InterfaceAudience;
|
import org.apache.hadoop.classification.InterfaceAudience;
|
||||||
import org.apache.hadoop.classification.InterfaceStability;
|
import org.apache.hadoop.classification.InterfaceStability;
|
||||||
import org.apache.hadoop.fs.azurebfs.contracts.services.AzureServiceErrorCode;
|
import org.apache.hadoop.fs.azurebfs.contracts.services.AzureServiceErrorCode;
|
||||||
|
import org.apache.hadoop.fs.azurebfs.oauth2.AzureADAuthenticator.HttpException;
|
||||||
import org.apache.hadoop.fs.azurebfs.services.AbfsHttpOperation;
|
import org.apache.hadoop.fs.azurebfs.services.AbfsHttpOperation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -59,6 +60,14 @@ public AbfsRestOperationException(
|
|||||||
this.errorMessage = errorMessage;
|
this.errorMessage = errorMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AbfsRestOperationException(final HttpException innerException) {
|
||||||
|
super(innerException.getMessage());
|
||||||
|
|
||||||
|
this.statusCode = innerException.getHttpErrorCode();
|
||||||
|
this.errorCode = AzureServiceErrorCode.UNKNOWN;
|
||||||
|
this.errorMessage = innerException.getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
public int getStatusCode() {
|
public int getStatusCode() {
|
||||||
return this.statusCode;
|
return this.statusCode;
|
||||||
}
|
}
|
||||||
|
@ -161,14 +161,28 @@ public static AzureADToken getTokenUsingRefreshToken(String clientId,
|
|||||||
return getTokenCall(authEndpoint, qp.serialize(), null, null);
|
return getTokenCall(authEndpoint, qp.serialize(), null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class HttpException extends IOException {
|
|
||||||
|
/**
|
||||||
|
* This exception class contains the http error code,
|
||||||
|
* requestId and error message, it is thrown when AzureADAuthenticator
|
||||||
|
* failed to get the Azure Active Directory token.
|
||||||
|
*/
|
||||||
|
public static class HttpException extends IOException {
|
||||||
private int httpErrorCode;
|
private int httpErrorCode;
|
||||||
private String requestId;
|
private String requestId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets Http error status code.
|
||||||
|
* @return http error code.
|
||||||
|
*/
|
||||||
public int getHttpErrorCode() {
|
public int getHttpErrorCode() {
|
||||||
return this.httpErrorCode;
|
return this.httpErrorCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets http request id .
|
||||||
|
* @return http request id.
|
||||||
|
*/
|
||||||
public String getRequestId() {
|
public String getRequestId() {
|
||||||
return this.requestId;
|
return this.requestId;
|
||||||
}
|
}
|
||||||
@ -188,21 +202,17 @@ private static AzureADToken getTokenCall(String authEndpoint, String body,
|
|||||||
= new ExponentialRetryPolicy(3, 0, 1000, 2);
|
= new ExponentialRetryPolicy(3, 0, 1000, 2);
|
||||||
|
|
||||||
int httperror = 0;
|
int httperror = 0;
|
||||||
String requestId;
|
|
||||||
String httpExceptionMessage = null;
|
|
||||||
IOException ex = null;
|
IOException ex = null;
|
||||||
boolean succeeded = false;
|
boolean succeeded = false;
|
||||||
int retryCount = 0;
|
int retryCount = 0;
|
||||||
do {
|
do {
|
||||||
httperror = 0;
|
httperror = 0;
|
||||||
requestId = "";
|
|
||||||
ex = null;
|
ex = null;
|
||||||
try {
|
try {
|
||||||
token = getTokenSingleCall(authEndpoint, body, headers, httpMethod);
|
token = getTokenSingleCall(authEndpoint, body, headers, httpMethod);
|
||||||
} catch (HttpException e) {
|
} catch (HttpException e) {
|
||||||
httperror = e.httpErrorCode;
|
httperror = e.httpErrorCode;
|
||||||
requestId = e.requestId;
|
ex = e;
|
||||||
httpExceptionMessage = e.getMessage();
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
ex = e;
|
ex = e;
|
||||||
}
|
}
|
||||||
@ -210,13 +220,8 @@ private static AzureADToken getTokenCall(String authEndpoint, String body,
|
|||||||
retryCount++;
|
retryCount++;
|
||||||
} while (!succeeded && retryPolicy.shouldRetry(retryCount, httperror));
|
} while (!succeeded && retryPolicy.shouldRetry(retryCount, httperror));
|
||||||
if (!succeeded) {
|
if (!succeeded) {
|
||||||
if (ex != null) {
|
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
if (httperror != 0) {
|
|
||||||
throw new IOException(httpExceptionMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,7 +268,7 @@ private static AzureADToken getTokenSingleCall(
|
|||||||
InputStream httpResponseStream = conn.getInputStream();
|
InputStream httpResponseStream = conn.getInputStream();
|
||||||
token = parseTokenFromStream(httpResponseStream);
|
token = parseTokenFromStream(httpResponseStream);
|
||||||
} else {
|
} else {
|
||||||
String responseBody = consumeInputStream(conn.getInputStream(), 1024);
|
String responseBody = consumeInputStream(conn.getErrorStream(), 1024);
|
||||||
String proxies = "none";
|
String proxies = "none";
|
||||||
String httpProxy = System.getProperty("http.proxy");
|
String httpProxy = System.getProperty("http.proxy");
|
||||||
String httpsProxy = System.getProperty("https.proxy");
|
String httpsProxy = System.getProperty("https.proxy");
|
||||||
@ -273,11 +278,11 @@ private static AzureADToken getTokenSingleCall(
|
|||||||
String logMessage =
|
String logMessage =
|
||||||
"AADToken: HTTP connection failed for getting token from AzureAD. Http response: "
|
"AADToken: HTTP connection failed for getting token from AzureAD. Http response: "
|
||||||
+ httpResponseCode + " " + conn.getResponseMessage()
|
+ httpResponseCode + " " + conn.getResponseMessage()
|
||||||
+ " Content-Type: " + responseContentType
|
+ "\nContent-Type: " + responseContentType
|
||||||
+ " Content-Length: " + responseContentLength
|
+ " Content-Length: " + responseContentLength
|
||||||
+ " Request ID: " + requestId.toString()
|
+ " Request ID: " + requestId.toString()
|
||||||
+ " Proxies: " + proxies
|
+ " Proxies: " + proxies
|
||||||
+ " First 1K of Body: " + responseBody;
|
+ "\nFirst 1K of Body: " + responseBody;
|
||||||
LOG.debug(logMessage);
|
LOG.debug(logMessage);
|
||||||
throw new HttpException(httpResponseCode, requestId, logMessage);
|
throw new HttpException(httpResponseCode, requestId, logMessage);
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
import org.apache.hadoop.fs.azurebfs.contracts.exceptions.AzureBlobFileSystemException;
|
import org.apache.hadoop.fs.azurebfs.contracts.exceptions.AzureBlobFileSystemException;
|
||||||
import org.apache.hadoop.fs.azurebfs.contracts.exceptions.InvalidAbfsRestOperationException;
|
import org.apache.hadoop.fs.azurebfs.contracts.exceptions.InvalidAbfsRestOperationException;
|
||||||
import org.apache.hadoop.fs.azurebfs.constants.HttpHeaderConfigurations;
|
import org.apache.hadoop.fs.azurebfs.constants.HttpHeaderConfigurations;
|
||||||
|
import org.apache.hadoop.fs.azurebfs.oauth2.AzureADAuthenticator.HttpException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The AbfsRestOperation for Rest AbfsClient.
|
* The AbfsRestOperation for Rest AbfsClient.
|
||||||
@ -175,6 +176,14 @@ private boolean executeHttpOperation(final int retryCount) throws AzureBlobFileS
|
|||||||
if (!client.getRetryPolicy().shouldRetry(retryCount, -1)) {
|
if (!client.getRetryPolicy().shouldRetry(retryCount, -1)) {
|
||||||
throw new InvalidAbfsRestOperationException(ex);
|
throw new InvalidAbfsRestOperationException(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// once HttpException is thrown by AzureADAuthenticator,
|
||||||
|
// it indicates the policy in AzureADAuthenticator determined
|
||||||
|
// retry is not needed
|
||||||
|
if (ex instanceof HttpException) {
|
||||||
|
throw new AbfsRestOperationException((HttpException) ex);
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
} finally {
|
} finally {
|
||||||
AbfsClientThrottlingIntercept.updateMetrics(operationType, httpOperation);
|
AbfsClientThrottlingIntercept.updateMetrics(operationType, httpOperation);
|
||||||
|
Loading…
Reference in New Issue
Block a user