From 8ac22a45ccda8ebe5f086a5d7f23cb2c3a7c3c82 Mon Sep 17 00:00:00 2001
From: Jaykumar Gosar
Date: Tue, 7 Mar 2023 13:04:07 -0800
Subject: [PATCH 01/13] Accept and use the new AWS Credentials interfaces
In AwsClientBuilder and other places where customers used to be able to provide
AwsCredentialsProvider.
---
.../codegen/poet/client/SyncClientClass.java | 2 +
.../auth/credentials/CredentialUtils.java | 60 ++++++++++++++++++-
.../signer/AwsSignerExecutionAttribute.java | 1 +
.../AwsRequestOverrideConfiguration.java | 43 ++++++++++++-
.../client/builder/AwsClientBuilder.java | 32 +++++++++-
.../builder/AwsDefaultClientBuilder.java | 34 +++++++++--
.../client/config/AwsClientOption.java | 17 ++++++
.../internal/AwsExecutionContextBuilder.java | 30 ----------
.../AuthorizationStrategyFactory.java | 6 +-
.../AwsCredentialsAuthorizationStrategy.java | 42 ++++++++-----
.../config/AwsClientOptionValidation.java | 4 +-
.../awscore/presigner/SdkPresigner.java | 33 +++++++++-
.../awscore/client/utils/HttpTestUtils.java | 2 +-
.../AwsExecutionContextBuilderTest.java | 2 +-
...sCredentialsAuthorizationStrategyTest.java | 12 ++--
pom.xml | 3 +
.../presigner/DefaultPollyPresigner.java | 28 +++++++--
.../polly/presigner/PollyPresigner.java | 5 ++
.../presigner/DefaultPollyPresignerTest.java | 4 +-
.../services/rds/DefaultRdsUtilities.java | 23 ++++---
.../awssdk/services/rds/RdsUtilities.java | 16 ++++-
.../GenerateAuthenticationTokenRequest.java | 26 +++++++-
.../internal/signing/DefaultSdkPresigner.java | 15 ++++-
.../services/s3/presigner/S3Presigner.java | 5 ++
24 files changed, 360 insertions(+), 85 deletions(-)
diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/SyncClientClass.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/SyncClientClass.java
index a653fd96c9e6..d917c5d801f5 100644
--- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/SyncClientClass.java
+++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/SyncClientClass.java
@@ -243,6 +243,8 @@ private List operationMethodSpecs(OperationModel opModel) {
method.addStatement("$T cachedEndpoint = null", URI.class);
method.beginControlFlow("if (endpointDiscoveryEnabled)");
+ // TODO: If new clientOption for CREDENTIALS_IDENTITY_PROVIDER is used, this needs to be updated.
+ // Also see if use of AwsRequestOverrideConfiguration::credentialsProvider should be changed to new method.
method.addCode("$T key = $N.overrideConfiguration()", String.class, opModel.getInput().getVariableName())
.addCode(" .flatMap($T::credentialsProvider)", AwsRequestOverrideConfiguration.class)
.addCode(" .orElseGet(() -> clientConfiguration.option($T.CREDENTIALS_PROVIDER))", AwsClientOption.class)
diff --git a/core/auth/src/main/java/software/amazon/awssdk/auth/credentials/CredentialUtils.java b/core/auth/src/main/java/software/amazon/awssdk/auth/credentials/CredentialUtils.java
index 6e4879b59c2a..fa9d121d2d2d 100644
--- a/core/auth/src/main/java/software/amazon/awssdk/auth/credentials/CredentialUtils.java
+++ b/core/auth/src/main/java/software/amazon/awssdk/auth/credentials/CredentialUtils.java
@@ -16,6 +16,9 @@
package software.amazon.awssdk.auth.credentials;
import software.amazon.awssdk.annotations.SdkProtectedApi;
+import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.AwsSessionCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.IdentityProvider;
@SdkProtectedApi
public final class CredentialUtils {
@@ -27,7 +30,62 @@ private CredentialUtils() {
* Determine whether the provided credentials are anonymous credentials, indicating that the customer is not attempting to
* authenticate themselves.
*/
- public static boolean isAnonymous(AwsCredentials credentials) {
+ public static boolean isAnonymous(AwsCredentialsIdentity credentials) {
return credentials.secretAccessKey() == null && credentials.accessKeyId() == null;
}
+
+ /**
+ * Converts an {@link AwsCredentialsIdentity} to {@link AwsCredentials}.
+ *
+ * Usage of the new AwsCredentialsIdentity type is preferred over AwsCredentials. But some places may need to still
+ * convert to the older AwsCredentials type to work with existing code.
+ *
+ * The conversion is only aware of {@link AwsCredentialsIdentity} and {@link AwsSessionCredentialsIdentity} types. If the
+ * input is another sub-type that has other properties, they are not carried over. i.e.,
+ *
+ * - AwsSessionCredentialsIdentity -> AwsSessionCredentials
+ * - AwsCredentialsIdentity -> AwsBasicCredentials
+ *
+ *
+ *
+ * @param awsCredentialsIdentity The {@link AwsCredentialsIdentity} to convert
+ * @return The corresponding {@link AwsCredentials}
+ */
+ public static AwsCredentials toCredentials(AwsCredentialsIdentity awsCredentialsIdentity) {
+ // TODO: Is below safe? What if customer defines there own sub-type of AwsCredentialsIdentity?! Valid use case?
+ // If sub-type defines new properties, this conversion would be lossy. But does it matter, if no other code in
+ // `core` module care about types other than these 2?
+ // identity-spi defines 2 known types - AwsCredentialsIdentity and a sub-type AwsSessionCredentialsIdentity
+ if (awsCredentialsIdentity instanceof AwsSessionCredentialsIdentity) {
+ AwsSessionCredentialsIdentity awsSessionCredentialsIdentity = (AwsSessionCredentialsIdentity) awsCredentialsIdentity;
+ return AwsSessionCredentials.create(awsSessionCredentialsIdentity.accessKeyId(),
+ awsSessionCredentialsIdentity.secretAccessKey(),
+ awsSessionCredentialsIdentity.sessionToken());
+ }
+ if (isAnonymous(awsCredentialsIdentity)) {
+ return AwsBasicCredentials.ANONYMOUS_CREDENTIALS;
+ }
+ return AwsBasicCredentials.create(awsCredentialsIdentity.accessKeyId(),
+ awsCredentialsIdentity.secretAccessKey());
+ }
+
+ /**
+ * Converts an {@link IdentityProvider extends AwsCredentialsIdentity>} to {@link AwsCredentialsProvider} based on
+ * {@link #toCredentials(AwsCredentialsIdentity)}.
+ *
+ * Usage of the new IdentityProvider type is preferred over AwsCredentialsProvider. But some places may need to still
+ * convert to the older AwsCredentialsProvider type to work with existing code.
+ *
+ *
+ * @param identityProvider The {@link IdentityProvider extends AwsCredentialsIdentity>} to convert
+ * @return The corresponding {@link AwsCredentialsProvider}
+ */
+ public static AwsCredentialsProvider toCredentialsProvider(
+ IdentityProvider extends AwsCredentialsIdentity> identityProvider) {
+ return () -> {
+ // TODO: Exception handling for CompletionException thrown from join?
+ AwsCredentialsIdentity awsCredentialsIdentity = identityProvider.resolveIdentity().join();
+ return toCredentials(awsCredentialsIdentity);
+ };
+ }
}
diff --git a/core/auth/src/main/java/software/amazon/awssdk/auth/signer/AwsSignerExecutionAttribute.java b/core/auth/src/main/java/software/amazon/awssdk/auth/signer/AwsSignerExecutionAttribute.java
index a90eae258660..a9a7062d2bc1 100644
--- a/core/auth/src/main/java/software/amazon/awssdk/auth/signer/AwsSignerExecutionAttribute.java
+++ b/core/auth/src/main/java/software/amazon/awssdk/auth/signer/AwsSignerExecutionAttribute.java
@@ -36,6 +36,7 @@ public final class AwsSignerExecutionAttribute extends SdkExecutionAttribute {
/**
* The key under which the request credentials are set.
*/
+ // TODO: Can the type be changed to IdentityProvider? This class is @SdkProtectedApi
public static final ExecutionAttribute AWS_CREDENTIALS = new ExecutionAttribute<>("AwsCredentials");
/**
diff --git a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/AwsRequestOverrideConfiguration.java b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/AwsRequestOverrideConfiguration.java
index f101e0b06493..c077b743356d 100644
--- a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/AwsRequestOverrideConfiguration.java
+++ b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/AwsRequestOverrideConfiguration.java
@@ -19,7 +19,10 @@
import java.util.Optional;
import software.amazon.awssdk.annotations.SdkPublicApi;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.auth.credentials.CredentialUtils;
import software.amazon.awssdk.core.RequestOverrideConfiguration;
+import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.IdentityProvider;
import software.amazon.awssdk.utils.builder.SdkBuilder;
/**
@@ -58,10 +61,25 @@ public static AwsRequestOverrideConfiguration from(RequestOverrideConfiguration
*
* @return The optional {@link AwsCredentialsProvider}.
*/
+ // TODO: Note, this method is called from generated public classes, when endpoint discover is involved.
public Optional credentialsProvider() {
return Optional.ofNullable(credentialsProvider);
}
+ // TODO: Cannot change the return type of {@link #credentialsProvider()} so creating another method returning the same
+ // object but of new super type.
+ // TODO: As mentioned below, another option is to save reference of IdentityProvider extends AwsCredentialsProvider> and
+ // convert in above method. Either ways, need 2 methods to return the 2 different types.
+ /**
+ * The optional {@link IdentityProvider extends AwsCredentialsIdentity>} that will provide credentials to be used to
+ * authenticate this request.
+ *
+ * @return The optional {@link IdentityProvider extends AwsCredentialsIdentity>}.
+ */
+ public Optional> credentialsIdentityProvider() {
+ return Optional.ofNullable(credentialsProvider);
+ }
+
@Override
public Builder toBuilder() {
return new BuilderImpl(this);
@@ -103,7 +121,20 @@ public interface Builder extends RequestOverrideConfiguration.Builder,
* @param credentialsProvider The {@link AwsCredentialsProvider}.
* @return This object for chaining.
*/
- Builder credentialsProvider(AwsCredentialsProvider credentialsProvider);
+ default Builder credentialsProvider(AwsCredentialsProvider credentialsProvider) {
+ return credentialsProvider((IdentityProvider) credentialsProvider);
+ }
+
+ /**
+ * Set the optional {@link IdentityProvider extends AwsCredentialsIdentity>} that will provide credentials to be used
+ * to authenticate this request.
+ *
+ * @param credentialsProvider The {@link IdentityProvider extends AwsCredentialsIdentity>}.
+ * @return This object for chaining.
+ */
+ default Builder credentialsProvider(IdentityProvider extends AwsCredentialsIdentity> credentialsProvider) {
+ throw new UnsupportedOperationException();
+ }
/**
* Return the optional {@link AwsCredentialsProvider} that will provide credentials to be used to authenticate this
@@ -136,10 +167,20 @@ private BuilderImpl(AwsRequestOverrideConfiguration awsRequestOverrideConfig) {
@Override
public Builder credentialsProvider(AwsCredentialsProvider credentialsProvider) {
+ // TODO: Another option:
+ // credentialsProvider((IdentityProvider extends AwsCredentialsIdentity>) credentialsProvider);
+ // But that would lead to potentially converting a AwsCredentialsProvider to another AwsCredentialsProvider
+ // to fulfil AwsRequestOverrideConfiguration.credentialsProvider() to return AwsCredentialsProvider type.
this.awsCredentialsProvider = credentialsProvider;
return this;
}
+ @Override
+ public Builder credentialsProvider(IdentityProvider extends AwsCredentialsIdentity> credentialsProvider) {
+ this.awsCredentialsProvider = CredentialUtils.toCredentialsProvider(credentialsProvider);
+ return this;
+ }
+
@Override
public AwsCredentialsProvider credentialsProvider() {
return awsCredentialsProvider;
diff --git a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/builder/AwsClientBuilder.java b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/builder/AwsClientBuilder.java
index 73d757919235..1e6c3f1c8e2d 100644
--- a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/builder/AwsClientBuilder.java
+++ b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/builder/AwsClientBuilder.java
@@ -19,6 +19,8 @@
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.awscore.defaultsmode.DefaultsMode;
import software.amazon.awssdk.core.client.builder.SdkClientBuilder;
+import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.IdentityProvider;
import software.amazon.awssdk.regions.Region;
/**
@@ -49,8 +51,36 @@ public interface AwsClientBuilderIf the credentials are not found in any of the locations above, an exception will be thrown at {@link #build()} time.
*
+ *
+ * The last of {@link #credentialsProvider(AwsCredentialsProvider)} or {@link #credentialsProvider(IdentityProvider)}
+ * wins.
+ */
+ default BuilderT credentialsProvider(AwsCredentialsProvider credentialsProvider) {
+ return credentialsProvider((IdentityProvider) credentialsProvider);
+ }
+
+ /**
+ * Configure the credentials that should be used to authenticate with AWS.
+ *
+ * The default provider will attempt to identify the credentials automatically using the following checks:
+ *
+ * - Java System Properties -
aws.accessKeyId and aws.secretAccessKey
+ * - Environment Variables -
AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
+ * - Credential profiles file at the default location (~/.aws/credentials) shared by all AWS SDKs and the AWS CLI
+ * - Credentials delivered through the Amazon EC2 container service if AWS_CONTAINER_CREDENTIALS_RELATIVE_URI environment
+ * variable is set and security manager has permission to access the variable.
+ * - Instance profile credentials delivered through the Amazon EC2 metadata service
+ *
+ *
+ * If the credentials are not found in any of the locations above, an exception will be thrown at {@link #build()} time.
+ *
+ *
+ * The last of {@link #credentialsProvider(AwsCredentialsProvider)} or {@link #credentialsProvider(IdentityProvider)}
+ * wins.
*/
- BuilderT credentialsProvider(AwsCredentialsProvider credentialsProvider);
+ default BuilderT credentialsProvider(IdentityProvider extends AwsCredentialsIdentity> credentialsProvider) {
+ throw new UnsupportedOperationException();
+ }
/**
* Configure the region with which the SDK should communicate.
diff --git a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/builder/AwsDefaultClientBuilder.java b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/builder/AwsDefaultClientBuilder.java
index c41e604afccb..ec05762109aa 100644
--- a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/builder/AwsDefaultClientBuilder.java
+++ b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/builder/AwsDefaultClientBuilder.java
@@ -48,6 +48,8 @@
import software.amazon.awssdk.core.retry.RetryPolicy;
import software.amazon.awssdk.http.SdkHttpClient;
import software.amazon.awssdk.http.async.SdkAsyncHttpClient;
+import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.IdentityProvider;
import software.amazon.awssdk.profiles.ProfileFile;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.regions.ServiceMetadata;
@@ -191,7 +193,8 @@ protected final SdkClientConfiguration finalizeChildConfiguration(SdkClientConfi
configuration = mergeSmartDefaults(configuration);
return configuration.toBuilder()
- .option(AwsClientOption.CREDENTIALS_PROVIDER, resolveCredentials(configuration))
+ .option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER,
+ resolveCredentialsIdentityProvider(configuration))
.option(SdkClientOption.ENDPOINT, resolveEndpoint(configuration))
.option(SdkClientOption.EXECUTION_INTERCEPTORS, addAwsInterceptors(configuration))
.option(AwsClientOption.SIGNING_REGION, resolveSigningRegion(configuration))
@@ -349,9 +352,10 @@ private Boolean resolveUseFipsFromDefaultProvider(SdkClientConfiguration config)
/**
* Resolve the credentials that should be used based on the customer's configuration.
*/
- private AwsCredentialsProvider resolveCredentials(SdkClientConfiguration config) {
- return config.option(AwsClientOption.CREDENTIALS_PROVIDER) != null
- ? config.option(AwsClientOption.CREDENTIALS_PROVIDER)
+ private IdentityProvider extends AwsCredentialsIdentity> resolveCredentialsIdentityProvider(SdkClientConfiguration config) {
+ // Note, that CREDENTIALS_PROVIDER is never set. It is replaced with CREDENTIALS_IDENTITY_PROVIDER, so just check that
+ return config.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER) != null
+ ? config.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER)
: DefaultCredentialsProvider.builder()
.profileFile(config.option(SdkClientOption.PROFILE_FILE_SUPPLIER))
.profileName(config.option(SdkClientOption.PROFILE_NAME))
@@ -419,16 +423,34 @@ public final void setFipsEnabled(Boolean fipsEndpointEnabled) {
fipsEnabled(fipsEndpointEnabled);
}
+ // TODO: Should the existing method just be removed? Anyone passing the sub type would still
+ // use the method with the new super type?
@Override
public final BuilderT credentialsProvider(AwsCredentialsProvider credentialsProvider) {
- clientConfiguration.option(AwsClientOption.CREDENTIALS_PROVIDER, credentialsProvider);
- return thisBuilder();
+ // clientConfiguration.option(AwsClientOption.CREDENTIALS_PROVIDER, credentialsProvider);
+ // return thisBuilder();
+ // TODO: by delegating to {@link #credentialsProvider(IdentityProvider)} we longer set
+ // AwsClientOption.CREDENTIALS_PROVIDER, thus removing need for validating that only one of the 2 is set.
+ // It may even let us remove the old AwsClientOption (or change the type) - maybe?
+ return credentialsProvider((IdentityProvider extends AwsCredentialsIdentity>) credentialsProvider);
}
+ // TODO: Not sure where the setter is used. Is it ok to delegate to new type (transitively from
+ // {@link #credentialsProvider(AwsCredentialsIdentity))}?
public final void setCredentialsProvider(AwsCredentialsProvider credentialsProvider) {
credentialsProvider(credentialsProvider);
}
+ @Override
+ public final BuilderT credentialsProvider(IdentityProvider extends AwsCredentialsIdentity> identityProvider) {
+ clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER, identityProvider);
+ return thisBuilder();
+ }
+
+ public void setCredentialsProvider(IdentityProvider extends AwsCredentialsIdentity> identityProvider) {
+ credentialsProvider(identityProvider);
+ }
+
private List addAwsInterceptors(SdkClientConfiguration config) {
List interceptors = awsInterceptors();
interceptors = CollectionUtils.mergeLists(interceptors, config.option(SdkClientOption.EXECUTION_INTERCEPTORS));
diff --git a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/config/AwsClientOption.java b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/config/AwsClientOption.java
index a063adbca51f..6556065c6216 100644
--- a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/config/AwsClientOption.java
+++ b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/config/AwsClientOption.java
@@ -21,16 +21,29 @@
import software.amazon.awssdk.awscore.client.builder.AwsClientBuilder;
import software.amazon.awssdk.awscore.defaultsmode.DefaultsMode;
import software.amazon.awssdk.core.client.config.ClientOption;
+import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.IdentityProvider;
import software.amazon.awssdk.regions.Region;
@SdkProtectedApi
public final class AwsClientOption extends ClientOption {
+ // TODO: Should the existing option be removed?
+ // Or replaced with same name (CREDENTIALS_PROVIDER) but new type below?
+ // This class is SdkProtectedApi, and it seems customer cannot create an option with this directly (we do it in
+ // AwsDefaultClientBuilder). Is there risk of old generated code when there are mixed versions of modules?
+ // If it is kept, should it be marked @Deprecated?
/**
* @see AwsClientBuilder#credentialsProvider(AwsCredentialsProvider)
*/
public static final AwsClientOption CREDENTIALS_PROVIDER =
new AwsClientOption<>(AwsCredentialsProvider.class);
+ /**
+ * @see AwsClientBuilder#credentialsProvider(IdentityProvider)
+ */
+ public static final AwsClientOption> CREDENTIALS_IDENTITY_PROVIDER =
+ new AwsClientOption<>(new UnsafeValueType(IdentityProvider.class));
+
/**
* AWS Region the client was configured with. Note that this is not always the signing region in the case of global
* services like IAM.
@@ -85,4 +98,8 @@ public final class AwsClientOption extends ClientOption {
private AwsClientOption(Class valueClass) {
super(valueClass);
}
+
+ private AwsClientOption(UnsafeValueType valueType) {
+ super(valueType);
+ }
}
diff --git a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/AwsExecutionContextBuilder.java b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/AwsExecutionContextBuilder.java
index 32daaba3f3fb..0687cb793789 100644
--- a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/AwsExecutionContextBuilder.java
+++ b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/AwsExecutionContextBuilder.java
@@ -19,15 +19,12 @@
import static software.amazon.awssdk.core.interceptor.SdkExecutionAttribute.RESOLVED_CHECKSUM_SPECS;
import software.amazon.awssdk.annotations.SdkInternalApi;
-import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.auth.signer.AwsSignerExecutionAttribute;
import software.amazon.awssdk.awscore.AwsExecutionAttribute;
-import software.amazon.awssdk.awscore.AwsRequestOverrideConfiguration;
import software.amazon.awssdk.awscore.client.config.AwsClientOption;
import software.amazon.awssdk.awscore.internal.authcontext.AuthorizationStrategy;
import software.amazon.awssdk.awscore.internal.authcontext.AuthorizationStrategyFactory;
import software.amazon.awssdk.core.HttpChecksumConstant;
-import software.amazon.awssdk.core.RequestOverrideConfiguration;
import software.amazon.awssdk.core.SdkRequest;
import software.amazon.awssdk.core.SdkResponse;
import software.amazon.awssdk.core.client.config.SdkAdvancedClientOption;
@@ -138,33 +135,6 @@ private AwsExecutionContextBuilder() {
.build();
}
- /**
- * Resolves the credentials provider, with the request override configuration taking precedence over the
- * provided default.
- *
- * @return The credentials provider that will be used by the SDK to resolve credentials
- */
- public static AwsCredentialsProvider resolveCredentialsProvider(SdkRequest originalRequest,
- AwsCredentialsProvider defaultProvider) {
- return originalRequest.overrideConfiguration()
- .filter(c -> c instanceof AwsRequestOverrideConfiguration)
- .map(c -> (AwsRequestOverrideConfiguration) c)
- .flatMap(AwsRequestOverrideConfiguration::credentialsProvider)
- .orElse(defaultProvider);
- }
-
- /**
- * Request override signers take precedence over the default alternative, for instance what is specified in the
- * client. Request override signers can also be modified by modifyRequest interceptors.
- *
- * @return The signer that will be used by the SDK to sign the request
- */
- public static Signer resolveSigner(SdkRequest request, Signer defaultSigner) {
- return request.overrideConfiguration()
- .flatMap(RequestOverrideConfiguration::signer)
- .orElse(defaultSigner);
- }
-
/**
* Finalize {@link SdkRequest} by running beforeExecution and modifyRequest interceptors.
*
diff --git a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/authcontext/AuthorizationStrategyFactory.java b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/authcontext/AuthorizationStrategyFactory.java
index 938e2ff0a7f8..e56b44d01efe 100644
--- a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/authcontext/AuthorizationStrategyFactory.java
+++ b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/authcontext/AuthorizationStrategyFactory.java
@@ -16,7 +16,6 @@
package software.amazon.awssdk.awscore.internal.authcontext;
import software.amazon.awssdk.annotations.SdkInternalApi;
-import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.auth.token.credentials.SdkTokenProvider;
import software.amazon.awssdk.awscore.client.config.AwsClientOption;
import software.amazon.awssdk.core.CredentialType;
@@ -24,6 +23,8 @@
import software.amazon.awssdk.core.client.config.SdkAdvancedClientOption;
import software.amazon.awssdk.core.client.config.SdkClientConfiguration;
import software.amazon.awssdk.core.signer.Signer;
+import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.IdentityProvider;
import software.amazon.awssdk.metrics.MetricCollector;
/**
@@ -64,7 +65,8 @@ private TokenAuthorizationStrategy tokenAuthorizationStrategy() {
private AwsCredentialsAuthorizationStrategy awsCredentialsAuthorizationStrategy() {
Signer defaultSigner = clientConfiguration.option(SdkAdvancedClientOption.SIGNER);
- AwsCredentialsProvider defaultCredentialsProvider = clientConfiguration.option(AwsClientOption.CREDENTIALS_PROVIDER);
+ IdentityProvider extends AwsCredentialsIdentity> defaultCredentialsProvider =
+ clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER);
return AwsCredentialsAuthorizationStrategy.builder()
.request(request)
.defaultSigner(defaultSigner)
diff --git a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/authcontext/AwsCredentialsAuthorizationStrategy.java b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/authcontext/AwsCredentialsAuthorizationStrategy.java
index 01ad2dd5217b..8c6929e6dcba 100644
--- a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/authcontext/AwsCredentialsAuthorizationStrategy.java
+++ b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/authcontext/AwsCredentialsAuthorizationStrategy.java
@@ -18,7 +18,7 @@
import java.time.Duration;
import software.amazon.awssdk.annotations.SdkInternalApi;
import software.amazon.awssdk.auth.credentials.AwsCredentials;
-import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.auth.credentials.CredentialUtils;
import software.amazon.awssdk.auth.signer.AwsSignerExecutionAttribute;
import software.amazon.awssdk.awscore.AwsRequestOverrideConfiguration;
import software.amazon.awssdk.core.RequestOverrideConfiguration;
@@ -27,6 +27,8 @@
import software.amazon.awssdk.core.internal.util.MetricUtils;
import software.amazon.awssdk.core.metrics.CoreMetric;
import software.amazon.awssdk.core.signer.Signer;
+import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.IdentityProvider;
import software.amazon.awssdk.metrics.MetricCollector;
import software.amazon.awssdk.utils.Pair;
import software.amazon.awssdk.utils.Validate;
@@ -40,7 +42,7 @@ public final class AwsCredentialsAuthorizationStrategy implements AuthorizationS
private final SdkRequest request;
private final Signer defaultSigner;
- private final AwsCredentialsProvider defaultCredentialsProvider;
+ private final IdentityProvider extends AwsCredentialsIdentity> defaultCredentialsProvider;
private final MetricCollector metricCollector;
public AwsCredentialsAuthorizationStrategy(Builder builder) {
@@ -73,8 +75,15 @@ public Signer resolveSigner() {
*/
@Override
public void addCredentialsToExecutionAttributes(ExecutionAttributes executionAttributes) {
- AwsCredentialsProvider credentialsProvider = resolveCredentialsProvider(request, defaultCredentialsProvider);
- AwsCredentials credentials = resolveCredentials(credentialsProvider, metricCollector);
+ IdentityProvider extends AwsCredentialsIdentity> credentialsProvider =
+ resolveCredentialsProvider(request, defaultCredentialsProvider);
+ // TODO: Other option is casting:
+ // AwsCredentials credentials = (AwsCredentials) resolveCredentials(credentialsProvider, metricCollector);
+ // This may be unsafe if there is a sub-type of AwsCredentialsIdentity that is not AwsCredentials.
+ // Like if customer creates an OdinAwsCredentialsIdentity which directly is-a AwsCredentialsIdentity.
+ AwsCredentials credentials = CredentialUtils.toCredentials(resolveCredentials(credentialsProvider, metricCollector));
+
+ // TODO: Should the signer be changed to use AwsCredentialsIdentity? Maybe with Signer SRA work, not now.
executionAttributes.putAttribute(AwsSignerExecutionAttribute.AWS_CREDENTIALS, credentials);
}
@@ -84,22 +93,27 @@ public void addCredentialsToExecutionAttributes(ExecutionAttributes executionAtt
*
* @return The credentials provider that will be used by the SDK to resolve credentials
*/
- private static AwsCredentialsProvider resolveCredentialsProvider(SdkRequest originalRequest,
- AwsCredentialsProvider defaultProvider) {
+ private static IdentityProvider extends AwsCredentialsIdentity> resolveCredentialsProvider(
+ SdkRequest originalRequest,
+ IdentityProvider extends AwsCredentialsIdentity> defaultProvider) {
return originalRequest.overrideConfiguration()
.filter(c -> c instanceof AwsRequestOverrideConfiguration)
.map(c -> (AwsRequestOverrideConfiguration) c)
- .flatMap(AwsRequestOverrideConfiguration::credentialsProvider)
+ .flatMap(AwsRequestOverrideConfiguration::credentialsIdentityProvider)
.orElse(defaultProvider);
}
- private static AwsCredentials resolveCredentials(AwsCredentialsProvider credentialsProvider,
- MetricCollector metricCollector) {
+ private static AwsCredentialsIdentity resolveCredentials(
+ IdentityProvider extends AwsCredentialsIdentity> credentialsProvider,
+ MetricCollector metricCollector) {
Validate.notNull(credentialsProvider, "No credentials provider exists to resolve credentials from.");
- Pair measured = MetricUtils.measureDuration(credentialsProvider::resolveCredentials);
+ // TODO: Exception handling for join()?
+ Pair extends AwsCredentialsIdentity, Duration> measured =
+ MetricUtils.measureDuration(() -> credentialsProvider.resolveIdentity().join());
+
metricCollector.reportMetric(CoreMetric.CREDENTIALS_FETCH_DURATION, measured.right());
- AwsCredentials credentials = measured.left();
+ AwsCredentialsIdentity credentials = measured.left();
Validate.validState(credentials != null, "Credential providers must never return null.");
return credentials;
@@ -108,7 +122,7 @@ private static AwsCredentials resolveCredentials(AwsCredentialsProvider credenti
public static final class Builder {
private SdkRequest request;
private Signer defaultSigner;
- private AwsCredentialsProvider defaultCredentialsProvider;
+ private IdentityProvider extends AwsCredentialsIdentity> defaultCredentialsProvider;
private MetricCollector metricCollector;
private Builder() {
@@ -132,11 +146,11 @@ public Builder defaultSigner(Signer defaultSigner) {
return this;
}
- public AwsCredentialsProvider defaultCredentialsProvider() {
+ public IdentityProvider extends AwsCredentialsIdentity> defaultCredentialsProvider() {
return this.defaultCredentialsProvider;
}
- public Builder defaultCredentialsProvider(AwsCredentialsProvider defaultCredentialsProvider) {
+ public Builder defaultCredentialsProvider(IdentityProvider extends AwsCredentialsIdentity> defaultCredentialsProvider) {
this.defaultCredentialsProvider = defaultCredentialsProvider;
return this;
}
diff --git a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/client/config/AwsClientOptionValidation.java b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/client/config/AwsClientOptionValidation.java
index 5dce8619099a..03138a42a3e6 100644
--- a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/client/config/AwsClientOptionValidation.java
+++ b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/client/config/AwsClientOptionValidation.java
@@ -39,8 +39,8 @@ public static void validateSyncClientOptions(SdkClientConfiguration c) {
}
private static void validateClientOptions(SdkClientConfiguration c) {
- require("credentialsProvider", c.option(AwsClientOption.CREDENTIALS_PROVIDER));
-
+ // TODO: where does the field name come from? Should it be "credentialsIdentityProvider"?
+ require("credentialsProvider", c.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER));
require("overrideConfiguration.advancedOption[AWS_REGION]", c.option(AwsClientOption.AWS_REGION));
require("overrideConfiguration.advancedOption[SIGNING_REGION]", c.option(AwsClientOption.SIGNING_REGION));
require("overrideConfiguration.advancedOption[SERVICE_SIGNING_NAME]",
diff --git a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/presigner/SdkPresigner.java b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/presigner/SdkPresigner.java
index f39bbb258b70..2d4fd8c9c1a4 100644
--- a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/presigner/SdkPresigner.java
+++ b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/presigner/SdkPresigner.java
@@ -18,6 +18,8 @@
import java.net.URI;
import software.amazon.awssdk.annotations.SdkPublicApi;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.IdentityProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.utils.SdkAutoCloseable;
@@ -72,8 +74,37 @@ interface Builder {
* If the credentials are not found in any of the locations above, an exception will be thrown at {@link #build()}
* time.
*
+ *
+ * The last of {@link #credentialsProvider(AwsCredentialsProvider)} or {@link #credentialsProvider(IdentityProvider)}
+ * wins.
+ */
+ default Builder credentialsProvider(AwsCredentialsProvider credentialsProvider) {
+ return credentialsProvider((IdentityProvider extends AwsCredentialsIdentity>) credentialsProvider);
+ }
+
+ /**
+ * Configure the credentials that should be used to authenticate with AWS.
+ *
+ * The default provider will attempt to identify the credentials automatically using the following checks:
+ *
+ * - Java System Properties -
aws.accessKeyId and aws.secretAccessKey
+ * - Environment Variables -
AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
+ * - Credential profiles file at the default location (~/.aws/credentials) shared by all AWS SDKs and the AWS CLI
+ * - Credentials delivered through the Amazon EC2 container service if AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
+ * environment variable is set and security manager has permission to access the variable.
+ * - Instance profile credentials delivered through the Amazon EC2 metadata service
+ *
+ *
+ * If the credentials are not found in any of the locations above, an exception will be thrown at {@link #build()}
+ * time.
+ *
+ *
+ * The last of {@link #credentialsProvider(AwsCredentialsProvider)} or {@link #credentialsProvider(IdentityProvider)}
+ * wins.
*/
- Builder credentialsProvider(AwsCredentialsProvider credentialsProvider);
+ default Builder credentialsProvider(IdentityProvider extends AwsCredentialsIdentity> credentialsProvider) {
+ throw new UnsupportedOperationException();
+ }
/**
* Configure whether the SDK should use the AWS dualstack endpoint.
diff --git a/core/aws-core/src/test/java/software/amazon/awssdk/awscore/client/utils/HttpTestUtils.java b/core/aws-core/src/test/java/software/amazon/awssdk/awscore/client/utils/HttpTestUtils.java
index e92e771f390f..37577e99376e 100644
--- a/core/aws-core/src/test/java/software/amazon/awssdk/awscore/client/utils/HttpTestUtils.java
+++ b/core/aws-core/src/test/java/software/amazon/awssdk/awscore/client/utils/HttpTestUtils.java
@@ -54,7 +54,7 @@ public static SdkClientConfiguration testClientConfiguration() {
.option(SdkClientOption.RETRY_POLICY, RetryPolicy.defaultRetryPolicy())
.option(SdkClientOption.ADDITIONAL_HTTP_HEADERS, new HashMap<>())
.option(SdkClientOption.CRC32_FROM_COMPRESSED_DATA_ENABLED, false)
- .option(AwsClientOption.CREDENTIALS_PROVIDER, DefaultCredentialsProvider.create())
+ .option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER, DefaultCredentialsProvider.create())
.option(SdkAdvancedClientOption.SIGNER, new NoOpSigner())
.option(SdkAdvancedClientOption.USER_AGENT_PREFIX, "")
.option(SdkAdvancedClientOption.USER_AGENT_SUFFIX, "")
diff --git a/core/aws-core/src/test/java/software/amazon/awssdk/awscore/internal/AwsExecutionContextBuilderTest.java b/core/aws-core/src/test/java/software/amazon/awssdk/awscore/internal/AwsExecutionContextBuilderTest.java
index 67ef23a8426c..f6b67e84b2ba 100644
--- a/core/aws-core/src/test/java/software/amazon/awssdk/awscore/internal/AwsExecutionContextBuilderTest.java
+++ b/core/aws-core/src/test/java/software/amazon/awssdk/awscore/internal/AwsExecutionContextBuilderTest.java
@@ -209,7 +209,7 @@ private SdkClientConfiguration.Builder testClientConfiguration() {
return SdkClientConfiguration.builder()
.option(SdkClientOption.EXECUTION_INTERCEPTORS, new ArrayList<>())
.option(SdkClientOption.EXECUTION_INTERCEPTORS, interceptorList)
- .option(AwsClientOption.CREDENTIALS_PROVIDER, DefaultCredentialsProvider.create())
+ .option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER, DefaultCredentialsProvider.create())
.option(SdkAdvancedClientOption.SIGNER, this.defaultSigner);
}
}
diff --git a/core/aws-core/src/test/java/software/amazon/awssdk/awscore/internal/authcontext/AwsCredentialsAuthorizationStrategyTest.java b/core/aws-core/src/test/java/software/amazon/awssdk/awscore/internal/authcontext/AwsCredentialsAuthorizationStrategyTest.java
index 282e048052dc..2561ece34c1f 100644
--- a/core/aws-core/src/test/java/software/amazon/awssdk/awscore/internal/authcontext/AwsCredentialsAuthorizationStrategyTest.java
+++ b/core/aws-core/src/test/java/software/amazon/awssdk/awscore/internal/authcontext/AwsCredentialsAuthorizationStrategyTest.java
@@ -17,7 +17,6 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
-import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import java.util.Optional;
@@ -26,8 +25,10 @@
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
+import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.AwsCredentials;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.auth.signer.AwsSignerExecutionAttribute;
import software.amazon.awssdk.awscore.AwsRequestOverrideConfiguration;
import software.amazon.awssdk.core.SdkRequest;
@@ -41,14 +42,17 @@ public class AwsCredentialsAuthorizationStrategyTest {
@Mock SdkRequest sdkRequest;
@Mock Signer defaultSigner;
@Mock Signer requestOverrideSigner;
- @Mock AwsCredentialsProvider credentialsProvider;
- @Mock AwsCredentials credentials;
+ AwsCredentialsProvider credentialsProvider;
+ AwsCredentials credentials;
@Mock MetricCollector metricCollector;
@Before
public void setUp() throws Exception {
when(sdkRequest.overrideConfiguration()).thenReturn(Optional.empty());
- when(credentialsProvider.resolveCredentials()).thenReturn(credentials);
+ // TODO: The below with using @Mock for credentialsProvider and credentials was giving a compile error, so not using mock
+ // when(credentialsProvider.resolveIdentity()).thenReturn(CompletableFuture.completedFuture(credentials));
+ credentials = AwsBasicCredentials.create("foo", "bar");
+ credentialsProvider = StaticCredentialsProvider.create(credentials);
}
@Test
diff --git a/pom.xml b/pom.xml
index a502bb6daf8b..4815145c74e8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -634,6 +634,9 @@
software.amazon.awssdk.auth.credentials.AwsCredentials
software.amazon.awssdk.auth.token.credentials.SdkToken
+
+
+ software.amazon.awssdk.auth.credentials.CredentialUtils
true
diff --git a/services/polly/src/main/java/software/amazon/awssdk/services/polly/internal/presigner/DefaultPollyPresigner.java b/services/polly/src/main/java/software/amazon/awssdk/services/polly/internal/presigner/DefaultPollyPresigner.java
index d939bdbc389d..702e7efc7bd1 100644
--- a/services/polly/src/main/java/software/amazon/awssdk/services/polly/internal/presigner/DefaultPollyPresigner.java
+++ b/services/polly/src/main/java/software/amazon/awssdk/services/polly/internal/presigner/DefaultPollyPresigner.java
@@ -30,6 +30,7 @@
import software.amazon.awssdk.annotations.SdkInternalApi;
import software.amazon.awssdk.auth.credentials.AwsCredentials;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.auth.credentials.CredentialUtils;
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
import software.amazon.awssdk.auth.signer.Aws4Signer;
import software.amazon.awssdk.auth.signer.AwsSignerExecutionAttribute;
@@ -48,6 +49,8 @@
import software.amazon.awssdk.core.signer.Signer;
import software.amazon.awssdk.http.SdkHttpFullRequest;
import software.amazon.awssdk.http.SdkHttpMethod;
+import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.IdentityProvider;
import software.amazon.awssdk.profiles.ProfileFile;
import software.amazon.awssdk.profiles.ProfileFileSystemSetting;
import software.amazon.awssdk.regions.Region;
@@ -72,7 +75,7 @@ public final class DefaultPollyPresigner implements PollyPresigner {
private final Supplier profileFile;
private final String profileName;
private final Region region;
- private final AwsCredentialsProvider credentialsProvider;
+ private final IdentityProvider extends AwsCredentialsIdentity> credentialsProvider;
private final URI endpointOverride;
private final Boolean dualstackEnabled;
private final Boolean fipsEnabled;
@@ -112,7 +115,10 @@ public Region region() {
return region;
}
- public AwsCredentialsProvider credentialsProvider() {
+ // TODO: Why are these 3 getters public? And why methods instead of accessing the members directly - used only inside this
+ // class. And this class is @SdkInternalApi
+ // Maybe package scope for unit test
+ public IdentityProvider extends AwsCredentialsIdentity> credentialsProvider() {
return credentialsProvider;
}
@@ -198,7 +204,7 @@ private SdkHttpFullRequest presignRequest(PollyRequest requestToPresign,
private ExecutionAttributes createExecutionAttributes(PresignRequest presignRequest, PollyRequest requestToPresign) {
Instant signatureExpiration = Instant.now().plus(presignRequest.signatureDuration());
- AwsCredentials credentials = resolveCredentialsProvider(requestToPresign).resolveCredentials();
+ AwsCredentials credentials = resolveCredentials(resolveCredentialsProvider(requestToPresign));
Validate.validState(credentials != null, "Credential providers must never return null.");
return new ExecutionAttributes()
@@ -212,11 +218,16 @@ private ExecutionAttributes createExecutionAttributes(PresignRequest presignRequ
.putAttribute(PRESIGNER_EXPIRATION, signatureExpiration);
}
- private AwsCredentialsProvider resolveCredentialsProvider(PollyRequest request) {
- return request.overrideConfiguration().flatMap(AwsRequestOverrideConfiguration::credentialsProvider)
+ private IdentityProvider extends AwsCredentialsIdentity> resolveCredentialsProvider(PollyRequest request) {
+ return request.overrideConfiguration().flatMap(AwsRequestOverrideConfiguration::credentialsIdentityProvider)
.orElse(credentialsProvider());
}
+ private AwsCredentials resolveCredentials(IdentityProvider extends AwsCredentialsIdentity> credentialsProvider) {
+ AwsCredentialsIdentity credentials = credentialsProvider.resolveIdentity().join();
+ return CredentialUtils.toCredentials(credentials);
+ }
+
private Presigner resolvePresigner(PollyRequest request) {
Signer signer = request.overrideConfiguration().flatMap(AwsRequestOverrideConfiguration::signer)
.orElse(DEFAULT_SIGNER);
@@ -255,7 +266,7 @@ private URI resolveEndpoint() {
public static class BuilderImpl implements PollyPresigner.Builder {
private Region region;
- private AwsCredentialsProvider credentialsProvider;
+ private IdentityProvider extends AwsCredentialsIdentity> credentialsProvider;
private URI endpointOverride;
private Boolean dualstackEnabled;
private Boolean fipsEnabled;
@@ -268,6 +279,11 @@ public Builder region(Region region) {
@Override
public Builder credentialsProvider(AwsCredentialsProvider credentialsProvider) {
+ return credentialsProvider((IdentityProvider extends AwsCredentialsIdentity>) credentialsProvider);
+ }
+
+ @Override
+ public Builder credentialsProvider(IdentityProvider extends AwsCredentialsIdentity> credentialsProvider) {
this.credentialsProvider = credentialsProvider;
return this;
}
diff --git a/services/polly/src/main/java/software/amazon/awssdk/services/polly/presigner/PollyPresigner.java b/services/polly/src/main/java/software/amazon/awssdk/services/polly/presigner/PollyPresigner.java
index 90602e481e86..61a24fa74ed9 100644
--- a/services/polly/src/main/java/software/amazon/awssdk/services/polly/presigner/PollyPresigner.java
+++ b/services/polly/src/main/java/software/amazon/awssdk/services/polly/presigner/PollyPresigner.java
@@ -22,6 +22,8 @@
import software.amazon.awssdk.awscore.presigner.PresignedRequest;
import software.amazon.awssdk.awscore.presigner.SdkPresigner;
import software.amazon.awssdk.http.SdkHttpClient;
+import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.IdentityProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.polly.internal.presigner.DefaultPollyPresigner;
import software.amazon.awssdk.services.polly.model.PollyRequest;
@@ -163,6 +165,9 @@ interface Builder extends SdkPresigner.Builder {
@Override
Builder credentialsProvider(AwsCredentialsProvider credentialsProvider);
+ @Override
+ Builder credentialsProvider(IdentityProvider extends AwsCredentialsIdentity> credentialsProvider);
+
@Override
Builder dualstackEnabled(Boolean dualstackEnabled);
diff --git a/services/polly/src/test/java/software/amazon/awssdk/services/polly/internal/presigner/DefaultPollyPresignerTest.java b/services/polly/src/test/java/software/amazon/awssdk/services/polly/internal/presigner/DefaultPollyPresignerTest.java
index 4d5cc4973ff3..78c2c78ee374 100644
--- a/services/polly/src/test/java/software/amazon/awssdk/services/polly/internal/presigner/DefaultPollyPresignerTest.java
+++ b/services/polly/src/test/java/software/amazon/awssdk/services/polly/internal/presigner/DefaultPollyPresignerTest.java
@@ -31,6 +31,8 @@
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.awscore.AwsRequestOverrideConfiguration;
+import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.IdentityProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.polly.model.OutputFormat;
import software.amazon.awssdk.services.polly.model.SynthesizeSpeechRequest;
@@ -195,7 +197,7 @@ void presigner_credentialsProviderSetToNullByBuilder_createsDefaultCredentialsPr
.build();
- AwsCredentialsProvider awsCredentialsProvider = presigner.credentialsProvider();
+ IdentityProvider extends AwsCredentialsIdentity> awsCredentialsProvider = presigner.credentialsProvider();
assertThat(awsCredentialsProvider).isNotNull();
}
diff --git a/services/rds/src/main/java/software/amazon/awssdk/services/rds/DefaultRdsUtilities.java b/services/rds/src/main/java/software/amazon/awssdk/services/rds/DefaultRdsUtilities.java
index f77082792631..d5e9a958df18 100644
--- a/services/rds/src/main/java/software/amazon/awssdk/services/rds/DefaultRdsUtilities.java
+++ b/services/rds/src/main/java/software/amazon/awssdk/services/rds/DefaultRdsUtilities.java
@@ -20,13 +20,16 @@
import java.time.Instant;
import software.amazon.awssdk.annotations.Immutable;
import software.amazon.awssdk.annotations.SdkInternalApi;
-import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.auth.credentials.AwsCredentials;
+import software.amazon.awssdk.auth.credentials.CredentialUtils;
import software.amazon.awssdk.auth.signer.Aws4Signer;
import software.amazon.awssdk.auth.signer.params.Aws4PresignerParams;
import software.amazon.awssdk.awscore.client.config.AwsClientOption;
import software.amazon.awssdk.core.client.config.SdkClientConfiguration;
import software.amazon.awssdk.http.SdkHttpFullRequest;
import software.amazon.awssdk.http.SdkHttpMethod;
+import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.IdentityProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.rds.model.GenerateAuthenticationTokenRequest;
import software.amazon.awssdk.utils.StringUtils;
@@ -39,7 +42,7 @@ final class DefaultRdsUtilities implements RdsUtilities {
private final Aws4Signer signer = Aws4Signer.create();
private final Region region;
- private final AwsCredentialsProvider credentialsProvider;
+ private final IdentityProvider extends AwsCredentialsIdentity> credentialsProvider;
private final Clock clock;
DefaultRdsUtilities(DefaultBuilder builder) {
@@ -79,7 +82,7 @@ public String generateAuthenticationToken(GenerateAuthenticationTokenRequest req
Aws4PresignerParams presignRequest = Aws4PresignerParams.builder()
.signingClockOverride(clock)
.expirationTime(expirationTime)
- .awsCredentials(resolveCredentials(request).resolveCredentials())
+ .awsCredentials(resolveCredentials(request))
.signingName("rds-db")
.signingRegion(resolveRegion(request))
.build();
@@ -105,13 +108,13 @@ private Region resolveRegion(GenerateAuthenticationTokenRequest request) {
"or RdsUtilities object");
}
- private AwsCredentialsProvider resolveCredentials(GenerateAuthenticationTokenRequest request) {
+ private AwsCredentials resolveCredentials(GenerateAuthenticationTokenRequest request) {
if (request.credentialsProvider() != null) {
- return request.credentialsProvider();
+ return request.credentialsProvider().resolveCredentials();
}
if (this.credentialsProvider != null) {
- return this.credentialsProvider;
+ return CredentialUtils.toCredentials(this.credentialsProvider.resolveIdentity().join());
}
throw new IllegalArgumentException("CredentialProvider should be provided either in GenerateAuthenticationTokenRequest " +
@@ -121,13 +124,14 @@ private AwsCredentialsProvider resolveCredentials(GenerateAuthenticationTokenReq
@SdkInternalApi
static final class DefaultBuilder implements Builder {
private Region region;
- private AwsCredentialsProvider credentialsProvider;
+ private IdentityProvider extends AwsCredentialsIdentity> credentialsProvider;
DefaultBuilder() {
}
Builder clientConfiguration(SdkClientConfiguration clientConfiguration) {
- this.credentialsProvider = clientConfiguration.option(AwsClientOption.CREDENTIALS_PROVIDER);
+ // TODO: update
+ this.credentialsProvider = clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER);
this.region = clientConfiguration.option(AwsClientOption.AWS_REGION);
return this;
@@ -139,8 +143,9 @@ public Builder region(Region region) {
return this;
}
+ // TODO: {@link #credentialsProvider(AwsCredentialsProvider)} uses the default implementation which call this
@Override
- public Builder credentialsProvider(AwsCredentialsProvider credentialsProvider) {
+ public Builder credentialsProvider(IdentityProvider extends AwsCredentialsIdentity> credentialsProvider) {
this.credentialsProvider = credentialsProvider;
return this;
}
diff --git a/services/rds/src/main/java/software/amazon/awssdk/services/rds/RdsUtilities.java b/services/rds/src/main/java/software/amazon/awssdk/services/rds/RdsUtilities.java
index d7ce5e19c06b..7e7394ec776c 100644
--- a/services/rds/src/main/java/software/amazon/awssdk/services/rds/RdsUtilities.java
+++ b/services/rds/src/main/java/software/amazon/awssdk/services/rds/RdsUtilities.java
@@ -18,6 +18,8 @@
import java.util.function.Consumer;
import software.amazon.awssdk.annotations.SdkPublicApi;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.IdentityProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.rds.model.GenerateAuthenticationTokenRequest;
@@ -96,7 +98,19 @@ interface Builder {
*
* @return This object for method chaining
*/
- Builder credentialsProvider(AwsCredentialsProvider credentialsProvider);
+ default Builder credentialsProvider(AwsCredentialsProvider credentialsProvider) {
+ return credentialsProvider((IdentityProvider extends AwsCredentialsIdentity>) credentialsProvider);
+ }
+
+ /**
+ * The default credentials provider to use when working with the methods in {@link RdsUtilities} class.
+ *
+ * @return This object for method chaining
+ */
+ default Builder credentialsProvider(IdentityProvider extends AwsCredentialsIdentity> credentialsProvider) {
+ throw new UnsupportedOperationException();
+ }
+
/**
* Create a {@link RdsUtilities}
diff --git a/services/rds/src/main/java/software/amazon/awssdk/services/rds/model/GenerateAuthenticationTokenRequest.java b/services/rds/src/main/java/software/amazon/awssdk/services/rds/model/GenerateAuthenticationTokenRequest.java
index fb13d6f95353..7f0492f8692a 100644
--- a/services/rds/src/main/java/software/amazon/awssdk/services/rds/model/GenerateAuthenticationTokenRequest.java
+++ b/services/rds/src/main/java/software/amazon/awssdk/services/rds/model/GenerateAuthenticationTokenRequest.java
@@ -18,6 +18,9 @@
import software.amazon.awssdk.annotations.NotThreadSafe;
import software.amazon.awssdk.annotations.SdkPublicApi;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.auth.credentials.CredentialUtils;
+import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.IdentityProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.rds.RdsUtilities;
import software.amazon.awssdk.utils.Validate;
@@ -77,6 +80,8 @@ public Region region() {
* @return The credentials provider to sign the IAM auth request with. If specified, takes precedence over the value
* specified in {@link RdsUtilities.Builder#credentialsProvider(AwsCredentialsProvider)}}
*/
+ // TODO: should another method returning IdentityProvider extends AwsCredentialsIdentity> be added and used in
+ // DefaultRdsUtilities?
public AwsCredentialsProvider credentialsProvider() {
return credentialsProvider;
}
@@ -131,10 +136,23 @@ public interface Builder extends CopyableBuilder) credentialsProvider);
+ }
+
+ /**
+ * The credentials provider to sign the IAM auth request with. If specified, takes precedence over the value
+ * specified in {@link RdsUtilities.Builder#credentialsProvider(IdentityProvider)}}
+ *
+ * @return This object for method chaining
+ */
+ default Builder credentialsProvider(IdentityProvider extends AwsCredentialsIdentity> credentialsProvider) {
+ throw new UnsupportedOperationException();
+ }
@Override
GenerateAuthenticationTokenRequest build();
@@ -188,6 +206,12 @@ public Builder credentialsProvider(AwsCredentialsProvider credentialsProvider) {
return this;
}
+ @Override
+ public Builder credentialsProvider(IdentityProvider extends AwsCredentialsIdentity> credentialsProvider) {
+ this.credentialsProvider = CredentialUtils.toCredentialsProvider(credentialsProvider);
+ return this;
+ }
+
@Override
public GenerateAuthenticationTokenRequest build() {
return new GenerateAuthenticationTokenRequest(this);
diff --git a/services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/signing/DefaultSdkPresigner.java b/services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/signing/DefaultSdkPresigner.java
index b6df6e29fe7b..7a96ea5f0230 100644
--- a/services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/signing/DefaultSdkPresigner.java
+++ b/services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/signing/DefaultSdkPresigner.java
@@ -23,6 +23,8 @@
import software.amazon.awssdk.awscore.endpoint.DualstackEnabledProvider;
import software.amazon.awssdk.awscore.endpoint.FipsEnabledProvider;
import software.amazon.awssdk.awscore.presigner.SdkPresigner;
+import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.IdentityProvider;
import software.amazon.awssdk.profiles.ProfileFile;
import software.amazon.awssdk.profiles.ProfileFileSystemSetting;
import software.amazon.awssdk.regions.Region;
@@ -42,7 +44,7 @@ public abstract class DefaultSdkPresigner implements SdkPresigner {
private final String profileName;
private final Region region;
private final URI endpointOverride;
- private final AwsCredentialsProvider credentialsProvider;
+ private final IdentityProvider extends AwsCredentialsIdentity> credentialsProvider;
private final Boolean dualstackEnabled;
private final boolean fipsEnabled;
@@ -88,7 +90,9 @@ protected Region region() {
return region;
}
- protected AwsCredentialsProvider credentialsProvider() {
+ // TODO: only called in DefaultS3Presigner.invokeInterceptorsAndCreateExecutionContext to build the
+ // AwsCredentialsAuthorizationStrategy which now accepts IdentityProvider
+ protected IdentityProvider extends AwsCredentialsIdentity> credentialsProvider() {
return credentialsProvider;
}
@@ -116,7 +120,7 @@ public void close() {
public abstract static class Builder>
implements SdkPresigner.Builder {
private Region region;
- private AwsCredentialsProvider credentialsProvider;
+ private IdentityProvider extends AwsCredentialsIdentity> credentialsProvider;
private Boolean dualstackEnabled;
private Boolean fipsEnabled;
private URI endpointOverride;
@@ -132,6 +136,11 @@ public B region(Region region) {
@Override
public B credentialsProvider(AwsCredentialsProvider credentialsProvider) {
+ return credentialsProvider((IdentityProvider extends AwsCredentialsIdentity>) credentialsProvider);
+ }
+
+ @Override
+ public B credentialsProvider(IdentityProvider extends AwsCredentialsIdentity> credentialsProvider) {
this.credentialsProvider = credentialsProvider;
return thisBuilder();
}
diff --git a/services/s3/src/main/java/software/amazon/awssdk/services/s3/presigner/S3Presigner.java b/services/s3/src/main/java/software/amazon/awssdk/services/s3/presigner/S3Presigner.java
index c2aa3e457403..6d9be8376e26 100644
--- a/services/s3/src/main/java/software/amazon/awssdk/services/s3/presigner/S3Presigner.java
+++ b/services/s3/src/main/java/software/amazon/awssdk/services/s3/presigner/S3Presigner.java
@@ -28,6 +28,8 @@
import software.amazon.awssdk.awscore.presigner.SdkPresigner;
import software.amazon.awssdk.core.SdkRequest;
import software.amazon.awssdk.http.SdkHttpClient;
+import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.IdentityProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.regions.providers.DefaultAwsRegionProviderChain;
import software.amazon.awssdk.services.s3.S3Configuration;
@@ -539,6 +541,9 @@ interface Builder extends SdkPresigner.Builder {
@Override
Builder credentialsProvider(AwsCredentialsProvider credentialsProvider);
+ @Override
+ Builder credentialsProvider(IdentityProvider extends AwsCredentialsIdentity> credentialsProvider);
+
@Override
Builder dualstackEnabled(Boolean dualstackEnabled);
From 6c3095b3efa610bf3069284adc5442634361e51f Mon Sep 17 00:00:00 2001
From: Jaykumar Gosar
Date: Fri, 10 Mar 2023 22:35:19 -0800
Subject: [PATCH 02/13] Update client codegen for endpoint discovery
---
.../codegen/poet/client/AsyncClientClass.java | 7 ++++---
.../codegen/poet/client/SyncClientClass.java | 9 ++++-----
.../client/test-endpoint-discovery-async.java | 18 +++++++++---------
.../client/test-endpoint-discovery-sync.java | 18 +++++++++---------
4 files changed, 26 insertions(+), 26 deletions(-)
diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientClass.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientClass.java
index 7fd06cf8aa34..455d6c4b3056 100644
--- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientClass.java
+++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientClass.java
@@ -363,9 +363,10 @@ protected MethodSpec.Builder operationBody(MethodSpec.Builder builder, Operation
builder.beginControlFlow("if (endpointDiscoveryEnabled)");
builder.addCode("$T key = $N.overrideConfiguration()", String.class, opModel.getInput().getVariableName())
- .addCode(" .flatMap($T::credentialsProvider)", AwsRequestOverrideConfiguration.class)
- .addCode(" .orElseGet(() -> clientConfiguration.option($T.CREDENTIALS_PROVIDER))", AwsClientOption.class)
- .addCode(" .resolveCredentials().accessKeyId();");
+ .addCode(" .flatMap($T::credentialsIdentityProvider)", AwsRequestOverrideConfiguration.class)
+ .addCode(" .orElseGet(() -> clientConfiguration.option($T.CREDENTIALS_IDENTITY_PROVIDER))",
+ AwsClientOption.class)
+ .addCode(" .resolveIdentity().join().accessKeyId();");
builder.addCode("$1T endpointDiscoveryRequest = $1T.builder()", EndpointDiscoveryRequest.class)
.addCode(" .required($L)", opModel.getInputShape().getEndpointDiscovery().isRequired())
diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/SyncClientClass.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/SyncClientClass.java
index d917c5d801f5..519538135d73 100644
--- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/SyncClientClass.java
+++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/SyncClientClass.java
@@ -243,12 +243,11 @@ private List operationMethodSpecs(OperationModel opModel) {
method.addStatement("$T cachedEndpoint = null", URI.class);
method.beginControlFlow("if (endpointDiscoveryEnabled)");
- // TODO: If new clientOption for CREDENTIALS_IDENTITY_PROVIDER is used, this needs to be updated.
- // Also see if use of AwsRequestOverrideConfiguration::credentialsProvider should be changed to new method.
method.addCode("$T key = $N.overrideConfiguration()", String.class, opModel.getInput().getVariableName())
- .addCode(" .flatMap($T::credentialsProvider)", AwsRequestOverrideConfiguration.class)
- .addCode(" .orElseGet(() -> clientConfiguration.option($T.CREDENTIALS_PROVIDER))", AwsClientOption.class)
- .addCode(" .resolveCredentials().accessKeyId();");
+ .addCode(" .flatMap($T::credentialsIdentityProvider)", AwsRequestOverrideConfiguration.class)
+ .addCode(" .orElseGet(() -> clientConfiguration.option($T.CREDENTIALS_IDENTITY_PROVIDER))",
+ AwsClientOption.class)
+ .addCode(" .resolveIdentity().join().accessKeyId();");
method.addCode("$1T endpointDiscoveryRequest = $1T.builder()", EndpointDiscoveryRequest.class)
.addCode(" .required($L)", opModel.getInputShape().getEndpointDiscovery().isRequired())
diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-endpoint-discovery-async.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-endpoint-discovery-async.java
index 12ee3816aa6f..529d555c142e 100644
--- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-endpoint-discovery-async.java
+++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-endpoint-discovery-async.java
@@ -174,9 +174,9 @@ public CompletableFuture testDiscovery
URI cachedEndpoint = null;
if (endpointDiscoveryEnabled) {
String key = testDiscoveryIdentifiersRequiredRequest.overrideConfiguration()
- .flatMap(AwsRequestOverrideConfiguration::credentialsProvider)
- .orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_PROVIDER)).resolveCredentials()
- .accessKeyId();
+ .flatMap(AwsRequestOverrideConfiguration::credentialsIdentityProvider)
+ .orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER))
+ .resolveIdentity().join().accessKeyId();
EndpointDiscoveryRequest endpointDiscoveryRequest = EndpointDiscoveryRequest.builder().required(true)
.defaultEndpoint(clientConfiguration.option(SdkClientOption.ENDPOINT))
.overrideConfiguration(testDiscoveryIdentifiersRequiredRequest.overrideConfiguration().orElse(null))
@@ -242,9 +242,9 @@ public CompletableFuture testDiscoveryOptional(
URI cachedEndpoint = null;
if (endpointDiscoveryEnabled) {
String key = testDiscoveryOptionalRequest.overrideConfiguration()
- .flatMap(AwsRequestOverrideConfiguration::credentialsProvider)
- .orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_PROVIDER)).resolveCredentials()
- .accessKeyId();
+ .flatMap(AwsRequestOverrideConfiguration::credentialsIdentityProvider)
+ .orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER))
+ .resolveIdentity().join().accessKeyId();
EndpointDiscoveryRequest endpointDiscoveryRequest = EndpointDiscoveryRequest.builder().required(false)
.defaultEndpoint(clientConfiguration.option(SdkClientOption.ENDPOINT))
.overrideConfiguration(testDiscoveryOptionalRequest.overrideConfiguration().orElse(null)).build();
@@ -317,9 +317,9 @@ public CompletableFuture testDiscoveryRequired(
URI cachedEndpoint = null;
if (endpointDiscoveryEnabled) {
String key = testDiscoveryRequiredRequest.overrideConfiguration()
- .flatMap(AwsRequestOverrideConfiguration::credentialsProvider)
- .orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_PROVIDER)).resolveCredentials()
- .accessKeyId();
+ .flatMap(AwsRequestOverrideConfiguration::credentialsIdentityProvider)
+ .orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER))
+ .resolveIdentity().join().accessKeyId();
EndpointDiscoveryRequest endpointDiscoveryRequest = EndpointDiscoveryRequest.builder().required(true)
.defaultEndpoint(clientConfiguration.option(SdkClientOption.ENDPOINT))
.overrideConfiguration(testDiscoveryRequiredRequest.overrideConfiguration().orElse(null)).build();
diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-endpoint-discovery-sync.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-endpoint-discovery-sync.java
index d2fbf21bd173..6845c352a625 100644
--- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-endpoint-discovery-sync.java
+++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-endpoint-discovery-sync.java
@@ -151,9 +151,9 @@ public TestDiscoveryIdentifiersRequiredResponse testDiscoveryIdentifiersRequired
URI cachedEndpoint = null;
if (endpointDiscoveryEnabled) {
String key = testDiscoveryIdentifiersRequiredRequest.overrideConfiguration()
- .flatMap(AwsRequestOverrideConfiguration::credentialsProvider)
- .orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_PROVIDER)).resolveCredentials()
- .accessKeyId();
+ .flatMap(AwsRequestOverrideConfiguration::credentialsIdentityProvider)
+ .orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER))
+ .resolveIdentity().join().accessKeyId();
EndpointDiscoveryRequest endpointDiscoveryRequest = EndpointDiscoveryRequest.builder().required(true)
.defaultEndpoint(clientConfiguration.option(SdkClientOption.ENDPOINT))
.overrideConfiguration(testDiscoveryIdentifiersRequiredRequest.overrideConfiguration().orElse(null)).build();
@@ -208,9 +208,9 @@ public TestDiscoveryOptionalResponse testDiscoveryOptional(TestDiscoveryOptional
URI cachedEndpoint = null;
if (endpointDiscoveryEnabled) {
String key = testDiscoveryOptionalRequest.overrideConfiguration()
- .flatMap(AwsRequestOverrideConfiguration::credentialsProvider)
- .orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_PROVIDER)).resolveCredentials()
- .accessKeyId();
+ .flatMap(AwsRequestOverrideConfiguration::credentialsIdentityProvider)
+ .orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER))
+ .resolveIdentity().join().accessKeyId();
EndpointDiscoveryRequest endpointDiscoveryRequest = EndpointDiscoveryRequest.builder().required(false)
.defaultEndpoint(clientConfiguration.option(SdkClientOption.ENDPOINT))
.overrideConfiguration(testDiscoveryOptionalRequest.overrideConfiguration().orElse(null)).build();
@@ -272,9 +272,9 @@ public TestDiscoveryRequiredResponse testDiscoveryRequired(TestDiscoveryRequired
URI cachedEndpoint = null;
if (endpointDiscoveryEnabled) {
String key = testDiscoveryRequiredRequest.overrideConfiguration()
- .flatMap(AwsRequestOverrideConfiguration::credentialsProvider)
- .orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_PROVIDER)).resolveCredentials()
- .accessKeyId();
+ .flatMap(AwsRequestOverrideConfiguration::credentialsIdentityProvider)
+ .orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER))
+ .resolveIdentity().join().accessKeyId();
EndpointDiscoveryRequest endpointDiscoveryRequest = EndpointDiscoveryRequest.builder().required(true)
.defaultEndpoint(clientConfiguration.option(SdkClientOption.ENDPOINT))
.overrideConfiguration(testDiscoveryRequiredRequest.overrideConfiguration().orElse(null)).build();
From 2247529dcbc5cf29e0981f34c3f139472c0ee650 Mon Sep 17 00:00:00 2001
From: Jaykumar Gosar
Date: Thu, 23 Mar 2023 23:54:06 -0700
Subject: [PATCH 03/13] Address some of Matt's feedback
---
.../auth/credentials/CredentialUtils.java | 11 +++--
.../signer/AwsSignerExecutionAttribute.java | 1 -
.../AwsRequestOverrideConfiguration.java | 42 ++++++++++---------
.../builder/AwsDefaultClientBuilder.java | 31 +++++++-------
.../client/config/AwsClientOption.java | 10 ++---
.../AuthorizationStrategyFactory.java | 5 ++-
.../AwsCredentialsAuthorizationStrategy.java | 5 ---
.../config/AwsClientOptionValidation.java | 1 -
...sCredentialsAuthorizationStrategyTest.java | 2 -
pom.xml | 3 --
.../presigner/DefaultPollyPresigner.java | 35 +++++-----------
.../services/rds/DefaultRdsUtilities.java | 7 ++--
.../GenerateAuthenticationTokenRequest.java | 29 +++++++------
.../internal/signing/DefaultSdkPresigner.java | 2 -
14 files changed, 82 insertions(+), 102 deletions(-)
diff --git a/core/auth/src/main/java/software/amazon/awssdk/auth/credentials/CredentialUtils.java b/core/auth/src/main/java/software/amazon/awssdk/auth/credentials/CredentialUtils.java
index fa9d121d2d2d..b56e2d0d7def 100644
--- a/core/auth/src/main/java/software/amazon/awssdk/auth/credentials/CredentialUtils.java
+++ b/core/auth/src/main/java/software/amazon/awssdk/auth/credentials/CredentialUtils.java
@@ -26,6 +26,14 @@ public final class CredentialUtils {
private CredentialUtils() {
}
+ /**
+ * Determine whether the provided credentials are anonymous credentials, indicating that the customer is not attempting to
+ * authenticate themselves.
+ */
+ public static boolean isAnonymous(AwsCredentials credentials) {
+ return isAnonymous((AwsCredentialsIdentity) credentials);
+ }
+
/**
* Determine whether the provided credentials are anonymous credentials, indicating that the customer is not attempting to
* authenticate themselves.
@@ -52,9 +60,6 @@ public static boolean isAnonymous(AwsCredentialsIdentity credentials) {
* @return The corresponding {@link AwsCredentials}
*/
public static AwsCredentials toCredentials(AwsCredentialsIdentity awsCredentialsIdentity) {
- // TODO: Is below safe? What if customer defines there own sub-type of AwsCredentialsIdentity?! Valid use case?
- // If sub-type defines new properties, this conversion would be lossy. But does it matter, if no other code in
- // `core` module care about types other than these 2?
// identity-spi defines 2 known types - AwsCredentialsIdentity and a sub-type AwsSessionCredentialsIdentity
if (awsCredentialsIdentity instanceof AwsSessionCredentialsIdentity) {
AwsSessionCredentialsIdentity awsSessionCredentialsIdentity = (AwsSessionCredentialsIdentity) awsCredentialsIdentity;
diff --git a/core/auth/src/main/java/software/amazon/awssdk/auth/signer/AwsSignerExecutionAttribute.java b/core/auth/src/main/java/software/amazon/awssdk/auth/signer/AwsSignerExecutionAttribute.java
index a9a7062d2bc1..a90eae258660 100644
--- a/core/auth/src/main/java/software/amazon/awssdk/auth/signer/AwsSignerExecutionAttribute.java
+++ b/core/auth/src/main/java/software/amazon/awssdk/auth/signer/AwsSignerExecutionAttribute.java
@@ -36,7 +36,6 @@ public final class AwsSignerExecutionAttribute extends SdkExecutionAttribute {
/**
* The key under which the request credentials are set.
*/
- // TODO: Can the type be changed to IdentityProvider? This class is @SdkProtectedApi
public static final ExecutionAttribute AWS_CREDENTIALS = new ExecutionAttribute<>("AwsCredentials");
/**
diff --git a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/AwsRequestOverrideConfiguration.java b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/AwsRequestOverrideConfiguration.java
index c077b743356d..5c8b959d4f5f 100644
--- a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/AwsRequestOverrideConfiguration.java
+++ b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/AwsRequestOverrideConfiguration.java
@@ -30,11 +30,11 @@
*/
@SdkPublicApi
public final class AwsRequestOverrideConfiguration extends RequestOverrideConfiguration {
- private final AwsCredentialsProvider credentialsProvider;
+ private final IdentityProvider extends AwsCredentialsIdentity> credentialsProvider;
private AwsRequestOverrideConfiguration(Builder builder) {
super(builder);
- this.credentialsProvider = builder.credentialsProvider();
+ this.credentialsProvider = builder.credentialsIdentityProvider();
}
/**
@@ -61,15 +61,10 @@ public static AwsRequestOverrideConfiguration from(RequestOverrideConfiguration
*
* @return The optional {@link AwsCredentialsProvider}.
*/
- // TODO: Note, this method is called from generated public classes, when endpoint discover is involved.
public Optional credentialsProvider() {
- return Optional.ofNullable(credentialsProvider);
+ return Optional.ofNullable(CredentialUtils.toCredentialsProvider(credentialsProvider));
}
- // TODO: Cannot change the return type of {@link #credentialsProvider()} so creating another method returning the same
- // object but of new super type.
- // TODO: As mentioned below, another option is to save reference of IdentityProvider extends AwsCredentialsProvider> and
- // convert in above method. Either ways, need 2 methods to return the 2 different types.
/**
* The optional {@link IdentityProvider extends AwsCredentialsIdentity>} that will provide credentials to be used to
* authenticate this request.
@@ -132,6 +127,7 @@ default Builder credentialsProvider(AwsCredentialsProvider credentialsProvider)
* @param credentialsProvider The {@link IdentityProvider extends AwsCredentialsIdentity>}.
* @return This object for chaining.
*/
+ // review TODO: Should this be named credentialsIdentityProvider for symmetry with the "get" method
default Builder credentialsProvider(IdentityProvider extends AwsCredentialsIdentity> credentialsProvider) {
throw new UnsupportedOperationException();
}
@@ -144,14 +140,21 @@ default Builder credentialsProvider(IdentityProvider extends AwsCredentialsIde
*/
AwsCredentialsProvider credentialsProvider();
+ /**
+ * Return the optional {@link IdentityProvider extends AwsCredentialsIdentity>} that will provide credentials to be
+ * used to authenticate this request.
+ *
+ * @return The optional {@link IdentityProvider extends AwsCredentialsIdentity>}.
+ */
+ IdentityProvider extends AwsCredentialsIdentity> credentialsIdentityProvider();
+
@Override
AwsRequestOverrideConfiguration build();
}
private static final class BuilderImpl extends RequestOverrideConfiguration.BuilderImpl implements Builder {
- private AwsCredentialsProvider awsCredentialsProvider;
-
+ private IdentityProvider extends AwsCredentialsIdentity> awsCredentialsProvider;
private BuilderImpl() {
}
@@ -165,24 +168,25 @@ private BuilderImpl(AwsRequestOverrideConfiguration awsRequestOverrideConfig) {
this.awsCredentialsProvider = awsRequestOverrideConfig.credentialsProvider;
}
+ // review TODO: remove this since it is the same as the default interface implementation
+ // @Override
+ // public Builder credentialsProvider(AwsCredentialsProvider credentialsProvider) {
+ // return credentialsProvider((IdentityProvider extends AwsCredentialsIdentity>) credentialsProvider);
+ // }
+
@Override
- public Builder credentialsProvider(AwsCredentialsProvider credentialsProvider) {
- // TODO: Another option:
- // credentialsProvider((IdentityProvider extends AwsCredentialsIdentity>) credentialsProvider);
- // But that would lead to potentially converting a AwsCredentialsProvider to another AwsCredentialsProvider
- // to fulfil AwsRequestOverrideConfiguration.credentialsProvider() to return AwsCredentialsProvider type.
+ public Builder credentialsProvider(IdentityProvider extends AwsCredentialsIdentity> credentialsProvider) {
this.awsCredentialsProvider = credentialsProvider;
return this;
}
@Override
- public Builder credentialsProvider(IdentityProvider extends AwsCredentialsIdentity> credentialsProvider) {
- this.awsCredentialsProvider = CredentialUtils.toCredentialsProvider(credentialsProvider);
- return this;
+ public AwsCredentialsProvider credentialsProvider() {
+ return CredentialUtils.toCredentialsProvider(awsCredentialsProvider);
}
@Override
- public AwsCredentialsProvider credentialsProvider() {
+ public IdentityProvider extends AwsCredentialsIdentity> credentialsIdentityProvider() {
return awsCredentialsProvider;
}
diff --git a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/builder/AwsDefaultClientBuilder.java b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/builder/AwsDefaultClientBuilder.java
index ec05762109aa..92342b97e47b 100644
--- a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/builder/AwsDefaultClientBuilder.java
+++ b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/builder/AwsDefaultClientBuilder.java
@@ -25,6 +25,7 @@
import software.amazon.awssdk.annotations.SdkProtectedApi;
import software.amazon.awssdk.annotations.SdkTestInternalApi;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.auth.credentials.CredentialUtils;
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
import software.amazon.awssdk.awscore.client.config.AwsAdvancedClientOption;
import software.amazon.awssdk.awscore.client.config.AwsClientOption;
@@ -192,9 +193,11 @@ protected final SdkClientConfiguration finalizeChildConfiguration(SdkClientConfi
configuration = mergeSmartDefaults(configuration);
+ IdentityProvider extends AwsCredentialsIdentity> identityProvider = resolveCredentialsIdentityProvider(configuration);
return configuration.toBuilder()
- .option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER,
- resolveCredentialsIdentityProvider(configuration))
+ .option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER, identityProvider)
+ // CREDENTIALS_PROVIDER is also set, since older clients may be relying on it
+ .option(AwsClientOption.CREDENTIALS_PROVIDER, toCredentialsProvider(identityProvider))
.option(SdkClientOption.ENDPOINT, resolveEndpoint(configuration))
.option(SdkClientOption.EXECUTION_INTERCEPTORS, addAwsInterceptors(configuration))
.option(AwsClientOption.SIGNING_REGION, resolveSigningRegion(configuration))
@@ -353,7 +356,6 @@ private Boolean resolveUseFipsFromDefaultProvider(SdkClientConfiguration config)
* Resolve the credentials that should be used based on the customer's configuration.
*/
private IdentityProvider extends AwsCredentialsIdentity> resolveCredentialsIdentityProvider(SdkClientConfiguration config) {
- // Note, that CREDENTIALS_PROVIDER is never set. It is replaced with CREDENTIALS_IDENTITY_PROVIDER, so just check that
return config.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER) != null
? config.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER)
: DefaultCredentialsProvider.builder()
@@ -362,6 +364,15 @@ private IdentityProvider extends AwsCredentialsIdentity> resolveCredentialsIde
.build();
}
+ // If resolveCredentialsIdentityProvider returns a DefaultCredentialsProvider (which is the more common usage), this avoids
+ // wrapping it in another AwsCredentialsProvider.
+ private AwsCredentialsProvider toCredentialsProvider(IdentityProvider extends AwsCredentialsIdentity> identityProvider) {
+ return identityProvider instanceof AwsCredentialsProvider ? (AwsCredentialsProvider) identityProvider :
+ CredentialUtils.toCredentialsProvider(identityProvider);
+ }
+
+
+
private RetryPolicy resolveAwsRetryPolicy(SdkClientConfiguration config) {
RetryPolicy policy = config.option(SdkClientOption.RETRY_POLICY);
@@ -423,20 +434,6 @@ public final void setFipsEnabled(Boolean fipsEndpointEnabled) {
fipsEnabled(fipsEndpointEnabled);
}
- // TODO: Should the existing method just be removed? Anyone passing the sub type would still
- // use the method with the new super type?
- @Override
- public final BuilderT credentialsProvider(AwsCredentialsProvider credentialsProvider) {
- // clientConfiguration.option(AwsClientOption.CREDENTIALS_PROVIDER, credentialsProvider);
- // return thisBuilder();
- // TODO: by delegating to {@link #credentialsProvider(IdentityProvider)} we longer set
- // AwsClientOption.CREDENTIALS_PROVIDER, thus removing need for validating that only one of the 2 is set.
- // It may even let us remove the old AwsClientOption (or change the type) - maybe?
- return credentialsProvider((IdentityProvider extends AwsCredentialsIdentity>) credentialsProvider);
- }
-
- // TODO: Not sure where the setter is used. Is it ok to delegate to new type (transitively from
- // {@link #credentialsProvider(AwsCredentialsIdentity))}?
public final void setCredentialsProvider(AwsCredentialsProvider credentialsProvider) {
credentialsProvider(credentialsProvider);
}
diff --git a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/config/AwsClientOption.java b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/config/AwsClientOption.java
index 6556065c6216..aefab749f178 100644
--- a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/config/AwsClientOption.java
+++ b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/config/AwsClientOption.java
@@ -27,14 +27,14 @@
@SdkProtectedApi
public final class AwsClientOption extends ClientOption {
- // TODO: Should the existing option be removed?
- // Or replaced with same name (CREDENTIALS_PROVIDER) but new type below?
- // This class is SdkProtectedApi, and it seems customer cannot create an option with this directly (we do it in
- // AwsDefaultClientBuilder). Is there risk of old generated code when there are mixed versions of modules?
- // If it is kept, should it be marked @Deprecated?
/**
+ // * This option is deprecated in favor of {@link #CREDENTIALS_IDENTITY_PROVIDER}.
* @see AwsClientBuilder#credentialsProvider(AwsCredentialsProvider)
*/
+ @Deprecated
+ // smithy codegen TODO: This could be removed when doing a minor version bump where we told customers we'll be breaking
+ // protected APIs. Postpone this to when we do Smithy code generator migration, where we'll likely have to start
+ // breaking a lot of protected things.
public static final AwsClientOption CREDENTIALS_PROVIDER =
new AwsClientOption<>(AwsCredentialsProvider.class);
diff --git a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/authcontext/AuthorizationStrategyFactory.java b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/authcontext/AuthorizationStrategyFactory.java
index e56b44d01efe..0cffb7e9b355 100644
--- a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/authcontext/AuthorizationStrategyFactory.java
+++ b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/authcontext/AuthorizationStrategyFactory.java
@@ -65,8 +65,11 @@ private TokenAuthorizationStrategy tokenAuthorizationStrategy() {
private AwsCredentialsAuthorizationStrategy awsCredentialsAuthorizationStrategy() {
Signer defaultSigner = clientConfiguration.option(SdkAdvancedClientOption.SIGNER);
+ // Older generated clients may still be using CREDENTIALS_PROVIDER, so fall back to that.
IdentityProvider extends AwsCredentialsIdentity> defaultCredentialsProvider =
- clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER);
+ clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER) != null
+ ? clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER)
+ : clientConfiguration.option(AwsClientOption.CREDENTIALS_PROVIDER);
return AwsCredentialsAuthorizationStrategy.builder()
.request(request)
.defaultSigner(defaultSigner)
diff --git a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/authcontext/AwsCredentialsAuthorizationStrategy.java b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/authcontext/AwsCredentialsAuthorizationStrategy.java
index 8c6929e6dcba..2ca040911efe 100644
--- a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/authcontext/AwsCredentialsAuthorizationStrategy.java
+++ b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/authcontext/AwsCredentialsAuthorizationStrategy.java
@@ -77,12 +77,7 @@ public Signer resolveSigner() {
public void addCredentialsToExecutionAttributes(ExecutionAttributes executionAttributes) {
IdentityProvider extends AwsCredentialsIdentity> credentialsProvider =
resolveCredentialsProvider(request, defaultCredentialsProvider);
- // TODO: Other option is casting:
- // AwsCredentials credentials = (AwsCredentials) resolveCredentials(credentialsProvider, metricCollector);
- // This may be unsafe if there is a sub-type of AwsCredentialsIdentity that is not AwsCredentials.
- // Like if customer creates an OdinAwsCredentialsIdentity which directly is-a AwsCredentialsIdentity.
AwsCredentials credentials = CredentialUtils.toCredentials(resolveCredentials(credentialsProvider, metricCollector));
-
// TODO: Should the signer be changed to use AwsCredentialsIdentity? Maybe with Signer SRA work, not now.
executionAttributes.putAttribute(AwsSignerExecutionAttribute.AWS_CREDENTIALS, credentials);
}
diff --git a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/client/config/AwsClientOptionValidation.java b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/client/config/AwsClientOptionValidation.java
index 03138a42a3e6..d72f41356aa6 100644
--- a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/client/config/AwsClientOptionValidation.java
+++ b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/client/config/AwsClientOptionValidation.java
@@ -39,7 +39,6 @@ public static void validateSyncClientOptions(SdkClientConfiguration c) {
}
private static void validateClientOptions(SdkClientConfiguration c) {
- // TODO: where does the field name come from? Should it be "credentialsIdentityProvider"?
require("credentialsProvider", c.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER));
require("overrideConfiguration.advancedOption[AWS_REGION]", c.option(AwsClientOption.AWS_REGION));
require("overrideConfiguration.advancedOption[SIGNING_REGION]", c.option(AwsClientOption.SIGNING_REGION));
diff --git a/core/aws-core/src/test/java/software/amazon/awssdk/awscore/internal/authcontext/AwsCredentialsAuthorizationStrategyTest.java b/core/aws-core/src/test/java/software/amazon/awssdk/awscore/internal/authcontext/AwsCredentialsAuthorizationStrategyTest.java
index 2561ece34c1f..884e80d5ae28 100644
--- a/core/aws-core/src/test/java/software/amazon/awssdk/awscore/internal/authcontext/AwsCredentialsAuthorizationStrategyTest.java
+++ b/core/aws-core/src/test/java/software/amazon/awssdk/awscore/internal/authcontext/AwsCredentialsAuthorizationStrategyTest.java
@@ -49,8 +49,6 @@ public class AwsCredentialsAuthorizationStrategyTest {
@Before
public void setUp() throws Exception {
when(sdkRequest.overrideConfiguration()).thenReturn(Optional.empty());
- // TODO: The below with using @Mock for credentialsProvider and credentials was giving a compile error, so not using mock
- // when(credentialsProvider.resolveIdentity()).thenReturn(CompletableFuture.completedFuture(credentials));
credentials = AwsBasicCredentials.create("foo", "bar");
credentialsProvider = StaticCredentialsProvider.create(credentials);
}
diff --git a/pom.xml b/pom.xml
index 4815145c74e8..a502bb6daf8b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -634,9 +634,6 @@
software.amazon.awssdk.auth.credentials.AwsCredentials
software.amazon.awssdk.auth.token.credentials.SdkToken
-
-
- software.amazon.awssdk.auth.credentials.CredentialUtils
true
diff --git a/services/polly/src/main/java/software/amazon/awssdk/services/polly/internal/presigner/DefaultPollyPresigner.java b/services/polly/src/main/java/software/amazon/awssdk/services/polly/internal/presigner/DefaultPollyPresigner.java
index 702e7efc7bd1..201818e8a358 100644
--- a/services/polly/src/main/java/software/amazon/awssdk/services/polly/internal/presigner/DefaultPollyPresigner.java
+++ b/services/polly/src/main/java/software/amazon/awssdk/services/polly/internal/presigner/DefaultPollyPresigner.java
@@ -28,7 +28,6 @@
import java.util.function.Supplier;
import java.util.stream.Stream;
import software.amazon.awssdk.annotations.SdkInternalApi;
-import software.amazon.awssdk.auth.credentials.AwsCredentials;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.auth.credentials.CredentialUtils;
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
@@ -111,21 +110,10 @@ private DefaultPollyPresigner(BuilderImpl builder) {
.orElse(false);
}
- public Region region() {
- return region;
- }
-
- // TODO: Why are these 3 getters public? And why methods instead of accessing the members directly - used only inside this
- // class. And this class is @SdkInternalApi
- // Maybe package scope for unit test
- public IdentityProvider extends AwsCredentialsIdentity> credentialsProvider() {
+ IdentityProvider extends AwsCredentialsIdentity> credentialsProvider() {
return credentialsProvider;
}
- public URI endpointOverride() {
- return endpointOverride;
- }
-
@Override
public void close() {
IoUtils.closeIfCloseable(credentialsProvider, null);
@@ -204,14 +192,14 @@ private SdkHttpFullRequest presignRequest(PollyRequest requestToPresign,
private ExecutionAttributes createExecutionAttributes(PresignRequest presignRequest, PollyRequest requestToPresign) {
Instant signatureExpiration = Instant.now().plus(presignRequest.signatureDuration());
- AwsCredentials credentials = resolveCredentials(resolveCredentialsProvider(requestToPresign));
+ AwsCredentialsIdentity credentials = resolveCredentials(resolveCredentialsProvider(requestToPresign));
Validate.validState(credentials != null, "Credential providers must never return null.");
return new ExecutionAttributes()
- .putAttribute(AwsSignerExecutionAttribute.AWS_CREDENTIALS, credentials)
+ .putAttribute(AwsSignerExecutionAttribute.AWS_CREDENTIALS, CredentialUtils.toCredentials(credentials))
.putAttribute(AwsSignerExecutionAttribute.SERVICE_SIGNING_NAME, SIGNING_NAME)
- .putAttribute(AwsExecutionAttribute.AWS_REGION, region())
- .putAttribute(AwsSignerExecutionAttribute.SIGNING_REGION, region())
+ .putAttribute(AwsExecutionAttribute.AWS_REGION, region)
+ .putAttribute(AwsSignerExecutionAttribute.SIGNING_REGION, region)
.putAttribute(SdkInternalExecutionAttribute.IS_FULL_DUPLEX, false)
.putAttribute(SdkExecutionAttribute.CLIENT_TYPE, ClientType.SYNC)
.putAttribute(SdkExecutionAttribute.SERVICE_NAME, SERVICE_NAME)
@@ -220,12 +208,11 @@ private ExecutionAttributes createExecutionAttributes(PresignRequest presignRequ
private IdentityProvider extends AwsCredentialsIdentity> resolveCredentialsProvider(PollyRequest request) {
return request.overrideConfiguration().flatMap(AwsRequestOverrideConfiguration::credentialsIdentityProvider)
- .orElse(credentialsProvider());
+ .orElse(credentialsProvider);
}
- private AwsCredentials resolveCredentials(IdentityProvider extends AwsCredentialsIdentity> credentialsProvider) {
- AwsCredentialsIdentity credentials = credentialsProvider.resolveIdentity().join();
- return CredentialUtils.toCredentials(credentials);
+ private AwsCredentialsIdentity resolveCredentials(IdentityProvider extends AwsCredentialsIdentity> credentialsProvider) {
+ return credentialsProvider.resolveIdentity().join();
}
private Presigner resolvePresigner(PollyRequest request) {
@@ -251,12 +238,12 @@ private void applyEndpoint(SdkHttpFullRequest.Builder httpRequestBuilder) {
}
private URI resolveEndpoint() {
- if (endpointOverride() != null) {
- return endpointOverride();
+ if (endpointOverride != null) {
+ return endpointOverride;
}
return new DefaultServiceEndpointBuilder(SERVICE_NAME, "https")
- .withRegion(region())
+ .withRegion(region)
.withProfileFile(profileFile)
.withProfileName(profileName)
.withDualstackEnabled(dualstackEnabled)
diff --git a/services/rds/src/main/java/software/amazon/awssdk/services/rds/DefaultRdsUtilities.java b/services/rds/src/main/java/software/amazon/awssdk/services/rds/DefaultRdsUtilities.java
index d5e9a958df18..fd40e016bc9d 100644
--- a/services/rds/src/main/java/software/amazon/awssdk/services/rds/DefaultRdsUtilities.java
+++ b/services/rds/src/main/java/software/amazon/awssdk/services/rds/DefaultRdsUtilities.java
@@ -108,9 +108,10 @@ private Region resolveRegion(GenerateAuthenticationTokenRequest request) {
"or RdsUtilities object");
}
+ // TODO: update this to use AwsCredentialsIdentity when we migrate Signers to accept the new type.
private AwsCredentials resolveCredentials(GenerateAuthenticationTokenRequest request) {
- if (request.credentialsProvider() != null) {
- return request.credentialsProvider().resolveCredentials();
+ if (request.credentialsIdentityProvider() != null) {
+ return CredentialUtils.toCredentials(request.credentialsIdentityProvider().resolveIdentity().join());
}
if (this.credentialsProvider != null) {
@@ -130,7 +131,6 @@ static final class DefaultBuilder implements Builder {
}
Builder clientConfiguration(SdkClientConfiguration clientConfiguration) {
- // TODO: update
this.credentialsProvider = clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER);
this.region = clientConfiguration.option(AwsClientOption.AWS_REGION);
@@ -143,7 +143,6 @@ public Builder region(Region region) {
return this;
}
- // TODO: {@link #credentialsProvider(AwsCredentialsProvider)} uses the default implementation which call this
@Override
public Builder credentialsProvider(IdentityProvider extends AwsCredentialsIdentity> credentialsProvider) {
this.credentialsProvider = credentialsProvider;
diff --git a/services/rds/src/main/java/software/amazon/awssdk/services/rds/model/GenerateAuthenticationTokenRequest.java b/services/rds/src/main/java/software/amazon/awssdk/services/rds/model/GenerateAuthenticationTokenRequest.java
index 7f0492f8692a..9c7f79888b0e 100644
--- a/services/rds/src/main/java/software/amazon/awssdk/services/rds/model/GenerateAuthenticationTokenRequest.java
+++ b/services/rds/src/main/java/software/amazon/awssdk/services/rds/model/GenerateAuthenticationTokenRequest.java
@@ -37,7 +37,7 @@ public final class GenerateAuthenticationTokenRequest implements
private final int port;
private final String username;
private final Region region;
- private final AwsCredentialsProvider credentialsProvider;
+ private final IdentityProvider extends AwsCredentialsIdentity> credentialsProvider;
private GenerateAuthenticationTokenRequest(BuilderImpl builder) {
this.hostname = Validate.notEmpty(builder.hostname, "hostname");
@@ -78,11 +78,17 @@ public Region region() {
/**
* @return The credentials provider to sign the IAM auth request with. If specified, takes precedence over the value
- * specified in {@link RdsUtilities.Builder#credentialsProvider(AwsCredentialsProvider)}}
+ * specified in {@link RdsUtilities.Builder#credentialsProvider}}
*/
- // TODO: should another method returning IdentityProvider extends AwsCredentialsIdentity> be added and used in
- // DefaultRdsUtilities?
public AwsCredentialsProvider credentialsProvider() {
+ return CredentialUtils.toCredentialsProvider(credentialsProvider);
+ }
+
+ /**
+ * @return The credentials provider to sign the IAM auth request with. If specified, takes precedence over the value
+ * specified in {@link RdsUtilities.Builder#credentialsProvider(AwsCredentialsProvider)}}
+ */
+ public IdentityProvider extends AwsCredentialsIdentity> credentialsIdentityProvider() {
return credentialsProvider;
}
@@ -135,8 +141,7 @@ public interface Builder extends CopyableBuilder credentialsProvider;
private BuilderImpl() {
}
@@ -200,15 +205,9 @@ public Builder region(Region region) {
return this;
}
- @Override
- public Builder credentialsProvider(AwsCredentialsProvider credentialsProvider) {
- this.credentialsProvider = credentialsProvider;
- return this;
- }
-
@Override
public Builder credentialsProvider(IdentityProvider extends AwsCredentialsIdentity> credentialsProvider) {
- this.credentialsProvider = CredentialUtils.toCredentialsProvider(credentialsProvider);
+ this.credentialsProvider = credentialsProvider;
return this;
}
diff --git a/services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/signing/DefaultSdkPresigner.java b/services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/signing/DefaultSdkPresigner.java
index 7a96ea5f0230..921e7101a410 100644
--- a/services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/signing/DefaultSdkPresigner.java
+++ b/services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/signing/DefaultSdkPresigner.java
@@ -90,8 +90,6 @@ protected Region region() {
return region;
}
- // TODO: only called in DefaultS3Presigner.invokeInterceptorsAndCreateExecutionContext to build the
- // AwsCredentialsAuthorizationStrategy which now accepts IdentityProvider
protected IdentityProvider extends AwsCredentialsIdentity> credentialsProvider() {
return credentialsProvider;
}
From 30635e281b2dd22372d810943d48877434759b4e Mon Sep 17 00:00:00 2001
From: Jaykumar Gosar
Date: Mon, 27 Mar 2023 15:29:16 -0700
Subject: [PATCH 04/13] Switch one usage of
overrideConfiguration.credentialsProvider
To use the new credentialsIdentityProvider() instead.
---
.../services/s3/internal/crt/DefaultS3CrtAsyncClient.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/crt/DefaultS3CrtAsyncClient.java b/services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/crt/DefaultS3CrtAsyncClient.java
index df8597a2e4ea..4f18a1fb4b05 100644
--- a/services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/crt/DefaultS3CrtAsyncClient.java
+++ b/services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/crt/DefaultS3CrtAsyncClient.java
@@ -253,7 +253,7 @@ private static void validateOverrideConfiguration(SdkRequest request) {
}
// TODO: support request-level credential override
- if (overrideConfiguration.credentialsProvider().isPresent()) {
+ if (overrideConfiguration.credentialsIdentityProvider().isPresent()) {
throw new UnsupportedOperationException("Request-level credentials override is not supported");
}
From 093be1f96e46bfdba6f8e24cdda30617fe757f64 Mon Sep 17 00:00:00 2001
From: Jaykumar Gosar
Date: Mon, 27 Mar 2023 16:38:25 -0700
Subject: [PATCH 05/13] Update tests to mock new IdentityProvider
---
.../awssdk/services/metrics/CoreMetricsTest.java | 10 ++++++----
.../SyncClientMetricPublisherResolutionTest.java | 11 +++++++----
.../AsyncClientMetricPublisherResolutionTest.java | 11 +++++++----
.../metrics/async/AsyncCoreMetricsTest.java | 15 +++++----------
.../async/AsyncEventStreamingCoreMetricsTest.java | 9 +++++----
.../async/AsyncStreamingCoreMetricsTest.java | 9 +++++----
6 files changed, 35 insertions(+), 30 deletions(-)
diff --git a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/CoreMetricsTest.java b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/CoreMetricsTest.java
index 0594f635d7ad..6e60d0307b7c 100644
--- a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/CoreMetricsTest.java
+++ b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/CoreMetricsTest.java
@@ -26,6 +26,7 @@
import java.io.IOException;
import java.time.Duration;
import java.util.List;
+import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import org.junit.After;
import org.junit.Before;
@@ -37,7 +38,6 @@
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
-import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.core.metrics.CoreMetric;
import software.amazon.awssdk.http.AbortableInputStream;
import software.amazon.awssdk.http.ExecutableHttpRequest;
@@ -46,6 +46,8 @@
import software.amazon.awssdk.http.HttpMetric;
import software.amazon.awssdk.http.SdkHttpClient;
import software.amazon.awssdk.http.SdkHttpFullResponse;
+import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.IdentityProvider;
import software.amazon.awssdk.metrics.MetricCollection;
import software.amazon.awssdk.metrics.MetricPublisher;
import software.amazon.awssdk.regions.Region;
@@ -70,7 +72,7 @@ public class CoreMetricsTest {
private SdkHttpClient mockHttpClient;
@Mock
- private AwsCredentialsProvider mockCredentialsProvider;
+ private IdentityProvider mockCredentialsProvider;
@Mock
private MetricPublisher mockPublisher;
@@ -106,13 +108,13 @@ public void setup() throws IOException {
when(mockHttpClient.prepareRequest(any(HttpExecuteRequest.class)))
.thenReturn(mockExecuteRequest);
- when(mockCredentialsProvider.resolveCredentials()).thenAnswer(invocation -> {
+ when(mockCredentialsProvider.resolveIdentity()).thenAnswer(invocation -> {
try {
Thread.sleep(100);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
- return AwsBasicCredentials.create("foo", "bar");
+ return CompletableFuture.completedFuture(AwsBasicCredentials.create("foo", "bar"));
});
}
diff --git a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/SyncClientMetricPublisherResolutionTest.java b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/SyncClientMetricPublisherResolutionTest.java
index e07c73703883..f2e2a0741728 100644
--- a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/SyncClientMetricPublisherResolutionTest.java
+++ b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/SyncClientMetricPublisherResolutionTest.java
@@ -20,22 +20,25 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
+
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Arrays;
+import java.util.concurrent.CompletableFuture;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
-import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.http.AbortableInputStream;
import software.amazon.awssdk.http.ExecutableHttpRequest;
import software.amazon.awssdk.http.HttpExecuteRequest;
import software.amazon.awssdk.http.HttpExecuteResponse;
import software.amazon.awssdk.http.SdkHttpClient;
import software.amazon.awssdk.http.SdkHttpFullResponse;
+import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.IdentityProvider;
import software.amazon.awssdk.metrics.MetricCollection;
import software.amazon.awssdk.metrics.MetricPublisher;
import software.amazon.awssdk.regions.Region;
@@ -49,7 +52,7 @@ public class SyncClientMetricPublisherResolutionTest {
private SdkHttpClient mockHttpClient;
@Mock
- private AwsCredentialsProvider mockCredentialsProvider;
+ private IdentityProvider mockCredentialsProvider;
private ProtocolRestJsonClient client;
@@ -153,13 +156,13 @@ private ProtocolRestJsonClient clientWithPublishers(MetricPublisher... metricPub
when(mockHttpClient.prepareRequest(any(HttpExecuteRequest.class)))
.thenReturn(mockExecuteRequest);
- when(mockCredentialsProvider.resolveCredentials()).thenAnswer(invocation -> {
+ when(mockCredentialsProvider.resolveIdentity()).thenAnswer(invocation -> {
try {
Thread.sleep(100);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
- return AwsBasicCredentials.create("foo", "bar");
+ return CompletableFuture.completedFuture(AwsBasicCredentials.create("foo", "bar"));
});
if (metricPublishers != null) {
diff --git a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/async/AsyncClientMetricPublisherResolutionTest.java b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/async/AsyncClientMetricPublisherResolutionTest.java
index 64d43fbe7560..3fabac4b7f10 100644
--- a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/async/AsyncClientMetricPublisherResolutionTest.java
+++ b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/async/AsyncClientMetricPublisherResolutionTest.java
@@ -21,10 +21,12 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
+
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import java.io.IOException;
import java.net.URI;
import java.util.Arrays;
+import java.util.concurrent.CompletableFuture;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
@@ -34,7 +36,8 @@
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
-import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.IdentityProvider;
import software.amazon.awssdk.metrics.MetricCollection;
import software.amazon.awssdk.metrics.MetricPublisher;
import software.amazon.awssdk.regions.Region;
@@ -45,7 +48,7 @@
@RunWith(MockitoJUnitRunner.class)
public class AsyncClientMetricPublisherResolutionTest {
@Mock
- private AwsCredentialsProvider mockCredentialsProvider;
+ private IdentityProvider mockCredentialsProvider;
@Rule
public WireMockRule wireMock = new WireMockRule(0);
@@ -58,13 +61,13 @@ public class AsyncClientMetricPublisherResolutionTest {
@Before
public void setup() {
- when(mockCredentialsProvider.resolveCredentials()).thenAnswer(invocation -> {
+ when(mockCredentialsProvider.resolveIdentity()).thenAnswer(invocation -> {
try {
Thread.sleep(100);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
- return AwsBasicCredentials.create("foo", "bar");
+ return CompletableFuture.completedFuture(AwsBasicCredentials.create("foo", "bar"));
});
}
diff --git a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/async/AsyncCoreMetricsTest.java b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/async/AsyncCoreMetricsTest.java
index 7649fbae6fb0..30d04c2721a1 100644
--- a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/async/AsyncCoreMetricsTest.java
+++ b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/async/AsyncCoreMetricsTest.java
@@ -24,12 +24,8 @@
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import java.io.IOException;
import java.net.URI;
-import java.util.ArrayList;
-import java.util.List;
import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
import java.util.function.Supplier;
-import java.util.stream.Collectors;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
@@ -38,14 +34,13 @@
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
-import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.IdentityProvider;
import software.amazon.awssdk.metrics.MetricCollection;
import software.amazon.awssdk.metrics.MetricPublisher;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.protocolrestjson.ProtocolRestJsonAsyncClient;
import software.amazon.awssdk.services.protocolrestjson.model.PaginatedOperationWithResultKeyResponse;
-import software.amazon.awssdk.services.protocolrestjson.model.SimpleStruct;
-import software.amazon.awssdk.services.protocolrestjson.paginators.PaginatedOperationWithResultKeyIterable;
import software.amazon.awssdk.services.protocolrestjson.paginators.PaginatedOperationWithResultKeyPublisher;
/**
@@ -55,7 +50,7 @@
public class AsyncCoreMetricsTest extends BaseAsyncCoreMetricsTest {
@Mock
- private AwsCredentialsProvider mockCredentialsProvider;
+ private IdentityProvider mockCredentialsProvider;
@Mock
private MetricPublisher mockPublisher;
@@ -75,13 +70,13 @@ public void setup() throws IOException {
.overrideConfiguration(c -> c.addMetricPublisher(mockPublisher).retryPolicy(b -> b.numRetries(MAX_RETRIES)))
.build();
- when(mockCredentialsProvider.resolveCredentials()).thenAnswer(invocation -> {
+ when(mockCredentialsProvider.resolveIdentity()).thenAnswer(invocation -> {
try {
Thread.sleep(100);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
- return AwsBasicCredentials.create("foo", "bar");
+ return CompletableFuture.completedFuture(AwsBasicCredentials.create("foo", "bar"));
});
}
diff --git a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/async/AsyncEventStreamingCoreMetricsTest.java b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/async/AsyncEventStreamingCoreMetricsTest.java
index 534217c04110..b647df9e6f28 100644
--- a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/async/AsyncEventStreamingCoreMetricsTest.java
+++ b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/async/AsyncEventStreamingCoreMetricsTest.java
@@ -28,9 +28,10 @@
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
-import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.core.async.EmptyPublisher;
import software.amazon.awssdk.core.signer.NoOpSigner;
+import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.IdentityProvider;
import software.amazon.awssdk.metrics.MetricPublisher;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.protocolrestjson.ProtocolRestJsonAsyncClient;
@@ -46,7 +47,7 @@ public class AsyncEventStreamingCoreMetricsTest extends BaseAsyncCoreMetricsTest
public WireMockRule wireMock = new WireMockRule(0);
@Mock
- private AwsCredentialsProvider mockCredentialsProvider;
+ private IdentityProvider mockCredentialsProvider;
@Mock
private MetricPublisher mockPublisher;
@@ -64,13 +65,13 @@ public void setup() {
.retryPolicy(b -> b.numRetries(MAX_RETRIES)))
.build();
- when(mockCredentialsProvider.resolveCredentials()).thenAnswer(invocation -> {
+ when(mockCredentialsProvider.resolveIdentity()).thenAnswer(invocation -> {
try {
Thread.sleep(100);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
- return AwsBasicCredentials.create("foo", "bar");
+ return CompletableFuture.completedFuture(AwsBasicCredentials.create("foo", "bar"));
});
}
diff --git a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/async/AsyncStreamingCoreMetricsTest.java b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/async/AsyncStreamingCoreMetricsTest.java
index 15b1aa5bf129..b73a85506785 100644
--- a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/async/AsyncStreamingCoreMetricsTest.java
+++ b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/async/AsyncStreamingCoreMetricsTest.java
@@ -29,8 +29,9 @@
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
-import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.core.async.AsyncRequestBody;
+import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.IdentityProvider;
import software.amazon.awssdk.metrics.MetricPublisher;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.protocolrestjson.ProtocolRestJsonAsyncClient;
@@ -43,7 +44,7 @@
public class AsyncStreamingCoreMetricsTest extends BaseAsyncCoreMetricsTest {
@Mock
- private AwsCredentialsProvider mockCredentialsProvider;
+ private IdentityProvider mockCredentialsProvider;
@Mock
private MetricPublisher mockPublisher;
@@ -62,13 +63,13 @@ public void setup() throws IOException {
.overrideConfiguration(c -> c.addMetricPublisher(mockPublisher).retryPolicy(b -> b.numRetries(MAX_RETRIES)))
.build();
- when(mockCredentialsProvider.resolveCredentials()).thenAnswer(invocation -> {
+ when(mockCredentialsProvider.resolveIdentity()).thenAnswer(invocation -> {
try {
Thread.sleep(100);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
- return AwsBasicCredentials.create("foo", "bar");
+ return CompletableFuture.completedFuture(AwsBasicCredentials.create("foo", "bar"));
});
}
From 0a6bab35971cdf9b321da6bf91307be92cbaf343 Mon Sep 17 00:00:00 2001
From: Jaykumar Gosar
Date: Mon, 27 Mar 2023 15:30:28 -0700
Subject: [PATCH 06/13] Handle null for CredentialUtils conversion methods
---
.../amazon/awssdk/auth/credentials/CredentialUtils.java | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/core/auth/src/main/java/software/amazon/awssdk/auth/credentials/CredentialUtils.java b/core/auth/src/main/java/software/amazon/awssdk/auth/credentials/CredentialUtils.java
index b56e2d0d7def..2b855d145b3d 100644
--- a/core/auth/src/main/java/software/amazon/awssdk/auth/credentials/CredentialUtils.java
+++ b/core/auth/src/main/java/software/amazon/awssdk/auth/credentials/CredentialUtils.java
@@ -60,6 +60,9 @@ public static boolean isAnonymous(AwsCredentialsIdentity credentials) {
* @return The corresponding {@link AwsCredentials}
*/
public static AwsCredentials toCredentials(AwsCredentialsIdentity awsCredentialsIdentity) {
+ if (awsCredentialsIdentity == null) {
+ return null;
+ }
// identity-spi defines 2 known types - AwsCredentialsIdentity and a sub-type AwsSessionCredentialsIdentity
if (awsCredentialsIdentity instanceof AwsSessionCredentialsIdentity) {
AwsSessionCredentialsIdentity awsSessionCredentialsIdentity = (AwsSessionCredentialsIdentity) awsCredentialsIdentity;
@@ -87,6 +90,9 @@ public static AwsCredentials toCredentials(AwsCredentialsIdentity awsCredentials
*/
public static AwsCredentialsProvider toCredentialsProvider(
IdentityProvider extends AwsCredentialsIdentity> identityProvider) {
+ if (identityProvider == null) {
+ return null;
+ }
return () -> {
// TODO: Exception handling for CompletionException thrown from join?
AwsCredentialsIdentity awsCredentialsIdentity = identityProvider.resolveIdentity().join();
From 96bce3a0cf4791de349194360a107a2f530c873d Mon Sep 17 00:00:00 2001
From: Jaykumar Gosar
Date: Mon, 27 Mar 2023 23:41:40 -0700
Subject: [PATCH 07/13] Add IdentityProvider overload to
S3CrtAsyncClientBuilder
---
.../services/s3/S3CrtAsyncClientBuilder.java | 29 ++++++++++++++-
.../crt/CrtCredentialsProviderAdapter.java | 20 +++++------
.../internal/crt/DefaultS3CrtAsyncClient.java | 36 +++----------------
.../crt/S3NativeClientConfiguration.java | 7 ++--
4 files changed, 47 insertions(+), 45 deletions(-)
diff --git a/services/s3/src/main/java/software/amazon/awssdk/services/s3/S3CrtAsyncClientBuilder.java b/services/s3/src/main/java/software/amazon/awssdk/services/s3/S3CrtAsyncClientBuilder.java
index bba228b798eb..83dca2275214 100644
--- a/services/s3/src/main/java/software/amazon/awssdk/services/s3/S3CrtAsyncClientBuilder.java
+++ b/services/s3/src/main/java/software/amazon/awssdk/services/s3/S3CrtAsyncClientBuilder.java
@@ -19,6 +19,8 @@
import java.nio.file.Path;
import software.amazon.awssdk.annotations.SdkPublicApi;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.IdentityProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
@@ -30,6 +32,29 @@
@SdkPublicApi
public interface S3CrtAsyncClientBuilder extends SdkBuilder {
+ /**
+ * Configure the credentials that should be used to authenticate with S3.
+ *
+ * The default provider will attempt to identify the credentials automatically using the following checks:
+ *
+ * - Java System Properties -
aws.accessKeyId and aws.secretKey
+ * - Environment Variables -
AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
+ * - Credential profiles file at the default location (~/.aws/credentials) shared by all AWS SDKs and the AWS CLI
+ * - Credentials delivered through the Amazon EC2 container service if AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
+ * environment variable is set and security manager has permission to access the variable.
+ * - Instance profile credentials delivered through the Amazon EC2 metadata service
+ *
+ *
+ * If the credentials are not found in any of the locations above, an exception will be thrown at {@link #build()}
+ * time.
+ *
+ *
+ * @param credentialsProvider the credentials to use
+ * @return This builder for method chaining.
+ */
+ default S3CrtAsyncClientBuilder credentialsProvider(AwsCredentialsProvider credentialsProvider) {
+ return credentialsProvider((IdentityProvider extends AwsCredentialsIdentity>) credentialsProvider);
+ }
/**
* Configure the credentials that should be used to authenticate with S3.
@@ -51,7 +76,9 @@ public interface S3CrtAsyncClientBuilder extends SdkBuilder credentialsProvider) {
+ throw new UnsupportedOperationException();
+ }
/**
* Configure the region with which the SDK should communicate.
diff --git a/services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/crt/CrtCredentialsProviderAdapter.java b/services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/crt/CrtCredentialsProviderAdapter.java
index 9ce93b028a93..8098782aaefc 100644
--- a/services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/crt/CrtCredentialsProviderAdapter.java
+++ b/services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/crt/CrtCredentialsProviderAdapter.java
@@ -19,12 +19,13 @@
import java.nio.charset.StandardCharsets;
import software.amazon.awssdk.annotations.SdkInternalApi;
import software.amazon.awssdk.auth.credentials.AnonymousCredentialsProvider;
-import software.amazon.awssdk.auth.credentials.AwsCredentials;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
-import software.amazon.awssdk.auth.credentials.AwsSessionCredentials;
import software.amazon.awssdk.crt.auth.credentials.Credentials;
import software.amazon.awssdk.crt.auth.credentials.CredentialsProvider;
import software.amazon.awssdk.crt.auth.credentials.DelegateCredentialsProvider;
+import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.AwsSessionCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.IdentityProvider;
import software.amazon.awssdk.utils.SdkAutoCloseable;
/**
@@ -32,10 +33,10 @@
*/
@SdkInternalApi
public final class CrtCredentialsProviderAdapter implements SdkAutoCloseable {
- private final AwsCredentialsProvider credentialsProvider;
+ private final IdentityProvider extends AwsCredentialsIdentity> credentialsProvider;
private final CredentialsProvider crtCredentials;
- public CrtCredentialsProviderAdapter(AwsCredentialsProvider credentialsProvider) {
+ public CrtCredentialsProviderAdapter(IdentityProvider extends AwsCredentialsIdentity> credentialsProvider) {
this.credentialsProvider = credentialsProvider;
this.crtCredentials = new DelegateCredentialsProvider.DelegateCredentialsProviderBuilder()
.withHandler(() -> {
@@ -44,18 +45,17 @@ public CrtCredentialsProviderAdapter(AwsCredentialsProvider credentialsProvider)
return Credentials.createAnonymousCredentials();
}
- AwsCredentials sdkCredentials = credentialsProvider.resolveCredentials();
+ // TODO: Exception handling for join?
+ AwsCredentialsIdentity sdkCredentials = credentialsProvider.resolveIdentity().join();
byte[] accessKey = sdkCredentials.accessKeyId().getBytes(StandardCharsets.UTF_8);
byte[] secreteKey = sdkCredentials.secretAccessKey().getBytes(StandardCharsets.UTF_8);
byte[] sessionTokens = null;
- if (sdkCredentials instanceof AwsSessionCredentials) {
+ if (sdkCredentials instanceof AwsSessionCredentialsIdentity) {
sessionTokens =
- ((AwsSessionCredentials) sdkCredentials).sessionToken().getBytes(StandardCharsets.UTF_8);
+ ((AwsSessionCredentialsIdentity) sdkCredentials).sessionToken().getBytes(StandardCharsets.UTF_8);
}
- return new Credentials(accessKey,
- secreteKey,
- sessionTokens);
+ return new Credentials(accessKey, secreteKey, sessionTokens);
}).build();
}
diff --git a/services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/crt/DefaultS3CrtAsyncClient.java b/services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/crt/DefaultS3CrtAsyncClient.java
index 4f18a1fb4b05..b8506e7ac03f 100644
--- a/services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/crt/DefaultS3CrtAsyncClient.java
+++ b/services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/crt/DefaultS3CrtAsyncClient.java
@@ -22,7 +22,6 @@
import java.net.URI;
import java.util.concurrent.CompletableFuture;
import software.amazon.awssdk.annotations.SdkInternalApi;
-import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.awscore.AwsRequest;
import software.amazon.awssdk.awscore.AwsRequestOverrideConfiguration;
import software.amazon.awssdk.core.SdkRequest;
@@ -37,6 +36,8 @@
import software.amazon.awssdk.core.retry.RetryPolicy;
import software.amazon.awssdk.core.signer.NoOpSigner;
import software.amazon.awssdk.http.SdkHttpExecutionAttributes;
+import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.IdentityProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.DelegatingS3AsyncClient;
import software.amazon.awssdk.services.s3.S3AsyncClient;
@@ -110,7 +111,7 @@ private static S3CrtAsyncHttpClient.Builder initializeS3CrtAsyncHttpClient(Defau
public static final class DefaultS3CrtClientBuilder implements S3CrtAsyncClientBuilder {
private Long readBufferSizeInBytes;
- private AwsCredentialsProvider credentialsProvider;
+ private IdentityProvider extends AwsCredentialsIdentity> credentialsProvider;
private Region region;
private Long minimalPartSizeInBytes;
private Double targetThroughputInGbps;
@@ -118,36 +119,9 @@ public static final class DefaultS3CrtClientBuilder implements S3CrtAsyncClientB
private URI endpointOverride;
private Boolean checksumValidationEnabled;
- public AwsCredentialsProvider credentialsProvider() {
- return credentialsProvider;
- }
-
- public Region region() {
- return region;
- }
-
- public Long minimumPartSizeInBytes() {
- return minimalPartSizeInBytes;
- }
-
- public Double targetThroughputInGbps() {
- return targetThroughputInGbps;
- }
-
- public Integer maxConcurrency() {
- return maxConcurrency;
- }
-
- public URI endpointOverride() {
- return endpointOverride;
- }
-
- public Long readBufferSizeInBytes() {
- return readBufferSizeInBytes;
- }
-
@Override
- public S3CrtAsyncClientBuilder credentialsProvider(AwsCredentialsProvider credentialsProvider) {
+ public S3CrtAsyncClientBuilder credentialsProvider(
+ IdentityProvider extends AwsCredentialsIdentity> credentialsProvider) {
this.credentialsProvider = credentialsProvider;
return this;
}
diff --git a/services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/crt/S3NativeClientConfiguration.java b/services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/crt/S3NativeClientConfiguration.java
index 86a64fe1034c..142deadb289c 100644
--- a/services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/crt/S3NativeClientConfiguration.java
+++ b/services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/crt/S3NativeClientConfiguration.java
@@ -17,10 +17,11 @@
import java.net.URI;
import software.amazon.awssdk.annotations.SdkInternalApi;
-import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
import software.amazon.awssdk.crt.auth.credentials.CredentialsProvider;
import software.amazon.awssdk.crt.io.ClientBootstrap;
+import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.IdentityProvider;
import software.amazon.awssdk.regions.providers.DefaultAwsRegionProviderChain;
import software.amazon.awssdk.utils.SdkAutoCloseable;
@@ -119,7 +120,7 @@ public void close() {
public static final class Builder {
private Long readBufferSizeInBytes;
private String signingRegion;
- private AwsCredentialsProvider credentialsProvider;
+ private IdentityProvider extends AwsCredentialsIdentity> credentialsProvider;
private Long partSizeInBytes;
private Double targetThroughputInGbps;
private Integer maxConcurrency;
@@ -134,7 +135,7 @@ public Builder signingRegion(String signingRegion) {
return this;
}
- public Builder credentialsProvider(AwsCredentialsProvider credentialsProvider) {
+ public Builder credentialsProvider(IdentityProvider extends AwsCredentialsIdentity> credentialsProvider) {
this.credentialsProvider = credentialsProvider;
return this;
}
From 4d372c9bbb225eb3128068985a36f9b12f51de93 Mon Sep 17 00:00:00 2001
From: Jaykumar Gosar
Date: Tue, 28 Mar 2023 14:09:05 -0700
Subject: [PATCH 08/13] Add a TODO for removing a join() later
---
.../codegen/poet/client/test-endpoint-discovery-async.java | 1 +
1 file changed, 1 insertion(+)
diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-endpoint-discovery-async.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-endpoint-discovery-async.java
index 529d555c142e..06458aaa5617 100644
--- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-endpoint-discovery-async.java
+++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-endpoint-discovery-async.java
@@ -176,6 +176,7 @@ public CompletableFuture testDiscovery
String key = testDiscoveryIdentifiersRequiredRequest.overrideConfiguration()
.flatMap(AwsRequestOverrideConfiguration::credentialsIdentityProvider)
.orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER))
+ // TODO: avoid join inside async
.resolveIdentity().join().accessKeyId();
EndpointDiscoveryRequest endpointDiscoveryRequest = EndpointDiscoveryRequest.builder().required(true)
.defaultEndpoint(clientConfiguration.option(SdkClientOption.ENDPOINT))
From 952a4fcba36d0add775e1cf45f75819aac269e73 Mon Sep 17 00:00:00 2001
From: Jaykumar Gosar
Date: Tue, 28 Mar 2023 14:12:44 -0700
Subject: [PATCH 09/13] Add TODO for AwsCredentialsProviderChain
---
.../awssdk/auth/credentials/AwsCredentialsProviderChain.java | 1 +
1 file changed, 1 insertion(+)
diff --git a/core/auth/src/main/java/software/amazon/awssdk/auth/credentials/AwsCredentialsProviderChain.java b/core/auth/src/main/java/software/amazon/awssdk/auth/credentials/AwsCredentialsProviderChain.java
index 3dd4a4ae4011..8a46cfc306e7 100644
--- a/core/auth/src/main/java/software/amazon/awssdk/auth/credentials/AwsCredentialsProviderChain.java
+++ b/core/auth/src/main/java/software/amazon/awssdk/auth/credentials/AwsCredentialsProviderChain.java
@@ -45,6 +45,7 @@
* This chain implements {@link AutoCloseable}. When closed, it will call the {@link AutoCloseable#close()} on any credential
* providers in the chain that need to be closed.
*/
+// TODO: deprecate with new IdentityProvider chain in identity-spi
@SdkPublicApi
public final class AwsCredentialsProviderChain
implements AwsCredentialsProvider,
From 51834e397ca354f5facdfcee213c17b363de6c6e Mon Sep 17 00:00:00 2001
From: Jaykumar Gosar
Date: Tue, 28 Mar 2023 23:35:03 -0700
Subject: [PATCH 10/13] Add unit tests and few other minor changes
---
.../codegen/poet/client/AsyncClientClass.java | 1 +
.../client/test-endpoint-discovery-async.java | 1 -
.../auth/credentials/CredentialUtilsTest.java | 115 ++++++++++++++++++
.../AwsRequestOverrideConfiguration.java | 9 +-
.../builder/AwsDefaultClientBuilder.java | 2 +-
.../AwsRequestOverrideConfigurationTest.java | 54 ++++++++
.../AuthorizationStrategyFactoryTest.java | 45 ++++++-
.../presigner/DefaultPollyPresignerTest.java | 29 ++++-
.../services/rds/DefaultRdsUtilitiesTest.java | 54 ++++++--
.../service/AwsIntegrationTestBase.java | 7 +-
10 files changed, 291 insertions(+), 26 deletions(-)
create mode 100644 core/auth/src/test/java/software/amazon/awssdk/auth/credentials/CredentialUtilsTest.java
create mode 100644 core/aws-core/src/test/java/software/amazon/awssdk/awscore/AwsRequestOverrideConfigurationTest.java
diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientClass.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientClass.java
index 455d6c4b3056..8ca21f5a5612 100644
--- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientClass.java
+++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientClass.java
@@ -366,6 +366,7 @@ protected MethodSpec.Builder operationBody(MethodSpec.Builder builder, Operation
.addCode(" .flatMap($T::credentialsIdentityProvider)", AwsRequestOverrideConfiguration.class)
.addCode(" .orElseGet(() -> clientConfiguration.option($T.CREDENTIALS_IDENTITY_PROVIDER))",
AwsClientOption.class)
+ // TODO: avoid join inside async
.addCode(" .resolveIdentity().join().accessKeyId();");
builder.addCode("$1T endpointDiscoveryRequest = $1T.builder()", EndpointDiscoveryRequest.class)
diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-endpoint-discovery-async.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-endpoint-discovery-async.java
index 06458aaa5617..529d555c142e 100644
--- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-endpoint-discovery-async.java
+++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-endpoint-discovery-async.java
@@ -176,7 +176,6 @@ public CompletableFuture testDiscovery
String key = testDiscoveryIdentifiersRequiredRequest.overrideConfiguration()
.flatMap(AwsRequestOverrideConfiguration::credentialsIdentityProvider)
.orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER))
- // TODO: avoid join inside async
.resolveIdentity().join().accessKeyId();
EndpointDiscoveryRequest endpointDiscoveryRequest = EndpointDiscoveryRequest.builder().required(true)
.defaultEndpoint(clientConfiguration.option(SdkClientOption.ENDPOINT))
diff --git a/core/auth/src/test/java/software/amazon/awssdk/auth/credentials/CredentialUtilsTest.java b/core/auth/src/test/java/software/amazon/awssdk/auth/credentials/CredentialUtilsTest.java
new file mode 100644
index 000000000000..2b68ad493a0c
--- /dev/null
+++ b/core/auth/src/test/java/software/amazon/awssdk/auth/credentials/CredentialUtilsTest.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package software.amazon.awssdk.auth.credentials;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.jupiter.api.Test;
+import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.AwsSessionCredentialsIdentity;
+
+public class CredentialUtilsTest {
+
+ @Test
+ public void isAnonymous_AwsCredentials_true() {
+ assertThat(CredentialUtils.isAnonymous(AwsBasicCredentials.ANONYMOUS_CREDENTIALS)).isTrue();
+ }
+
+ @Test
+ public void isAnonymous_AwsCredentials_false() {
+ assertThat(CredentialUtils.isAnonymous(AwsBasicCredentials.create("akid", "skid"))).isFalse();
+ }
+
+ @Test
+ public void isAnonymous_AwsCredentialsIdentity_true() {
+ assertThat(CredentialUtils.isAnonymous((AwsCredentialsIdentity) AwsBasicCredentials.ANONYMOUS_CREDENTIALS)).isTrue();
+ }
+
+ @Test
+ public void isAnonymous_AwsCredentialsIdentity_false() {
+ assertThat(CredentialUtils.isAnonymous((AwsCredentialsIdentity) AwsBasicCredentials.create("akid", "skid"))).isFalse();
+ }
+
+ @Test
+ public void toCredentials_null_returnsNull() {
+ assertThat(CredentialUtils.toCredentials(null)).isNull();
+ }
+
+ @Test
+ public void toCredentials_AwsSessionCredentialsIdentity_returnsAwsSessionCredentials() {
+ AwsCredentials awsCredentials = CredentialUtils.toCredentials(new AwsSessionCredentialsIdentity() {
+ @Override
+ public String accessKeyId() {
+ return "akid";
+ }
+
+ @Override
+ public String secretAccessKey() {
+ return "skid";
+ }
+
+ @Override
+ public String sessionToken() {
+ return "session";
+ }
+ });
+
+ assertThat(awsCredentials).isInstanceOf(AwsSessionCredentials.class);
+ AwsSessionCredentials awsSessionCredentials = (AwsSessionCredentials) awsCredentials;
+ assertThat(awsSessionCredentials.accessKeyId()).isEqualTo("akid");
+ assertThat(awsSessionCredentials.secretAccessKey()).isEqualTo("skid");
+ assertThat(awsSessionCredentials.sessionToken()).isEqualTo("session");
+ }
+
+ @Test
+ public void toCredentials_AwsCredentialsIdentity_returnsAwsCredentials() {
+ AwsCredentials awsCredentials = CredentialUtils.toCredentials(new AwsCredentialsIdentity() {
+ @Override
+ public String accessKeyId() {
+ return "akid";
+ }
+
+ @Override
+ public String secretAccessKey() {
+ return "skid";
+ }
+ });
+
+ assertThat(awsCredentials.accessKeyId()).isEqualTo("akid");
+ assertThat(awsCredentials.secretAccessKey()).isEqualTo("skid");
+ }
+
+ @Test
+ public void toCredentials_Anonymous_returnsAnonymous() {
+ AwsCredentials awsCredentials = CredentialUtils.toCredentials(AwsBasicCredentials.ANONYMOUS_CREDENTIALS);
+ assertThat(awsCredentials.accessKeyId()).isNull();
+ assertThat(awsCredentials.secretAccessKey()).isNull();
+ }
+
+ @Test
+ public void toCredentialsProvider_null_returnsNull() {
+ assertThat(CredentialUtils.toCredentialsProvider(null)).isNull();
+ }
+
+ @Test
+ public void toCredentialsProvider_IdentityProvider_converts() {
+ AwsCredentialsProvider credentialsProvider = CredentialUtils.toCredentialsProvider(
+ StaticCredentialsProvider.create(AwsBasicCredentials.create("akid", "skid")));
+ AwsCredentials credentials = credentialsProvider.resolveCredentials();
+ assertThat(credentials.accessKeyId()).isEqualTo("akid");
+ assertThat(credentials.secretAccessKey()).isEqualTo("skid");
+ }
+}
\ No newline at end of file
diff --git a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/AwsRequestOverrideConfiguration.java b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/AwsRequestOverrideConfiguration.java
index 5c8b959d4f5f..5f3dc71b10c6 100644
--- a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/AwsRequestOverrideConfiguration.java
+++ b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/AwsRequestOverrideConfiguration.java
@@ -132,6 +132,9 @@ default Builder credentialsProvider(IdentityProvider extends AwsCredentialsIde
throw new UnsupportedOperationException();
}
+ // review TODO: Not sure why the builder should have a public getter. Currently it was called from constructor of
+ // AwsRequestOverrideConfiguration. But it is private and should probably take BuilderImpl. Still can't remove this
+ // method, but maybe can avoid adding credentialsIdentityProvider() to Builder.
/**
* Return the optional {@link AwsCredentialsProvider} that will provide credentials to be used to authenticate this
* request.
@@ -168,12 +171,6 @@ private BuilderImpl(AwsRequestOverrideConfiguration awsRequestOverrideConfig) {
this.awsCredentialsProvider = awsRequestOverrideConfig.credentialsProvider;
}
- // review TODO: remove this since it is the same as the default interface implementation
- // @Override
- // public Builder credentialsProvider(AwsCredentialsProvider credentialsProvider) {
- // return credentialsProvider((IdentityProvider extends AwsCredentialsIdentity>) credentialsProvider);
- // }
-
@Override
public Builder credentialsProvider(IdentityProvider extends AwsCredentialsIdentity> credentialsProvider) {
this.awsCredentialsProvider = credentialsProvider;
diff --git a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/builder/AwsDefaultClientBuilder.java b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/builder/AwsDefaultClientBuilder.java
index 92342b97e47b..09fc9c4b1fc9 100644
--- a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/builder/AwsDefaultClientBuilder.java
+++ b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/builder/AwsDefaultClientBuilder.java
@@ -444,7 +444,7 @@ public final BuilderT credentialsProvider(IdentityProvider extends AwsCredenti
return thisBuilder();
}
- public void setCredentialsProvider(IdentityProvider extends AwsCredentialsIdentity> identityProvider) {
+ public final void setCredentialsProvider(IdentityProvider extends AwsCredentialsIdentity> identityProvider) {
credentialsProvider(identityProvider);
}
diff --git a/core/aws-core/src/test/java/software/amazon/awssdk/awscore/AwsRequestOverrideConfigurationTest.java b/core/aws-core/src/test/java/software/amazon/awssdk/awscore/AwsRequestOverrideConfigurationTest.java
new file mode 100644
index 000000000000..94ebe7bc810a
--- /dev/null
+++ b/core/aws-core/src/test/java/software/amazon/awssdk/awscore/AwsRequestOverrideConfigurationTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package software.amazon.awssdk.awscore;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.Test;
+import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
+import software.amazon.awssdk.auth.credentials.AwsCredentials;
+import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
+import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.IdentityProvider;
+
+public class AwsRequestOverrideConfigurationTest {
+
+ @Test
+ public void testCredentialsProviderWorksWithBothOldAndNewInterfaceTypes() {
+ AwsCredentialsProvider credentialsProvider = StaticCredentialsProvider.create(
+ AwsBasicCredentials.create("akid","skid"));
+
+ AwsRequestOverrideConfiguration configuration1 = AwsRequestOverrideConfiguration
+ .builder().credentialsProvider(credentialsProvider).build();
+
+ AwsRequestOverrideConfiguration configuration2 = AwsRequestOverrideConfiguration
+ .builder().credentialsProvider((IdentityProvider) credentialsProvider).build();
+
+ assertCredentialsEqual(configuration1.credentialsProvider().get(), configuration1.credentialsIdentityProvider().get());
+ assertCredentialsEqual(configuration2.credentialsProvider().get(), configuration2.credentialsIdentityProvider().get());
+ assertCredentialsEqual(configuration1.credentialsProvider().get(), configuration2.credentialsIdentityProvider().get());
+ assertCredentialsEqual(configuration2.credentialsProvider().get(), configuration1.credentialsIdentityProvider().get());
+ }
+
+ private void assertCredentialsEqual(AwsCredentialsProvider credentialsProvider,
+ IdentityProvider extends AwsCredentialsIdentity> identityProvider) {
+ AwsCredentials creds1 = credentialsProvider.resolveCredentials();
+ AwsCredentialsIdentity creds2 = identityProvider.resolveIdentity().join();
+ assertThat(creds1.accessKeyId()).isEqualTo(creds2.accessKeyId());
+ assertThat(creds1.secretAccessKey()).isEqualTo(creds2.secretAccessKey());
+ }
+}
\ No newline at end of file
diff --git a/core/aws-core/src/test/java/software/amazon/awssdk/awscore/internal/authcontext/AuthorizationStrategyFactoryTest.java b/core/aws-core/src/test/java/software/amazon/awssdk/awscore/internal/authcontext/AuthorizationStrategyFactoryTest.java
index 1f48149c45ca..ec5ab60b60ef 100644
--- a/core/aws-core/src/test/java/software/amazon/awssdk/awscore/internal/authcontext/AuthorizationStrategyFactoryTest.java
+++ b/core/aws-core/src/test/java/software/amazon/awssdk/awscore/internal/authcontext/AuthorizationStrategyFactoryTest.java
@@ -16,19 +16,35 @@
package software.amazon.awssdk.awscore.internal.authcontext;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.when;
-import org.junit.jupiter.api.Test;
+import java.util.Optional;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
+import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
+import software.amazon.awssdk.auth.signer.AwsSignerExecutionAttribute;
+import software.amazon.awssdk.awscore.client.config.AwsClientOption;
import software.amazon.awssdk.core.CredentialType;
import software.amazon.awssdk.core.SdkRequest;
import software.amazon.awssdk.core.client.config.SdkClientConfiguration;
+import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
import software.amazon.awssdk.metrics.MetricCollector;
+@RunWith(MockitoJUnitRunner.class)
public class AuthorizationStrategyFactoryTest {
@Mock SdkRequest sdkRequest;
@Mock MetricCollector metricCollector;
+ @Before
+ public void setUp() throws Exception {
+ when(sdkRequest.overrideConfiguration()).thenReturn(Optional.empty());
+ }
+
@Test
public void credentialTypeBearerToken_returnsTokenStrategy() {
AuthorizationStrategyFactory factory = new AuthorizationStrategyFactory(sdkRequest, metricCollector,
@@ -39,10 +55,33 @@ public void credentialTypeBearerToken_returnsTokenStrategy() {
@Test
public void credentialTypeAwsCredentials_returnsCredentialsStrategy() {
- AuthorizationStrategyFactory factory = new AuthorizationStrategyFactory(sdkRequest, metricCollector,
- SdkClientConfiguration.builder().build());
+ SdkClientConfiguration configuration = SdkClientConfiguration
+ .builder()
+ .option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER, StaticCredentialsProvider.create(AwsBasicCredentials.create(
+ "akid", "skid")))
+ .build();
+ AuthorizationStrategyFactory factory = new AuthorizationStrategyFactory(sdkRequest, metricCollector, configuration);
AuthorizationStrategy authorizationStrategy = factory.strategyFor(CredentialType.of("AWS"));
assertThat(authorizationStrategy).isExactlyInstanceOf(AwsCredentialsAuthorizationStrategy.class);
+ ExecutionAttributes attributes = new ExecutionAttributes();
+ authorizationStrategy.addCredentialsToExecutionAttributes(attributes);
+ assertThat(attributes.getAttribute(AwsSignerExecutionAttribute.AWS_CREDENTIALS).accessKeyId()).isEqualTo("akid");
+ assertThat(attributes.getAttribute(AwsSignerExecutionAttribute.AWS_CREDENTIALS).secretAccessKey()).isEqualTo("skid");
}
+ @Test
+ public void credentialTypeAwsCredentials_withOldClientOption_returnsCredentialsStrategy() {
+ SdkClientConfiguration configuration = SdkClientConfiguration
+ .builder()
+ .option(AwsClientOption.CREDENTIALS_PROVIDER, StaticCredentialsProvider.create(AwsBasicCredentials.create(
+ "akid", "skid")))
+ .build();
+ AuthorizationStrategyFactory factory = new AuthorizationStrategyFactory(sdkRequest, metricCollector, configuration);
+ AuthorizationStrategy authorizationStrategy = factory.strategyFor(CredentialType.of("AWS"));
+ assertThat(authorizationStrategy).isExactlyInstanceOf(AwsCredentialsAuthorizationStrategy.class);
+ ExecutionAttributes attributes = new ExecutionAttributes();
+ authorizationStrategy.addCredentialsToExecutionAttributes(attributes);
+ assertThat(attributes.getAttribute(AwsSignerExecutionAttribute.AWS_CREDENTIALS).accessKeyId()).isEqualTo("akid");
+ assertThat(attributes.getAttribute(AwsSignerExecutionAttribute.AWS_CREDENTIALS).secretAccessKey()).isEqualTo("skid");
+ }
}
diff --git a/services/polly/src/test/java/software/amazon/awssdk/services/polly/internal/presigner/DefaultPollyPresignerTest.java b/services/polly/src/test/java/software/amazon/awssdk/services/polly/internal/presigner/DefaultPollyPresignerTest.java
index 78c2c78ee374..30491ef287ea 100644
--- a/services/polly/src/test/java/software/amazon/awssdk/services/polly/internal/presigner/DefaultPollyPresignerTest.java
+++ b/services/polly/src/test/java/software/amazon/awssdk/services/polly/internal/presigner/DefaultPollyPresignerTest.java
@@ -27,7 +27,6 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
-import software.amazon.awssdk.auth.credentials.AwsCredentials;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.awscore.AwsRequestOverrideConfiguration;
@@ -50,7 +49,7 @@ class DefaultPollyPresignerTest {
.text("Hello presigners!")
.build();
- private AwsCredentialsProvider credentialsProvider;
+ private IdentityProvider credentialsProvider;
@BeforeEach
public void methodSetup() {
@@ -59,7 +58,9 @@ public void methodSetup() {
@Test
void presign_requestLevelCredentials_honored() {
- AwsCredentials requestCredentials = AwsBasicCredentials.create("akid2", "skid2");
+ IdentityProvider requestCedentialsProvider = StaticCredentialsProvider.create(
+ AwsBasicCredentials.create("akid2", "skid2")
+ );
PollyPresigner presigner = DefaultPollyPresigner.builder()
.region(Region.US_EAST_1)
@@ -68,7 +69,7 @@ void presign_requestLevelCredentials_honored() {
SynthesizeSpeechRequest synthesizeSpeechRequest = BASIC_SYNTHESIZE_SPEECH_REQUEST.toBuilder()
.overrideConfiguration(AwsRequestOverrideConfiguration.builder()
- .credentialsProvider(StaticCredentialsProvider.create(requestCredentials)).build())
+ .credentialsProvider(requestCedentialsProvider).build())
.build();
SynthesizeSpeechPresignRequest presignRequest = SynthesizeSpeechPresignRequest.builder()
@@ -188,6 +189,24 @@ void close_closesCustomCloseableCredentialsProvider() throws IOException {
verify(mockCredentialsProvider).close();
}
+ @Test
+ void presigner_credentialsProviderSetAsAwsCredentialsProvider_delegatesCorrectly() {
+ AwsCredentialsProvider credentialsProvider = StaticCredentialsProvider.create(AwsBasicCredentials.create("akid", "skid"));
+ DefaultPollyPresigner presigner1 = (DefaultPollyPresigner)
+ DefaultPollyPresigner.builder()
+ .region(Region.US_EAST_1)
+ .credentialsProvider(credentialsProvider)
+ .build();
+
+ DefaultPollyPresigner presigner2 = (DefaultPollyPresigner)
+ DefaultPollyPresigner.builder()
+ .region(Region.US_EAST_1)
+ .credentialsProvider((IdentityProvider) credentialsProvider)
+ .build();
+
+ assertThat(presigner1.credentialsProvider()).isSameAs(presigner2.credentialsProvider());
+ }
+
@Test
void presigner_credentialsProviderSetToNullByBuilder_createsDefaultCredentialsProvider() {
DefaultPollyPresigner presigner = (DefaultPollyPresigner)
@@ -201,6 +220,6 @@ void presigner_credentialsProviderSetToNullByBuilder_createsDefaultCredentialsPr
assertThat(awsCredentialsProvider).isNotNull();
}
- private interface TestCredentialsProvider extends AwsCredentialsProvider, Closeable {
+ private interface TestCredentialsProvider extends IdentityProvider, Closeable {
}
}
diff --git a/services/rds/src/test/java/software/amazon/awssdk/services/rds/DefaultRdsUtilitiesTest.java b/services/rds/src/test/java/software/amazon/awssdk/services/rds/DefaultRdsUtilitiesTest.java
index a8648196dadb..9830cc8f3b40 100644
--- a/services/rds/src/test/java/software/amazon/awssdk/services/rds/DefaultRdsUtilitiesTest.java
+++ b/services/rds/src/test/java/software/amazon/awssdk/services/rds/DefaultRdsUtilitiesTest.java
@@ -6,19 +6,23 @@
import java.time.Clock;
import java.time.ZoneId;
import java.time.ZonedDateTime;
+import java.util.function.Consumer;
import org.junit.jupiter.api.Test;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
+import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.IdentityProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.rds.DefaultRdsUtilities.DefaultBuilder;
+import software.amazon.awssdk.services.rds.model.GenerateAuthenticationTokenRequest;
public class DefaultRdsUtilitiesTest {
private final ZoneId utcZone = ZoneId.of("UTC").normalized();
private final Clock fixedClock = Clock.fixed(ZonedDateTime.of(2016, 11, 7, 17, 39, 33, 0, utcZone).toInstant(), utcZone);
@Test
- public void testTokenGenerationWithBuilderDefaults() {
+ public void testTokenGenerationWithBuilderDefaultsUsingAwsCredentialsProvider() {
AwsCredentialsProvider credentialsProvider = StaticCredentialsProvider.create(
AwsBasicCredentials.create("access_key", "secret_key")
);
@@ -26,6 +30,22 @@ public void testTokenGenerationWithBuilderDefaults() {
.credentialsProvider(credentialsProvider)
.region(Region.US_EAST_1);
+ testTokenGenerationWithBuilderDefaults(utilitiesBuilder);
+ }
+
+ @Test
+ public void testTokenGenerationWithBuilderDefaultsUsingIdentityProvider() {
+ IdentityProvider credentialsProvider = StaticCredentialsProvider.create(
+ AwsBasicCredentials.create("access_key", "secret_key")
+ );
+ DefaultBuilder utilitiesBuilder = (DefaultBuilder) RdsUtilities.builder()
+ .credentialsProvider(credentialsProvider)
+ .region(Region.US_EAST_1);
+
+ testTokenGenerationWithBuilderDefaults(utilitiesBuilder);
+ }
+
+ private void testTokenGenerationWithBuilderDefaults(DefaultBuilder utilitiesBuilder) {
DefaultRdsUtilities rdsUtilities = new DefaultRdsUtilities(utilitiesBuilder, fixedClock);
String authenticationToken = rdsUtilities.generateAuthenticationToken(builder -> {
@@ -42,22 +62,42 @@ public void testTokenGenerationWithBuilderDefaults() {
}
@Test
- public void testTokenGenerationWithOverriddenCredentials() {
+ public void testTokenGenerationWithOverriddenCredentialsUsingAwsCredentialsProvider() {
AwsCredentialsProvider credentialsProvider = StaticCredentialsProvider.create(
AwsBasicCredentials.create("foo", "bar")
);
DefaultBuilder utilitiesBuilder = (DefaultBuilder) RdsUtilities.builder()
.credentialsProvider(credentialsProvider)
.region(Region.US_EAST_1);
+ testTokenGenerationWithOverriddenCredentials(utilitiesBuilder, builder -> {
+ builder.credentialsProvider(StaticCredentialsProvider.create(
+ AwsBasicCredentials.create("access_key", "secret_key")));
+ });
+ }
+
+ @Test
+ public void testTokenGenerationWithOverriddenCredentialsUsingIdentityProvider() {
+ IdentityProvider credentialsProvider = StaticCredentialsProvider.create(
+ AwsBasicCredentials.create("foo", "bar")
+ );
+ DefaultBuilder utilitiesBuilder = (DefaultBuilder) RdsUtilities.builder()
+ .credentialsProvider(credentialsProvider)
+ .region(Region.US_EAST_1);
+ testTokenGenerationWithOverriddenCredentials(utilitiesBuilder, builder -> {
+ builder.credentialsProvider((IdentityProvider) StaticCredentialsProvider.create(
+ AwsBasicCredentials.create("access_key", "secret_key")));
+ });
+ }
+
+ private void testTokenGenerationWithOverriddenCredentials(DefaultBuilder utilitiesBuilder,
+ Consumer credsBuilder) {
DefaultRdsUtilities rdsUtilities = new DefaultRdsUtilities(utilitiesBuilder, fixedClock);
String authenticationToken = rdsUtilities.generateAuthenticationToken(builder -> {
builder.username("mySQLUser")
.hostname("host.us-east-1.amazonaws.com")
.port(3306)
- .credentialsProvider(StaticCredentialsProvider.create(
- AwsBasicCredentials.create("access_key", "secret_key")
- ));
+ .applyMutation(credsBuilder);
});
String expectedToken = "host.us-east-1.amazonaws.com:3306/?DBUser=mySQLUser&Action=connect&" +
@@ -69,7 +109,7 @@ public void testTokenGenerationWithOverriddenCredentials() {
@Test
public void testTokenGenerationWithOverriddenRegion() {
- AwsCredentialsProvider credentialsProvider = StaticCredentialsProvider.create(
+ IdentityProvider credentialsProvider = StaticCredentialsProvider.create(
AwsBasicCredentials.create("access_key", "secret_key")
);
DefaultBuilder utilitiesBuilder = (DefaultBuilder) RdsUtilities.builder()
@@ -94,7 +134,7 @@ public void testTokenGenerationWithOverriddenRegion() {
@Test
public void testMissingRegionThrowsException() {
- AwsCredentialsProvider credentialsProvider = StaticCredentialsProvider.create(
+ IdentityProvider credentialsProvider = StaticCredentialsProvider.create(
AwsBasicCredentials.create("access_key", "secret_key")
);
DefaultBuilder utilitiesBuilder = (DefaultBuilder) RdsUtilities.builder()
diff --git a/test/service-test-utils/src/main/java/software/amazon/awssdk/testutils/service/AwsIntegrationTestBase.java b/test/service-test-utils/src/main/java/software/amazon/awssdk/testutils/service/AwsIntegrationTestBase.java
index 2b9de9dd2b03..70c9564fd2ae 100644
--- a/test/service-test-utils/src/main/java/software/amazon/awssdk/testutils/service/AwsIntegrationTestBase.java
+++ b/test/service-test-utils/src/main/java/software/amazon/awssdk/testutils/service/AwsIntegrationTestBase.java
@@ -19,11 +19,12 @@
import java.io.InputStream;
import reactor.blockhound.BlockHound;
import software.amazon.awssdk.auth.credentials.AwsCredentials;
-import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProviderChain;
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
+import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.IdentityProvider;
import software.amazon.awssdk.utils.IoUtils;
public abstract class AwsIntegrationTestBase {
@@ -57,9 +58,9 @@ protected static AwsCredentials getCredentials() {
}
/**
- * @return AwsCredentialsProvider to use during tests. Setup by base fixture
+ * @return {@link IdentityProvider} to use during tests. Setup by base fixture
*/
- protected static AwsCredentialsProvider getCredentialsProvider() {
+ protected static IdentityProvider getCredentialsProvider() {
return StaticCredentialsProvider.create(CREDENTIALS);
}
From b2098a66be8a2d8bb8df74c9f0a6e2eff51f8207 Mon Sep 17 00:00:00 2001
From: Jaykumar Gosar
Date: Wed, 29 Mar 2023 00:12:25 -0700
Subject: [PATCH 11/13] Remove unnecessary fallback from
AuthorizationStrategyFactory
---
.../auth/credentials/CredentialUtilsTest.java | 2 +-
.../AuthorizationStrategyFactory.java | 5 +--
.../AwsRequestOverrideConfigurationTest.java | 2 +-
.../AuthorizationStrategyFactoryTest.java | 45 ++-----------------
4 files changed, 6 insertions(+), 48 deletions(-)
diff --git a/core/auth/src/test/java/software/amazon/awssdk/auth/credentials/CredentialUtilsTest.java b/core/auth/src/test/java/software/amazon/awssdk/auth/credentials/CredentialUtilsTest.java
index 2b68ad493a0c..10eb7855e6bc 100644
--- a/core/auth/src/test/java/software/amazon/awssdk/auth/credentials/CredentialUtilsTest.java
+++ b/core/auth/src/test/java/software/amazon/awssdk/auth/credentials/CredentialUtilsTest.java
@@ -112,4 +112,4 @@ public void toCredentialsProvider_IdentityProvider_converts() {
assertThat(credentials.accessKeyId()).isEqualTo("akid");
assertThat(credentials.secretAccessKey()).isEqualTo("skid");
}
-}
\ No newline at end of file
+}
diff --git a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/authcontext/AuthorizationStrategyFactory.java b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/authcontext/AuthorizationStrategyFactory.java
index 0cffb7e9b355..e56b44d01efe 100644
--- a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/authcontext/AuthorizationStrategyFactory.java
+++ b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/authcontext/AuthorizationStrategyFactory.java
@@ -65,11 +65,8 @@ private TokenAuthorizationStrategy tokenAuthorizationStrategy() {
private AwsCredentialsAuthorizationStrategy awsCredentialsAuthorizationStrategy() {
Signer defaultSigner = clientConfiguration.option(SdkAdvancedClientOption.SIGNER);
- // Older generated clients may still be using CREDENTIALS_PROVIDER, so fall back to that.
IdentityProvider extends AwsCredentialsIdentity> defaultCredentialsProvider =
- clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER) != null
- ? clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER)
- : clientConfiguration.option(AwsClientOption.CREDENTIALS_PROVIDER);
+ clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER);
return AwsCredentialsAuthorizationStrategy.builder()
.request(request)
.defaultSigner(defaultSigner)
diff --git a/core/aws-core/src/test/java/software/amazon/awssdk/awscore/AwsRequestOverrideConfigurationTest.java b/core/aws-core/src/test/java/software/amazon/awssdk/awscore/AwsRequestOverrideConfigurationTest.java
index 94ebe7bc810a..ef009f8242f4 100644
--- a/core/aws-core/src/test/java/software/amazon/awssdk/awscore/AwsRequestOverrideConfigurationTest.java
+++ b/core/aws-core/src/test/java/software/amazon/awssdk/awscore/AwsRequestOverrideConfigurationTest.java
@@ -51,4 +51,4 @@ private void assertCredentialsEqual(AwsCredentialsProvider credentialsProvider,
assertThat(creds1.accessKeyId()).isEqualTo(creds2.accessKeyId());
assertThat(creds1.secretAccessKey()).isEqualTo(creds2.secretAccessKey());
}
-}
\ No newline at end of file
+}
diff --git a/core/aws-core/src/test/java/software/amazon/awssdk/awscore/internal/authcontext/AuthorizationStrategyFactoryTest.java b/core/aws-core/src/test/java/software/amazon/awssdk/awscore/internal/authcontext/AuthorizationStrategyFactoryTest.java
index ec5ab60b60ef..1f48149c45ca 100644
--- a/core/aws-core/src/test/java/software/amazon/awssdk/awscore/internal/authcontext/AuthorizationStrategyFactoryTest.java
+++ b/core/aws-core/src/test/java/software/amazon/awssdk/awscore/internal/authcontext/AuthorizationStrategyFactoryTest.java
@@ -16,35 +16,19 @@
package software.amazon.awssdk.awscore.internal.authcontext;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.when;
-import java.util.Optional;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
-import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
-import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
-import software.amazon.awssdk.auth.signer.AwsSignerExecutionAttribute;
-import software.amazon.awssdk.awscore.client.config.AwsClientOption;
import software.amazon.awssdk.core.CredentialType;
import software.amazon.awssdk.core.SdkRequest;
import software.amazon.awssdk.core.client.config.SdkClientConfiguration;
-import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
import software.amazon.awssdk.metrics.MetricCollector;
-@RunWith(MockitoJUnitRunner.class)
public class AuthorizationStrategyFactoryTest {
@Mock SdkRequest sdkRequest;
@Mock MetricCollector metricCollector;
- @Before
- public void setUp() throws Exception {
- when(sdkRequest.overrideConfiguration()).thenReturn(Optional.empty());
- }
-
@Test
public void credentialTypeBearerToken_returnsTokenStrategy() {
AuthorizationStrategyFactory factory = new AuthorizationStrategyFactory(sdkRequest, metricCollector,
@@ -55,33 +39,10 @@ public void credentialTypeBearerToken_returnsTokenStrategy() {
@Test
public void credentialTypeAwsCredentials_returnsCredentialsStrategy() {
- SdkClientConfiguration configuration = SdkClientConfiguration
- .builder()
- .option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER, StaticCredentialsProvider.create(AwsBasicCredentials.create(
- "akid", "skid")))
- .build();
- AuthorizationStrategyFactory factory = new AuthorizationStrategyFactory(sdkRequest, metricCollector, configuration);
+ AuthorizationStrategyFactory factory = new AuthorizationStrategyFactory(sdkRequest, metricCollector,
+ SdkClientConfiguration.builder().build());
AuthorizationStrategy authorizationStrategy = factory.strategyFor(CredentialType.of("AWS"));
assertThat(authorizationStrategy).isExactlyInstanceOf(AwsCredentialsAuthorizationStrategy.class);
- ExecutionAttributes attributes = new ExecutionAttributes();
- authorizationStrategy.addCredentialsToExecutionAttributes(attributes);
- assertThat(attributes.getAttribute(AwsSignerExecutionAttribute.AWS_CREDENTIALS).accessKeyId()).isEqualTo("akid");
- assertThat(attributes.getAttribute(AwsSignerExecutionAttribute.AWS_CREDENTIALS).secretAccessKey()).isEqualTo("skid");
}
- @Test
- public void credentialTypeAwsCredentials_withOldClientOption_returnsCredentialsStrategy() {
- SdkClientConfiguration configuration = SdkClientConfiguration
- .builder()
- .option(AwsClientOption.CREDENTIALS_PROVIDER, StaticCredentialsProvider.create(AwsBasicCredentials.create(
- "akid", "skid")))
- .build();
- AuthorizationStrategyFactory factory = new AuthorizationStrategyFactory(sdkRequest, metricCollector, configuration);
- AuthorizationStrategy authorizationStrategy = factory.strategyFor(CredentialType.of("AWS"));
- assertThat(authorizationStrategy).isExactlyInstanceOf(AwsCredentialsAuthorizationStrategy.class);
- ExecutionAttributes attributes = new ExecutionAttributes();
- authorizationStrategy.addCredentialsToExecutionAttributes(attributes);
- assertThat(attributes.getAttribute(AwsSignerExecutionAttribute.AWS_CREDENTIALS).accessKeyId()).isEqualTo("akid");
- assertThat(attributes.getAttribute(AwsSignerExecutionAttribute.AWS_CREDENTIALS).secretAccessKey()).isEqualTo("skid");
- }
}
From 22370c274eee2d286e219474f78ba8fc79d8586f Mon Sep 17 00:00:00 2001
From: Jaykumar Gosar
Date: Wed, 29 Mar 2023 00:44:24 -0700
Subject: [PATCH 12/13] Fix test in S3
---
.../crt/CrtCredentialProviderAdapterTest.java | 23 ++++++++-----------
1 file changed, 10 insertions(+), 13 deletions(-)
diff --git a/services/s3/src/test/java/software/amazon/awssdk/services/s3/internal/crt/CrtCredentialProviderAdapterTest.java b/services/s3/src/test/java/software/amazon/awssdk/services/s3/internal/crt/CrtCredentialProviderAdapterTest.java
index a4da9d11f18b..f191d1effc70 100644
--- a/services/s3/src/test/java/software/amazon/awssdk/services/s3/internal/crt/CrtCredentialProviderAdapterTest.java
+++ b/services/s3/src/test/java/software/amazon/awssdk/services/s3/internal/crt/CrtCredentialProviderAdapterTest.java
@@ -20,24 +20,25 @@
import static org.mockito.Mockito.when;
import java.nio.charset.StandardCharsets;
+import java.util.concurrent.CompletableFuture;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import software.amazon.awssdk.auth.credentials.AnonymousCredentialsProvider;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
-import software.amazon.awssdk.auth.credentials.AwsCredentials;
-import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.auth.credentials.AwsSessionCredentials;
import software.amazon.awssdk.auth.credentials.HttpCredentialsProvider;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.crt.auth.credentials.Credentials;
import software.amazon.awssdk.crt.auth.credentials.CredentialsProvider;
+import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.IdentityProvider;
import software.amazon.awssdk.utils.SdkAutoCloseable;
public class CrtCredentialProviderAdapterTest {
@Test
void crtCredentials_withSession_shouldConvert() {
- AwsCredentialsProvider awsCredentialsProvider = StaticCredentialsProvider
+ IdentityProvider extends AwsCredentialsIdentity> awsCredentialsProvider = StaticCredentialsProvider
.create(AwsSessionCredentials.create("foo", "bar", "session"));
CredentialsProvider crtCredentialsProvider = new CrtCredentialsProviderAdapter(awsCredentialsProvider)
@@ -52,7 +53,7 @@ void crtCredentials_withSession_shouldConvert() {
@Test
void crtCredentials_withoutSession_shouldConvert() {
- AwsCredentialsProvider awsCredentialsProvider = StaticCredentialsProvider
+ IdentityProvider extends AwsCredentialsIdentity> awsCredentialsProvider = StaticCredentialsProvider
.create(AwsBasicCredentials.create("foo", "bar"));
CredentialsProvider crtCredentialsProvider = new CrtCredentialsProviderAdapter(awsCredentialsProvider)
@@ -67,8 +68,8 @@ void crtCredentials_withoutSession_shouldConvert() {
@Test
void crtCredentials_provideAwsCredentials_shouldInvokeResolveAndClose() {
- AwsCredentialsProvider awsCredentialsProvider = Mockito.mock(HttpCredentialsProvider.class);
- AwsCredentials credentials = new AwsCredentials() {
+ IdentityProvider extends AwsCredentialsIdentity> awsCredentialsProvider = Mockito.mock(HttpCredentialsProvider.class);
+ AwsCredentialsIdentity credentials = new AwsCredentialsIdentity() {
@Override
public String accessKeyId() {
return "foo";
@@ -79,7 +80,7 @@ public String secretAccessKey() {
return "bar";
}
};
- when(awsCredentialsProvider.resolveCredentials()).thenReturn(credentials);
+ when(awsCredentialsProvider.resolveIdentity()).thenAnswer(invocation -> CompletableFuture.completedFuture(credentials));
CrtCredentialsProviderAdapter adapter = new CrtCredentialsProviderAdapter(awsCredentialsProvider);
CredentialsProvider crtCredentialsProvider = adapter.crtCredentials();
@@ -87,7 +88,7 @@ public String secretAccessKey() {
Credentials crtCredentials = crtCredentialsProvider.getCredentials().join();
assertThat(crtCredentials.getAccessKeyId()).isEqualTo("foo".getBytes(StandardCharsets.UTF_8));
assertThat(crtCredentials.getSecretAccessKey()).isEqualTo("bar".getBytes(StandardCharsets.UTF_8));
- verify(awsCredentialsProvider).resolveCredentials();
+ verify(awsCredentialsProvider).resolveIdentity();
adapter.close();
verify((SdkAutoCloseable) awsCredentialsProvider).close();
@@ -95,7 +96,7 @@ public String secretAccessKey() {
@Test
void crtCredentials_anonymousCredentialsProvider_shouldWork() {
- AwsCredentialsProvider awsCredentialsProvider = AnonymousCredentialsProvider.create();
+ IdentityProvider extends AwsCredentialsIdentity> awsCredentialsProvider = AnonymousCredentialsProvider.create();
CrtCredentialsProviderAdapter adapter = new CrtCredentialsProviderAdapter(awsCredentialsProvider);
CredentialsProvider crtCredentialsProvider = adapter.crtCredentials();
@@ -104,9 +105,5 @@ void crtCredentials_anonymousCredentialsProvider_shouldWork() {
assertThat(crtCredentials.getAccessKeyId()).isNull();
assertThat(crtCredentials.getSecretAccessKey()).isNull();
-
}
-
-
-
}
From c7fb92fece786f4356e28ccd447cdd8f35e4a5c8 Mon Sep 17 00:00:00 2001
From: Jaykumar Gosar
Date: Fri, 31 Mar 2023 16:35:14 -0700
Subject: [PATCH 13/13] Address PR feedback
---
.../AwsCredentialsProviderChain.java | 1 -
.../auth/credentials/CredentialUtils.java | 4 +++
.../auth/credentials/CredentialUtilsTest.java | 28 ++++++++++++++++++-
.../client/config/AwsClientOption.java | 2 +-
.../internal/crt/DefaultS3CrtAsyncClient.java | 28 +++++++++++++++++++
5 files changed, 60 insertions(+), 3 deletions(-)
diff --git a/core/auth/src/main/java/software/amazon/awssdk/auth/credentials/AwsCredentialsProviderChain.java b/core/auth/src/main/java/software/amazon/awssdk/auth/credentials/AwsCredentialsProviderChain.java
index 8a46cfc306e7..3dd4a4ae4011 100644
--- a/core/auth/src/main/java/software/amazon/awssdk/auth/credentials/AwsCredentialsProviderChain.java
+++ b/core/auth/src/main/java/software/amazon/awssdk/auth/credentials/AwsCredentialsProviderChain.java
@@ -45,7 +45,6 @@
* This chain implements {@link AutoCloseable}. When closed, it will call the {@link AutoCloseable#close()} on any credential
* providers in the chain that need to be closed.
*/
-// TODO: deprecate with new IdentityProvider chain in identity-spi
@SdkPublicApi
public final class AwsCredentialsProviderChain
implements AwsCredentialsProvider,
diff --git a/core/auth/src/main/java/software/amazon/awssdk/auth/credentials/CredentialUtils.java b/core/auth/src/main/java/software/amazon/awssdk/auth/credentials/CredentialUtils.java
index 2b855d145b3d..7eabc4ad18d8 100644
--- a/core/auth/src/main/java/software/amazon/awssdk/auth/credentials/CredentialUtils.java
+++ b/core/auth/src/main/java/software/amazon/awssdk/auth/credentials/CredentialUtils.java
@@ -63,6 +63,10 @@ public static AwsCredentials toCredentials(AwsCredentialsIdentity awsCredentials
if (awsCredentialsIdentity == null) {
return null;
}
+ if (awsCredentialsIdentity instanceof AwsCredentials) {
+ return (AwsCredentials) awsCredentialsIdentity;
+ }
+
// identity-spi defines 2 known types - AwsCredentialsIdentity and a sub-type AwsSessionCredentialsIdentity
if (awsCredentialsIdentity instanceof AwsSessionCredentialsIdentity) {
AwsSessionCredentialsIdentity awsSessionCredentialsIdentity = (AwsSessionCredentialsIdentity) awsCredentialsIdentity;
diff --git a/core/auth/src/test/java/software/amazon/awssdk/auth/credentials/CredentialUtilsTest.java b/core/auth/src/test/java/software/amazon/awssdk/auth/credentials/CredentialUtilsTest.java
index 10eb7855e6bc..bfd6e9e5c90a 100644
--- a/core/auth/src/test/java/software/amazon/awssdk/auth/credentials/CredentialUtilsTest.java
+++ b/core/auth/src/test/java/software/amazon/awssdk/auth/credentials/CredentialUtilsTest.java
@@ -48,6 +48,14 @@ public void toCredentials_null_returnsNull() {
assertThat(CredentialUtils.toCredentials(null)).isNull();
}
+
+ @Test
+ public void toCredentials_AwsSessionCredentials_doesNotCreateNewObject() {
+ AwsSessionCredentialsIdentity input = AwsSessionCredentials.create("ak", "sk", "session");
+ AwsCredentials output = CredentialUtils.toCredentials(input);
+ assertThat(output).isSameAs(input);
+ }
+
@Test
public void toCredentials_AwsSessionCredentialsIdentity_returnsAwsSessionCredentials() {
AwsCredentials awsCredentials = CredentialUtils.toCredentials(new AwsSessionCredentialsIdentity() {
@@ -74,6 +82,13 @@ public String sessionToken() {
assertThat(awsSessionCredentials.sessionToken()).isEqualTo("session");
}
+ @Test
+ public void toCredentials_AwsCredentials_doesNotCreateNewObject() {
+ AwsCredentialsIdentity input = AwsBasicCredentials.create("ak", "sk");
+ AwsCredentials output = CredentialUtils.toCredentials(input);
+ assertThat(output).isSameAs(input);
+ }
+
@Test
public void toCredentials_AwsCredentialsIdentity_returnsAwsCredentials() {
AwsCredentials awsCredentials = CredentialUtils.toCredentials(new AwsCredentialsIdentity() {
@@ -94,7 +109,18 @@ public String secretAccessKey() {
@Test
public void toCredentials_Anonymous_returnsAnonymous() {
- AwsCredentials awsCredentials = CredentialUtils.toCredentials(AwsBasicCredentials.ANONYMOUS_CREDENTIALS);
+ AwsCredentials awsCredentials = CredentialUtils.toCredentials(new AwsCredentialsIdentity() {
+ @Override
+ public String accessKeyId() {
+ return null;
+ }
+
+ @Override
+ public String secretAccessKey() {
+ return null;
+ }
+ });
+
assertThat(awsCredentials.accessKeyId()).isNull();
assertThat(awsCredentials.secretAccessKey()).isNull();
}
diff --git a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/config/AwsClientOption.java b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/config/AwsClientOption.java
index aefab749f178..44280cb5615f 100644
--- a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/config/AwsClientOption.java
+++ b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/config/AwsClientOption.java
@@ -28,7 +28,7 @@
@SdkProtectedApi
public final class AwsClientOption extends ClientOption {
/**
- // * This option is deprecated in favor of {@link #CREDENTIALS_IDENTITY_PROVIDER}.
+ * This option is deprecated in favor of {@link #CREDENTIALS_IDENTITY_PROVIDER}.
* @see AwsClientBuilder#credentialsProvider(AwsCredentialsProvider)
*/
@Deprecated
diff --git a/services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/crt/DefaultS3CrtAsyncClient.java b/services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/crt/DefaultS3CrtAsyncClient.java
index b8506e7ac03f..7ac41d4005fd 100644
--- a/services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/crt/DefaultS3CrtAsyncClient.java
+++ b/services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/crt/DefaultS3CrtAsyncClient.java
@@ -119,6 +119,34 @@ public static final class DefaultS3CrtClientBuilder implements S3CrtAsyncClientB
private URI endpointOverride;
private Boolean checksumValidationEnabled;
+ public IdentityProvider extends AwsCredentialsIdentity> credentialsProvider() {
+ return credentialsProvider;
+ }
+
+ public Region region() {
+ return region;
+ }
+
+ public Long minimumPartSizeInBytes() {
+ return minimalPartSizeInBytes;
+ }
+
+ public Double targetThroughputInGbps() {
+ return targetThroughputInGbps;
+ }
+
+ public Integer maxConcurrency() {
+ return maxConcurrency;
+ }
+
+ public URI endpointOverride() {
+ return endpointOverride;
+ }
+
+ public Long readBufferSizeInBytes() {
+ return readBufferSizeInBytes;
+ }
+
@Override
public S3CrtAsyncClientBuilder credentialsProvider(
IdentityProvider extends AwsCredentialsIdentity> credentialsProvider) {