2727import java .util .concurrent .atomic .AtomicInteger ;
2828import java .util .stream .Collectors ;
2929
30- import com .amazonaws .AmazonClientException ;
3130import com .amazonaws .auth .AWSCredentials ;
3231import com .amazonaws .auth .AWSCredentialsProvider ;
33- import com .amazonaws .auth .AnonymousAWSCredentials ;
32+ import com .amazonaws .auth .BasicAWSCredentials ;
33+ import com .amazonaws .auth .BasicSessionCredentials ;
3434import org .apache .hadoop .classification .VisibleForTesting ;
35+ import org .apache .hadoop .fs .s3a .adapter .V1V2AwsCredentialProviderAdapter ;
3536import org .apache .hadoop .util .Preconditions ;
37+
3638import org .slf4j .Logger ;
3739import org .slf4j .LoggerFactory ;
3840
4345import org .apache .hadoop .fs .s3a .auth .NoAwsCredentialsException ;
4446import 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 *
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 ) {
0 commit comments