Skip to content

Commit 6d2a29f

Browse files
authored
"Add Business Metrics for Credential Providers" (#6457)
* Reapply "Add Business Metrics for Credential Providers (#6443)" This reverts commit e34c7b3. * Address PR feedback * Additional Chnages: - Address PR feedback Remaning sourceFeatureID to sourceChain * Address PR feedback * Use singleton list instead of splitting in ApplyUserAgentStage
1 parent 843e2b9 commit 6d2a29f

File tree

50 files changed

+1914
-159
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

+1914
-159
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."
6+
}

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

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525
* provider via the 'software.amazon.awssdk.services.sts.internal.StsProfileCredentialsProviderFactory', assuming STS is on the
2626
* classpath.
2727
*/
28-
@FunctionalInterface
2928
@SdkProtectedApi
29+
@FunctionalInterface
3030
public interface ChildProfileCredentialsProviderFactory {
3131
/**
3232
* Create a credentials provider for the provided profile, using the provided source credentials provider to authenticate
@@ -41,4 +41,70 @@ public interface ChildProfileCredentialsProviderFactory {
4141
* @return The credentials provider with permissions derived from the source credentials provider and profile.
4242
*/
4343
AwsCredentialsProvider create(AwsCredentialsProvider sourceCredentialsProvider, Profile profile);
44+
45+
/**
46+
* Create a credentials provider for the provided profile, using the provided source credentials provider to authenticate
47+
* with AWS. In the case of STS, the returned credentials provider is for a role that has been assumed, and the provided
48+
* source credentials provider is the credentials that should be used to authenticate that the user is allowed to assume
49+
* that role.
50+
*
51+
* @param request The request containing all parameters needed to create the child credentials provider.
52+
* @return The credentials provider with permissions derived from the request parameters.
53+
*/
54+
default AwsCredentialsProvider create(ChildProfileCredentialsRequest request) {
55+
return create(request.sourceCredentialsProvider(), request.profile());
56+
}
57+
58+
final class ChildProfileCredentialsRequest {
59+
private final AwsCredentialsProvider sourceCredentialsProvider;
60+
private final Profile profile;
61+
private final String sourceChain;
62+
63+
private ChildProfileCredentialsRequest(Builder builder) {
64+
this.sourceCredentialsProvider = builder.sourceCredentialsProvider;
65+
this.profile = builder.profile;
66+
this.sourceChain = builder.sourceChain;
67+
}
68+
69+
public static Builder builder() {
70+
return new Builder();
71+
}
72+
73+
public AwsCredentialsProvider sourceCredentialsProvider() {
74+
return sourceCredentialsProvider;
75+
}
76+
77+
public Profile profile() {
78+
return profile;
79+
}
80+
81+
public String sourceChain() {
82+
return sourceChain;
83+
}
84+
85+
public static final class Builder {
86+
private AwsCredentialsProvider sourceCredentialsProvider;
87+
private Profile profile;
88+
private String sourceChain;
89+
90+
public Builder sourceCredentialsProvider(AwsCredentialsProvider sourceCredentialsProvider) {
91+
this.sourceCredentialsProvider = sourceCredentialsProvider;
92+
return this;
93+
}
94+
95+
public Builder profile(Profile profile) {
96+
this.profile = profile;
97+
return this;
98+
}
99+
100+
public Builder sourceChain(String sourceChain) {
101+
this.sourceChain = sourceChain;
102+
return this;
103+
}
104+
105+
public ChildProfileCredentialsRequest build() {
106+
return new ChildProfileCredentialsRequest(this);
107+
}
108+
}
109+
}
44110
}

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

Lines changed: 28 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 sourceChain;
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.sourceChain = builder.sourceChain;
106+
this.providerName = StringUtils.isEmpty(builder.sourceChain)
107+
? PROVIDER_NAME
108+
: builder.sourceChain + "," + PROVIDER_NAME;
109+
this.httpCredentialsLoader = HttpCredentialsLoader.create(this.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() {
@@ -318,6 +326,7 @@ private static final class BuilderImpl implements Builder {
318326
private String endpoint;
319327
private Boolean asyncCredentialUpdateEnabled;
320328
private String asyncThreadName;
329+
private String sourceChain;
321330

322331
private BuilderImpl() {
323332
asyncThreadName("container-credentials-provider");
@@ -327,6 +336,7 @@ private BuilderImpl(ContainerCredentialsProvider credentialsProvider) {
327336
this.endpoint = credentialsProvider.endpoint;
328337
this.asyncCredentialUpdateEnabled = credentialsProvider.asyncCredentialUpdateEnabled;
329338
this.asyncThreadName = credentialsProvider.asyncThreadName;
339+
this.sourceChain = credentialsProvider.sourceChain;
330340
}
331341

332342
@Override
@@ -359,6 +369,21 @@ public void setAsyncThreadName(String asyncThreadName) {
359369
asyncThreadName(asyncThreadName);
360370
}
361371

372+
/**
373+
* An optional string denoting previous credentials providers that are chained with this one.
374+
* <p><b>Note:</b> This method is primarily intended for use by AWS SDK internal components
375+
* and should not be used directly by external users.</p>
376+
*/
377+
@Override
378+
public Builder sourceChain(String sourceChain) {
379+
this.sourceChain = sourceChain;
380+
return this;
381+
}
382+
383+
public void setSourceChain(String sourceChain) {
384+
sourceChain(sourceChain);
385+
}
386+
362387
@Override
363388
public ContainerCredentialsProvider build() {
364389
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: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,15 @@ interface Builder<TypeToBuildT extends HttpCredentialsProvider, BuilderT extends
4848
*/
4949
BuilderT endpoint(String endpoint);
5050

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

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

Lines changed: 30 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 sourceChain;
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.sourceChain = builder.sourceChain;
112+
this.providerName = StringUtils.isEmpty(builder.sourceChain)
113+
? PROVIDER_NAME
114+
: builder.sourceChain + "," + PROVIDER_NAME;
105115

106-
this.httpCredentialsLoader = HttpCredentialsLoader.create(PROVIDER_NAME);
116+
this.httpCredentialsLoader = HttpCredentialsLoader.create(this.providerName);
107117
this.configProvider =
108118
Ec2MetadataConfigProvider.builder()
109119
.profileFile(profileFile)
@@ -204,7 +214,7 @@ public void close() {
204214

205215
@Override
206216
public String toString() {
207-
return ToString.create(PROVIDER_NAME);
217+
return ToString.create(CLASS_NAME);
208218
}
209219

210220
private ResourcesEndpointProvider createEndpointProvider() {
@@ -372,6 +382,7 @@ static final class BuilderImpl implements Builder {
372382
private Supplier<ProfileFile> profileFile;
373383
private String profileName;
374384
private Duration staleTime;
385+
private String sourceChain;
375386

376387
private BuilderImpl() {
377388
asyncThreadName("instance-profile-credentials-provider");
@@ -385,6 +396,7 @@ private BuilderImpl(InstanceProfileCredentialsProvider provider) {
385396
this.profileFile = provider.profileFile;
386397
this.profileName = provider.profileName;
387398
this.staleTime = provider.staleTime;
399+
this.sourceChain = provider.sourceChain;
388400
}
389401

390402
Builder clock(Clock clock) {
@@ -463,6 +475,21 @@ public void setStaleTime(Duration duration) {
463475
staleTime(duration);
464476
}
465477

478+
/**
479+
* An optional string denoting previous credentials providers that are chained with this one.
480+
* <p><b>Note:</b> This method is primarily intended for use by AWS SDK internal components
481+
* and should not be used directly by external users.</p>
482+
*/
483+
@Override
484+
public Builder sourceChain(String sourceChain) {
485+
this.sourceChain = sourceChain;
486+
return this;
487+
}
488+
489+
public void setSourceChain(String sourceChain) {
490+
sourceChain(sourceChain);
491+
}
492+
466493
@Override
467494
public InstanceProfileCredentialsProvider build() {
468495
return new InstanceProfileCredentialsProvider(this);

0 commit comments

Comments
 (0)