Skip to content

HADOOP-17576. ABFS: Disable throttling update for auth failures #2761

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Apr 9, 2021
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
import org.apache.hadoop.fs.azurebfs.contracts.exceptions.AzureBlobFileSystemException;
import org.apache.hadoop.fs.azurebfs.contracts.exceptions.InvalidAbfsRestOperationException;
import org.apache.hadoop.fs.azurebfs.constants.HttpHeaderConfigurations;
import org.apache.hadoop.fs.azurebfs.oauth2.AzureADAuthenticator.HttpException;

/**
* The AbfsRestOperation for Rest AbfsClient.
Expand Down Expand Up @@ -233,7 +232,13 @@ private boolean executeHttpOperation(final int retryCount) throws AzureBlobFileS
hasRequestBody ? bufferLength : 0);
break;
}
} catch (IOException e) {
LOG.debug("Auth failure: {}, {}", method, url);
throw new AbfsRestOperationException(-1, null,
"Auth failure: " + e.getMessage(), e);
}

try {
// dump the headers
AbfsIoUtils.dumpHeadersToDebugLog("Request Headers",
httpOperation.getConnection().getRequestProperties());
Expand All @@ -256,9 +261,7 @@ private boolean executeHttpOperation(final int retryCount) throws AzureBlobFileS
}
} catch (UnknownHostException ex) {
String hostname = null;
if (httpOperation != null) {
hostname = httpOperation.getHost();
}
hostname = httpOperation.getHost();
LOG.warn("Unknown host name: %s. Retrying to resolve the host name...",
hostname);
if (!client.getRetryPolicy().shouldRetry(retryCount, -1)) {
Expand All @@ -267,24 +270,13 @@ private boolean executeHttpOperation(final int retryCount) throws AzureBlobFileS
return false;
} catch (IOException ex) {
if (LOG.isDebugEnabled()) {
if (httpOperation != null) {
LOG.debug("HttpRequestFailure: " + httpOperation.toString(), ex);
} else {
LOG.debug("HttpRequestFailure: " + method + "," + url, ex);
}
LOG.debug("HttpRequestFailure: {}, {}", httpOperation.toString(), ex);
}

if (!client.getRetryPolicy().shouldRetry(retryCount, -1)) {
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;
} finally {
AbfsClientThrottlingIntercept.updateMetrics(operationType, httpOperation);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,31 @@

import java.io.IOException;

import org.assertj.core.api.Assertions;
import org.junit.Assert;
import org.junit.Test;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.azurebfs.contracts.exceptions.AbfsRestOperationException;
import org.apache.hadoop.fs.azurebfs.contracts.services.AzureServiceErrorCode;
import org.apache.hadoop.fs.azurebfs.oauth2.RetryTestTokenProvider;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;

import org.junit.Assert;
import org.junit.Test;

import static org.apache.hadoop.fs.azurebfs.constants.AbfsHttpConstants.DOT;
import static org.apache.hadoop.fs.azurebfs.constants.ConfigurationKeys.AZURE_CREATE_REMOTE_FILESYSTEM_DURING_INITIALIZATION;
import static org.apache.hadoop.fs.azurebfs.constants.ConfigurationKeys.FS_AZURE_ACCOUNT_AUTH_TYPE_PROPERTY_NAME;
import static org.apache.hadoop.fs.azurebfs.constants.ConfigurationKeys.FS_AZURE_ACCOUNT_TOKEN_PROVIDER_TYPE_PROPERTY_NAME;
import static org.apache.hadoop.fs.azurebfs.constants.TestConfigurationKeys.FS_AZURE_ABFS_ACCOUNT_NAME;
import static org.apache.hadoop.test.LambdaTestUtils.intercept;

/**
* Verify the AbfsRestOperationException error message format.
* */
public class ITestAbfsRestOperationException extends AbstractAbfsIntegrationTest{
private static final String RETRY_TEST_TOKEN_PROVIDER = "org.apache.hadoop.fs.azurebfs.oauth2.RetryTestTokenProvider";

public ITestAbfsRestOperationException() throws Exception {
super();
}
Expand Down Expand Up @@ -114,4 +124,35 @@ public void testWithDifferentCustomTokenFetchRetry(int numOfRetries) throws Exce
+ ") done, does not match with fs.azure.custom.token.fetch.retry.count configured (" + numOfRetries
+ ")", RetryTestTokenProvider.reTryCount == numOfRetries);
}

@Test
public void testAuthFailException() throws Exception {
Configuration config = new Configuration(getRawConfiguration());
String accountName = config
.get(FS_AZURE_ABFS_ACCOUNT_NAME);
// Setup to configure custom token provider
config.set(FS_AZURE_ACCOUNT_AUTH_TYPE_PROPERTY_NAME + DOT
+ accountName, "Custom");
config.set(
FS_AZURE_ACCOUNT_TOKEN_PROVIDER_TYPE_PROPERTY_NAME + DOT + accountName,
RETRY_TEST_TOKEN_PROVIDER);
// Stop filesystem creation as it will lead to calls to store.
config.set(AZURE_CREATE_REMOTE_FILESYSTEM_DURING_INITIALIZATION, "false");

final AzureBlobFileSystem fs = getFileSystem(config);
try {
fs.getFileStatus(new Path("/"));
fail("Should fail at auth token fetch call");
} catch (AbfsRestOperationException e) {
String errorDesc = "Should throw RestOp exception on AAD failure";
Assertions.assertThat(e.getStatusCode())
.describedAs("Incorrect status code. " + errorDesc).isEqualTo(-1);
Assertions.assertThat(e.getErrorCode())
.describedAs("Incorrect error code. " + errorDesc)
.isEqualTo(AzureServiceErrorCode.UNKNOWN);
Assertions.assertThat(e.getErrorMessage())
.describedAs("Incorrect error message. " + errorDesc)
.contains("Auth failure: ");
}
}
}