Skip to content

Commit 19720d9

Browse files
authored
Add Business Metrics for Credential Providers (#6443)
* Feature ID implementation for S3 Express Bucket (#6409) * Feature ID implementation for S3 Express Bucket * Address PR feedback * Fixing checkstyles * Feature IDs implementation for credentials (#6415) * Feature IDs implementation for credentials * Fixing test failure * Adding unit tests * Add business metrics support for STS, SSO and Profile credential providers (#6426) * Feature IDs implementation for STS credentials * Add business metric for SSO Creds * Address PR feedback * Adding missed test files * Additional changes * Fixing checkstyle * Address PR feedback * Additional Changes: Address PR feedback Adding Unit tests Apply PR feedback to previous PR * Fixing sonarqube issues and test failures * Adding region dependency in auth-tests * Delete .changes/next-release/feature-AWSSDKforJavav2-aa60cd3.json Removing one feature specific changelog * Renaming source to sourceFeatureId and modifying java docs * Removing S3 Express featureID * Removing import
1 parent 1295ae2 commit 19720d9

File tree

50 files changed

+1820
-126
lines changed

Some content is hidden

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

50 files changed

+1820
-126
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"type": "feature",
3+
"category": "AWS SDK for Java v2",
4+
"contributor": "",
5+
"description": "Adds business metrics tracking for credential providers and S3_Express_Bucket."
6+
}

core/auth/src/main/java/software/amazon/awssdk/auth/credentials/ChildProfileCredentialsProviderFactory.java

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,45 @@ public interface ChildProfileCredentialsProviderFactory {
4040
* provider.
4141
* @return The credentials provider with permissions derived from the source credentials provider and profile.
4242
*/
43-
AwsCredentialsProvider create(AwsCredentialsProvider sourceCredentialsProvider, Profile profile);
43+
default AwsCredentialsProvider create(AwsCredentialsProvider sourceCredentialsProvider, Profile profile) {
44+
ChildProfileCredentialsRequest request = new ChildProfileCredentialsRequest(sourceCredentialsProvider, profile, null);
45+
return create(request);
46+
}
47+
48+
/**
49+
* Create a credentials provider for the provided profile, using the provided source credentials provider to authenticate
50+
* with AWS. In the case of STS, the returned credentials provider is for a role that has been assumed, and the provided
51+
* source credentials provider is the credentials that should be used to authenticate that the user is allowed to assume
52+
* that role.
53+
*
54+
* @param request The request containing all parameters needed to create the child credentials provider.
55+
* @return The credentials provider with permissions derived from the request parameters.
56+
*/
57+
AwsCredentialsProvider create(ChildProfileCredentialsRequest request);
58+
59+
final class ChildProfileCredentialsRequest {
60+
private final AwsCredentialsProvider sourceCredentialsProvider;
61+
private final Profile profile;
62+
private final String sourceFeatureId;
63+
64+
public ChildProfileCredentialsRequest(AwsCredentialsProvider sourceCredentialsProvider,
65+
Profile profile,
66+
String sourceFeatureId) {
67+
this.sourceCredentialsProvider = sourceCredentialsProvider;
68+
this.profile = profile;
69+
this.sourceFeatureId = sourceFeatureId;
70+
}
71+
72+
public AwsCredentialsProvider sourceCredentialsProvider() {
73+
return sourceCredentialsProvider;
74+
}
75+
76+
public Profile profile() {
77+
return profile;
78+
}
79+
80+
public String sourceFeatureId() {
81+
return sourceFeatureId;
82+
}
83+
}
4484
}

core/auth/src/main/java/software/amazon/awssdk/auth/credentials/ContainerCredentialsProvider.java

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import software.amazon.awssdk.auth.credentials.internal.HttpCredentialsLoader.LoadedCredentials;
4040
import software.amazon.awssdk.core.SdkSystemSetting;
4141
import software.amazon.awssdk.core.exception.SdkClientException;
42+
import software.amazon.awssdk.core.useragent.BusinessMetricFeatureId;
4243
import software.amazon.awssdk.core.util.SdkUserAgent;
4344
import software.amazon.awssdk.regions.util.ResourcesEndpointProvider;
4445
import software.amazon.awssdk.regions.util.ResourcesEndpointRetryPolicy;
@@ -72,7 +73,8 @@
7273
public final class ContainerCredentialsProvider
7374
implements HttpCredentialsProvider,
7475
ToCopyableBuilder<ContainerCredentialsProvider.Builder, ContainerCredentialsProvider> {
75-
private static final String PROVIDER_NAME = "ContainerCredentialsProvider";
76+
private static final String CLASS_NAME = "ContainerCredentialsProvider";
77+
private static final String PROVIDER_NAME = BusinessMetricFeatureId.CREDENTIALS_HTTP.value();
7678
private static final Predicate<InetAddress> IS_LOOPBACK_ADDRESS = InetAddress::isLoopbackAddress;
7779
private static final Predicate<InetAddress> ALLOWED_HOSTS_RULES = IS_LOOPBACK_ADDRESS;
7880
private static final String HTTPS = "https";
@@ -90,6 +92,8 @@ public final class ContainerCredentialsProvider
9092
private final Boolean asyncCredentialUpdateEnabled;
9193

9294
private final String asyncThreadName;
95+
private final String sourceFeatureId;
96+
private final String providerName;
9397

9498
/**
9599
* @see #builder()
@@ -98,7 +102,11 @@ private ContainerCredentialsProvider(BuilderImpl builder) {
98102
this.endpoint = builder.endpoint;
99103
this.asyncCredentialUpdateEnabled = builder.asyncCredentialUpdateEnabled;
100104
this.asyncThreadName = builder.asyncThreadName;
101-
this.httpCredentialsLoader = HttpCredentialsLoader.create(PROVIDER_NAME);
105+
this.sourceFeatureId = builder.sourceFeatureId;
106+
this.providerName = StringUtils.isEmpty(builder.sourceFeatureId)
107+
? PROVIDER_NAME
108+
: builder.sourceFeatureId + "," + PROVIDER_NAME;
109+
this.httpCredentialsLoader = HttpCredentialsLoader.create(providerName());
102110

103111
if (Boolean.TRUE.equals(builder.asyncCredentialUpdateEnabled)) {
104112
Validate.paramNotBlank(builder.asyncThreadName, "asyncThreadName");
@@ -126,7 +134,7 @@ public static Builder builder() {
126134

127135
@Override
128136
public String toString() {
129-
return ToString.create(PROVIDER_NAME);
137+
return ToString.create(CLASS_NAME);
130138
}
131139

132140
private RefreshResult<AwsCredentials> refreshCredentials() {
@@ -160,6 +168,10 @@ private Instant prefetchTime(Instant expiration) {
160168
return ComparableUtils.minimum(oneHourFromNow, fifteenMinutesBeforeExpiration);
161169
}
162170

171+
private String providerName() {
172+
return this.providerName;
173+
}
174+
163175
@Override
164176
public AwsCredentials resolveCredentials() {
165177
return credentialsCache.get();
@@ -318,6 +330,7 @@ private static final class BuilderImpl implements Builder {
318330
private String endpoint;
319331
private Boolean asyncCredentialUpdateEnabled;
320332
private String asyncThreadName;
333+
private String sourceFeatureId;
321334

322335
private BuilderImpl() {
323336
asyncThreadName("container-credentials-provider");
@@ -327,6 +340,7 @@ private BuilderImpl(ContainerCredentialsProvider credentialsProvider) {
327340
this.endpoint = credentialsProvider.endpoint;
328341
this.asyncCredentialUpdateEnabled = credentialsProvider.asyncCredentialUpdateEnabled;
329342
this.asyncThreadName = credentialsProvider.asyncThreadName;
343+
this.sourceFeatureId = credentialsProvider.sourceFeatureId;
330344
}
331345

332346
@Override
@@ -359,6 +373,16 @@ public void setAsyncThreadName(String asyncThreadName) {
359373
asyncThreadName(asyncThreadName);
360374
}
361375

376+
@Override
377+
public Builder sourceFeatureId(String sourceFeatureId) {
378+
this.sourceFeatureId = sourceFeatureId;
379+
return this;
380+
}
381+
382+
public void setSourceFeatureId(String sourceFeatureId) {
383+
sourceFeatureId(sourceFeatureId);
384+
}
385+
362386
@Override
363387
public ContainerCredentialsProvider build() {
364388
return new ContainerCredentialsProvider(this);

core/auth/src/main/java/software/amazon/awssdk/auth/credentials/EnvironmentVariableCredentialsProvider.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import java.util.Optional;
1919
import software.amazon.awssdk.annotations.SdkPublicApi;
2020
import software.amazon.awssdk.auth.credentials.internal.SystemSettingsCredentialsProvider;
21+
import software.amazon.awssdk.core.useragent.BusinessMetricFeatureId;
2122
import software.amazon.awssdk.utils.SystemSetting;
2223
import software.amazon.awssdk.utils.ToString;
2324

@@ -28,7 +29,8 @@
2829
@SdkPublicApi
2930
public final class EnvironmentVariableCredentialsProvider extends SystemSettingsCredentialsProvider {
3031

31-
private static final String PROVIDER_NAME = "EnvironmentVariableCredentialsProvider";
32+
private static final String CLASS_NAME = "EnvironmentVariableCredentialsProvider";
33+
private static final String PROVIDER_NAME = BusinessMetricFeatureId.CREDENTIALS_ENV_VARS.value();
3234

3335
private EnvironmentVariableCredentialsProvider() {
3436
}
@@ -52,6 +54,6 @@ protected String provider() {
5254

5355
@Override
5456
public String toString() {
55-
return ToString.create(PROVIDER_NAME);
57+
return ToString.create(CLASS_NAME);
5658
}
5759
}

core/auth/src/main/java/software/amazon/awssdk/auth/credentials/HttpCredentialsProvider.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package software.amazon.awssdk.auth.credentials;
1717

1818
import software.amazon.awssdk.annotations.SdkPublicApi;
19+
import software.amazon.awssdk.core.useragent.BusinessMetricFeatureId;
1920
import software.amazon.awssdk.utils.SdkAutoCloseable;
2021

2122
/**
@@ -48,6 +49,16 @@ interface Builder<TypeToBuildT extends HttpCredentialsProvider, BuilderT extends
4849
*/
4950
BuilderT endpoint(String endpoint);
5051

52+
/**
53+
* An optional string list of {@link BusinessMetricFeatureId} denoting previous credentials providers
54+
* that are chained with this one.
55+
* <p><b>Note:</b> This method is primarily intended for use by AWS SDK internal components
56+
* and should not be used directly by external users.</p>
57+
*/
58+
default BuilderT sourceFeatureId(String sourceFeatureId) {
59+
throw new UnsupportedOperationException();
60+
}
61+
5162
/**
5263
* Build the credentials provider based on the configuration on this builder.
5364
*/

core/auth/src/main/java/software/amazon/awssdk/auth/credentials/InstanceProfileCredentialsProvider.java

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,15 @@
3737
import software.amazon.awssdk.core.SdkSystemSetting;
3838
import software.amazon.awssdk.core.exception.SdkClientException;
3939
import software.amazon.awssdk.core.exception.SdkServiceException;
40+
import software.amazon.awssdk.core.useragent.BusinessMetricFeatureId;
4041
import software.amazon.awssdk.profiles.ProfileFile;
4142
import software.amazon.awssdk.profiles.ProfileFileSupplier;
4243
import software.amazon.awssdk.profiles.ProfileFileSystemSetting;
4344
import software.amazon.awssdk.profiles.ProfileProperty;
4445
import software.amazon.awssdk.regions.util.HttpResourcesUtils;
4546
import software.amazon.awssdk.regions.util.ResourcesEndpointProvider;
4647
import software.amazon.awssdk.utils.Logger;
48+
import software.amazon.awssdk.utils.StringUtils;
4749
import software.amazon.awssdk.utils.ToString;
4850
import software.amazon.awssdk.utils.Validate;
4951
import software.amazon.awssdk.utils.builder.CopyableBuilder;
@@ -67,7 +69,8 @@ public final class InstanceProfileCredentialsProvider
6769
implements HttpCredentialsProvider,
6870
ToCopyableBuilder<InstanceProfileCredentialsProvider.Builder, InstanceProfileCredentialsProvider> {
6971
private static final Logger log = Logger.loggerFor(InstanceProfileCredentialsProvider.class);
70-
private static final String PROVIDER_NAME = "InstanceProfileCredentialsProvider";
72+
private static final String CLASS_NAME = "InstanceProfileCredentialsProvider";
73+
private static final String PROVIDER_NAME = BusinessMetricFeatureId.CREDENTIALS_IMDS.value();
7174
private static final String EC2_METADATA_TOKEN_HEADER = "x-aws-ec2-metadata-token";
7275
private static final String SECURITY_CREDENTIALS_RESOURCE = "/latest/meta-data/iam/security-credentials/";
7376
private static final String TOKEN_RESOURCE = "/latest/api/token";
@@ -90,6 +93,9 @@ public final class InstanceProfileCredentialsProvider
9093

9194
private final Duration staleTime;
9295

96+
private final String sourceFeatureId;
97+
private final String providerName;
98+
9399
/**
94100
* @see #builder()
95101
*/
@@ -102,8 +108,12 @@ private InstanceProfileCredentialsProvider(BuilderImpl builder) {
102108
.orElseGet(() -> ProfileFileSupplier.fixedProfileFile(ProfileFile.defaultProfileFile()));
103109
this.profileName = Optional.ofNullable(builder.profileName)
104110
.orElseGet(ProfileFileSystemSetting.AWS_PROFILE::getStringValueOrThrow);
111+
this.sourceFeatureId = builder.sourceFeatureId;
112+
this.providerName = StringUtils.isEmpty(builder.sourceFeatureId)
113+
? PROVIDER_NAME
114+
: builder.sourceFeatureId + "," + PROVIDER_NAME;
105115

106-
this.httpCredentialsLoader = HttpCredentialsLoader.create(PROVIDER_NAME);
116+
this.httpCredentialsLoader = HttpCredentialsLoader.create(providerName());
107117
this.configProvider =
108118
Ec2MetadataConfigProvider.builder()
109119
.profileFile(profileFile)
@@ -202,9 +212,13 @@ public void close() {
202212
credentialsCache.close();
203213
}
204214

215+
private String providerName() {
216+
return this.providerName;
217+
}
218+
205219
@Override
206220
public String toString() {
207-
return ToString.create(PROVIDER_NAME);
221+
return ToString.create(CLASS_NAME);
208222
}
209223

210224
private ResourcesEndpointProvider createEndpointProvider() {
@@ -372,6 +386,7 @@ static final class BuilderImpl implements Builder {
372386
private Supplier<ProfileFile> profileFile;
373387
private String profileName;
374388
private Duration staleTime;
389+
private String sourceFeatureId;
375390

376391
private BuilderImpl() {
377392
asyncThreadName("instance-profile-credentials-provider");
@@ -385,6 +400,7 @@ private BuilderImpl(InstanceProfileCredentialsProvider provider) {
385400
this.profileFile = provider.profileFile;
386401
this.profileName = provider.profileName;
387402
this.staleTime = provider.staleTime;
403+
this.sourceFeatureId = provider.sourceFeatureId;
388404
}
389405

390406
Builder clock(Clock clock) {
@@ -463,6 +479,16 @@ public void setStaleTime(Duration duration) {
463479
staleTime(duration);
464480
}
465481

482+
@Override
483+
public Builder sourceFeatureId(String sourceFeatureId) {
484+
this.sourceFeatureId = sourceFeatureId;
485+
return this;
486+
}
487+
488+
public void setSourceFeatureId(String sourceFeatureId) {
489+
sourceFeatureId(sourceFeatureId);
490+
}
491+
466492
@Override
467493
public InstanceProfileCredentialsProvider build() {
468494
return new InstanceProfileCredentialsProvider(this);

0 commit comments

Comments
 (0)