Skip to content

Commit a2db6cf

Browse files
committed
add user agent business metric for account id endpoints
1 parent 66499f1 commit a2db6cf

File tree

14 files changed

+217
-124
lines changed

14 files changed

+217
-124
lines changed

generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClientConfiguration.h

+2-18
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,13 @@ namespace Aws
2121

2222
DynamoDBClientConfiguration(const DynamoDBClientConfiguration& other)
2323
: Aws::Client::GenericClientConfiguration(other),
24-
enableEndpointDiscovery(BaseClientConfigClass::enableEndpointDiscovery),
25-
accountId{other.accountId},
26-
accountIdEndpointMode{other.accountIdEndpointMode}
24+
enableEndpointDiscovery(BaseClientConfigClass::enableEndpointDiscovery)
2725
{
2826
}
2927

3028
DynamoDBClientConfiguration(DynamoDBClientConfiguration&& other) noexcept
3129
: Aws::Client::GenericClientConfiguration(std::move(other)),
32-
enableEndpointDiscovery(BaseClientConfigClass::enableEndpointDiscovery),
33-
accountId{std::move(other.accountId)},
34-
accountIdEndpointMode{std::move(other.accountIdEndpointMode)}
30+
enableEndpointDiscovery(BaseClientConfigClass::enableEndpointDiscovery)
3531
{
3632
}
3733

@@ -40,8 +36,6 @@ namespace Aws
4036
if (this == &other)
4137
return *this;
4238
Aws::Client::GenericClientConfiguration::operator =(other);
43-
accountId = other.accountId;
44-
accountIdEndpointMode = other.accountIdEndpointMode;
4539
return *this;
4640
}
4741

@@ -50,8 +44,6 @@ namespace Aws
5044
if (this == &other)
5145
return *this;
5246
Aws::Client::GenericClientConfiguration::operator =(std::move(other));
53-
accountId = std::move(other.accountId);
54-
accountIdEndpointMode = std::move(other.accountIdEndpointMode);
5547
return *this;
5648
}
5749

@@ -90,14 +82,6 @@ namespace Aws
9082
*/
9183
Aws::Crt::Optional<bool>& enableEndpointDiscovery;
9284

93-
/**
94-
* The AWS AccountId used for the request.
95-
*/
96-
Aws::String accountId;
97-
/**
98-
* The AccountId Endpoint Mode.
99-
*/
100-
Aws::String accountIdEndpointMode = "preferred";
10185
private:
10286
void LoadDynamoDBSpecificConfig(const Aws::String& profileName);
10387
};

generated/src/aws-cpp-sdk-dynamodb/source/DynamoDBClientConfiguration.cpp

-9
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,6 @@ void DynamoDBClientConfiguration::LoadDynamoDBSpecificConfig(const Aws::String&
4545
if(!enableEndpointDiscovery) {
4646
enableEndpointDiscovery = IsEndpointDiscoveryEnabled(this->endpointOverride, inputProfileName);
4747
}
48-
// accountId is intentionally not set here: AWS_ACCOUNT_ID env variable may not match the provided credentials.
49-
// it must be set by an auth provider / identity resolver or by an SDK user.
50-
static const char AWS_ACCOUNT_ID_ENDPOINT_MODE_ENVIRONMENT_VARIABLE[] = "AWS_ACCOUNT_ID_ENDPOINT_MODE";
51-
static const char AWS_ACCOUNT_ID_ENDPOINT_MODE_CONFIG_FILE_OPTION[] = "account_id_endpoint_mode";
52-
accountIdEndpointMode = ClientConfiguration::LoadConfigFromEnvOrProfile(AWS_ACCOUNT_ID_ENDPOINT_MODE_ENVIRONMENT_VARIABLE,
53-
inputProfileName,
54-
AWS_ACCOUNT_ID_ENDPOINT_MODE_CONFIG_FILE_OPTION,
55-
{"required", "disabled", "preferred"}, /* allowed values */
56-
"preferred" /* default value */);
5748
}
5849

5950
DynamoDBClientConfiguration::DynamoDBClientConfiguration(const Client::ClientConfigurationInitValues &configuration)

generated/src/aws-cpp-sdk-s3control/include/aws/s3control/S3ControlClientConfiguration.h

-34
Original file line numberDiff line numberDiff line change
@@ -18,36 +18,6 @@ namespace Aws
1818
{
1919
using BaseClientConfigClass = Aws::Client::GenericClientConfiguration;
2020

21-
S3ControlClientConfiguration(const S3ControlClientConfiguration& other)
22-
: Aws::Client::GenericClientConfiguration(other),
23-
accountId{other.accountId}
24-
{
25-
}
26-
27-
S3ControlClientConfiguration(S3ControlClientConfiguration&& other) noexcept
28-
: Aws::Client::GenericClientConfiguration(std::move(other)),
29-
accountId{std::move(other.accountId)}
30-
{
31-
}
32-
33-
S3ControlClientConfiguration& operator=(const S3ControlClientConfiguration& other)
34-
{
35-
if (this == &other)
36-
return *this;
37-
Aws::Client::GenericClientConfiguration::operator =(other);
38-
accountId = other.accountId;
39-
return *this;
40-
}
41-
42-
S3ControlClientConfiguration& operator=(S3ControlClientConfiguration&& other) noexcept
43-
{
44-
if (this == &other)
45-
return *this;
46-
Aws::Client::GenericClientConfiguration::operator =(std::move(other));
47-
accountId = std::move(other.accountId);
48-
return *this;
49-
}
50-
5121
S3ControlClientConfiguration(const Client::ClientConfigurationInitValues &configuration = {});
5222

5323
/**
@@ -72,10 +42,6 @@ namespace Aws
7242
S3ControlClientConfiguration(const Client::ClientConfiguration& config);
7343
bool useArnRegion = false;
7444
Client::AWSAuthV4Signer::PayloadSigningPolicy payloadSigningPolicy = Client::AWSAuthV4Signer::PayloadSigningPolicy::RequestDependent;
75-
/**
76-
* The Account ID used to send the request. This is an optional parameter that will be set automatically for operations that require it.
77-
*/
78-
Aws::String accountId;
7945
private:
8046
void LoadS3ControlSpecificConfig(const Aws::String& profileName);
8147
};

generated/src/aws-cpp-sdk-s3control/source/S3ControlClientConfiguration.cpp

-2
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ void S3ControlClientConfiguration::LoadS3ControlSpecificConfig(const Aws::String
2424
{
2525
useArnRegion = true;
2626
}
27-
// accountId is intentionally not set here: AWS_ACCOUNT_ID env variable may not match the provided credentials.
28-
// it must be set by an auth provider / identity resolver or by an SDK user.
2927
}
3028

3129
S3ControlClientConfiguration::S3ControlClientConfiguration(const Client::ClientConfigurationInitValues &configuration)

src/aws-cpp-sdk-core/include/aws/core/client/ClientConfiguration.h

+10
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,16 @@ namespace Aws
465465
*/
466466
bool useAnonymousAuth = false;
467467
} winHTTPOptions;
468+
469+
/**
470+
* The AWS AccountId used for the request.
471+
*/
472+
Aws::String accountId;
473+
474+
/**
475+
* The AccountId Endpoint Mode.
476+
*/
477+
Aws::String accountIdEndpointMode = "preferred";
468478
};
469479

470480
/**

src/aws-cpp-sdk-core/include/aws/core/client/UserAgent.h

+4
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ enum class UserAgentFeature {
2626
FLEXIBLE_CHECKSUMS_REQ_WHEN_REQUIRED,
2727
FLEXIBLE_CHECKSUMS_RES_WHEN_SUPPORTED,
2828
FLEXIBLE_CHECKSUMS_RES_WHEN_REQUIRED,
29+
ACCOUNT_ID_MODE_PREFERRED,
30+
ACCOUNT_ID_MODE_DISABLED,
31+
ACCOUNT_ID_MODE_REQUIRED,
32+
RESOLVED_ACCOUNT_ID,
2933
};
3034

3135
class AWS_CORE_API UserAgent {

src/aws-cpp-sdk-core/include/smithy/client/AwsSmithyClient.h

+7-19
Original file line numberDiff line numberDiff line change
@@ -346,32 +346,20 @@ namespace client
346346
ResponseT,
347347
ErrorMarshallerT>>;
348348

349-
/**
350-
* SFINAE implementation for refreshing client context params enabled if the client configuration
351-
* type has a AccountId member. If there is a corresponding member we want to use that in the endpoint
352-
* calculation and set it as a client context parameter.
353-
*/
354-
template <typename T, typename = void>
355-
struct HasAccountId : std::false_type {};
356-
357-
template<typename T>
358-
struct HasAccountId<T, decltype(void(std::declval<T>().accountId))> : std::true_type {};
359-
360-
template<typename ConfigT = ServiceClientConfigurationT, typename std::enable_if<HasAccountId<ConfigT>::value, int>::type = 0>
361349
GetContextEndpointParametersOutcome GetContextEndpointParametersImpl(const AwsSmithyClientAsyncRequestContext& ctx) const {
362350
Aws::Vector<Aws::Endpoint::EndpointParameter> endpointParameters;
363351
const auto resolvedAccountId = ctx.m_awsIdentity->accountId();
364-
if (resolvedAccountId.has_value() && !resolvedAccountId.value().empty() && m_clientConfiguration.accountId.empty()) {
352+
const auto resolvedNonEmptyAccountId = resolvedAccountId.has_value() && !resolvedAccountId.value().empty();
353+
// Set user agent if account ID was resolved in identity provider
354+
if (resolvedNonEmptyAccountId) {
355+
ctx.m_pRequest->AddUserAgentFeature(Aws::Client::UserAgentFeature::RESOLVED_ACCOUNT_ID);
356+
}
357+
// Only set EP param if client configuration does not have a configured account ID and we resolved a account id
358+
if (resolvedNonEmptyAccountId && m_clientConfiguration.accountId.empty()) {
365359
endpointParameters.emplace_back("AccountId", resolvedAccountId.value(), Aws::Endpoint::EndpointParameter::ParameterOrigin::OPERATION_CONTEXT);
366360
}
367361
return endpointParameters;
368362
}
369-
370-
template<typename ConfigT = ServiceClientConfigurationT, typename std::enable_if<!HasAccountId<ConfigT>::value, int>::type = 0>
371-
GetContextEndpointParametersOutcome GetContextEndpointParametersImpl(const AwsSmithyClientAsyncRequestContext& ctx) const {
372-
AWS_UNREFERENCED_PARAM(ctx);
373-
return Aws::Vector<Aws::Endpoint::EndpointParameter>{};
374-
}
375363
};
376364

377365
} // namespace client

src/aws-cpp-sdk-core/source/client/ClientConfiguration.cpp

+14-4
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ static const char* REQUEST_MIN_COMPRESSION_SIZE_BYTES_CONFIG_VAR = "request_min_
3939
static const char* AWS_EXECUTION_ENV = "AWS_EXECUTION_ENV";
4040
static const char* DISABLE_IMDSV1_CONFIG_VAR = "AWS_EC2_METADATA_V1_DISABLED";
4141
static const char* DISABLE_IMDSV1_ENV_VAR = "ec2_metadata_v1_disabled";
42+
static const char* AWS_ACCOUNT_ID_ENDPOINT_MODE_ENVIRONMENT_VARIABLE = "AWS_ACCOUNT_ID_ENDPOINT_MODE";
43+
static const char* AWS_ACCOUNT_ID_ENDPOINT_MODE_CONFIG_FILE_OPTION = "account_id_endpoint_mode";
4244

4345
using RequestChecksumConfigurationEnumMapping = std::pair<const char*, RequestChecksumCalculation>;
4446
static const std::array<RequestChecksumConfigurationEnumMapping, 2> REQUEST_CHECKSUM_CONFIG_MAPPING = {{
@@ -278,12 +280,21 @@ void setConfigFromEnvOrProfile(ClientConfiguration &config)
278280
if (disableIMDSv1 == "true") {
279281
config.disableImdsV1 = true;
280282
}
283+
284+
// accountId is intentionally not set here: AWS_ACCOUNT_ID env variable may not match the provided credentials.
285+
// it must be set by an auth provider / identity resolver or by an SDK user.
286+
config.accountIdEndpointMode = ClientConfiguration::LoadConfigFromEnvOrProfile(AWS_ACCOUNT_ID_ENDPOINT_MODE_ENVIRONMENT_VARIABLE,
287+
config.profileName,
288+
AWS_ACCOUNT_ID_ENDPOINT_MODE_CONFIG_FILE_OPTION,
289+
{"required", "disabled", "preferred"}, /* allowed values */
290+
"preferred" /* default value */);
281291
}
282292

283293
ClientConfiguration::ClientConfiguration()
284294
{
285295
this->disableIMDS = false;
286296
setLegacyClientConfigurationParameters(*this);
297+
setConfigFromEnvOrProfile(*this);;
287298

288299
if (!this->disableIMDS &&
289300
region.empty() &&
@@ -300,13 +311,13 @@ ClientConfiguration::ClientConfiguration()
300311
return;
301312
}
302313
region = Aws::String(Aws::Region::US_EAST_1);
303-
setConfigFromEnvOrProfile(*this);
304314
}
305315

306316
ClientConfiguration::ClientConfiguration(const ClientConfigurationInitValues &configuration)
307317
{
308318
this->disableIMDS = configuration.shouldDisableIMDS;
309319
setLegacyClientConfigurationParameters(*this);
320+
setConfigFromEnvOrProfile(*this);
310321

311322
if (!this->disableIMDS &&
312323
region.empty() &&
@@ -323,7 +334,6 @@ ClientConfiguration::ClientConfiguration(const ClientConfigurationInitValues &co
323334
return;
324335
}
325336
region = Aws::String(Aws::Region::US_EAST_1);
326-
setConfigFromEnvOrProfile(*this);
327337
}
328338

329339
ClientConfiguration::ClientConfiguration(const char* profile, bool shouldDisableIMDS)
@@ -333,6 +343,7 @@ ClientConfiguration::ClientConfiguration(const char* profile, bool shouldDisable
333343
this->profileName = Aws::String(profile);
334344
}
335345
setLegacyClientConfigurationParameters(*this);
346+
setConfigFromEnvOrProfile(*this);
336347
// Call EC2 Instance Metadata service only once
337348
Aws::String ec2MetadataRegion;
338349
bool hasEc2MetadataRegion = false;
@@ -368,13 +379,13 @@ ClientConfiguration::ClientConfiguration(const char* profile, bool shouldDisable
368379
}
369380

370381
AWS_LOGSTREAM_WARN(CLIENT_CONFIG_TAG, "User specified profile: [" << profile << "] is not found, will use the SDK resolved one.");
371-
setConfigFromEnvOrProfile(*this);
372382
}
373383

374384
ClientConfiguration::ClientConfiguration(bool /*useSmartDefaults*/, const char* defaultMode, bool shouldDisableIMDS)
375385
{
376386
this->disableIMDS = shouldDisableIMDS;
377387
setLegacyClientConfigurationParameters(*this);
388+
setConfigFromEnvOrProfile(*this);
378389

379390
// Call EC2 Instance Metadata service only once
380391
Aws::String ec2MetadataRegion;
@@ -397,7 +408,6 @@ ClientConfiguration::ClientConfiguration(bool /*useSmartDefaults*/, const char*
397408
}
398409

399410
Aws::Config::Defaults::SetSmartDefaultsConfigurationParameters(*this, defaultMode, hasEc2MetadataRegion, ec2MetadataRegion);
400-
setConfigFromEnvOrProfile(*this);
401411
}
402412

403413
std::shared_ptr<RetryStrategy> InitRetryStrategy(Aws::String retryMode)

src/aws-cpp-sdk-core/source/client/UserAgent.cpp

+27-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
#include <aws/core/utils/logging/LogMacros.h>
1010
#include <aws/core/utils/memory/stl/AWSStringStream.h>
1111
#include <aws/crt/Config.h>
12+
#include <aws/crt/Optional.h>
1213

14+
#include <iterator>
1315
#include <numeric>
1416
#include <utility>
1517

@@ -33,7 +35,11 @@ const std::pair<UserAgentFeature, const char*> BUSINESS_METRIC_MAPPING[] = {
3335
{UserAgentFeature::FLEXIBLE_CHECKSUMS_REQ_WHEN_SUPPORTED, "Z"},
3436
{UserAgentFeature::FLEXIBLE_CHECKSUMS_REQ_WHEN_REQUIRED, "a"},
3537
{UserAgentFeature::FLEXIBLE_CHECKSUMS_RES_WHEN_SUPPORTED, "b"},
36-
{UserAgentFeature::FLEXIBLE_CHECKSUMS_RES_WHEN_REQUIRED, "c"}
38+
{UserAgentFeature::FLEXIBLE_CHECKSUMS_RES_WHEN_REQUIRED, "c"},
39+
{UserAgentFeature::ACCOUNT_ID_MODE_PREFERRED, "P"},
40+
{UserAgentFeature::ACCOUNT_ID_MODE_DISABLED , "Q"},
41+
{UserAgentFeature::ACCOUNT_ID_MODE_REQUIRED, "R"},
42+
{UserAgentFeature::RESOLVED_ACCOUNT_ID, "T"},
3743
};
3844

3945
Aws::String BusinessMetricForFeature(UserAgentFeature feature) {
@@ -53,6 +59,22 @@ const std::pair<const char*, UserAgentFeature> RETRY_FEATURE_MAPPING[] = {
5359
{"adaptive", UserAgentFeature::RETRY_MODE_ADAPTIVE},
5460
};
5561

62+
const std::pair<const char*, UserAgentFeature> ACCOUNT_ID_MODE_MAPPING[] = {
63+
{"preferred", UserAgentFeature::ACCOUNT_ID_MODE_PREFERRED},
64+
{"disabled", UserAgentFeature::ACCOUNT_ID_MODE_DISABLED},
65+
{"required", UserAgentFeature::ACCOUNT_ID_MODE_REQUIRED},
66+
};
67+
68+
Aws::Crt::Optional<UserAgentFeature> BusinessMetricForAccountIdMode(const Aws::String& accountIdMode) {
69+
const auto *const accountIdFeature = std::find_if(std::begin(ACCOUNT_ID_MODE_MAPPING),
70+
std::end(ACCOUNT_ID_MODE_MAPPING),
71+
[&accountIdMode](const std::pair<const char*, UserAgentFeature>& mapping) -> bool { return mapping.first == accountIdMode; });
72+
if (accountIdFeature == std::end(ACCOUNT_ID_MODE_MAPPING)) {
73+
return {};
74+
}
75+
return accountIdFeature->second;
76+
}
77+
5678
const char* EXEC_ENV_VAR = "AWS_EXECUTION_ENV";
5779
const char* METADATA = "md";
5880
const char* METADATA_DELIMINATOR = "/";
@@ -94,6 +116,10 @@ UserAgent::UserAgent(const ClientConfiguration& clientConfiguration,
94116
#undef XSTR
95117
#endif
96118
{
119+
const auto accountIdMode = BusinessMetricForAccountIdMode(clientConfiguration.accountIdEndpointMode);
120+
if (accountIdMode.has_value()) {
121+
m_features.emplace(accountIdMode.value());
122+
}
97123
}
98124

99125
Aws::String UserAgent::SerializeWithFeatures(const Aws::Set<UserAgentFeature>& features) const {

0 commit comments

Comments
 (0)