Skip to content

Commit acb31b6

Browse files
ahmarsuhailsteveloughran
authored andcommitted
HADOOP-18073. Upgrade AWS SDK to v2 in S3A [work in progress]
See aws_sdk_v2_changelog.md for details. Co-authored-by: Ahmar Suhail <[email protected]> Co-authored-by: Alessandro Passaro <[email protected]> HADOOP-18073. Address review comments. (#31) addresses review comments + yetus errors Co-authored-by: Ahmar Suhail <[email protected]> Move MultiObjectDeleteException to impl Reinstate old constants Move TransferManager initialization to ClientFactory Add unit tests for BlockingEnumeration Add unit tests for SelectEventStreamPublisher updates new providers in TestS3AAWSCredentialsProvider to V2 update GET range referrer header logic to V2 adds in unit check for bytes HADOOP-18565. Complete outstanding items for the AWS SDK V2 upgrade. (apache#5421) Changes include * use bundled transfer manager * adds transfer listener to upload * adds support for custom signers * don't set default endpoint * removes v1 sdk bundle, only use core package * implements region caching + many more Note: spotbugs is warning about inconsistent synchronization in accessing a new s3a FS field. This will be fixed in a follow-up patch. Contributed by Ahmar Suhail fixes issues after rebase Change-Id: I1d4b658979c725a88f6b54832bb7d106ffc2347d
1 parent c35f316 commit acb31b6

File tree

187 files changed

+7030
-5222
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

187 files changed

+7030
-5222
lines changed

hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/statistics/StoreStatisticNames.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,10 @@ public final class StoreStatisticNames {
407407
public static final String MULTIPART_UPLOAD_LIST
408408
= "multipart_upload_list";
409409

410+
/** Probe for store region: {@value}. */
411+
public static final String STORE_REGION_PROBE
412+
= "store_region_probe";
413+
410414
private StoreStatisticNames() {
411415
}
412416

hadoop-project/pom.xml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,8 @@
184184
<surefire.fork.timeout>900</surefire.fork.timeout>
185185
<aws-java-sdk.version>1.12.367</aws-java-sdk.version>
186186
<hsqldb.version>2.7.1</hsqldb.version>
187+
<aws-java-sdk-v2.version>2.19.12</aws-java-sdk-v2.version>
188+
<awscrt.version>0.21.0</awscrt.version>
187189
<frontend-maven-plugin.version>1.11.2</frontend-maven-plugin.version>
188190
<jasmine-maven-plugin.version>2.1</jasmine-maven-plugin.version>
189191
<phantomjs-maven-plugin.version>0.7</phantomjs-maven-plugin.version>
@@ -1128,15 +1130,25 @@
11281130
</dependency>
11291131
<dependency>
11301132
<groupId>com.amazonaws</groupId>
1131-
<artifactId>aws-java-sdk-bundle</artifactId>
1133+
<artifactId>aws-java-sdk-core</artifactId>
11321134
<version>${aws-java-sdk.version}</version>
1135+
</dependency>
1136+
<dependency>
1137+
<groupId>software.amazon.awssdk</groupId>
1138+
<artifactId>bundle</artifactId>
1139+
<version>${aws-java-sdk-v2.version}</version>
11331140
<exclusions>
11341141
<exclusion>
11351142
<groupId>io.netty</groupId>
11361143
<artifactId>*</artifactId>
11371144
</exclusion>
11381145
</exclusions>
11391146
</dependency>
1147+
<dependency>
1148+
<groupId>software.amazon.awssdk.crt</groupId>
1149+
<artifactId>aws-crt</artifactId>
1150+
<version>${awscrt.version}</version>
1151+
</dependency>
11401152
<dependency>
11411153
<groupId>org.apache.mina</groupId>
11421154
<artifactId>mina-core</artifactId>

hadoop-tools/hadoop-aws/pom.xml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,17 @@
496496
</dependency>
497497
<dependency>
498498
<groupId>com.amazonaws</groupId>
499-
<artifactId>aws-java-sdk-bundle</artifactId>
499+
<artifactId>aws-java-sdk-core</artifactId>
500+
<scope>compile</scope>
501+
</dependency>
502+
<dependency>
503+
<groupId>software.amazon.awssdk</groupId>
504+
<artifactId>bundle</artifactId>
505+
<scope>compile</scope>
506+
</dependency>
507+
<dependency>
508+
<groupId>software.amazon.awssdk.crt</groupId>
509+
<artifactId>aws-crt</artifactId>
500510
<scope>compile</scope>
501511
</dependency>
502512
<dependency>

hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/AWSBadRequestException.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
package org.apache.hadoop.fs.s3a;
2020

21-
import com.amazonaws.AmazonServiceException;
21+
import software.amazon.awssdk.awscore.exception.AwsServiceException;
2222

2323
/**
2424
* A 400 "Bad Request" exception was received.
@@ -36,7 +36,7 @@ public class AWSBadRequestException extends AWSServiceIOException {
3636
* @param cause the underlying cause
3737
*/
3838
public AWSBadRequestException(String operation,
39-
AmazonServiceException cause) {
39+
AwsServiceException cause) {
4040
super(operation, cause);
4141
}
4242
}

hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/AWSClientIOException.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,34 +18,33 @@
1818

1919
package org.apache.hadoop.fs.s3a;
2020

21-
import com.amazonaws.AmazonClientException;
22-
import com.amazonaws.SdkBaseException;
21+
import software.amazon.awssdk.core.exception.SdkException;
2322
import org.apache.hadoop.util.Preconditions;
2423

2524
import java.io.IOException;
2625

26+
2727
/**
28-
* IOException equivalent of an {@link AmazonClientException}.
28+
* IOException equivalent of an {@link SdkException}.
2929
*/
3030
public class AWSClientIOException extends IOException {
3131

3232
private final String operation;
3333

3434
public AWSClientIOException(String operation,
35-
SdkBaseException cause) {
35+
SdkException cause) {
3636
super(cause);
3737
Preconditions.checkArgument(operation != null, "Null 'operation' argument");
3838
Preconditions.checkArgument(cause != null, "Null 'cause' argument");
3939
this.operation = operation;
4040
}
4141

42-
public AmazonClientException getCause() {
43-
return (AmazonClientException) super.getCause();
42+
public SdkException getCause() {
43+
return (SdkException) super.getCause();
4444
}
4545

4646
@Override
4747
public String getMessage() {
4848
return operation + ": " + getCause().getMessage();
4949
}
50-
5150
}

hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/AWSCredentialProviderList.java

Lines changed: 67 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,14 @@
2727
import java.util.concurrent.atomic.AtomicInteger;
2828
import java.util.stream.Collectors;
2929

30-
import com.amazonaws.AmazonClientException;
3130
import com.amazonaws.auth.AWSCredentials;
3231
import com.amazonaws.auth.AWSCredentialsProvider;
33-
import com.amazonaws.auth.AnonymousAWSCredentials;
32+
import com.amazonaws.auth.BasicAWSCredentials;
33+
import com.amazonaws.auth.BasicSessionCredentials;
3434
import org.apache.hadoop.classification.VisibleForTesting;
35+
import org.apache.hadoop.fs.s3a.adapter.V1V2AwsCredentialProviderAdapter;
3536
import org.apache.hadoop.util.Preconditions;
37+
3638
import org.slf4j.Logger;
3739
import org.slf4j.LoggerFactory;
3840

@@ -43,6 +45,12 @@
4345
import org.apache.hadoop.fs.s3a.auth.NoAwsCredentialsException;
4446
import org.apache.hadoop.io.IOUtils;
4547

48+
import software.amazon.awssdk.auth.credentials.AnonymousCredentialsProvider;
49+
import software.amazon.awssdk.auth.credentials.AwsCredentials;
50+
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
51+
import software.amazon.awssdk.auth.credentials.AwsSessionCredentials;
52+
import software.amazon.awssdk.core.exception.SdkException;
53+
4654
/**
4755
* A list of providers.
4856
*
@@ -51,17 +59,17 @@
5159
* <ol>
5260
* <li>Allows extra providers to be added dynamically.</li>
5361
* <li>If any provider in the chain throws an exception other than
54-
* an {@link AmazonClientException}, that is rethrown, rather than
62+
* an {@link SdkException}, that is rethrown, rather than
5563
* swallowed.</li>
5664
* <li>Has some more diagnostics.</li>
57-
* <li>On failure, the last "relevant" AmazonClientException raised is
65+
* <li>On failure, the last "relevant" {@link SdkException} raised is
5866
* rethrown; exceptions other than 'no credentials' have priority.</li>
59-
* <li>Special handling of {@link AnonymousAWSCredentials}.</li>
67+
* <li>Special handling of {@link AnonymousCredentialsProvider}.</li>
6068
* </ol>
6169
*/
6270
@InterfaceAudience.Private
6371
@InterfaceStability.Evolving
64-
public final class AWSCredentialProviderList implements AWSCredentialsProvider,
72+
public final class AWSCredentialProviderList implements AwsCredentialsProvider,
6573
AutoCloseable {
6674

6775
private static final Logger LOG = LoggerFactory.getLogger(
@@ -73,9 +81,9 @@ public final class AWSCredentialProviderList implements AWSCredentialsProvider,
7381
CREDENTIALS_REQUESTED_WHEN_CLOSED
7482
= "Credentials requested after provider list was closed";
7583

76-
private final List<AWSCredentialsProvider> providers = new ArrayList<>(1);
84+
private final List<AwsCredentialsProvider> providers = new ArrayList<>(1);
7785
private boolean reuseLastProvider = true;
78-
private AWSCredentialsProvider lastProvider;
86+
private AwsCredentialsProvider lastProvider;
7987

8088
private final AtomicInteger refCount = new AtomicInteger(1);
8189

@@ -99,7 +107,9 @@ public AWSCredentialProviderList() {
99107
*/
100108
public AWSCredentialProviderList(
101109
Collection<AWSCredentialsProvider> providers) {
102-
this.providers.addAll(providers);
110+
for (AWSCredentialsProvider provider: providers) {
111+
this.providers.add(V1V2AwsCredentialProviderAdapter.adapt(provider));
112+
}
103113
}
104114

105115
/**
@@ -110,6 +120,19 @@ public AWSCredentialProviderList(
110120
public AWSCredentialProviderList(final String name,
111121
final AWSCredentialsProvider... providerArgs) {
112122
setName(name);
123+
for (AWSCredentialsProvider provider: providerArgs) {
124+
this.providers.add(V1V2AwsCredentialProviderAdapter.adapt(provider));
125+
}
126+
}
127+
128+
/**
129+
* Create with an initial list of SDK V2 credential providers.
130+
* @param name name for error messages, may be ""
131+
* @param providerArgs provider list.
132+
*/
133+
public AWSCredentialProviderList(final String name,
134+
final AwsCredentialsProvider... providerArgs) {
135+
setName(name);
113136
Collections.addAll(providers, providerArgs);
114137
}
115138

@@ -127,12 +150,21 @@ public void setName(final String name) {
127150

128151
/**
129152
* Add a new provider.
130-
* @param p provider
153+
* @param provider provider
131154
*/
132-
public void add(AWSCredentialsProvider p) {
133-
providers.add(p);
155+
public void add(AWSCredentialsProvider provider) {
156+
providers.add(V1V2AwsCredentialProviderAdapter.adapt(provider));
134157
}
135158

159+
/**
160+
* Add a new SDK V2 provider.
161+
* @param provider provider
162+
*/
163+
public void add(AwsCredentialsProvider provider) {
164+
providers.add(provider);
165+
}
166+
167+
136168
/**
137169
* Add all providers from another list to this one.
138170
* @param other the other list.
@@ -142,15 +174,18 @@ public void addAll(AWSCredentialProviderList other) {
142174
}
143175

144176
/**
145-
* Refresh all child entries.
177+
* This method will get credentials using SDK V2's resolveCredentials and then convert it into
178+
* V1 credentials. This required by delegation token binding classes.
179+
* @return SDK V1 credentials
146180
*/
147-
@Override
148-
public void refresh() {
149-
if (isClosed()) {
150-
return;
151-
}
152-
for (AWSCredentialsProvider provider : providers) {
153-
provider.refresh();
181+
public AWSCredentials getCredentials() {
182+
AwsCredentials credentials = resolveCredentials();
183+
if (credentials instanceof AwsSessionCredentials) {
184+
return new BasicSessionCredentials(credentials.accessKeyId(),
185+
credentials.secretAccessKey(),
186+
((AwsSessionCredentials) credentials).sessionToken());
187+
} else {
188+
return new BasicAWSCredentials(credentials.accessKeyId(), credentials.secretAccessKey());
154189
}
155190
}
156191

@@ -160,26 +195,26 @@ public void refresh() {
160195
* @return a set of credentials (possibly anonymous), for authenticating.
161196
*/
162197
@Override
163-
public AWSCredentials getCredentials() {
198+
public AwsCredentials resolveCredentials() {
164199
if (isClosed()) {
165200
LOG.warn(CREDENTIALS_REQUESTED_WHEN_CLOSED);
166201
throw new NoAuthWithAWSException(name +
167202
CREDENTIALS_REQUESTED_WHEN_CLOSED);
168203
}
169204
checkNotEmpty();
170205
if (reuseLastProvider && lastProvider != null) {
171-
return lastProvider.getCredentials();
206+
return lastProvider.resolveCredentials();
172207
}
173208

174-
AmazonClientException lastException = null;
175-
for (AWSCredentialsProvider provider : providers) {
209+
SdkException lastException = null;
210+
for (AwsCredentialsProvider provider : providers) {
176211
try {
177-
AWSCredentials credentials = provider.getCredentials();
212+
AwsCredentials credentials = provider.resolveCredentials();
178213
Preconditions.checkNotNull(credentials,
179214
"Null credentials returned by %s", provider);
180-
if ((credentials.getAWSAccessKeyId() != null &&
181-
credentials.getAWSSecretKey() != null)
182-
|| (credentials instanceof AnonymousAWSCredentials)) {
215+
if ((credentials.accessKeyId() != null && credentials.secretAccessKey() != null) || (
216+
provider instanceof AnonymousCredentialsProvider
217+
|| provider instanceof AnonymousAWSCredentialsProvider)) {
183218
lastProvider = provider;
184219
LOG.debug("Using credentials from {}", provider);
185220
return credentials;
@@ -196,7 +231,7 @@ public AWSCredentials getCredentials() {
196231
}
197232
LOG.debug("No credentials from {}: {}",
198233
provider, e.toString());
199-
} catch (AmazonClientException e) {
234+
} catch (SdkException e) {
200235
lastException = e;
201236
LOG.debug("No credentials provided by {}: {}",
202237
provider, e.toString(), e);
@@ -223,13 +258,13 @@ public AWSCredentials getCredentials() {
223258
* @return providers
224259
*/
225260
@VisibleForTesting
226-
List<AWSCredentialsProvider> getProviders() {
261+
List<AwsCredentialsProvider> getProviders() {
227262
return providers;
228263
}
229264

230265
/**
231266
* Verify that the provider list is not empty.
232-
* @throws AmazonClientException if there are no providers.
267+
* @throws SdkException if there are no providers.
233268
*/
234269
public void checkNotEmpty() {
235270
if (providers.isEmpty()) {
@@ -317,7 +352,7 @@ public void close() {
317352
}
318353

319354
// do this outside the synchronized block.
320-
for (AWSCredentialsProvider p : providers) {
355+
for (AwsCredentialsProvider p : providers) {
321356
if (p instanceof Closeable) {
322357
IOUtils.closeStream((Closeable) p);
323358
} else if (p instanceof AutoCloseable) {

hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/AWSNoResponseException.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@
1818

1919
package org.apache.hadoop.fs.s3a;
2020

21-
import com.amazonaws.AmazonServiceException;
21+
import software.amazon.awssdk.awscore.exception.AwsServiceException;
2222

2323
/**
2424
* Status code 443, no response from server. This is considered idempotent.
2525
*/
2626
public class AWSNoResponseException extends AWSServiceIOException {
2727
public AWSNoResponseException(String operation,
28-
AmazonServiceException cause) {
28+
AwsServiceException cause) {
2929
super(operation, cause);
3030
}
3131
}

hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/AWSRedirectException.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
package org.apache.hadoop.fs.s3a;
2020

21-
import com.amazonaws.AmazonServiceException;
21+
import software.amazon.awssdk.awscore.exception.AwsServiceException;
2222

2323
/**
2424
* Request is redirected.
@@ -32,7 +32,7 @@ public class AWSRedirectException extends AWSServiceIOException {
3232
* @param cause the underlying cause
3333
*/
3434
public AWSRedirectException(String operation,
35-
AmazonServiceException cause) {
35+
AwsServiceException cause) {
3636
super(operation, cause);
3737
}
3838
}

0 commit comments

Comments
 (0)