Skip to content

Commit 82ad9b5

Browse files
snvijayaDadanielZ
authored andcommitted
HADOOP-16660. ABFS: Make RetryCount in ExponentialRetryPolicy Configurable.
Contributed by Sneha Vijayarajan.
1 parent 9e69628 commit 82ad9b5

File tree

6 files changed

+120
-10
lines changed

6 files changed

+120
-10
lines changed

hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/AzureBlobFileSystemStore.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,7 +1129,9 @@ private void initializeClient(URI uri, String fileSystemName, String accountName
11291129
abfsConfiguration.getRawConfiguration());
11301130
}
11311131

1132-
this.client = new AbfsClient(baseUrl, creds, abfsConfiguration, new ExponentialRetryPolicy(), tokenProvider, abfsPerfTracker);
1132+
this.client = new AbfsClient(baseUrl, creds, abfsConfiguration,
1133+
new ExponentialRetryPolicy(abfsConfiguration.getMaxIoRetries()),
1134+
tokenProvider, abfsPerfTracker);
11331135
}
11341136

11351137
private String getOctalNotation(FsPermission fsPermission) {
@@ -1353,4 +1355,4 @@ public String toString() {
13531355
AbfsClient getClient() {
13541356
return this.client;
13551357
}
1356-
}
1358+
}

hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/services/AbfsRestOperation.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,11 @@ void execute() throws AzureBlobFileSystemException {
130130
}
131131

132132
int retryCount = 0;
133+
LOG.debug("First execution of REST operation - {}", operationType);
133134
while (!executeHttpOperation(retryCount++)) {
134135
try {
136+
LOG.debug("Retrying REST operation {}. RetryCount = {}",
137+
operationType, retryCount);
135138
Thread.sleep(client.getRetryPolicy().getRetryInterval(retryCount));
136139
} catch (InterruptedException ex) {
137140
Thread.currentThread().interrupt();

hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/services/ExponentialRetryPolicy.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,6 @@
2525
* Retry policy used by AbfsClient.
2626
* */
2727
public class ExponentialRetryPolicy {
28-
/**
29-
* Represents the default number of retry attempts.
30-
*/
31-
private static final int DEFAULT_CLIENT_RETRY_COUNT = 30;
32-
3328
/**
3429
* Represents the default amount of time used when calculating a random delta in the exponential
3530
* delay between retries.
@@ -86,8 +81,10 @@ public class ExponentialRetryPolicy {
8681
/**
8782
* Initializes a new instance of the {@link ExponentialRetryPolicy} class.
8883
*/
89-
public ExponentialRetryPolicy() {
90-
this(DEFAULT_CLIENT_RETRY_COUNT, DEFAULT_MIN_BACKOFF, DEFAULT_MAX_BACKOFF, DEFAULT_CLIENT_BACKOFF);
84+
public ExponentialRetryPolicy(final int maxIoRetries) {
85+
86+
this(maxIoRetries, DEFAULT_MIN_BACKOFF, DEFAULT_MAX_BACKOFF,
87+
DEFAULT_CLIENT_BACKOFF);
9188
}
9289

9390
/**

hadoop-tools/hadoop-azure/src/test/java/org/apache/hadoop/fs/azurebfs/ITestAbfsRestOperationException.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,17 @@
2020

2121
import java.io.IOException;
2222

23+
import org.apache.hadoop.conf.Configuration;
24+
import org.apache.hadoop.fs.azurebfs.oauth2.RetryTestTokenProvider;
2325
import org.apache.hadoop.fs.FileStatus;
26+
import org.apache.hadoop.fs.FileSystem;
2427
import org.apache.hadoop.fs.Path;
2528

2629
import org.junit.Assert;
2730
import org.junit.Test;
2831

32+
import static org.apache.hadoop.test.LambdaTestUtils.intercept;
33+
2934
/**
3035
* Verify the AbfsRestOperationException error message format.
3136
* */
@@ -72,4 +77,40 @@ public void testAbfsRestOperationExceptionFormat() throws IOException {
7277
&& errorFields[5].contains("Time"));
7378
}
7479
}
80+
81+
@Test
82+
public void testRequestRetryConfig() throws Exception {
83+
testRetryLogic(0);
84+
testRetryLogic(3);
85+
}
86+
87+
public void testRetryLogic(int numOfRetries) throws Exception {
88+
AzureBlobFileSystem fs = this.getFileSystem();
89+
90+
Configuration config = new Configuration(this.getRawConfiguration());
91+
String accountName = config.get("fs.azure.abfs.account.name");
92+
// Setup to configure custom token provider
93+
config.set("fs.azure.account.auth.type." + accountName, "Custom");
94+
config.set("fs.azure.account.oauth.provider.type." + accountName, "org.apache.hadoop.fs"
95+
+ ".azurebfs.oauth2.RetryTestTokenProvider");
96+
config.set("fs.azure.io.retry.max.retries", Integer.toString(numOfRetries));
97+
// Stop filesystem creation as it will lead to calls to store.
98+
config.set("fs.azure.createRemoteFileSystemDuringInitialization", "false");
99+
100+
final AzureBlobFileSystem fs1 =
101+
(AzureBlobFileSystem) FileSystem.newInstance(fs.getUri(),
102+
config);
103+
RetryTestTokenProvider.ResetStatusToFirstTokenFetch();
104+
105+
intercept(Exception.class,
106+
()-> {
107+
fs1.getFileStatus(new Path("/"));
108+
});
109+
110+
// Number of retries done should be as configured
111+
Assert.assertTrue(
112+
"Number of token fetch retries (" + RetryTestTokenProvider.reTryCount
113+
+ ") done, does not match with max " + "retry count configured (" + numOfRetries
114+
+ ")", RetryTestTokenProvider.reTryCount == numOfRetries);
115+
}
75116
}

hadoop-tools/hadoop-azure/src/test/java/org/apache/hadoop/fs/azurebfs/TestAbfsConfigurationFieldsValidation.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,4 +182,4 @@ public void testSSLSocketFactoryConfiguration()
182182
assertEquals(DelegatingSSLSocketFactory.SSLChannelMode.OpenSSL, localAbfsConfiguration.getPreferredSSLFactoryOption());
183183
}
184184

185-
}
185+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
package org.apache.hadoop.fs.azurebfs.oauth2;
19+
20+
import java.io.IOException;
21+
import java.util.Date;
22+
23+
import org.apache.hadoop.conf.Configuration;
24+
import org.apache.hadoop.fs.azurebfs.extensions.CustomTokenProviderAdaptee;
25+
import org.slf4j.Logger;
26+
import org.slf4j.LoggerFactory;
27+
28+
/**
29+
* Test Token provider which should throw exception and trigger retries
30+
*/
31+
public class RetryTestTokenProvider implements CustomTokenProviderAdaptee {
32+
33+
// Need to track first token fetch otherwise will get counted as a retry too.
34+
private static boolean isThisFirstTokenFetch = true;
35+
public static int reTryCount = 0;
36+
37+
private static final Logger LOG = LoggerFactory
38+
.getLogger(RetryTestTokenProvider.class);
39+
40+
@Override
41+
public void initialize(Configuration configuration, String accountName)
42+
throws IOException {
43+
44+
}
45+
46+
public static void ResetStatusToFirstTokenFetch() {
47+
isThisFirstTokenFetch = true;
48+
reTryCount = 0;
49+
}
50+
51+
@Override
52+
public String getAccessToken() throws IOException {
53+
if (isThisFirstTokenFetch) {
54+
isThisFirstTokenFetch = false;
55+
} else {
56+
reTryCount++;
57+
}
58+
59+
LOG.debug("RetryTestTokenProvider: Throw an exception in fetching tokens");
60+
throw new IOException("test exception");
61+
}
62+
63+
@Override
64+
public Date getExpiryTime() {
65+
return new Date();
66+
}
67+
}

0 commit comments

Comments
 (0)