Skip to content

Commit 19f53a9

Browse files
authored
Changes to enable Smithy S3 CRT (#3352)
1 parent d960f4a commit 19f53a9

19 files changed

+1395
-100
lines changed

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,21 @@ namespace smithy
7171
std::shared_ptr<Aws::Utils::Threading::Executor> m_pExecutor;
7272
std::shared_ptr<interceptor::InterceptorContext> m_interceptorContext;
7373
std::shared_ptr<smithy::AwsIdentity> m_awsIdentity;
74+
75+
AwsSmithyClientAsyncRequestContext() = default;
76+
77+
AwsSmithyClientAsyncRequestContext(
78+
Aws::AmazonWebServiceRequest const * const request,
79+
const char* requestName,
80+
std::shared_ptr<Aws::Utils::Threading::Executor> pExecutor):
81+
m_invocationId{Aws::Utils::UUID::PseudoRandomUUID()},
82+
m_pRequest{request},
83+
m_requestName{requestName ? requestName : m_pRequest ? m_pRequest->GetServiceRequestName() : ""},
84+
m_retryCount{0},
85+
m_pExecutor{pExecutor}
86+
{
87+
88+
}
7489
};
7590
} // namespace client
7691
} // namespace smithy

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,10 @@ namespace client
206206
virtual bool AdjustClockSkew(HttpResponseOutcome& outcome, const AuthSchemeOption& authSchemeOption) const = 0;
207207
virtual IdentityOutcome ResolveIdentity(const AwsSmithyClientAsyncRequestContext& ctx) const = 0;
208208
virtual GetContextEndpointParametersOutcome GetContextEndpointParameters(const AwsSmithyClientAsyncRequestContext& ctx) const = 0;
209+
AwsSmithyClientBase::ResolveEndpointOutcome ResolveEndpointFromRequest(
210+
Aws::AmazonWebServiceRequest const * const request,
211+
const char* requestName,
212+
EndpointUpdateCallback&& endpointCallback) const;
209213

210214
/* AwsSmithyClientT class binds its config reference to this pointer, so don't remove const and don't re-allocate it.
211215
* This is done to avoid duplication of config object between this base and actual service template classes.
@@ -220,6 +224,13 @@ namespace client
220224
std::shared_ptr<smithy::client::UserAgentInterceptor> m_userAgentInterceptor;
221225
private:
222226
void UpdateAuthSchemeFromEndpoint(const Aws::Endpoint::AWSEndpoint& endpoint, AuthSchemeOption& authscheme) const;
227+
228+
bool ResolveIdentityAuth(
229+
std::shared_ptr<AwsSmithyClientAsyncRequestContext>& pRequestCtx,
230+
ResponseHandlerFunc&& responseHandler,
231+
EndpointUpdateCallback&& endpointCallback
232+
) const;
233+
223234
};
224235
} // namespace client
225236
} // namespace smithy

src/aws-cpp-sdk-core/include/smithy/identity/resolver/built-in/DefaultAwsCredentialIdentityResolver.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ namespace smithy {
2727

2828
};
2929

30+
DefaultAwsCredentialIdentityResolver(const Aws::Auth::DefaultAWSCredentialsProviderChain& credChain): legacyChain_sp{Aws::MakeShared<Aws::Auth::DefaultAWSCredentialsProviderChain>(ALLOC_ID, credChain)}{
31+
32+
};
33+
3034
DefaultAwsCredentialIdentityResolver(const DefaultAwsCredentialIdentityResolver& other) = delete;
3135
DefaultAwsCredentialIdentityResolver(DefaultAwsCredentialIdentityResolver&& other) noexcept = default;
3236
DefaultAwsCredentialIdentityResolver& operator=(const DefaultAwsCredentialIdentityResolver& other) = delete;

src/aws-cpp-sdk-core/source/smithy/client/AwsSmithyClientBase.cpp

Lines changed: 96 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -177,49 +177,19 @@ AwsSmithyClientBase::BuildHttpRequest(const std::shared_ptr<AwsSmithyClientAsync
177177
return httpRequest;
178178
}
179179

180-
void AwsSmithyClientBase::MakeRequestAsync(Aws::AmazonWebServiceRequest const* const request,
181-
const char* requestName,
182-
Aws::Http::HttpMethod method,
183-
EndpointUpdateCallback&& endpointCallback,
184-
ResponseHandlerFunc&& responseHandler,
185-
std::shared_ptr<Aws::Utils::Threading::Executor> pExecutor) const
180+
181+
bool AwsSmithyClientBase::ResolveIdentityAuth(
182+
std::shared_ptr<AwsSmithyClientAsyncRequestContext>& pRequestCtx,
183+
ResponseHandlerFunc&& responseHandler,
184+
EndpointUpdateCallback&& endpointCallback
185+
) const
186186
{
187-
if(!responseHandler)
188-
{
189-
assert(!"Missing a mandatory response handler!");
190-
AWS_LOGSTREAM_FATAL(AWS_SMITHY_CLIENT_LOG, "Unable to continue AWSClient request: response handler is missing!");
191-
return;
192-
}
193187

194-
std::shared_ptr<AwsSmithyClientAsyncRequestContext> pRequestCtx =
195-
Aws::MakeShared<AwsSmithyClientAsyncRequestContext>(AWS_SMITHY_CLIENT_LOG);
196-
if (!pRequestCtx)
197-
{
198-
AWS_LOGSTREAM_ERROR(AWS_SMITHY_CLIENT_LOG, "Failed to allocate an AwsSmithyClientAsyncRequestContext under a shared ptr");
199-
auto outcome = HttpResponseOutcome(ClientError(CoreErrors::MEMORY_ALLOCATION, "", "Failed to allocate async request context", false/*retryable*/));
200-
pExecutor->Submit([outcome, responseHandler]() mutable
201-
{
202-
responseHandler(std::move(outcome));
203-
} );
204-
return;
205-
}
206-
pRequestCtx->m_pExecutor = pExecutor;
207-
pRequestCtx->m_pRequest = request;
208-
if (requestName)
209-
pRequestCtx->m_requestName = requestName;
210-
else if (pRequestCtx->m_pRequest)
211-
pRequestCtx->m_requestName = pRequestCtx->m_pRequest->GetServiceRequestName();
212-
pRequestCtx->m_method = method;
213-
pRequestCtx->m_retryCount = 0;
214-
pRequestCtx->m_invocationId = Aws::Utils::UUID::PseudoRandomUUID();
215188
auto authSchemeOptionOutcome = this->SelectAuthSchemeOption(*pRequestCtx);
216189
if (!authSchemeOptionOutcome.IsSuccess())
217190
{
218-
pExecutor->Submit([authSchemeOptionOutcome, responseHandler]() mutable
219-
{
220-
responseHandler(std::move(authSchemeOptionOutcome));
221-
} );
222-
return;
191+
responseHandler(std::move(authSchemeOptionOutcome));
192+
return false;
223193
}
224194
pRequestCtx->m_authSchemeOption = std::move(authSchemeOptionOutcome.GetResultWithOwnership());
225195
assert(pRequestCtx->m_authSchemeOption.schemeId);
@@ -228,26 +198,23 @@ void AwsSmithyClientBase::MakeRequestAsync(Aws::AmazonWebServiceRequest const* c
228198
auto identityOutcome = this->ResolveIdentity(*pRequestCtx);
229199
if (!identityOutcome.IsSuccess())
230200
{
231-
pExecutor->Submit([identityOutcome, responseHandler]() mutable
232-
{
233-
responseHandler(std::move(identityOutcome));
234-
});
235-
return;
201+
responseHandler(std::move(identityOutcome));
202+
return false;
236203
}
204+
237205
pRequestCtx->m_awsIdentity = std::move(identityOutcome.GetResultWithOwnership());
238206

239207
// get endpoint params from operation context
240208
const auto contextEndpointParameters = this->GetContextEndpointParameters(*pRequestCtx);
209+
241210
if (!contextEndpointParameters.IsSuccess())
242211
{
243-
pExecutor->Submit([contextEndpointParameters, responseHandler]() mutable
244-
{
245-
responseHandler(std::move(contextEndpointParameters.GetError()));
246-
});
247-
return;
212+
responseHandler(std::move(contextEndpointParameters.GetError()));
213+
214+
return false;
248215
}
249216

250-
Aws::Endpoint::EndpointParameters epParams = request ? request->GetEndpointContextParams() : Aws::Endpoint::EndpointParameters();
217+
Aws::Endpoint::EndpointParameters epParams = pRequestCtx->m_pRequest ? pRequestCtx->m_pRequest->GetEndpointContextParams() : Aws::Endpoint::EndpointParameters();
251218
const auto authSchemeEpParams = pRequestCtx->m_authSchemeOption.endpointParameters();
252219
epParams.insert(epParams.end(), authSchemeEpParams.begin(), authSchemeEpParams.end());
253220
const auto contextParams = contextEndpointParameters.GetResult();
@@ -260,25 +227,63 @@ void AwsSmithyClientBase::MakeRequestAsync(Aws::AmazonWebServiceRequest const* c
260227
epResolutionOutcome.GetError().GetExceptionName(),
261228
epResolutionOutcome.GetError().GetMessage(),
262229
false});
263-
264-
pExecutor->Submit([epOutcome, responseHandler]() mutable
265-
{
266-
responseHandler(std::move(epOutcome));
267-
} );
268-
return;
230+
responseHandler(std::move(epOutcome));
231+
return false;
269232
}
270233
pRequestCtx->m_endpoint = std::move(epResolutionOutcome.GetResultWithOwnership());
271-
272234
if (!Aws::Utils::IsValidHost(pRequestCtx->m_endpoint.GetURI().GetAuthority()))
273235
{
274236
AWS_LOGSTREAM_ERROR(AWS_SMITHY_CLIENT_LOG, "Invalid DNS Label found in URI host");
275237
auto outcome = HttpResponseOutcome(ClientError(CoreErrors::VALIDATION, "", "Invalid DNS Label found in URI host", false/*retryable*/));
238+
responseHandler(std::move(outcome));
239+
return false;
240+
}
241+
return true;
242+
}
243+
244+
void AwsSmithyClientBase::MakeRequestAsync(Aws::AmazonWebServiceRequest const* const request,
245+
const char* requestName,
246+
Aws::Http::HttpMethod method,
247+
EndpointUpdateCallback&& endpointCallback,
248+
ResponseHandlerFunc&& responseHandler,
249+
std::shared_ptr<Aws::Utils::Threading::Executor> pExecutor) const
250+
{
251+
if(!responseHandler)
252+
{
253+
assert(!"Missing a mandatory response handler!");
254+
AWS_LOGSTREAM_FATAL(AWS_SMITHY_CLIENT_LOG, "Unable to continue AWSClient request: response handler is missing!");
255+
return;
256+
}
257+
258+
std::shared_ptr<AwsSmithyClientAsyncRequestContext> pRequestCtx =
259+
Aws::MakeShared<AwsSmithyClientAsyncRequestContext>(AWS_SMITHY_CLIENT_LOG, request, requestName, pExecutor );
260+
if (!pRequestCtx)
261+
{
262+
AWS_LOGSTREAM_ERROR(AWS_SMITHY_CLIENT_LOG, "Failed to allocate an AwsSmithyClientAsyncRequestContext under a shared ptr");
263+
auto outcome = HttpResponseOutcome(ClientError(CoreErrors::MEMORY_ALLOCATION, "", "Failed to allocate async request context", false/*retryable*/));
276264
pExecutor->Submit([outcome, responseHandler]() mutable
277265
{
278266
responseHandler(std::move(outcome));
279267
} );
280268
return;
281269
}
270+
271+
pRequestCtx->m_method = method;
272+
ResponseHandlerFunc modifiedResponseHandler = [&](HttpResponseOutcome&& outcome){
273+
auto capturedOutcome = std::make_shared<HttpResponseOutcome>(std::move(outcome));
274+
pExecutor->Submit([capturedOutcome, &responseHandler]()
275+
{
276+
responseHandler(std::move(*capturedOutcome));
277+
});
278+
};
279+
280+
if(!ResolveIdentityAuth(
281+
pRequestCtx,
282+
std::move(modifiedResponseHandler),
283+
std::move(endpointCallback)))
284+
{
285+
return;
286+
}
282287
pRequestCtx->m_requestInfo.attempt = 1;
283288
pRequestCtx->m_requestInfo.maxAttempts = 0;
284289
pRequestCtx->m_interceptorContext = Aws::MakeShared<InterceptorContext>(AWS_SMITHY_CLIENT_LOG, *request);
@@ -682,4 +687,39 @@ void AwsSmithyClientBase::AppendToUserAgent(const Aws::String& valueToAppend)
682687
{
683688
assert(m_userAgentInterceptor);
684689
m_userAgentInterceptor->AddLegacyFeaturesToUserAgent(valueToAppend);
690+
}
691+
692+
/*
693+
blocking API to resolve endpoint from request
694+
*/
695+
AwsSmithyClientBase::ResolveEndpointOutcome AwsSmithyClientBase::ResolveEndpointFromRequest(
696+
Aws::AmazonWebServiceRequest const * const request,
697+
const char* requestName,
698+
EndpointUpdateCallback&& endpointCallback) const
699+
{
700+
ResolveEndpointOutcome outcome = ClientError(CoreErrors::INTERNAL_FAILURE, "", "Response handler was not called", false);
701+
ResponseHandlerFunc responseHandler = [&outcome](HttpResponseOutcome&& asyncOutcome)
702+
{
703+
outcome = std::move(asyncOutcome);
704+
};
705+
706+
std::shared_ptr<AwsSmithyClientAsyncRequestContext> pRequestCtx = Aws::MakeShared<AwsSmithyClientAsyncRequestContext>(AWS_SMITHY_CLIENT_LOG, request, requestName, nullptr);
707+
if (!pRequestCtx)
708+
{
709+
AWS_LOGSTREAM_ERROR(AWS_SMITHY_CLIENT_LOG, "Failed to allocate an AwsSmithyClientAsyncRequestContext under a shared ptr");
710+
auto result = HttpResponseOutcome(ClientError(CoreErrors::MEMORY_ALLOCATION, "", "Failed to allocate async request context", false/*retryable*/));
711+
responseHandler(std::move(result));
712+
}
713+
else
714+
{
715+
if(this->ResolveIdentityAuth(
716+
pRequestCtx,
717+
std::move(responseHandler),
718+
std::move(endpointCallback)
719+
))
720+
{
721+
outcome = std::move(pRequestCtx->m_endpoint);
722+
}
723+
}
724+
return outcome;
685725
}

tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/generators/cpp/CppClientGenerator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -791,7 +791,7 @@ protected SdkFileEntry GenerateLegacyClientSourceFile(final ServiceModel service
791791
"aws.auth#sigv4a", "smithy::SigV4aAuthScheme",
792792
"bearer", "smithy::BearerTokenAuthScheme",
793793
"v4","smithy::SigV4AuthScheme",
794-
"sigv4-s3express","S3::S3ExpressSigV4AuthScheme",
794+
"sigv4-s3express","S3ExpressSigV4AuthScheme",
795795
"v2","smithy::SigV4AuthScheme"
796796
);
797797

@@ -808,7 +808,7 @@ protected String mapAuthSchemes(final String authSchemeName) {
808808
"aws.auth#sigv4a", "smithy::SigV4aAuthSchemeOption::sigV4aAuthSchemeOption",
809809
"bearer", "smithy::BearerTokenAuthSchemeOption::bearerTokenAuthSchemeOption",
810810
"v4", "smithy::SigV4AuthSchemeOption::sigV4AuthSchemeOption",
811-
"sigv4-s3express", "S3::S3ExpressSigV4AuthSchemeOption::s3ExpressSigV4AuthSchemeOption",
811+
"sigv4-s3express", "S3ExpressSigV4AuthSchemeOption::s3ExpressSigV4AuthSchemeOption",
812812
"v2", "smithy::SigV4AuthSchemeOption::sigV4AuthSchemeOption"
813813
);
814814

tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/generators/cpp/s3/S3RestXmlCppClientGenerator.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -480,8 +480,16 @@ protected List<SdkFileEntry> generateClientSourceFile(final List<ServiceModel> s
480480
}
481481
Map<String, String> templateOverride = new HashMap<>();
482482
if ("S3-CRT".equalsIgnoreCase(serviceModels.get(i).getMetadata().getProjectName())) {
483-
templateOverride.put("ServiceClientSourceInit_template",
484-
"/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/s3-crt/S3CrtServiceClientSourceInit.vm");
483+
if (serviceModels.get(i).isUseSmithyClient())
484+
{
485+
templateOverride.put("ServiceClientSourceInit_template",
486+
"/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/s3-crt/SmithyS3CrtServiceClientSourceInit.vm");
487+
}
488+
else
489+
{
490+
templateOverride.put("ServiceClientSourceInit_template",
491+
"/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/s3-crt/S3CrtServiceClientSourceInit.vm");
492+
}
485493
}
486494
VelocityContext context = createContext(serviceModels.get(i));
487495
context.put("CppViewHelper", CppViewHelper.class);

tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/ServiceClientSourceHeaders.vm

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@
5252
#end
5353
#if($serviceModel.metadata.namespace == "S3Crt")
5454
\#include <aws/s3-crt/S3CrtIdentityProviderAdapter.h>
55+
#if($serviceModel.isUseSmithyClient())
56+
\#include <smithy/client/AwsSmithyClientAsyncRequestContext.h>
57+
#end
5558
#end
5659

5760
\#include <smithy/tracing/TracingUtils.h>

tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ClientHeader.vm

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -280,11 +280,7 @@ namespace ${rootNamespace}
280280
bool m_enableHostPrefixInjection = false;
281281
Aws::String m_configScheme;
282282
#end##-#if(!$serviceModel.endpointRules)
283-
#if($serviceModel.endpointRules)
284-
#if($serviceNamespace == "S3Crt")
285-
${metadata.classNamePrefix}::ClientConfiguration m_clientConfiguration;
286-
#end
287-
#end
283+
288284
#if($serviceNamespace == "S3Crt")
289285
struct aws_s3_client* m_s3CrtClient = {};
290286
struct aws_signing_config_aws m_s3CrtSigningConfig = {};

tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ExpressAuthSchemeResolverHeader.vm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ namespace ${serviceNamespace} {
4040
{
4141
{Aws::Auth::ASYMMETRIC_SIGV4_SIGNER, smithy::SigV4aAuthSchemeOption::sigV4aAuthSchemeOption},
4242
{Aws::Auth::SIGV4_SIGNER, smithy::SigV4AuthSchemeOption::sigV4AuthSchemeOption},
43-
{S3::S3_EXPRESS_SIGNER_NAME, S3ExpressSigV4AuthSchemeOption::s3ExpressSigV4AuthSchemeOption}
43+
{${serviceNamespace}::S3_EXPRESS_SIGNER_NAME, S3ExpressSigV4AuthSchemeOption::s3ExpressSigV4AuthSchemeOption}
4444
};
4545
authSchemes.reserve(authSchemeMap.size());
4646
auto authschemeMapper = [&](const Aws::String& schemeId){

tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ExpressIdentityProviderHeader.vm

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
\#include <aws/${metadata.projectName}/S3ExpressIdentity.h>
1414
\#include <thread>
1515
\#include <condition_variable>
16-
\#include <aws/s3/S3_EXPORTS.h>
16+
\#include <aws/${metadata.projectName}/${metadata.classNamePrefix}_EXPORTS.h>
1717

1818
namespace ${rootNamespace} {
1919
namespace Http {
@@ -24,7 +24,7 @@ namespace ${rootNamespace} {
2424
class ${serviceNamespace}Client;
2525
class ${CppViewHelper.computeExportValue($serviceNamespace)} S3ExpressIdentityProvider : public smithy::IdentityResolverBase<S3ExpressIdentity> {
2626
public:
27-
explicit S3ExpressIdentityProvider(const S3Client& s3Client);
27+
explicit S3ExpressIdentityProvider(const ${serviceNamespace}Client& s3Client);
2828
ResolveIdentityFutureOutcome getIdentity(
2929
const IdentityProperties& identityProperties,
3030
const AdditionalParameters& additionalParameters) override;
@@ -37,7 +37,7 @@ namespace ${rootNamespace} {
3737
S3ExpressIdentity GetCredentialsFromBucket(const Aws::String& bucketName) const;
3838

3939
private:
40-
const Aws::S3::S3Client& m_s3Client;
40+
const ${serviceNamespace}Client& m_s3Client;
4141
mutable std::mutex m_bucketNameMapMutex;
4242
Aws::Map<Aws::String, std::shared_ptr<std::mutex>> m_bucketNameMutex;
4343

@@ -48,9 +48,9 @@ namespace ${rootNamespace} {
4848

4949
class ${CppViewHelper.computeExportValue($serviceNamespace)} DefaultS3ExpressIdentityProvider : public S3ExpressIdentityProvider {
5050
public:
51-
explicit DefaultS3ExpressIdentityProvider(const S3Client& s3Client);
51+
explicit DefaultS3ExpressIdentityProvider(const ${serviceNamespace}Client& s3Client);
5252
explicit DefaultS3ExpressIdentityProvider(
53-
const S3Client& s3Client,
53+
const ${serviceNamespace}Client& s3Client,
5454
std::shared_ptr<Utils::ConcurrentCache<Aws::String, S3ExpressIdentity>> credentialsCache);
5555
DefaultS3ExpressIdentityProvider(const DefaultS3ExpressIdentityProvider& other) = delete;
5656
DefaultS3ExpressIdentityProvider(DefaultS3ExpressIdentityProvider&& other) noexcept = delete;
@@ -66,11 +66,11 @@ namespace ${rootNamespace} {
6666
class ${CppViewHelper.computeExportValue($serviceNamespace)} DefaultAsyncS3ExpressIdentityProvider : public S3ExpressIdentityProvider {
6767
public:
6868
explicit DefaultAsyncS3ExpressIdentityProvider(
69-
const S3Client& s3Client,
69+
const ${serviceNamespace}Client& s3Client,
7070
std::chrono::minutes refreshPeriod = std::chrono::minutes(1));
7171

7272
explicit DefaultAsyncS3ExpressIdentityProvider(
73-
const S3Client& s3Client,
73+
const ${serviceNamespace}Client& s3Client,
7474
std::shared_ptr<Utils::ConcurrentCache<Aws::String, S3ExpressIdentity>> credentialsCache,
7575
std::chrono::minutes refreshPeriod = std::chrono::minutes(1));
7676

0 commit comments

Comments
 (0)