diff --git a/src/aws-cpp-sdk-core/include/smithy/client/AwsLegacyClient.h b/src/aws-cpp-sdk-core/include/smithy/client/AwsLegacyClient.h new file mode 100644 index 000000000000..9e890899bbfa --- /dev/null +++ b/src/aws-cpp-sdk-core/include/smithy/client/AwsLegacyClient.h @@ -0,0 +1,106 @@ +/** +* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +#pragma once + +#include +#include + +namespace smithy { +namespace client +{ + /* + This Class exists only to provide a way to access the legacy client APIs + */ + template + class AwsLegacyClientT + { + protected: + ResponseT MakeRequest(const Aws::Http::URI& uri, + const Aws::AmazonWebServiceRequest& request, + Aws::Http::HttpMethod method = Aws::Http::HttpMethod::HTTP_POST, + const char* signerName = Aws::Auth::SIGV4_SIGNER, + const char* signerRegionOverride = nullptr, + const char* signerServiceNameOverride = nullptr) const + { + AWS_UNREFERENCED_PARAM(uri); + AWS_UNREFERENCED_PARAM(signerName); + AWS_UNREFERENCED_PARAM(signerRegionOverride); + AWS_UNREFERENCED_PARAM(signerServiceNameOverride); + AWS_LOGSTREAM_WARN(ServiceNameT, "Using Deprecated API. Please use appropriate client constructor"); + auto endpointCallback = [](const Aws::Endpoint::AWSEndpoint& ) { + }; + return static_cast(this)->MakeRequestDeserialize(&request, + ServiceNameT, + method, + std::move(endpointCallback)); + } + + ResponseT MakeRequest(const Aws::Http::URI& uri, + Aws::Http::HttpMethod method = Aws::Http::HttpMethod::HTTP_POST, + const char* signerName = Aws::Auth::SIGV4_SIGNER, + const char* requestName = "", + const char* signerRegionOverride = nullptr, + const char* signerServiceNameOverride = nullptr) const + { + AWS_UNREFERENCED_PARAM(uri); + AWS_UNREFERENCED_PARAM(signerName); + AWS_UNREFERENCED_PARAM(signerRegionOverride); + AWS_UNREFERENCED_PARAM(signerServiceNameOverride); + AWS_LOGSTREAM_WARN(ServiceNameT, "Using Deprecated API. Please use appropriate client constructor"); + auto endpointCallback = [](const Aws::Endpoint::AWSEndpoint& ) { + }; + return static_cast(this)->MakeRequestDeserialize(nullptr, + requestName, + method, + std::move(endpointCallback)); + } + + ResponseT MakeRequest(const Aws::AmazonWebServiceRequest& request, + const Aws::Endpoint::AWSEndpoint& endpoint, + Aws::Http::HttpMethod method = Aws::Http::HttpMethod::HTTP_POST, + const char* signerName = Aws::Auth::SIGV4_SIGNER, + const char* signerRegionOverride = nullptr, + const char* signerServiceNameOverride = nullptr) const + { + AWS_UNREFERENCED_PARAM(endpoint); + AWS_UNREFERENCED_PARAM(signerName); + AWS_UNREFERENCED_PARAM(signerRegionOverride); + AWS_UNREFERENCED_PARAM(signerServiceNameOverride); + AWS_LOGSTREAM_WARN(ServiceNameT, "Using Deprecated API. Please use appropriate client constructor"); + auto endpointCallback = [](const Aws::Endpoint::AWSEndpoint& ) { + }; + return static_cast(this)->MakeRequestDeserialize(&request, + ServiceNameT, + method, + std::move(endpointCallback)); + } + + ResponseT MakeRequest(const Aws::Endpoint::AWSEndpoint& endpoint, + const char* requestName = "", + Aws::Http::HttpMethod method = Aws::Http::HttpMethod::HTTP_POST, + const char* signerName = Aws::Auth::SIGV4_SIGNER, + const char* signerRegionOverride = nullptr, + const char* signerServiceNameOverride = nullptr) const + { + AWS_UNREFERENCED_PARAM(endpoint); + AWS_UNREFERENCED_PARAM(signerName); + AWS_UNREFERENCED_PARAM(signerRegionOverride); + AWS_UNREFERENCED_PARAM(signerServiceNameOverride); + AWS_LOGSTREAM_WARN(ServiceNameT, "Using Deprecated API. Please use appropriate client constructor"); + auto endpointCallback = [](const Aws::Endpoint::AWSEndpoint& ) { + }; + return static_cast(this)->MakeRequestDeserialize(nullptr, + requestName, + method, + std::move(endpointCallback)); + } + + AwsLegacyClientT() = default; + }; + +} // namespace client +} // namespace smithy \ No newline at end of file diff --git a/src/aws-cpp-sdk-core/include/smithy/client/AwsSmithyClient.h b/src/aws-cpp-sdk-core/include/smithy/client/AwsSmithyClient.h index fd5ac8ee8ee3..00fdd703b643 100644 --- a/src/aws-cpp-sdk-core/include/smithy/client/AwsSmithyClient.h +++ b/src/aws-cpp-sdk-core/include/smithy/client/AwsSmithyClient.h @@ -24,6 +24,8 @@ #include #include #include +#include +#include namespace smithy { namespace client @@ -36,7 +38,15 @@ namespace client typename SerializerT, typename ResponseT, typename ErrorMarshallerT> - class AwsSmithyClientT : public AwsSmithyClientBase + class AwsSmithyClientT : public AwsSmithyClientBase, public AwsLegacyClientT> { public: static_assert(std::is_base_of::value, "MarshallerT must be derived from class Aws::Client::AWSErrorMarshaller"); @@ -213,6 +223,68 @@ namespace client return m_serializer->Deserialize(std::move(httpResponseOutcome), GetServiceClientName(), requestName); } + Aws::String GeneratePresignedUrl( + EndpointUpdateCallback&& endpointCallback, + Aws::Http::HttpMethod method, + const Aws::String& region, + const Aws::String& serviceName, + long long expirationInSeconds, + const Aws::Http::HeaderValueCollection& customizedHeaders, + const std::shared_ptr serviceSpecificParameters) const + { + AwsSmithyClientAsyncRequestContext ctx; + auto authSchemeOptionOutcome = SelectAuthSchemeOption( ctx); + auto authSchemeOption = std::move(authSchemeOptionOutcome.GetResultWithOwnership()); + + Aws::Endpoint::EndpointParameters epParams = Aws::Endpoint::EndpointParameters(); + const auto authSchemeEpParams = authSchemeOption.endpointParameters(); + epParams.insert(epParams.end(), authSchemeEpParams.begin(), authSchemeEpParams.end()); + if(serviceSpecificParameters) + { + auto bucketIt = serviceSpecificParameters->parameterMap.find("bucketName"); + if(bucketIt != serviceSpecificParameters->parameterMap.end()) + { + auto bucket = bucketIt->second; + epParams.emplace_back(Aws::String("Bucket"), bucket); + } + } + + auto epResolutionOutcome = this->ResolveEndpoint(std::move(epParams), std::move(endpointCallback)); + if (!epResolutionOutcome.IsSuccess()) + { + AWS_LOGSTREAM_ERROR(ServiceNameT, "Presigned URL generating failed. Encountered error: " << epResolutionOutcome.GetError().GetMessage()); + return {}; + } + auto endpoint = std::move(epResolutionOutcome.GetResultWithOwnership()); + const Aws::Http::URI& uri = endpoint.GetURI(); + auto signerRegionOverride = region; + auto signerServiceNameOverride = serviceName; + //signer name is needed for some identity resolvers + if (endpoint.GetAttributes()) { + if (endpoint.GetAttributes()->authScheme.GetSigningRegion()) { + signerRegionOverride = endpoint.GetAttributes()->authScheme.GetSigningRegion()->c_str(); + } + if (endpoint.GetAttributes()->authScheme.GetSigningRegionSet()) { + signerRegionOverride = endpoint.GetAttributes()->authScheme.GetSigningRegionSet()->c_str(); + } + if (endpoint.GetAttributes()->authScheme.GetSigningName()) { + signerServiceNameOverride = endpoint.GetAttributes()->authScheme.GetSigningName()->c_str(); + } + } + std::shared_ptr request = CreateHttpRequest(uri, method, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod); + request->SetServiceSpecificParameters(serviceSpecificParameters); + for (const auto& it: customizedHeaders) + { + request->SetHeaderValue(it.first.c_str(), it.second); + } + if (AwsClientRequestSigning::PreSignRequest(request, authSchemeOption, m_authSchemes, signerRegionOverride, signerServiceNameOverride, expirationInSeconds).IsSuccess()) + { + return request->GetURIString(); + } + return {}; + } + + //legacy Aws::String GeneratePresignedUrl(const Aws::Http::URI& uri, Aws::Http::HttpMethod method, const Aws::String& region, @@ -237,7 +309,7 @@ namespace client return {}; } - + Aws::String GeneratePresignedUrl(const Aws::Endpoint::AWSEndpoint& endpoint, Aws::Http::HttpMethod method, const Aws::String& region, @@ -263,8 +335,7 @@ namespace client } return GeneratePresignedUrl(uri, method, signerRegionOverride, signerServiceNameOverride, expirationInSeconds, customizedHeaders, serviceSpecificParameters); } - - protected: + /* Service client specific config, the actual object is stored in AwsSmithyClientBase by pointer * In order to avoid config object duplication, smithy template client access it by a reference. * So that base client has it by base config pointer, child smithy client has it by child config reference. @@ -274,6 +345,15 @@ namespace client std::shared_ptr m_authSchemeResolver{}; Aws::UnorderedMap m_authSchemes{}; std::shared_ptr m_serializer{}; + private: + friend class AwsLegacyClientT>; }; } // namespace client diff --git a/src/aws-cpp-sdk-core/include/smithy/client/AwsSmithyClientBase.h b/src/aws-cpp-sdk-core/include/smithy/client/AwsSmithyClientBase.h index eee6f68139f5..fbf7b89d5722 100644 --- a/src/aws-cpp-sdk-core/include/smithy/client/AwsSmithyClientBase.h +++ b/src/aws-cpp-sdk-core/include/smithy/client/AwsSmithyClientBase.h @@ -74,16 +74,16 @@ namespace client using HttpRequest = Aws::Http::HttpRequest; using HttpResponse = Aws::Http::HttpResponse; using CoreErrors = Aws::Client::CoreErrors; - using AWSError = Aws::Client::AWSError; - using ClientError = AWSError; - using SigningError = AWSError; + using AWSCoreError = Aws::Client::AWSError; + using ClientError = AWSCoreError; + using SigningError = AWSCoreError; using SigningOutcome = Aws::Utils::FutureOutcome, SigningError>; using EndpointUpdateCallback = std::function; - using HttpResponseOutcome = Aws::Utils::Outcome, AWSError>; + using HttpResponseOutcome = Aws::Utils::Outcome, AWSCoreError>; using ResponseHandlerFunc = std::function; - using SelectAuthSchemeOptionOutcome = Aws::Utils::Outcome; - using ResolveEndpointOutcome = Aws::Utils::Outcome; - using StreamOutcome = Aws::Utils::Outcome, AWSError >; + using SelectAuthSchemeOptionOutcome = Aws::Utils::Outcome; + using ResolveEndpointOutcome = Aws::Utils::Outcome; + using StreamOutcome = Aws::Utils::Outcome, AWSCoreError >; /* primary constructor */ AwsSmithyClientBase(Aws::UniquePtr&& clientConfig, @@ -149,6 +149,13 @@ namespace client void AppendToUserAgent(const Aws::String& valueToAppend); protected: + + //for backwards compatibility + const std::shared_ptr& GetErrorMarshaller() const + { + return m_errorMarshaller; + } + /** * Initialize client configuration with their factory method, unless the user has explicitly set the * configuration, and it is to be shallow copied between different clients, in which case, delete the diff --git a/tests/aws-cpp-sdk-s3-unit-tests/S3UnitTests.cpp b/tests/aws-cpp-sdk-s3-unit-tests/S3UnitTests.cpp index d05dd1571848..1346102ffcde 100644 --- a/tests/aws-cpp-sdk-s3-unit-tests/S3UnitTests.cpp +++ b/tests/aws-cpp-sdk-s3-unit-tests/S3UnitTests.cpp @@ -12,6 +12,7 @@ #include #include #include +#include using namespace Aws; using namespace Aws::Client; @@ -31,11 +32,34 @@ class S3TestClient : public S3Client template S3TestClient(Args&& ...args): S3Client(std::forward(args)...){ } + XmlOutcome MakeRequest(const Aws::Http::URI& uri, + const Aws::AmazonWebServiceRequest& request, + Aws::Http::HttpMethod method = Aws::Http::HttpMethod::HTTP_POST, + const char* signerName = Aws::Auth::SIGV4_SIGNER, + const char* signerRegionOverride = nullptr, + const char* signerServiceNameOverride = nullptr) const + { + return S3Client::MakeRequest(uri, request, method, signerName, signerRegionOverride, signerServiceNameOverride); + } + + + XmlOutcome MakeRequest(const Aws::Http::URI& uri, + Http::HttpMethod method = Http::HttpMethod::HTTP_POST, + const char* signerName = Aws::Auth::SIGV4_SIGNER, + const char* requestName = "", + const char* signerRegionOverride = nullptr, + const char* signerServiceNameOverride = nullptr) const + { + return S3Client::MakeRequest(uri, method, signerName, requestName, signerRegionOverride, signerServiceNameOverride); + } + private: S3TestClient() = default; friend class S3UnitTest_S3EmbeddedErrorTestNonOKResponse_Test; + + }; class NoRetry: public RetryStrategy @@ -459,4 +483,41 @@ TEST_F(S3UnitTest, RequestShouldNotIncludeAChecksumIfRequiredWithMD5Header) { [](const std::pair& keyValue) { return keyValue.first.find("x-amz-checksum") != Aws::String::npos; })); EXPECT_TRUE(std::any_of(headers.begin(), headers.end(), [](const std::pair& keyValue) { return keyValue.first.find("content-md5") != Aws::String::npos; })); +} + +TEST_F(S3UnitTest, testLegacyApi) +{ + HeadBucketRequest headBucketRequest; + headBucketRequest.SetBucket("dummy"); + + auto uri = _s3Client->GeneratePresignedUrl("dummy", + /*key=*/"", Aws::Http::HttpMethod::HTTP_HEAD); + + //We have to mock requset because it is used to create the return body, it actually isnt used. + auto mockRequest = Aws::MakeShared(ALLOCATION_TAG, "mockuri", HttpMethod::HTTP_GET); + mockRequest->SetResponseStreamFactory([]() -> IOStream* { + return Aws::New(ALLOCATION_TAG, "response-string", std::ios_base::in | std::ios_base::binary); + }); + + { + auto mockResponse = Aws::MakeShared(ALLOCATION_TAG, mockRequest); + mockResponse->SetResponseCode(HttpResponseCode::OK); + _mockHttpClient->AddResponseToReturn(mockResponse); + } + + auto outcome = _s3Client->MakeRequest(uri, headBucketRequest, Aws::Http::HttpMethod::HTTP_HEAD, + "SignatureV4"); + + EXPECT_TRUE(outcome.IsSuccess()); + + { + auto mockResponse = Aws::MakeShared(ALLOCATION_TAG, mockRequest); + mockResponse->SetResponseCode(HttpResponseCode::OK); + _mockHttpClient->AddResponseToReturn(mockResponse); + } + + auto outcome2 = _s3Client->MakeRequest(uri, Aws::Http::HttpMethod::HTTP_HEAD, + "SignatureV4"); + + EXPECT_TRUE(outcome2.IsSuccess()); } \ No newline at end of file diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/common/ServiceClientConfigurationHeader.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/common/ServiceClientConfigurationHeader.vm index 0ae5547c917b..2ef845cb29ea 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/common/ServiceClientConfigurationHeader.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/common/ServiceClientConfigurationHeader.vm @@ -167,12 +167,6 @@ namespace ${rootNamespace} IdentityProviderSupplier identityProviderSupplier = [](const ${metadata.classNamePrefix}Client &client) -> std::shared_ptr { return Aws::MakeShared("${metadata.classNamePrefix}ClientConfiguration", client); }; -#if($serviceModel.isUseSmithyClient()) - using SmithyIdentityProviderSupplier = std::function (const ${metadata.classNamePrefix}Client &)>; - SmithyIdentityProviderSupplier smithyIdentityProviderSupplier = [](const ${metadata.classNamePrefix}Client &client) -> std::shared_ptr { - return Aws::MakeShared("${metadata.classNamePrefix}ClientConfiguration", client); - }; -#end #end #if($metadata.hasEndpointDiscoveryTrait) diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ClientHeader.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ClientHeader.vm index 0614f8d3d88b..971a8f284a28 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ClientHeader.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ClientHeader.vm @@ -118,7 +118,7 @@ namespace ${rootNamespace} ${metadata.classNamePrefix}EndpointProviderBase, smithy::client::$serializer, smithy::client::$serializerOutcome, - Aws::Client::${metadata.classNamePrefix}ErrorMarshaller>, + Aws::Client::${metadata.classNamePrefix}ErrorMarshaller> { public: static const char* GetServiceName(); diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ClientSource.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ClientSource.vm index 33e4cb5a817a..fa9114644616 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ClientSource.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ClientSource.vm @@ -110,24 +110,14 @@ Aws::String ${className}::GeneratePresignedUrl(const Aws::String& bucket, return AwsSmithyClientT::GeneratePresignedUrl(uri, method, computeEndpointOutcome.GetResult().signerRegion.c_str(), computeEndpointOutcome.GetResult().signerServiceName.c_str(), expirationInSeconds, customizedHeaders, nullptr); #else - if (!m_endpointProvider) - { - AWS_LOGSTREAM_ERROR(ALLOCATION_TAG, "Presigned URL generating failed. Endpoint provider is not initialized."); - return {}; - } - ResolveEndpointOutcome computeEndpointOutcome = m_endpointProvider->ResolveEndpoint({{Aws::String("Bucket"), bucket}}); - if (!computeEndpointOutcome.IsSuccess()) - { - AWS_LOGSTREAM_ERROR(ALLOCATION_TAG, "Presigned URL generating failed. Encountered error: " << computeEndpointOutcome.GetError().GetMessage()); - return {}; - } - Aws::Endpoint::AWSEndpoint& endpoint = computeEndpointOutcome.GetResult(); - endpoint.AddPathSegments(key); Aws::Map params; params.emplace("bucketName", bucket); ServiceSpecificParameters serviceSpecificParameters{params}; auto serviceParams = Aws::MakeShared(ALLOCATION_TAG, serviceSpecificParameters); - return AwsSmithyClientT::GeneratePresignedUrl(endpoint, method, {}, {}, expirationInSeconds, customizedHeaders, serviceParams); + EndpointUpdateCallback endpointCallback = [&](Aws::Endpoint::AWSEndpoint& endpoint){ + endpoint.AddPathSegments(key); + }; + return AwsSmithyClientT::GeneratePresignedUrl(std::move(endpointCallback), method, {}, {}, expirationInSeconds, customizedHeaders, serviceParams); #end } diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ExpressAuthSchemeResolverHeader.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ExpressAuthSchemeResolverHeader.vm index 8e9a8a0d5133..505bba1e429b 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ExpressAuthSchemeResolverHeader.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ExpressAuthSchemeResolverHeader.vm @@ -35,30 +35,41 @@ namespace ${serviceNamespace} { //resolve endpoint first time to fetch auth schemes if(m_endpointProviderForAuth) { + Aws::Vector authSchemes{}; + Aws::UnorderedMap authSchemeMap = + { + {Aws::Auth::ASYMMETRIC_SIGV4_SIGNER, smithy::SigV4aAuthSchemeOption::sigV4aAuthSchemeOption}, + {Aws::Auth::SIGV4_SIGNER, smithy::SigV4AuthSchemeOption::sigV4AuthSchemeOption}, + {S3::S3_EXPRESS_SIGNER_NAME, S3ExpressSigV4AuthSchemeOption::s3ExpressSigV4AuthSchemeOption} + }; + authSchemes.reserve(authSchemeMap.size()); + auto authschemeMapper = [&](const Aws::String& schemeId){ + auto it = authSchemeMap.find(schemeId); + if (it != authSchemeMap.end()) + { + authSchemes.emplace_back(it->second); + authSchemeMap.erase(it); + } + }; auto epResolutionOutcome = m_endpointProviderForAuth->ResolveEndpoint(epParams); + if (epResolutionOutcome.IsSuccess()) { auto endpoint = std::move(epResolutionOutcome.GetResultWithOwnership()); if (endpoint.GetAttributes()) { auto authSchemeName = endpoint.GetAttributes()->authScheme.GetName(); - if(strcmp(authSchemeName.c_str(),Aws::Auth::ASYMMETRIC_SIGV4_SIGNER) == 0) - { - return {smithy::SigV4aAuthSchemeOption::sigV4aAuthSchemeOption}; - } - else if(strcmp(authSchemeName.c_str(),Aws::Auth::SIGV4_SIGNER) == 0) - { - return {smithy::SigV4AuthSchemeOption::sigV4AuthSchemeOption}; - } - else if(strcmp(authSchemeName.c_str(), S3::S3_EXPRESS_SIGNER_NAME) == 0) - { - return {S3ExpressSigV4AuthSchemeOption::s3ExpressSigV4AuthSchemeOption}; - } + authschemeMapper(authSchemeName); } } + std::transform(authSchemeMap.begin(), + authSchemeMap.end(), + std::back_inserter(authSchemes), + [&](const std::pair& elem){return elem.second;} ); + return authSchemes; } - return {smithy::SigV4AuthSchemeOption::sigV4AuthSchemeOption}; + return {}; } }; } diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ExpressIdentityProviderHeader.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ExpressIdentityProviderHeader.vm index dc81c1f50c1e..cd016958ec89 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ExpressIdentityProviderHeader.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ExpressIdentityProviderHeader.vm @@ -96,81 +96,5 @@ namespace ${rootNamespace} { mutable std::mutex m_shutDownMutex; mutable std::condition_variable m_shutdownCondition; }; - - /*------ Smithy version -----*/ - class ${CppViewHelper.computeExportValue($serviceNamespace)} SmithyS3ExpressIdentityProvider : public smithy::IdentityResolverBase { - public: - explicit SmithyS3ExpressIdentityProvider(const S3Client& s3Client); - ResolveIdentityFutureOutcome getIdentity( - const IdentityProperties& identityProperties, - const AdditionalParameters& additionalParameters) override; - - protected: - - virtual smithy::AwsCredentialIdentity GetS3ExpressAwsIdentity(const std::shared_ptr &serviceSpecificParameters) = 0; - smithy::AwsCredentialIdentity GetCredentialsFromBucket(const Aws::String& bucketName) const; - - private: - const Aws::S3::S3Client& m_s3Client; - mutable std::mutex m_bucketNameMapMutex; - Aws::Map> m_bucketNameMutex; - - protected: - std::shared_ptr GetMutexForBucketName(const Aws::String& bucketName); - }; - - class ${CppViewHelper.computeExportValue($serviceNamespace)} SmithyDefaultS3ExpressIdentityProvider : public SmithyS3ExpressIdentityProvider { - public: - explicit SmithyDefaultS3ExpressIdentityProvider(const S3Client& s3Client); - explicit SmithyDefaultS3ExpressIdentityProvider( - const S3Client& s3Client, - std::shared_ptr> credentialsCache); - SmithyDefaultS3ExpressIdentityProvider(const SmithyDefaultS3ExpressIdentityProvider& other) = delete; - SmithyDefaultS3ExpressIdentityProvider(SmithyDefaultS3ExpressIdentityProvider&& other) noexcept = delete; - SmithyDefaultS3ExpressIdentityProvider& operator=(const SmithyDefaultS3ExpressIdentityProvider& other) = delete; - SmithyDefaultS3ExpressIdentityProvider& operator=(SmithyDefaultS3ExpressIdentityProvider&& other) noexcept = delete; - virtual ~SmithyDefaultS3ExpressIdentityProvider() override = default; - - protected: - smithy::AwsCredentialIdentity GetS3ExpressAwsIdentity(const std::shared_ptr &serviceSpecificParameters) override; - - private: - mutable std::shared_ptr> m_credentialsCache; - }; - - class ${CppViewHelper.computeExportValue($serviceNamespace)} SmithyDefaultAsyncS3ExpressIdentityProvider : public SmithyS3ExpressIdentityProvider { - public: - explicit SmithyDefaultAsyncS3ExpressIdentityProvider( - const S3Client& s3Client, - std::chrono::minutes refreshPeriod = std::chrono::minutes(1)); - - explicit SmithyDefaultAsyncS3ExpressIdentityProvider( - const S3Client& s3Client, - std::shared_ptr> credentialsCache, - std::chrono::minutes refreshPeriod = std::chrono::minutes(1)); - - SmithyDefaultAsyncS3ExpressIdentityProvider(const SmithyDefaultAsyncS3ExpressIdentityProvider& other) = delete; - SmithyDefaultAsyncS3ExpressIdentityProvider(SmithyDefaultAsyncS3ExpressIdentityProvider&& other) noexcept = delete; - SmithyDefaultAsyncS3ExpressIdentityProvider& operator=( - const SmithyDefaultAsyncS3ExpressIdentityProvider& other) = delete; - SmithyDefaultAsyncS3ExpressIdentityProvider& operator=(SmithyDefaultAsyncS3ExpressIdentityProvider&& other) noexcept = delete; - virtual ~SmithyDefaultAsyncS3ExpressIdentityProvider() override; - protected: - smithy::AwsCredentialIdentity GetS3ExpressAwsIdentity(const std::shared_ptr &serviceSpecificParameters) override; - - private: - void refreshIdentities(std::chrono::minutes refreshPeriod); - void threadSafeKeyInsert(const Aws::String& key); - bool threadSafeKeyHas(const Aws::String& key); - void threadSafeKeyEmpty(); - - mutable std::shared_ptr> m_credentialsCache; - Aws::Set m_keysUsed; - mutable std::mutex m_keysUsedMutex; - mutable bool m_shouldStopBackgroundRefresh; - Aws::UniquePtr m_backgroundRefreshThread; - mutable std::mutex m_shutDownMutex; - mutable std::condition_variable m_shutdownCondition; - }; } } \ No newline at end of file diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ExpressIdentityProviderSource.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ExpressIdentityProviderSource.vm index 9818ce2176b1..0fdeda4d5ef7 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ExpressIdentityProviderSource.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ExpressIdentityProviderSource.vm @@ -206,187 +206,4 @@ void DefaultAsyncS3ExpressIdentityProvider::refreshIdentities(std::chrono::minut threadSafeKeyEmpty(); m_shutdownCondition.wait_for(lock, refreshPeriod, [this] { return m_shouldStopBackgroundRefresh; }); } -} - -/* Smithy version */ -SmithyS3ExpressIdentityProvider::SmithyS3ExpressIdentityProvider(const S3Client& s3Client) : m_s3Client(s3Client){} - - -SmithyS3ExpressIdentityProvider::ResolveIdentityFutureOutcome SmithyS3ExpressIdentityProvider::getIdentity( - const IdentityProperties& identityProperties, const AdditionalParameters& additionalParameters){ - const auto params = Aws::MakeShared(S3_EXPRESS_IDENTITY_PROVIDER); - for (const auto& paramMap: {identityProperties, additionalParameters}) - { - TransformAndInsert, String>(paramMap, - params->parameterMap, - [](const Aws::Crt::Variant& value) -> Aws::String - { - if (value.holds_alternative()) - { - return value.get() ? "true" : "false"; - } - if (value.holds_alternative()) - { - return value.get(); - } - return {}; - }); - } - - auto identity = Aws::MakeUnique("DefaultAwsCredentialIdentityResolver", GetS3ExpressAwsIdentity(params)); - - return ResolveIdentityFutureOutcome(std::move(identity)); -} - - -std::shared_ptr SmithyS3ExpressIdentityProvider::GetMutexForBucketName(const Aws::String& bucketName) { - std::lock_guard lock(m_bucketNameMapMutex); - auto it = m_bucketNameMutex.find(bucketName); - if (it != m_bucketNameMutex.end()) { - return it->second; - } - auto bucketMutex = Aws::MakeShared(S3_EXPRESS_IDENTITY_PROVIDER); - m_bucketNameMutex.emplace(bucketName, bucketMutex); - return bucketMutex; -} - -AwsCredentialIdentity SmithyS3ExpressIdentityProvider::GetCredentialsFromBucket(const Aws::String& bucketName) const { - auto outcome = m_s3Client.CreateSession(Model::CreateSessionRequest().WithBucket(bucketName)); - // If we fail the connect call return empty credentials and log an error message. - if (!outcome.IsSuccess()) { - AWS_LOGSTREAM_ERROR(S3_EXPRESS_IDENTITY_PROVIDER, "Failed to make S3Express Connect Call") - return {"", "", {""}, {}, Aws::Crt::Optional()}; - } - auto result = outcome.GetResult(); - const auto &credentials = result.GetCredentials(); - // if expiry is present, use it, otherwise default to 5 minutes expiry - auto expiry = [&]() -> Aws::Utils::DateTime { - if (credentials.ExpirationHasBeenSet()) { - return credentials.GetExpiration(); - } - return Aws::Utils::DateTime::Now() + minutes(5); - }(); - return {credentials.GetAccessKeyId(), - credentials.GetSecretAccessKey(), - credentials.GetSessionToken(), - expiry, - Aws::Crt::Optional()}; -} - - -SmithyDefaultS3ExpressIdentityProvider::SmithyDefaultS3ExpressIdentityProvider(const S3Client& s3Client) - : SmithyS3ExpressIdentityProvider{s3Client}, m_credentialsCache{Aws::MakeShared>(S3_EXPRESS_IDENTITY_PROVIDER, - DEFAULT_CACHE_SIZE)}{} - -SmithyDefaultS3ExpressIdentityProvider::SmithyDefaultS3ExpressIdentityProvider( - const S3Client& s3Client, - std::shared_ptr> credentialsCache) - : SmithyS3ExpressIdentityProvider{s3Client}, m_credentialsCache{credentialsCache} {} - -AwsCredentialIdentity SmithyDefaultS3ExpressIdentityProvider::GetS3ExpressAwsIdentity(const std::shared_ptr &serviceSpecificParameters) { - auto bucketNameIter = serviceSpecificParameters->parameterMap.find("bucketName"); - if (bucketNameIter == serviceSpecificParameters->parameterMap.end()) { - AWS_LOGSTREAM_ERROR(S3_EXPRESS_IDENTITY_PROVIDER, "property bucketName Required to make call") - return {"", "", {""}, {}, Aws::Crt::Optional()}; - } - std::lock_guard lock(*GetMutexForBucketName(bucketNameIter->second)); - AwsCredentialIdentity identity; - auto isInCache = m_credentialsCache->Get(bucketNameIter->second, identity); - if (!isInCache || (identity.expiration().has_value() && (identity.expiration().value() - minutes(1) < Aws::Utils::DateTime::Now())) ) { - identity = SmithyS3ExpressIdentityProvider::GetCredentialsFromBucket(bucketNameIter->second); - if (identity.expiration().has_value()) { - m_credentialsCache->Put(bucketNameIter->second, - identity, - std::chrono::milliseconds(identity.expiration().value().Millis() - Aws::Utils::DateTime::Now().Millis())); - } - } - return identity; -} - -SmithyDefaultAsyncS3ExpressIdentityProvider::SmithyDefaultAsyncS3ExpressIdentityProvider( - const S3Client& s3Client, std::chrono::minutes refreshPeriod) - : SmithyDefaultAsyncS3ExpressIdentityProvider(s3Client, - Aws::MakeShared>( - S3_EXPRESS_IDENTITY_PROVIDER, DEFAULT_CACHE_SIZE), - refreshPeriod) {} - -SmithyDefaultAsyncS3ExpressIdentityProvider::SmithyDefaultAsyncS3ExpressIdentityProvider( - const S3Client& s3Client, std::shared_ptr> credentialsCache, - std::chrono::minutes refreshPeriod) - : SmithyS3ExpressIdentityProvider(s3Client), m_credentialsCache(std::move(credentialsCache)) { - // Start a thread to background refresh the keys currently in the cache. - m_shouldStopBackgroundRefresh = false; - m_backgroundRefreshThread = Aws::MakeUnique( - S3_EXPRESS_IDENTITY_PROVIDER, std::thread(&SmithyDefaultAsyncS3ExpressIdentityProvider::refreshIdentities, this, refreshPeriod)); -} - -SmithyDefaultAsyncS3ExpressIdentityProvider::~SmithyDefaultAsyncS3ExpressIdentityProvider(){ - { - std::unique_lock lock(m_shutDownMutex); - m_shouldStopBackgroundRefresh = true; - m_shutdownCondition.notify_all(); - } - m_backgroundRefreshThread->join(); -} - -AwsCredentialIdentity SmithyDefaultAsyncS3ExpressIdentityProvider::GetS3ExpressAwsIdentity(const std::shared_ptr &serviceSpecificParameters){ - auto bucketNameIter = serviceSpecificParameters->parameterMap.find("bucketName"); - if (bucketNameIter == serviceSpecificParameters->parameterMap.end()) { - AWS_LOGSTREAM_ERROR(S3_EXPRESS_IDENTITY_PROVIDER, "property bucketName Required to make call") - return {"", "", {""}, {}, Aws::Crt::Optional()}; - } - threadSafeKeyInsert(bucketNameIter->second); - std::lock_guard lock(*GetMutexForBucketName(bucketNameIter->second)); - AwsCredentialIdentity identity; - auto isInCache = m_credentialsCache->Get(bucketNameIter->second, identity); - if (!isInCache || (identity.expiration().has_value() && (identity.expiration().value() - minutes(1) < Aws::Utils::DateTime::Now())) ) { - identity = SmithyS3ExpressIdentityProvider::GetCredentialsFromBucket(bucketNameIter->second); - if (identity.expiration().has_value()) { - m_credentialsCache->Put(bucketNameIter->second, - identity, - std::chrono::milliseconds(identity.expiration().value().Millis() - Aws::Utils::DateTime::Now().Millis())); - } - } - return identity; -} - -void SmithyDefaultAsyncS3ExpressIdentityProvider::threadSafeKeyEmpty() { - std::lock_guard lock(m_keysUsedMutex); - m_keysUsed.clear(); -} - -bool SmithyDefaultAsyncS3ExpressIdentityProvider::threadSafeKeyHas(const Aws::String& key) { - std::lock_guard lock(m_keysUsedMutex); - return m_keysUsed.find(key) != m_keysUsed.end(); -} - -void SmithyDefaultAsyncS3ExpressIdentityProvider::threadSafeKeyInsert(const Aws::String& key) { - std::lock_guard lock(m_keysUsedMutex); - m_keysUsed.insert(key); -} - -void SmithyDefaultAsyncS3ExpressIdentityProvider::refreshIdentities(std::chrono::minutes refreshPeriod) { - auto filterUnusedKeys = [&](const Aws::String &bucketName, const SmithyCacheValueType &valueType) -> bool { - std::lock_guard lock(*GetMutexForBucketName(bucketName)); - AWS_UNREFERENCED_PARAM(valueType); - return !threadSafeKeyHas(bucketName); - }; - auto refreshIdentityWhenCloseToExpiry = [&](const Aws::String &bucketName, - const SmithyCacheValueType &valueType) -> SmithyCacheValueType { - std::lock_guard lock(*GetMutexForBucketName(bucketName)); - if ((!valueType.val.expiration().has_value()) || - (duration_cast(refreshPeriod).count() < valueType.val.expiration().value().Millis() && - valueType.val.expiration().value() - refreshPeriod < Aws::Utils::DateTime::Now())) { - auto updatedIdentity = this->SmithyS3ExpressIdentityProvider::GetCredentialsFromBucket(bucketName); - return {updatedIdentity.expiration().value(), updatedIdentity}; - } - return valueType; - }; - std::unique_lock lock(m_shutDownMutex); - while (!m_shouldStopBackgroundRefresh) { - m_credentialsCache->Filter(filterUnusedKeys); - m_credentialsCache->Transform(refreshIdentityWhenCloseToExpiry); - threadSafeKeyEmpty(); - m_shutdownCondition.wait_for(lock, refreshPeriod, [this] { return m_shouldStopBackgroundRefresh; }); - } } \ No newline at end of file diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ExpressSigV4AuthSchemeHeader.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ExpressSigV4AuthSchemeHeader.vm index af8f22632bbc..9cd7f735fa5c 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ExpressSigV4AuthSchemeHeader.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ExpressSigV4AuthSchemeHeader.vm @@ -15,7 +15,7 @@ namespace ${rootNamespace} { namespace ${serviceNamespace} { constexpr char SIGV4_EXPRESS[] = "sigv4-s3express"; - class ${CppViewHelper.computeExportValue($serviceNamespace)} S3ExpressSigV4AuthScheme : public smithy::AuthScheme< smithy::AwsCredentialIdentityBase> + class ${CppViewHelper.computeExportValue($serviceNamespace)} S3ExpressSigV4AuthScheme : public smithy::AuthScheme { public: using AwsCredentialIdentityResolverT = smithy::IdentityResolverBase; @@ -29,7 +29,7 @@ namespace ${serviceNamespace} { bool urlEscapePath) : AuthScheme(SIGV4_EXPRESS), m_identityResolver{identityResolver}, - m_signer{Aws::MakeShared>("S3ExpressSigV4AuthScheme", serviceName, region, policy, urlEscapePath)} + m_signer{Aws::MakeShared>("S3ExpressSigV4AuthScheme", serviceName, region, policy, urlEscapePath)} { assert(m_identityResolver); assert(m_signer); diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ExpressSignerHeader.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ExpressSignerHeader.vm index 11dc855cb571..ed231693ae44 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ExpressSignerHeader.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ExpressSignerHeader.vm @@ -82,6 +82,35 @@ namespace { mutable std::mutex m_requestProcessing; }; + template + class SmithyS3ExpressSigner : public smithy::AwsSignerBase { + + public: + explicit SmithyS3ExpressSigner(const Aws::String& serviceName, const Aws::String& region) + : m_signer(serviceName, region) + { + } + + explicit SmithyS3ExpressSigner(const Aws::String& serviceName, const Aws::String& region, Aws::Client::AWSAuthV4Signer::PayloadSigningPolicy policy, bool escapeUrl) + : m_signer(serviceName, region, policy, escapeUrl) + { + } + + SigningFutureOutcome sign(std::shared_ptr httpRequest, const S3ExpressIdentity& identity, SigningProperties properties) + { + const smithy::AwsCredentialIdentity identityToUse{identity.accessKeyId(), identity.secretAccessKey(), identity.sessionToken(), identity.expiration(), identity.accountId()}; + return m_signer.sign(httpRequest, identityToUse, properties); + } + + SigningFutureOutcome presign(std::shared_ptr httpRequest, const S3ExpressIdentity& identity, SigningProperties properties, const Aws::String& region, const Aws::String& serviceName, long long expirationTimeInSeconds) + { + const smithy::AwsCredentialIdentity identityToUse{identity.accessKeyId(), identity.secretAccessKey(), identity.sessionToken(), identity.expiration(), identity.accountId()}; + return m_signer.presign(httpRequest, identityToUse, properties, region, serviceName, expirationTimeInSeconds); + } + + private: + S3ExpressSignerBase m_signer; + }; class AWS_S3_API S3ExpressSigner : public Aws::Client::AWSAuthV4Signer { public: @@ -138,6 +167,5 @@ namespace { const Aws::String m_region; const Aws::String m_endpoint; }; - } } diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ExpressSignerProviderSource.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ExpressSignerProviderSource.vm index 47ec52cd1f64..505585cc2aac 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ExpressSignerProviderSource.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ExpressSignerProviderSource.vm @@ -21,12 +21,12 @@ ${rootNamespace}::Auth::S3ExpressSignerProvider::S3ExpressSignerProvider( region, signingPolicy, urlEscapePath) { - m_signers.emplace_back(std::static_pointer_cast(Aws::MakeShared(CLASS_TAG, + m_signers.emplace_back(Aws::MakeShared(CLASS_TAG, S3ExpressIdentityProvider, credentialsProvider, serviceName.c_str(), region, signingPolicy, urlEscapePath, - AWSSigningAlgorithm::SIGV4))); + AWSSigningAlgorithm::SIGV4)); } \ No newline at end of file diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientSourceInit.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientSourceInit.vm index 0b69a4471dd3..77a69b98d24e 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientSourceInit.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientSourceInit.vm @@ -60,7 +60,7 @@ ${className}::${className}(const ${clientConfiguration}& clientConfiguration, return { #foreach($entry in $AuthSchemeMapEntries) #if($AuthSchemes && $AuthSchemes[$foreach.index] == $s3_express_auth) - {${entry}{clientConfiguration.smithyIdentityProviderSupplier(*this), GetServiceName(), Aws::Region::ComputeSignerRegion(clientConfiguration.region), clientConfiguration.payloadSigningPolicy, false}}, + {${entry}{clientConfiguration.identityProviderSupplier(*this), GetServiceName(), Aws::Region::ComputeSignerRegion(clientConfiguration.region), clientConfiguration.payloadSigningPolicy, false}}, #else {${entry}{credsResolver, GetServiceName(), Aws::Region::ComputeSignerRegion(clientConfiguration.region), clientConfiguration.payloadSigningPolicy, false}}, #end @@ -96,7 +96,7 @@ ${className}::${className}(const AWSCredentials& credentials, return { #foreach($entry in $AuthSchemeMapEntries) #if($AuthSchemes && $AuthSchemes[$foreach.index] == $s3_express_auth) - {${entry}{clientConfiguration.smithyIdentityProviderSupplier(*this), GetServiceName(), Aws::Region::ComputeSignerRegion(clientConfiguration.region), clientConfiguration.payloadSigningPolicy, false}}, + {${entry}{clientConfiguration.identityProviderSupplier(*this), GetServiceName(), Aws::Region::ComputeSignerRegion(clientConfiguration.region), clientConfiguration.payloadSigningPolicy, false}}, #else {${entry}{credsResolver, GetServiceName(), Aws::Region::ComputeSignerRegion(clientConfiguration.region), clientConfiguration.payloadSigningPolicy, false}}, #end @@ -132,7 +132,7 @@ ${className}::${className}(const std::shared_ptr& creden return { #foreach($entry in $AuthSchemeMapEntries) #if($AuthSchemes && $AuthSchemes[$foreach.index] == $s3_express_auth) - {${entry}{clientConfiguration.smithyIdentityProviderSupplier(*this), GetServiceName(), Aws::Region::ComputeSignerRegion(clientConfiguration.region), clientConfiguration.payloadSigningPolicy, false}}, + {${entry}{clientConfiguration.identityProviderSupplier(*this), GetServiceName(), Aws::Region::ComputeSignerRegion(clientConfiguration.region), clientConfiguration.payloadSigningPolicy, false}}, #else {${entry}{credsResolver, GetServiceName(), Aws::Region::ComputeSignerRegion(clientConfiguration.region), clientConfiguration.payloadSigningPolicy, false}}, #end @@ -167,7 +167,7 @@ ${className}::${className}(const Client::ClientConfiguration& clientConfiguratio return { #foreach($entry in $AuthSchemeMapEntries) #if($AuthSchemes && $AuthSchemes[$foreach.index] == $s3_express_auth) - {${entry}{Aws::MakeShared(ALLOCATION_TAG, *this), GetServiceName(), Aws::Region::ComputeSignerRegion(clientConfiguration.region), signPayloads, false}}, + {${entry}{Aws::MakeShared(ALLOCATION_TAG, *this), GetServiceName(), Aws::Region::ComputeSignerRegion(clientConfiguration.region), signPayloads, false}}, #else {${entry}{credsResolver, GetServiceName(), Aws::Region::ComputeSignerRegion(clientConfiguration.region), signPayloads, false}}, #end @@ -197,7 +197,7 @@ ${className}::${className}( return { #foreach($entry in $AuthSchemeMapEntries) #if($AuthSchemes && $AuthSchemes[$foreach.index] == $s3_express_auth) - {${entry}{Aws::MakeShared(ALLOCATION_TAG, *this), GetServiceName(), Aws::Region::ComputeSignerRegion(clientConfiguration.region), signPayloads, false}}, + {${entry}{Aws::MakeShared(ALLOCATION_TAG, *this), GetServiceName(), Aws::Region::ComputeSignerRegion(clientConfiguration.region), signPayloads, false}}, #else {${entry}{credsResolver, GetServiceName(), Aws::Region::ComputeSignerRegion(clientConfiguration.region), signPayloads, false}}, #end @@ -227,7 +227,7 @@ ${className}::${className}( return { #foreach($entry in $AuthSchemeMapEntries) #if($AuthSchemes && $AuthSchemes[$foreach.index] == $s3_express_auth) - {${entry}{Aws::MakeShared(ALLOCATION_TAG, *this), GetServiceName(), Aws::Region::ComputeSignerRegion(clientConfiguration.region), signPayloads, false}}, + {${entry}{Aws::MakeShared(ALLOCATION_TAG, *this), GetServiceName(), Aws::Region::ComputeSignerRegion(clientConfiguration.region), signPayloads, false}}, #else {${entry}{credsResolver, GetServiceName(), Aws::Region::ComputeSignerRegion(clientConfiguration.region), signPayloads, false}}, #end @@ -237,77 +237,20 @@ ${className}::${className}( }) {} -${className}& ${className}::operator=(const ${className} &rhs) { - if (&rhs == this) { - return *this; - } - - AwsSmithyClientBase::deepCopy(Aws::MakeUnique<${clientConfiguration}>(GetServiceName(), rhs.m_clientConfiguration), - GetServiceName(), - Aws::Http::CreateHttpClient(rhs.m_clientConfiguration), - Aws::MakeShared<${metadata.classNamePrefix}ErrorMarshaller>(GetServiceName())); - m_endpointProvider = rhs.m_endpointProvider; - m_authSchemeResolver = Aws::MakeShared<${AuthSchemeResolver}>(GetServiceName()); - m_errorMarshaller = Aws::MakeShared<${metadata.classNamePrefix}ErrorMarshaller>(GetServiceName()); - if (m_clientConfig.get()) { - m_clientConfiguration = *static_cast<${clientConfiguration}*>(m_clientConfig.get()); - m_serializer = Aws::MakeShared(GetServiceName(), m_clientConfiguration.telemetryProvider); - } - initClient(); - m_authSchemes = - [&]() -> Aws::UnorderedMap > { - auto credsResolver = Aws::MakeShared(ALLOCATION_TAG); - return { -#foreach($entry in $AuthSchemeMapEntries) -#if($AuthSchemes && $AuthSchemes[$foreach.index] == $s3_express_auth) - {${entry}{Aws::MakeShared(ALLOCATION_TAG, *this), GetServiceName(), Aws::Region::ComputeSignerRegion(m_clientConfiguration.region), m_clientConfiguration.payloadSigningPolicy, false}}, -#else - {${entry}{credsResolver, GetServiceName(), Aws::Region::ComputeSignerRegion(m_clientConfiguration.region), m_clientConfiguration.payloadSigningPolicy, false}}, -#end -#end - }; - }(); - return *this; -} - +${className}& ${className}::operator=(const ${className} &rhs) = default; -${className}& ${className}::operator=(${className} &&rhs) noexcept { - if (&rhs == this) { - return *this; - } - m_endpointProvider = std::move(rhs.m_endpointProvider); - m_authSchemeResolver = std::move(rhs.m_authSchemeResolver); - m_errorMarshaller = std::move(rhs.m_errorMarshaller); - if (m_clientConfig.get()) { - m_clientConfiguration = *static_cast<${clientConfiguration}*>(m_clientConfig.get()); - m_serializer = std::move(rhs.m_serializer); - } +${className}& ${className}::operator=(${className} &&rhs) = default; - m_authSchemes = - [&]() -> Aws::UnorderedMap > { - auto credsResolver = Aws::MakeShared(ALLOCATION_TAG); - return { -#foreach($entry in $AuthSchemeMapEntries) -#if($AuthSchemes && $AuthSchemes[$foreach.index] == $s3_express_auth) - {${entry}{Aws::MakeShared(ALLOCATION_TAG, *this), GetServiceName(), Aws::Region::ComputeSignerRegion(m_clientConfiguration.region), m_clientConfiguration.payloadSigningPolicy, false}}, -#else - {${entry}{credsResolver, GetServiceName(), Aws::Region::ComputeSignerRegion(m_clientConfiguration.region), m_clientConfiguration.payloadSigningPolicy, false}}, -#end -#end - }; - }(); - return *this; -} /* copy/move constructors */ ${className}::${className}(const ${className} &rhs) : - AwsSmithyClientT(rhs),Aws::Client::ClientWithAsyncTemplateMethods() { + Aws::Client::ClientWithAsyncTemplateMethods(), AwsSmithyClientT(rhs) { m_authSchemes = [&]() -> Aws::UnorderedMap > { auto credsResolver = Aws::MakeShared(ALLOCATION_TAG); return { #foreach($entry in $AuthSchemeMapEntries) #if($AuthSchemes && $AuthSchemes[$foreach.index] == $s3_express_auth) - {${entry}{Aws::MakeShared(ALLOCATION_TAG, *this), GetServiceName(), Aws::Region::ComputeSignerRegion(m_clientConfiguration.region), m_clientConfiguration.payloadSigningPolicy, false}}, + {${entry}{Aws::MakeShared(ALLOCATION_TAG, *this), GetServiceName(), Aws::Region::ComputeSignerRegion(m_clientConfiguration.region), m_clientConfiguration.payloadSigningPolicy, false}}, #else {${entry}{credsResolver, GetServiceName(), Aws::Region::ComputeSignerRegion(m_clientConfiguration.region), m_clientConfiguration.payloadSigningPolicy, false}}, #end