From 6a8062ae01b7035257c05a94e4c9ac4fcb49a3b9 Mon Sep 17 00:00:00 2001 From: Soumava Bera Date: Thu, 2 Jan 2025 16:54:59 -0500 Subject: [PATCH 01/13] copyable client changes --- .../include/smithy/client/AwsSmithyClient.h | 6 +- .../smithy/client/AwsSmithyClientBase.h | 82 +++++++++++++++++-- 2 files changed, 79 insertions(+), 9 deletions(-) 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 32e22e30e85..97971b0699c 100644 --- a/src/aws-cpp-sdk-core/include/smithy/client/AwsSmithyClient.h +++ b/src/aws-cpp-sdk-core/include/smithy/client/AwsSmithyClient.h @@ -39,12 +39,12 @@ namespace client const std::shared_ptr endpointProvider, const std::shared_ptr& authSchemeResolver, const Aws::UnorderedMap& authSchemes) - : AwsSmithyClientBase(Aws::MakeUnique(ServiceNameT, clientConfig), serviceName, httpClient, errorMarshaller), + : AwsSmithyClientBase(Aws::MakeShared(ServiceNameT, clientConfig), serviceName, httpClient, errorMarshaller), m_clientConfiguration(*static_cast(AwsSmithyClientBase::m_clientConfig.get())), m_endpointProvider(endpointProvider), m_authSchemeResolver(authSchemeResolver), m_authSchemes(authSchemes), - m_serializer(Aws::MakeUnique(ServiceNameT, m_clientConfiguration.telemetryProvider)) + m_serializer(Aws::MakeShared(ServiceNameT, m_clientConfiguration.telemetryProvider)) { m_serviceName = ServiceNameT; } @@ -135,7 +135,7 @@ namespace client std::shared_ptr m_endpointProvider{}; std::shared_ptr m_authSchemeResolver{}; Aws::UnorderedMap m_authSchemes{}; - Aws::UniquePtr m_serializer{}; + std::shared_ptr m_serializer{}; }; } // 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 045c9ce7d43..469943c90a8 100644 --- a/src/aws-cpp-sdk-core/include/smithy/client/AwsSmithyClientBase.h +++ b/src/aws-cpp-sdk-core/include/smithy/client/AwsSmithyClientBase.h @@ -17,6 +17,8 @@ #include #include #include +#include +#include namespace Aws { @@ -65,6 +67,8 @@ namespace client /* Non-template base client class that contains main Aws Client Request pipeline logic */ class SMITHY_API AwsSmithyClientBase { + private: + const char* ALLOC_TAG{"AwsSmithyClientBase"}; public: using HttpRequest = Aws::Http::HttpRequest; using HttpResponse = Aws::Http::HttpResponse; @@ -79,7 +83,7 @@ namespace client using SelectAuthSchemeOptionOutcome = Aws::Utils::Outcome; using ResolveEndpointOutcome = Aws::Utils::Outcome; - AwsSmithyClientBase(Aws::UniquePtr&& clientConfig, + AwsSmithyClientBase(std::shared_ptr&& clientConfig, Aws::String serviceName, std::shared_ptr httpClient, std::shared_ptr errorMarshaller) : @@ -119,10 +123,76 @@ namespace client m_userAgent = Aws::Client::ComputeUserAgentString(m_clientConfig.get()); } - AwsSmithyClientBase(const AwsSmithyClientBase&) = delete; - AwsSmithyClientBase(AwsSmithyClientBase&&) = delete; - AwsSmithyClientBase& operator=(const AwsSmithyClientBase&) = delete; - AwsSmithyClientBase& operator=(AwsSmithyClientBase&&) = delete; + + AwsSmithyClientBase& operator=(const AwsSmithyClientBase& target) + { + if (this != &target) + { + m_clientConfig = target.m_clientConfig; + m_serviceName = target.m_serviceName; + m_userAgent = target.m_userAgent; + m_httpClient = Aws::Http::CreateHttpClient(*target.m_clientConfig); + + // marshaller could be of different types + if (auto jsonMarshaller = std::dynamic_pointer_cast(m_errorMarshaller)) { + m_errorMarshaller = Aws::MakeShared(ALLOC_TAG); + } + else if (auto xmlMarshaller = std::dynamic_pointer_cast(m_errorMarshaller)) { + m_errorMarshaller = Aws::MakeShared(ALLOC_TAG); + } + else if (auto jsonQueryCompatibleMarshaller = std::dynamic_pointer_cast(m_errorMarshaller)) { + m_errorMarshaller = Aws::MakeShared(ALLOC_TAG); + } + + m_interceptors = {Aws::MakeShared(ALLOC_TAG)}; + } + return *this; + } + + AwsSmithyClientBase(const AwsSmithyClientBase& target): + m_clientConfig{target.m_clientConfig}, + m_serviceName{target.m_serviceName}, + m_userAgent{target.m_userAgent}, + m_httpClient{Aws::Http::CreateHttpClient(*target.m_clientConfig)} + { + // marshaller could be of different types + if (auto jsonMarshaller = std::dynamic_pointer_cast(m_errorMarshaller)) { + m_errorMarshaller = Aws::MakeShared(ALLOC_TAG); + } + else if (auto xmlMarshaller = std::dynamic_pointer_cast(m_errorMarshaller)) { + m_errorMarshaller = Aws::MakeShared(ALLOC_TAG); + } + else if (auto jsonQueryCompatibleMarshaller = std::dynamic_pointer_cast(m_errorMarshaller)) { + m_errorMarshaller = Aws::MakeShared(ALLOC_TAG); + } + + m_interceptors = {Aws::MakeShared(ALLOC_TAG)}; + } + + AwsSmithyClientBase(AwsSmithyClientBase&& target): + m_clientConfig{std::move(target.m_clientConfig)}, + m_serviceName{std::move(target.m_serviceName)}, + m_userAgent{std::move(target.m_userAgent)}, + m_httpClient{std::move(target.m_httpClient)}, + m_errorMarshaller{std::move(target.m_errorMarshaller)}, + m_interceptors{std::move(target.m_interceptors)} + { + + } + + AwsSmithyClientBase& operator=(AwsSmithyClientBase&& target) + { + if (this != &target) + { + m_clientConfig = std::move(target.m_clientConfig); + m_serviceName = std::move(std::move(target.m_serviceName)); + m_userAgent = std::move(target.m_userAgent); + m_httpClient = std::move(target.m_httpClient); + m_errorMarshaller = std::move(target.m_errorMarshaller); + m_interceptors = std::move(target.m_interceptors); + } + return *this; + } virtual ~AwsSmithyClientBase() = default; @@ -160,7 +230,7 @@ namespace client virtual bool AdjustClockSkew(HttpResponseOutcome& outcome, const AuthSchemeOption& authSchemeOption) const = 0; protected: - Aws::UniquePtr m_clientConfig; + std::shared_ptr m_clientConfig; Aws::String m_serviceName; Aws::String m_userAgent; From 2ce3bf970bbf3c7d8b3b06f014c2de5ad22c3d0c Mon Sep 17 00:00:00 2001 From: Soumava Bera Date: Sun, 5 Jan 2025 13:42:13 -0500 Subject: [PATCH 02/13] copy client changes with test case --- .../include/aws/dynamodb/DynamoDBClient.h | 5 +- .../aws/core/client/AWSClientAsyncCRTP.h | 23 +++ .../include/aws/core/utils/Cache.h | 25 +++ .../include/aws/core/utils/ConcurrentCache.h | 27 +++ .../include/smithy/client/AwsSmithyClient.h | 41 ++++- .../smithy/client/AwsSmithyClientBase.h | 48 +---- .../smithy/client/SmithyClientTest.cpp | 3 +- .../TableOperationTest.cpp | 171 ++++++++++++++++++ .../velocity/cpp/smithy/SmithyClientHeader.vm | 5 +- 9 files changed, 295 insertions(+), 53 deletions(-) diff --git a/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClient.h b/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClient.h index ad8f418f60a..2986ad28f5c 100644 --- a/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClient.h +++ b/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClient.h @@ -12,7 +12,7 @@ #include #include #include - +#include namespace Aws { namespace DynamoDB @@ -42,7 +42,8 @@ namespace DynamoDB Aws::Crt::Variant, DynamoDBEndpointProviderBase, smithy::client::JsonOutcomeSerializer, - smithy::client::JsonOutcome>, + smithy::client::JsonOutcome, + Aws::Client::DynamoDBErrorMarshaller>, Aws::Client::ClientWithAsyncTemplateMethods { public: diff --git a/src/aws-cpp-sdk-core/include/aws/core/client/AWSClientAsyncCRTP.h b/src/aws-cpp-sdk-core/include/aws/core/client/AWSClientAsyncCRTP.h index 7210ee38d69..e0a8b5b1dcf 100644 --- a/src/aws-cpp-sdk-core/include/aws/core/client/AWSClientAsyncCRTP.h +++ b/src/aws-cpp-sdk-core/include/aws/core/client/AWSClientAsyncCRTP.h @@ -75,6 +75,29 @@ namespace Client return *this; } + ClientWithAsyncTemplateMethods& operator=(ClientWithAsyncTemplateMethods&& other) + { + if (&other != this) + { + ShutdownSdkClient(static_cast(this)); + m_isInitialized = other.m_isInitialized.load(); + m_operationsProcessed = other.m_operationsProcessed.load(); + } + + return *this; + } + + ClientWithAsyncTemplateMethods(ClientWithAsyncTemplateMethods&& other): + m_isInitialized(other.m_isInitialized.load()), + m_operationsProcessed(other.m_operationsProcessed.load()) + { + + AwsServiceClientT* pThis = static_cast(this); + Aws::Utils::ComponentRegistry::RegisterComponent(AwsServiceClientT::GetServiceName(), + pThis, + &AwsServiceClientT::ShutdownSdkClient); + } + virtual ~ClientWithAsyncTemplateMethods() { AwsServiceClientT* pClient = static_cast(this); diff --git a/src/aws-cpp-sdk-core/include/aws/core/utils/Cache.h b/src/aws-cpp-sdk-core/include/aws/core/utils/Cache.h index 74d40ea02d1..99d6fdce2d7 100644 --- a/src/aws-cpp-sdk-core/include/aws/core/utils/Cache.h +++ b/src/aws-cpp-sdk-core/include/aws/core/utils/Cache.h @@ -27,6 +27,31 @@ namespace Aws explicit Cache(size_t initialSize = 1000) : m_maxSize(initialSize) { } + + //this can't be default as compiler wont implicitly create copy constructor for const qualified members + Cache(const Cache& other):m_entries{other.m_entries},m_maxSize{other.m_maxSize}{ + } + + Cache(Cache&& other):m_entries{std::move(other.m_entries)},m_maxSize{other.m_maxSize}{ + } + + //m_maxSize is a const, so we don't touch it + Cache& operator=(const Cache& other){ + if(&other == this){ + return *this; + } + m_entries = other.m_entries; + return *this; + } + + Cache& operator=(Cache&& other){ + if(&other == this){ + return *this; + } + m_entries = std::move(other.m_entries); + return *this; + } + struct Value { diff --git a/src/aws-cpp-sdk-core/include/aws/core/utils/ConcurrentCache.h b/src/aws-cpp-sdk-core/include/aws/core/utils/ConcurrentCache.h index f0c2b4346c4..bb0772f2998 100644 --- a/src/aws-cpp-sdk-core/include/aws/core/utils/ConcurrentCache.h +++ b/src/aws-cpp-sdk-core/include/aws/core/utils/ConcurrentCache.h @@ -19,6 +19,33 @@ namespace Aws public: explicit ConcurrentCache(size_t size = 1000) : m_cache(size) { } + + ConcurrentCache(const ConcurrentCache& other) : m_cache(other.m_cache) { + + } + + ConcurrentCache(ConcurrentCache& other) : m_cache(std::move(other.m_cache)) { + + } + + ConcurrentCache& operator=(const ConcurrentCache& other){ + if(&other != this) + { + m_cache = other.m_cache; + } + return *this; + } + + ConcurrentCache& operator=(ConcurrentCache&& other){ + if(&other != this) + { + m_cache = std::move(other.m_cache); + } + return *this; + } + + + bool Get(const TKey& key, TValue& value) const { Aws::Utils::Threading::ReaderLockGuard g(m_rwlock); 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 97971b0699c..070bf679a49 100644 --- a/src/aws-cpp-sdk-core/include/smithy/client/AwsSmithyClient.h +++ b/src/aws-cpp-sdk-core/include/smithy/client/AwsSmithyClient.h @@ -29,10 +29,15 @@ namespace client typename AuthSchemesVariantT, typename EndpointProviderT, typename SerializerT, - typename ResponseT> + typename ResponseT, + typename MarshallerT> class AwsSmithyClientT : public AwsSmithyClientBase { + private: + public: + static_assert(std::is_base_of::value, "MarshallerT must be derived from class Aws::Client::AWSErrorMarshaller"); + explicit AwsSmithyClientT(const ServiceClientConfigurationT& clientConfig, const Aws::String& serviceName, const std::shared_ptr& httpClient, const std::shared_ptr& errorMarshaller, @@ -49,6 +54,38 @@ namespace client m_serviceName = ServiceNameT; } + AwsSmithyClientT(const AwsSmithyClientT& other): + AwsSmithyClientBase(other), + m_clientConfiguration{other.m_clientConfiguration}, + m_endpointProvider{other.m_endpointProvider}, + m_authSchemeResolver{other.m_authSchemeResolver}, + m_authSchemes{other.m_authSchemes}, + m_serializer{Aws::MakeShared(ServiceNameT, m_clientConfiguration.telemetryProvider)} + { + m_errorMarshaller = Aws::MakeShared(other.m_serviceName.c_str()); + } + + + AwsSmithyClientT& operator=(const AwsSmithyClientT& other) + { + if(this != &other) + { + AwsSmithyClientBase::operator=(other); + m_clientConfiguration = other.m_clientConfiguration; + m_endpointProvider = other.m_endpointProvider; + m_authSchemeResolver = other.m_authSchemeResolver; + m_authSchemes = other.m_authSchemes; + m_serializer = Aws::MakeShared(other.m_serviceName.c_str(), m_clientConfiguration.telemetryProvider); + m_errorMarshaller = Aws::MakeShared(other.m_serviceName.c_str()); + } + + return *this; + } + + AwsSmithyClientT (AwsSmithyClientT&&) = default; + + AwsSmithyClientT& operator=(AwsSmithyClientT&&) = default; + virtual ~AwsSmithyClientT() = default; protected: @@ -131,7 +168,7 @@ namespace client } protected: - ServiceClientConfigurationT& m_clientConfiguration; + ServiceClientConfigurationT m_clientConfiguration; std::shared_ptr m_endpointProvider{}; std::shared_ptr m_authSchemeResolver{}; Aws::UnorderedMap m_authSchemes{}; 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 469943c90a8..43e9f0699b8 100644 --- a/src/aws-cpp-sdk-core/include/smithy/client/AwsSmithyClientBase.h +++ b/src/aws-cpp-sdk-core/include/smithy/client/AwsSmithyClientBase.h @@ -132,18 +132,6 @@ namespace client m_serviceName = target.m_serviceName; m_userAgent = target.m_userAgent; m_httpClient = Aws::Http::CreateHttpClient(*target.m_clientConfig); - - // marshaller could be of different types - if (auto jsonMarshaller = std::dynamic_pointer_cast(m_errorMarshaller)) { - m_errorMarshaller = Aws::MakeShared(ALLOC_TAG); - } - else if (auto xmlMarshaller = std::dynamic_pointer_cast(m_errorMarshaller)) { - m_errorMarshaller = Aws::MakeShared(ALLOC_TAG); - } - else if (auto jsonQueryCompatibleMarshaller = std::dynamic_pointer_cast(m_errorMarshaller)) { - m_errorMarshaller = Aws::MakeShared(ALLOC_TAG); - } - m_interceptors = {Aws::MakeShared(ALLOC_TAG)}; } return *this; @@ -155,44 +143,12 @@ namespace client m_userAgent{target.m_userAgent}, m_httpClient{Aws::Http::CreateHttpClient(*target.m_clientConfig)} { - // marshaller could be of different types - if (auto jsonMarshaller = std::dynamic_pointer_cast(m_errorMarshaller)) { - m_errorMarshaller = Aws::MakeShared(ALLOC_TAG); - } - else if (auto xmlMarshaller = std::dynamic_pointer_cast(m_errorMarshaller)) { - m_errorMarshaller = Aws::MakeShared(ALLOC_TAG); - } - else if (auto jsonQueryCompatibleMarshaller = std::dynamic_pointer_cast(m_errorMarshaller)) { - m_errorMarshaller = Aws::MakeShared(ALLOC_TAG); - } - m_interceptors = {Aws::MakeShared(ALLOC_TAG)}; } - AwsSmithyClientBase(AwsSmithyClientBase&& target): - m_clientConfig{std::move(target.m_clientConfig)}, - m_serviceName{std::move(target.m_serviceName)}, - m_userAgent{std::move(target.m_userAgent)}, - m_httpClient{std::move(target.m_httpClient)}, - m_errorMarshaller{std::move(target.m_errorMarshaller)}, - m_interceptors{std::move(target.m_interceptors)} - { + AwsSmithyClientBase(AwsSmithyClientBase&& target) = default; - } - - AwsSmithyClientBase& operator=(AwsSmithyClientBase&& target) - { - if (this != &target) - { - m_clientConfig = std::move(target.m_clientConfig); - m_serviceName = std::move(std::move(target.m_serviceName)); - m_userAgent = std::move(target.m_userAgent); - m_httpClient = std::move(target.m_httpClient); - m_errorMarshaller = std::move(target.m_errorMarshaller); - m_interceptors = std::move(target.m_interceptors); - } - return *this; - } + AwsSmithyClientBase& operator=(AwsSmithyClientBase&& target) = default; virtual ~AwsSmithyClientBase() = default; diff --git a/tests/aws-cpp-sdk-core-tests/smithy/client/SmithyClientTest.cpp b/tests/aws-cpp-sdk-core-tests/smithy/client/SmithyClientTest.cpp index daf888c8c3e..2200612c1b7 100644 --- a/tests/aws-cpp-sdk-core-tests/smithy/client/SmithyClientTest.cpp +++ b/tests/aws-cpp-sdk-core-tests/smithy/client/SmithyClientTest.cpp @@ -155,7 +155,8 @@ using MySmithyClient = smithy::client::AwsSmithyClientT; + Aws::String, + Aws::Client::XmlErrorMarshaller>; class TestClient : public MySmithyClient { diff --git a/tests/aws-cpp-sdk-dynamodb-integration-tests/TableOperationTest.cpp b/tests/aws-cpp-sdk-dynamodb-integration-tests/TableOperationTest.cpp index 38741a836ca..61cc394ba8c 100644 --- a/tests/aws-cpp-sdk-dynamodb-integration-tests/TableOperationTest.cpp +++ b/tests/aws-cpp-sdk-dynamodb-integration-tests/TableOperationTest.cpp @@ -130,6 +130,7 @@ class TableOperationTest : public ::testing::Test { { putItemResultSemaphore.notify_all(); } + } void DeleteItemOutcomeReceived(const DynamoDBClient* sender, const DeleteItemRequest& request, const DeleteItemOutcome& outcome, const std::shared_ptr& context) @@ -1510,5 +1511,175 @@ TEST_F(TableOperationTest, TestEndpointOverride) } } +TEST_F(TableOperationTest, TestClientCopy) +{ + + Aws::Http::TransferLibType transferType = Aws::Http::TransferLibType::DEFAULT_CLIENT; + auto limiter = Aws::MakeShared>(ALLOCATION_TAG, 200000); + // Create a client + ClientConfiguration config; + config.endpointOverride = ENDPOINT_OVERRIDE; + config.scheme = Scheme::HTTPS; + config.connectTimeoutMs = 30000; + config.requestTimeoutMs = 30000; + config.readRateLimiter = limiter; + config.writeRateLimiter = limiter; + config.httpLibOverride = transferType; + config.executor = Aws::MakeShared(ALLOCATION_TAG, 4); + config.disableExpectHeader = true; + config.enableHttpClientTrace = true; + + //invoke copy constructor + auto client = DynamoDBClient(config); + + DYNAMODB_INTEGRATION_TEST_ID = Aws::String(Aws::Utils::UUID::RandomUUID()).c_str(); + + //======test crud operations with callback =====/ + + Aws::String crudCallbacksTestTableName = BuildTableName(BASE_CRUD_CALLBACKS_TEST_TABLE); + { + //create a table and verify it's output + CreateTableRequest createTableRequest; + AttributeDefinition hashKey; + hashKey.SetAttributeName(HASH_KEY_NAME); + hashKey.SetAttributeType(ScalarAttributeType::S); + createTableRequest.AddAttributeDefinitions(hashKey); + KeySchemaElement hashKeySchemaElement; + hashKeySchemaElement.WithAttributeName(HASH_KEY_NAME).WithKeyType(KeyType::HASH); + createTableRequest.AddKeySchema(hashKeySchemaElement); + ProvisionedThroughput provisionedThroughput; + provisionedThroughput.SetReadCapacityUnits(50); + provisionedThroughput.SetWriteCapacityUnits(50); + createTableRequest.WithProvisionedThroughput(provisionedThroughput); + createTableRequest.WithTableName(crudCallbacksTestTableName); + + CreateTableOutcome createTableOutcome = client.CreateTable(createTableRequest); + if (createTableOutcome.IsSuccess()) + { + ASSERT_EQ(crudCallbacksTestTableName, createTableOutcome.GetResult().GetTableDescription().GetTableName()); + m_tablesCreated.emplace_back(crudCallbacksTestTableName); + } + else + { + ASSERT_EQ(createTableOutcome.GetError().GetErrorType(), DynamoDBErrors::RESOURCE_IN_USE); + } + } + + //since we need to wait for the table to finish creating anyways, + //let's go ahead and test describe table api while we are at it. + { + DescribeTableRequest describeTableRequest; + describeTableRequest.SetTableName(crudCallbacksTestTableName); + bool shouldContinue = true; + DescribeTableOutcome outcome = client.DescribeTable(describeTableRequest); + + while (shouldContinue) + { + if (outcome.IsSuccess() && outcome.GetResult().GetTable().GetTableStatus() == TableStatus::ACTIVE) + { + break; + } + else + { + std::this_thread::sleep_for(std::chrono::seconds(1)); + } + + outcome = client.DescribeTable(describeTableRequest); + } + } + + //registering a member function is ugly business even in modern c++ + auto putItemHandler = std::bind(&TableOperationTest::PutItemOutcomeReceived, this, std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, std::placeholders::_4); + + auto getItemHandler = std::bind(&TableOperationTest::GetItemOutcomeReceived, this, std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, std::placeholders::_4); + + auto putGetFunc = [&crudCallbacksTestTableName, putItemHandler, getItemHandler, this](DynamoDBClient& client){ + + //now put 50 items in the table asynchronously + Aws::String testValueColumnName = "TestValue"; + Aws::StringStream ss; + for (unsigned i = 0; i < 50; ++i) + { + ss << HASH_KEY_NAME << i; + PutItemRequest putItemRequest; + putItemRequest.SetTableName(crudCallbacksTestTableName); + AttributeValue hashKeyAttribute; + hashKeyAttribute.SetS(ss.str()); + ss.str(""); + putItemRequest.AddItem(HASH_KEY_NAME, hashKeyAttribute); + AttributeValue testValueAttribute; + ss << testValueColumnName << i; + testValueAttribute.SetS(ss.str()); + putItemRequest.AddItem(testValueColumnName, testValueAttribute); + ss.str(""); + client.PutItemAsync(putItemRequest, putItemHandler); + } + + //wait for the callbacks to finish. + std::unique_lock putItemResultLock(putItemResultMutex); + putItemResultSemaphore.wait(putItemResultLock); + + //now we get the items we were supposed to be putting and make sure + //they were put successfully. + for (unsigned i = 0; i < 50; ++i) + { + GetItemRequest getItemRequest; + ss << HASH_KEY_NAME << i; + AttributeValue hashKey; + hashKey.SetS(ss.str()); + getItemRequest.AddKey(HASH_KEY_NAME, hashKey); + getItemRequest.SetTableName(crudCallbacksTestTableName); + getItemRequest.SetConsistentRead(true); + + Aws::Vector attributesToGet; + attributesToGet.push_back(HASH_KEY_NAME); + attributesToGet.push_back(testValueColumnName); + ss.str(""); + client.GetItemAsync(getItemRequest, getItemHandler); + } + + //wait for the callbacks to finish. + std::unique_lock getItemResultLock(getItemResultMutex); + getItemResultSemaphore.wait(getItemResultLock); + + Aws::Map getItemResults; + //The values are not in order, so let's verify the values by using a map. + for (unsigned i = 0; i < 50; ++i) + { + GetItemOutcome outcome = getItemResultsFromCallbackTest[i]; + AWS_EXPECT_SUCCESS(outcome); + GetItemResult result = outcome.GetResult(); + Aws::Map returnedItemCollection = result.GetItem(); + getItemResults[returnedItemCollection[HASH_KEY_NAME].GetS()] = returnedItemCollection[testValueColumnName].GetS(); + } + + for (unsigned i = 0; i < 50; ++i) + { + ss << HASH_KEY_NAME << i; + Aws::String hashKey = ss.str(); + ss.str(""); + ss << testValueColumnName << i; + EXPECT_EQ(ss.str(), getItemResults[hashKey]); + ss.str(""); + } + putItemResultsFromCallbackTest.clear(); + getItemResultsFromCallbackTest.clear(); + + }; + + putGetFunc(client); + + DynamoDBClient client2 = client; + + putGetFunc(client2); + + auto client3 = std::move(client2); + + putGetFunc(client3); + +} + } // anonymous namespace diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientHeader.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientHeader.vm index 27d3ebf1478..161c289229b 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientHeader.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientHeader.vm @@ -21,7 +21,7 @@ \#include \#include \#include - +\#include namespace ${rootNamespace} { namespace ${serviceNamespace} @@ -42,7 +42,8 @@ namespace ${serviceNamespace} ${rootNamespace}::Crt::Variant<${AuthSchemeVariants}>, ${metadata.classNamePrefix}EndpointProviderBase, smithy::client::$serializer, - smithy::client::$serializerOutcome>, + smithy::client::$serializerOutcome, + Aws::Client::${metadata.classNamePrefix}ErrorMarshaller>, Aws::Client::ClientWithAsyncTemplateMethods<${className}> { public: From 93bc9eaba7050ce9827141135bc05b655ca94a5c Mon Sep 17 00:00:00 2001 From: Soumava Bera Date: Mon, 6 Jan 2025 10:55:33 -0500 Subject: [PATCH 03/13] don't make cachec copy constructible --- .../include/aws/core/utils/Cache.h | 25 --- .../include/aws/core/utils/ConcurrentCache.h | 27 --- .../TableOperationTest.cpp | 170 ------------------ 3 files changed, 222 deletions(-) diff --git a/src/aws-cpp-sdk-core/include/aws/core/utils/Cache.h b/src/aws-cpp-sdk-core/include/aws/core/utils/Cache.h index 99d6fdce2d7..74d40ea02d1 100644 --- a/src/aws-cpp-sdk-core/include/aws/core/utils/Cache.h +++ b/src/aws-cpp-sdk-core/include/aws/core/utils/Cache.h @@ -27,31 +27,6 @@ namespace Aws explicit Cache(size_t initialSize = 1000) : m_maxSize(initialSize) { } - - //this can't be default as compiler wont implicitly create copy constructor for const qualified members - Cache(const Cache& other):m_entries{other.m_entries},m_maxSize{other.m_maxSize}{ - } - - Cache(Cache&& other):m_entries{std::move(other.m_entries)},m_maxSize{other.m_maxSize}{ - } - - //m_maxSize is a const, so we don't touch it - Cache& operator=(const Cache& other){ - if(&other == this){ - return *this; - } - m_entries = other.m_entries; - return *this; - } - - Cache& operator=(Cache&& other){ - if(&other == this){ - return *this; - } - m_entries = std::move(other.m_entries); - return *this; - } - struct Value { diff --git a/src/aws-cpp-sdk-core/include/aws/core/utils/ConcurrentCache.h b/src/aws-cpp-sdk-core/include/aws/core/utils/ConcurrentCache.h index bb0772f2998..f0c2b4346c4 100644 --- a/src/aws-cpp-sdk-core/include/aws/core/utils/ConcurrentCache.h +++ b/src/aws-cpp-sdk-core/include/aws/core/utils/ConcurrentCache.h @@ -19,33 +19,6 @@ namespace Aws public: explicit ConcurrentCache(size_t size = 1000) : m_cache(size) { } - - ConcurrentCache(const ConcurrentCache& other) : m_cache(other.m_cache) { - - } - - ConcurrentCache(ConcurrentCache& other) : m_cache(std::move(other.m_cache)) { - - } - - ConcurrentCache& operator=(const ConcurrentCache& other){ - if(&other != this) - { - m_cache = other.m_cache; - } - return *this; - } - - ConcurrentCache& operator=(ConcurrentCache&& other){ - if(&other != this) - { - m_cache = std::move(other.m_cache); - } - return *this; - } - - - bool Get(const TKey& key, TValue& value) const { Aws::Utils::Threading::ReaderLockGuard g(m_rwlock); diff --git a/tests/aws-cpp-sdk-dynamodb-integration-tests/TableOperationTest.cpp b/tests/aws-cpp-sdk-dynamodb-integration-tests/TableOperationTest.cpp index 61cc394ba8c..42f068f2580 100644 --- a/tests/aws-cpp-sdk-dynamodb-integration-tests/TableOperationTest.cpp +++ b/tests/aws-cpp-sdk-dynamodb-integration-tests/TableOperationTest.cpp @@ -1511,175 +1511,5 @@ TEST_F(TableOperationTest, TestEndpointOverride) } } -TEST_F(TableOperationTest, TestClientCopy) -{ - - Aws::Http::TransferLibType transferType = Aws::Http::TransferLibType::DEFAULT_CLIENT; - auto limiter = Aws::MakeShared>(ALLOCATION_TAG, 200000); - // Create a client - ClientConfiguration config; - config.endpointOverride = ENDPOINT_OVERRIDE; - config.scheme = Scheme::HTTPS; - config.connectTimeoutMs = 30000; - config.requestTimeoutMs = 30000; - config.readRateLimiter = limiter; - config.writeRateLimiter = limiter; - config.httpLibOverride = transferType; - config.executor = Aws::MakeShared(ALLOCATION_TAG, 4); - config.disableExpectHeader = true; - config.enableHttpClientTrace = true; - - //invoke copy constructor - auto client = DynamoDBClient(config); - - DYNAMODB_INTEGRATION_TEST_ID = Aws::String(Aws::Utils::UUID::RandomUUID()).c_str(); - - //======test crud operations with callback =====/ - - Aws::String crudCallbacksTestTableName = BuildTableName(BASE_CRUD_CALLBACKS_TEST_TABLE); - { - //create a table and verify it's output - CreateTableRequest createTableRequest; - AttributeDefinition hashKey; - hashKey.SetAttributeName(HASH_KEY_NAME); - hashKey.SetAttributeType(ScalarAttributeType::S); - createTableRequest.AddAttributeDefinitions(hashKey); - KeySchemaElement hashKeySchemaElement; - hashKeySchemaElement.WithAttributeName(HASH_KEY_NAME).WithKeyType(KeyType::HASH); - createTableRequest.AddKeySchema(hashKeySchemaElement); - ProvisionedThroughput provisionedThroughput; - provisionedThroughput.SetReadCapacityUnits(50); - provisionedThroughput.SetWriteCapacityUnits(50); - createTableRequest.WithProvisionedThroughput(provisionedThroughput); - createTableRequest.WithTableName(crudCallbacksTestTableName); - - CreateTableOutcome createTableOutcome = client.CreateTable(createTableRequest); - if (createTableOutcome.IsSuccess()) - { - ASSERT_EQ(crudCallbacksTestTableName, createTableOutcome.GetResult().GetTableDescription().GetTableName()); - m_tablesCreated.emplace_back(crudCallbacksTestTableName); - } - else - { - ASSERT_EQ(createTableOutcome.GetError().GetErrorType(), DynamoDBErrors::RESOURCE_IN_USE); - } - } - - //since we need to wait for the table to finish creating anyways, - //let's go ahead and test describe table api while we are at it. - { - DescribeTableRequest describeTableRequest; - describeTableRequest.SetTableName(crudCallbacksTestTableName); - bool shouldContinue = true; - DescribeTableOutcome outcome = client.DescribeTable(describeTableRequest); - - while (shouldContinue) - { - if (outcome.IsSuccess() && outcome.GetResult().GetTable().GetTableStatus() == TableStatus::ACTIVE) - { - break; - } - else - { - std::this_thread::sleep_for(std::chrono::seconds(1)); - } - - outcome = client.DescribeTable(describeTableRequest); - } - } - - //registering a member function is ugly business even in modern c++ - auto putItemHandler = std::bind(&TableOperationTest::PutItemOutcomeReceived, this, std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3, std::placeholders::_4); - - auto getItemHandler = std::bind(&TableOperationTest::GetItemOutcomeReceived, this, std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3, std::placeholders::_4); - - auto putGetFunc = [&crudCallbacksTestTableName, putItemHandler, getItemHandler, this](DynamoDBClient& client){ - - //now put 50 items in the table asynchronously - Aws::String testValueColumnName = "TestValue"; - Aws::StringStream ss; - for (unsigned i = 0; i < 50; ++i) - { - ss << HASH_KEY_NAME << i; - PutItemRequest putItemRequest; - putItemRequest.SetTableName(crudCallbacksTestTableName); - AttributeValue hashKeyAttribute; - hashKeyAttribute.SetS(ss.str()); - ss.str(""); - putItemRequest.AddItem(HASH_KEY_NAME, hashKeyAttribute); - AttributeValue testValueAttribute; - ss << testValueColumnName << i; - testValueAttribute.SetS(ss.str()); - putItemRequest.AddItem(testValueColumnName, testValueAttribute); - ss.str(""); - client.PutItemAsync(putItemRequest, putItemHandler); - } - - //wait for the callbacks to finish. - std::unique_lock putItemResultLock(putItemResultMutex); - putItemResultSemaphore.wait(putItemResultLock); - - //now we get the items we were supposed to be putting and make sure - //they were put successfully. - for (unsigned i = 0; i < 50; ++i) - { - GetItemRequest getItemRequest; - ss << HASH_KEY_NAME << i; - AttributeValue hashKey; - hashKey.SetS(ss.str()); - getItemRequest.AddKey(HASH_KEY_NAME, hashKey); - getItemRequest.SetTableName(crudCallbacksTestTableName); - getItemRequest.SetConsistentRead(true); - - Aws::Vector attributesToGet; - attributesToGet.push_back(HASH_KEY_NAME); - attributesToGet.push_back(testValueColumnName); - ss.str(""); - client.GetItemAsync(getItemRequest, getItemHandler); - } - - //wait for the callbacks to finish. - std::unique_lock getItemResultLock(getItemResultMutex); - getItemResultSemaphore.wait(getItemResultLock); - - Aws::Map getItemResults; - //The values are not in order, so let's verify the values by using a map. - for (unsigned i = 0; i < 50; ++i) - { - GetItemOutcome outcome = getItemResultsFromCallbackTest[i]; - AWS_EXPECT_SUCCESS(outcome); - GetItemResult result = outcome.GetResult(); - Aws::Map returnedItemCollection = result.GetItem(); - getItemResults[returnedItemCollection[HASH_KEY_NAME].GetS()] = returnedItemCollection[testValueColumnName].GetS(); - } - - for (unsigned i = 0; i < 50; ++i) - { - ss << HASH_KEY_NAME << i; - Aws::String hashKey = ss.str(); - ss.str(""); - ss << testValueColumnName << i; - EXPECT_EQ(ss.str(), getItemResults[hashKey]); - ss.str(""); - } - putItemResultsFromCallbackTest.clear(); - getItemResultsFromCallbackTest.clear(); - - }; - - putGetFunc(client); - - DynamoDBClient client2 = client; - - putGetFunc(client2); - - auto client3 = std::move(client2); - - putGetFunc(client3); - -} - } // anonymous namespace From 177fc92534a10e3b76a348df429e2e34c0efa10b Mon Sep 17 00:00:00 2001 From: Soumava Bera Date: Mon, 6 Jan 2025 10:59:32 -0500 Subject: [PATCH 04/13] add new line for readablity --- .../awsclientgenerator/velocity/cpp/smithy/SmithyClientHeader.vm | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientHeader.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientHeader.vm index 161c289229b..0cf6b50a62f 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientHeader.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientHeader.vm @@ -21,6 +21,7 @@ \#include \#include \#include + \#include namespace ${rootNamespace} { From 9084d9576ff5db1dc3a5b23e0943e719d4c8fd54 Mon Sep 17 00:00:00 2001 From: Soumava Bera Date: Mon, 6 Jan 2025 11:17:59 -0500 Subject: [PATCH 05/13] removed assignemnt operators, move constructor to stick to backward compatibility --- .../aws/core/client/AWSClientAsyncCRTP.h | 35 ------------------- 1 file changed, 35 deletions(-) diff --git a/src/aws-cpp-sdk-core/include/aws/core/client/AWSClientAsyncCRTP.h b/src/aws-cpp-sdk-core/include/aws/core/client/AWSClientAsyncCRTP.h index e0a8b5b1dcf..8cb62ce7eb2 100644 --- a/src/aws-cpp-sdk-core/include/aws/core/client/AWSClientAsyncCRTP.h +++ b/src/aws-cpp-sdk-core/include/aws/core/client/AWSClientAsyncCRTP.h @@ -63,41 +63,6 @@ namespace Client &AwsServiceClientT::ShutdownSdkClient); } - ClientWithAsyncTemplateMethods& operator=(const ClientWithAsyncTemplateMethods& other) - { - if (&other != this) - { - ShutdownSdkClient(static_cast(this)); - m_operationsProcessed = 0; - m_isInitialized = other.m_isInitialized.load(); - } - - return *this; - } - - ClientWithAsyncTemplateMethods& operator=(ClientWithAsyncTemplateMethods&& other) - { - if (&other != this) - { - ShutdownSdkClient(static_cast(this)); - m_isInitialized = other.m_isInitialized.load(); - m_operationsProcessed = other.m_operationsProcessed.load(); - } - - return *this; - } - - ClientWithAsyncTemplateMethods(ClientWithAsyncTemplateMethods&& other): - m_isInitialized(other.m_isInitialized.load()), - m_operationsProcessed(other.m_operationsProcessed.load()) - { - - AwsServiceClientT* pThis = static_cast(this); - Aws::Utils::ComponentRegistry::RegisterComponent(AwsServiceClientT::GetServiceName(), - pThis, - &AwsServiceClientT::ShutdownSdkClient); - } - virtual ~ClientWithAsyncTemplateMethods() { AwsServiceClientT* pClient = static_cast(this); From 28954f70ac71ce6f0692071379edd776e10a3f63 Mon Sep 17 00:00:00 2001 From: Soumava Bera Date: Mon, 6 Jan 2025 11:20:06 -0500 Subject: [PATCH 06/13] removed move assignemnt operators, move constructor to stick to backward compatibility --- .../include/aws/core/client/AWSClientAsyncCRTP.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/aws-cpp-sdk-core/include/aws/core/client/AWSClientAsyncCRTP.h b/src/aws-cpp-sdk-core/include/aws/core/client/AWSClientAsyncCRTP.h index 8cb62ce7eb2..7210ee38d69 100644 --- a/src/aws-cpp-sdk-core/include/aws/core/client/AWSClientAsyncCRTP.h +++ b/src/aws-cpp-sdk-core/include/aws/core/client/AWSClientAsyncCRTP.h @@ -63,6 +63,18 @@ namespace Client &AwsServiceClientT::ShutdownSdkClient); } + ClientWithAsyncTemplateMethods& operator=(const ClientWithAsyncTemplateMethods& other) + { + if (&other != this) + { + ShutdownSdkClient(static_cast(this)); + m_operationsProcessed = 0; + m_isInitialized = other.m_isInitialized.load(); + } + + return *this; + } + virtual ~ClientWithAsyncTemplateMethods() { AwsServiceClientT* pClient = static_cast(this); From cc698884d35dcf6b150d2c612b79f98723a7af04 Mon Sep 17 00:00:00 2001 From: Soumava Bera Date: Mon, 6 Jan 2025 11:25:42 -0500 Subject: [PATCH 07/13] remove ws + regenerate client file --- .../aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClient.h | 1 + .../TableOperationTest.cpp | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClient.h b/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClient.h index 2986ad28f5c..c655c667210 100644 --- a/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClient.h +++ b/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClient.h @@ -12,6 +12,7 @@ #include #include #include + #include namespace Aws { diff --git a/tests/aws-cpp-sdk-dynamodb-integration-tests/TableOperationTest.cpp b/tests/aws-cpp-sdk-dynamodb-integration-tests/TableOperationTest.cpp index 42f068f2580..38741a836ca 100644 --- a/tests/aws-cpp-sdk-dynamodb-integration-tests/TableOperationTest.cpp +++ b/tests/aws-cpp-sdk-dynamodb-integration-tests/TableOperationTest.cpp @@ -130,7 +130,6 @@ class TableOperationTest : public ::testing::Test { { putItemResultSemaphore.notify_all(); } - } void DeleteItemOutcomeReceived(const DynamoDBClient* sender, const DeleteItemRequest& request, const DeleteItemOutcome& outcome, const std::shared_ptr& context) From 762e1d963806ff55ce6dcbf253f2ec50772edb97 Mon Sep 17 00:00:00 2001 From: Soumava Bera Date: Mon, 6 Jan 2025 12:49:11 -0500 Subject: [PATCH 08/13] cleanup --- .../aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClient.h | 2 +- src/aws-cpp-sdk-core/include/smithy/client/AwsSmithyClient.h | 3 +-- .../velocity/cpp/smithy/SmithyClientHeader.vm | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClient.h b/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClient.h index c655c667210..5cf100dfae0 100644 --- a/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClient.h +++ b/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClient.h @@ -12,8 +12,8 @@ #include #include #include - #include + namespace Aws { namespace DynamoDB 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 070bf679a49..3aca70330a5 100644 --- a/src/aws-cpp-sdk-core/include/smithy/client/AwsSmithyClient.h +++ b/src/aws-cpp-sdk-core/include/smithy/client/AwsSmithyClient.h @@ -55,14 +55,13 @@ namespace client } AwsSmithyClientT(const AwsSmithyClientT& other): - AwsSmithyClientBase(other), + AwsSmithyClientBase(other.m_clientConfig, other.m_serviceName, Aws::Http::CreateHttpClient(*other.m_clientConfig), Aws::MakeShared(other.m_serviceName.c_str())), m_clientConfiguration{other.m_clientConfiguration}, m_endpointProvider{other.m_endpointProvider}, m_authSchemeResolver{other.m_authSchemeResolver}, m_authSchemes{other.m_authSchemes}, m_serializer{Aws::MakeShared(ServiceNameT, m_clientConfiguration.telemetryProvider)} { - m_errorMarshaller = Aws::MakeShared(other.m_serviceName.c_str()); } diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientHeader.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientHeader.vm index 0cf6b50a62f..707ed09148d 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientHeader.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientHeader.vm @@ -21,8 +21,8 @@ \#include \#include \#include - \#include + namespace ${rootNamespace} { namespace ${serviceNamespace} From 57b90c837ebb982d8bf0e3ee29d2f9361843be70 Mon Sep 17 00:00:00 2001 From: Soumava Bera Date: Mon, 6 Jan 2025 14:28:58 -0500 Subject: [PATCH 09/13] fix warning on windows build --- src/aws-cpp-sdk-core/include/smithy/client/AwsSmithyClient.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 3aca70330a5..2bc4404c845 100644 --- a/src/aws-cpp-sdk-core/include/smithy/client/AwsSmithyClient.h +++ b/src/aws-cpp-sdk-core/include/smithy/client/AwsSmithyClient.h @@ -55,7 +55,7 @@ namespace client } AwsSmithyClientT(const AwsSmithyClientT& other): - AwsSmithyClientBase(other.m_clientConfig, other.m_serviceName, Aws::Http::CreateHttpClient(*other.m_clientConfig), Aws::MakeShared(other.m_serviceName.c_str())), + AwsSmithyClientBase(Aws::MakeShared(ServiceNameT, other.m_clientConfig), other.m_serviceName, Aws::Http::CreateHttpClient(*other.m_clientConfig), Aws::MakeShared(other.m_serviceName.c_str())), m_clientConfiguration{other.m_clientConfiguration}, m_endpointProvider{other.m_endpointProvider}, m_authSchemeResolver{other.m_authSchemeResolver}, From 2af030c10b370d6a1490d584f0eb3b6c76082119 Mon Sep 17 00:00:00 2001 From: Soumava Bera Date: Mon, 6 Jan 2025 16:49:21 -0500 Subject: [PATCH 10/13] client configuration copy initialization --- .../include/aws/dynamodb/DynamoDBClient.h | 42 +++++++++++++++++++ .../source/DynamoDBClient.cpp | 20 +++++++++ .../velocity/cpp/smithy/SmithyClientHeader.vm | 42 +++++++++++++++++++ .../cpp/smithy/SmithyClientSourceInit.vm | 20 +++++++++ 4 files changed, 124 insertions(+) diff --git a/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClient.h b/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClient.h index 5cf100dfae0..ccd7c31b6a8 100644 --- a/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClient.h +++ b/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClient.h @@ -51,6 +51,48 @@ namespace DynamoDB static const char* GetServiceName(); static const char* GetAllocationTag(); inline const char* GetServiceClientName() const override { return "DynamoDB"; } + + DynamoDBClient(const DynamoDBClient& other); + + DynamoDBClient(DynamoDBClient&& other); + + DynamoDBClient& operator=(const DynamoDBClient& other) + { + if(this == &other) + { + return *this; + } + smithy::client::AwsSmithyClientT, + Aws::Crt::Variant, + DynamoDBEndpointProviderBase, + smithy::client::JsonOutcomeSerializer, + smithy::client::JsonOutcome, + Aws::Client::DynamoDBErrorMarshaller>::operator=(other); + Aws::Client::ClientWithAsyncTemplateMethods::operator=(other); + init(m_clientConfiguration); + return *this; + } + + DynamoDBClient& operator=(DynamoDBClient&& other) + { + if(this == &other) + { + return *this; + } + smithy::client::AwsSmithyClientT, + Aws::Crt::Variant, + DynamoDBEndpointProviderBase, + smithy::client::JsonOutcomeSerializer, + smithy::client::JsonOutcome, + Aws::Client::DynamoDBErrorMarshaller>::operator=(other); + Aws::Client::ClientWithAsyncTemplateMethods::operator=(other); + init(m_clientConfiguration); + return *this; + } typedef DynamoDBClientConfiguration ClientConfigurationType; typedef DynamoDBEndpointProvider EndpointProviderType; diff --git a/generated/src/aws-cpp-sdk-dynamodb/source/DynamoDBClient.cpp b/generated/src/aws-cpp-sdk-dynamodb/source/DynamoDBClient.cpp index 9f90e7058f9..e16dd579935 100644 --- a/generated/src/aws-cpp-sdk-dynamodb/source/DynamoDBClient.cpp +++ b/generated/src/aws-cpp-sdk-dynamodb/source/DynamoDBClient.cpp @@ -228,6 +228,26 @@ void DynamoDBClient::OverrideEndpoint(const Aws::String& endpoint) m_endpointProvider->OverrideEndpoint(endpoint); } +DynamoDBClient::DynamoDBClient(const DynamoDBClient& other): + AwsSmithyClientT( + *other.m_clientConfig, + GetServiceName(), + Aws::Http::CreateHttpClient(other.m_clientConfiguration), + Aws::MakeShared(ALLOCATION_TAG), + other.m_endpointProvider, + Aws::MakeShared>(ALLOCATION_TAG), + other.m_authSchemes) +{ + init(m_clientConfiguration); +} + +DynamoDBClient::DynamoDBClient(DynamoDBClient&& other): + AwsSmithyClientT(std::move(other)), + Aws::Client::ClientWithAsyncTemplateMethods(std::move(other)) +{ + init(m_clientConfiguration); +} + BatchExecuteStatementOutcome DynamoDBClient::BatchExecuteStatement(const BatchExecuteStatementRequest& request) const { AWS_OPERATION_GUARD(BatchExecuteStatement); diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientHeader.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientHeader.vm index 707ed09148d..d38635a0044 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientHeader.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientHeader.vm @@ -51,6 +51,48 @@ namespace ${serviceNamespace} static const char* GetServiceName(); static const char* GetAllocationTag(); inline const char* GetServiceClientName() const override { return "${metadata.serviceId}"; } + + ${className}(const ${className}& other); + + ${className}(${className}&& other); + + ${className}& operator=(const ${className}& other) + { + if(this == &other) + { + return *this; + } + smithy::client::AwsSmithyClientT<${rootNamespace}::${serviceNamespace}::SERVICE_NAME, + ${serviceConfiguration}, + smithy::${AuthSchemeResolver}<>, + ${rootNamespace}::Crt::Variant<${AuthSchemeVariants}>, + ${metadata.classNamePrefix}EndpointProviderBase, + smithy::client::$serializer, + smithy::client::$serializerOutcome, + Aws::Client::${metadata.classNamePrefix}ErrorMarshaller>::operator=(other); + Aws::Client::ClientWithAsyncTemplateMethods<${className}>::operator=(other); + init(m_clientConfiguration); + return *this; + } + + ${className}& operator=(${className}&& other) + { + if(this == &other) + { + return *this; + } + smithy::client::AwsSmithyClientT<${rootNamespace}::${serviceNamespace}::SERVICE_NAME, + ${serviceConfiguration}, + smithy::${AuthSchemeResolver}<>, + ${rootNamespace}::Crt::Variant<${AuthSchemeVariants}>, + ${metadata.classNamePrefix}EndpointProviderBase, + smithy::client::$serializer, + smithy::client::$serializerOutcome, + Aws::Client::${metadata.classNamePrefix}ErrorMarshaller>::operator=(other); + Aws::Client::ClientWithAsyncTemplateMethods<${className}>::operator=(other); + init(m_clientConfiguration); + return *this; + } #parse("com/amazonaws/util/awsclientgenerator/velocity/cpp/ServiceClientHeaderConfigTypeDeclarations.vm") #parse("com/amazonaws/util/awsclientgenerator/velocity/cpp/ServiceClientHeaderConstructors.vm") 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 35fc81ecdc4..6fe9ddfc542 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 @@ -136,3 +136,23 @@ void ${className}::OverrideEndpoint(const Aws::String& endpoint) AWS_CHECK_PTR(SERVICE_NAME, m_endpointProvider); m_endpointProvider->OverrideEndpoint(endpoint); } + +${className}::${className}(const ${className}& other): + AwsSmithyClientT( + *other.m_clientConfig, + GetServiceName(), + Aws::Http::CreateHttpClient(other.m_clientConfiguration), + Aws::MakeShared<${metadata.classNamePrefix}ErrorMarshaller>(ALLOCATION_TAG), + other.m_endpointProvider, + Aws::MakeShared>(ALLOCATION_TAG), + other.m_authSchemes) +{ + init(m_clientConfiguration); +} + +${className}::${className}(${className}&& other): + AwsSmithyClientT(std::move(other)), + Aws::Client::ClientWithAsyncTemplateMethods<${className}>(std::move(other)) +{ + init(m_clientConfiguration); +} From 25b47380387d703cf3cba2ef27c1905ed67842c5 Mon Sep 17 00:00:00 2001 From: Soumava Bera Date: Mon, 6 Jan 2025 17:05:51 -0500 Subject: [PATCH 11/13] fix copy constructor logic + cleanup --- .../include/aws/dynamodb/DynamoDBClient.h | 20 +++---------------- .../source/DynamoDBClient.cpp | 3 ++- .../velocity/cpp/smithy/SmithyClientHeader.vm | 20 +++---------------- .../cpp/smithy/SmithyClientSourceInit.vm | 3 ++- 4 files changed, 10 insertions(+), 36 deletions(-) diff --git a/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClient.h b/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClient.h index ccd7c31b6a8..837210d1110 100644 --- a/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClient.h +++ b/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClient.h @@ -62,14 +62,7 @@ namespace DynamoDB { return *this; } - smithy::client::AwsSmithyClientT, - Aws::Crt::Variant, - DynamoDBEndpointProviderBase, - smithy::client::JsonOutcomeSerializer, - smithy::client::JsonOutcome, - Aws::Client::DynamoDBErrorMarshaller>::operator=(other); + AwsSmithyClientT::operator=(other); Aws::Client::ClientWithAsyncTemplateMethods::operator=(other); init(m_clientConfiguration); return *this; @@ -81,15 +74,8 @@ namespace DynamoDB { return *this; } - smithy::client::AwsSmithyClientT, - Aws::Crt::Variant, - DynamoDBEndpointProviderBase, - smithy::client::JsonOutcomeSerializer, - smithy::client::JsonOutcome, - Aws::Client::DynamoDBErrorMarshaller>::operator=(other); - Aws::Client::ClientWithAsyncTemplateMethods::operator=(other); + AwsSmithyClientT::operator=(std::move(other)); + Aws::Client::ClientWithAsyncTemplateMethods::operator=(std::move(other)); init(m_clientConfiguration); return *this; } diff --git a/generated/src/aws-cpp-sdk-dynamodb/source/DynamoDBClient.cpp b/generated/src/aws-cpp-sdk-dynamodb/source/DynamoDBClient.cpp index e16dd579935..9f1a0884390 100644 --- a/generated/src/aws-cpp-sdk-dynamodb/source/DynamoDBClient.cpp +++ b/generated/src/aws-cpp-sdk-dynamodb/source/DynamoDBClient.cpp @@ -236,7 +236,8 @@ DynamoDBClient::DynamoDBClient(const DynamoDBClient& other): Aws::MakeShared(ALLOCATION_TAG), other.m_endpointProvider, Aws::MakeShared>(ALLOCATION_TAG), - other.m_authSchemes) + other.m_authSchemes), + Aws::Client::ClientWithAsyncTemplateMethods(other) { init(m_clientConfiguration); } diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientHeader.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientHeader.vm index d38635a0044..e69ffb30625 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientHeader.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientHeader.vm @@ -62,14 +62,7 @@ namespace ${serviceNamespace} { return *this; } - smithy::client::AwsSmithyClientT<${rootNamespace}::${serviceNamespace}::SERVICE_NAME, - ${serviceConfiguration}, - smithy::${AuthSchemeResolver}<>, - ${rootNamespace}::Crt::Variant<${AuthSchemeVariants}>, - ${metadata.classNamePrefix}EndpointProviderBase, - smithy::client::$serializer, - smithy::client::$serializerOutcome, - Aws::Client::${metadata.classNamePrefix}ErrorMarshaller>::operator=(other); + AwsSmithyClientT::operator=(other); Aws::Client::ClientWithAsyncTemplateMethods<${className}>::operator=(other); init(m_clientConfiguration); return *this; @@ -81,15 +74,8 @@ namespace ${serviceNamespace} { return *this; } - smithy::client::AwsSmithyClientT<${rootNamespace}::${serviceNamespace}::SERVICE_NAME, - ${serviceConfiguration}, - smithy::${AuthSchemeResolver}<>, - ${rootNamespace}::Crt::Variant<${AuthSchemeVariants}>, - ${metadata.classNamePrefix}EndpointProviderBase, - smithy::client::$serializer, - smithy::client::$serializerOutcome, - Aws::Client::${metadata.classNamePrefix}ErrorMarshaller>::operator=(other); - Aws::Client::ClientWithAsyncTemplateMethods<${className}>::operator=(other); + AwsSmithyClientT::operator=(std::move(other)); + Aws::Client::ClientWithAsyncTemplateMethods<${className}>::operator=(std::move(other)); init(m_clientConfiguration); return *this; } 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 6fe9ddfc542..6381a47b2a0 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 @@ -145,7 +145,8 @@ ${className}::${className}(const ${className}& other): Aws::MakeShared<${metadata.classNamePrefix}ErrorMarshaller>(ALLOCATION_TAG), other.m_endpointProvider, Aws::MakeShared>(ALLOCATION_TAG), - other.m_authSchemes) + other.m_authSchemes), + Aws::Client::ClientWithAsyncTemplateMethods<${className}>(other) { init(m_clientConfiguration); } From 7e079b2fbea62a3c1e6834e21627645581b8fb2b Mon Sep 17 00:00:00 2001 From: Soumava Bera Date: Tue, 7 Jan 2025 11:49:12 -0500 Subject: [PATCH 12/13] config deep copy changes --- .../include/smithy/client/AwsSmithyClient.h | 6 ++-- .../smithy/client/AwsSmithyClientBase.h | 34 ++++++++++++++++--- 2 files changed, 33 insertions(+), 7 deletions(-) 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 2bc4404c845..e4cfe9c2bb3 100644 --- a/src/aws-cpp-sdk-core/include/smithy/client/AwsSmithyClient.h +++ b/src/aws-cpp-sdk-core/include/smithy/client/AwsSmithyClient.h @@ -56,7 +56,7 @@ namespace client AwsSmithyClientT(const AwsSmithyClientT& other): AwsSmithyClientBase(Aws::MakeShared(ServiceNameT, other.m_clientConfig), other.m_serviceName, Aws::Http::CreateHttpClient(*other.m_clientConfig), Aws::MakeShared(other.m_serviceName.c_str())), - m_clientConfiguration{other.m_clientConfiguration}, + m_clientConfiguration{*static_cast(AwsSmithyClientBase::m_clientConfig.get())}, m_endpointProvider{other.m_endpointProvider}, m_authSchemeResolver{other.m_authSchemeResolver}, m_authSchemes{other.m_authSchemes}, @@ -70,7 +70,7 @@ namespace client if(this != &other) { AwsSmithyClientBase::operator=(other); - m_clientConfiguration = other.m_clientConfiguration; + m_clientConfiguration = *static_cast(AwsSmithyClientBase::m_clientConfig.get()); m_endpointProvider = other.m_endpointProvider; m_authSchemeResolver = other.m_authSchemeResolver; m_authSchemes = other.m_authSchemes; @@ -167,7 +167,7 @@ namespace client } protected: - ServiceClientConfigurationT m_clientConfiguration; + ServiceClientConfigurationT& m_clientConfiguration; std::shared_ptr m_endpointProvider{}; std::shared_ptr m_authSchemeResolver{}; Aws::UnorderedMap m_authSchemes{}; 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 43e9f0699b8..fdf9effba07 100644 --- a/src/aws-cpp-sdk-core/include/smithy/client/AwsSmithyClientBase.h +++ b/src/aws-cpp-sdk-core/include/smithy/client/AwsSmithyClientBase.h @@ -69,6 +69,31 @@ namespace client { private: const char* ALLOC_TAG{"AwsSmithyClientBase"}; + + + void deepCopyClientConfiguration(const AwsSmithyClientBase& target) + { + //first create copy from target + m_clientConfig = Aws::MakeShared(target.m_serviceName.c_str(), *target.m_clientConfig); + + //then reinitialize appropriate fields unconditionally + assert(m_clientConfig->configFactories.retryStrategyCreateFn); + m_clientConfig->retryStrategy = m_clientConfig->configFactories.retryStrategyCreateFn(); + + assert(m_clientConfig->configFactories.executorCreateFn); + m_clientConfig->executor = m_clientConfig->configFactories.executorCreateFn(); + + assert(m_clientConfig->configFactories.writeRateLimiterCreateFn); + m_clientConfig->writeRateLimiter = m_clientConfig->configFactories.writeRateLimiterCreateFn(); + + assert(m_clientConfig->configFactories.readRateLimiterCreateFn); + m_clientConfig->readRateLimiter = m_clientConfig->configFactories.readRateLimiterCreateFn(); + + assert(m_clientConfig->configFactories.telemetryProviderCreateFn); + m_clientConfig->telemetryProvider = m_clientConfig->configFactories.telemetryProviderCreateFn(); + + } + public: using HttpRequest = Aws::Http::HttpRequest; using HttpResponse = Aws::Http::HttpResponse; @@ -128,22 +153,23 @@ namespace client { if (this != &target) { - m_clientConfig = target.m_clientConfig; + deepCopyClientConfiguration(target); m_serviceName = target.m_serviceName; m_userAgent = target.m_userAgent; m_httpClient = Aws::Http::CreateHttpClient(*target.m_clientConfig); m_interceptors = {Aws::MakeShared(ALLOC_TAG)}; + m_userAgent = Aws::Client::ComputeUserAgentString(m_clientConfig.get()); } return *this; } AwsSmithyClientBase(const AwsSmithyClientBase& target): - m_clientConfig{target.m_clientConfig}, m_serviceName{target.m_serviceName}, m_userAgent{target.m_userAgent}, - m_httpClient{Aws::Http::CreateHttpClient(*target.m_clientConfig)} + m_httpClient{Aws::Http::CreateHttpClient(*target.m_clientConfig)}, + m_interceptors{Aws::MakeShared(ALLOC_TAG)} { - m_interceptors = {Aws::MakeShared(ALLOC_TAG)}; + deepCopyClientConfiguration(target); } AwsSmithyClientBase(AwsSmithyClientBase&& target) = default; From e8f6d67ddb35c7cdef685e628e98b71aeb9b6f4b Mon Sep 17 00:00:00 2001 From: sbiscigl Date: Wed, 8 Jan 2025 14:56:28 -0500 Subject: [PATCH 13/13] update to deep copy --- .../include/aws/dynamodb/DynamoDBClient.h | 29 ----- .../source/DynamoDBClient.cpp | 59 +-------- .../include/smithy/client/AwsSmithyClient.h | 43 +++--- .../smithy/client/AwsSmithyClientBase.h | 123 +++++++----------- .../smithy/client/AwsSmithyClientBase.cpp | 46 ++++++- .../smithy/client/SmithyClientTest.cpp | 117 ++++++++++++++--- .../velocity/cpp/smithy/SmithyClientHeader.vm | 29 ----- .../cpp/smithy/SmithyClientSourceInit.vm | 62 +-------- 8 files changed, 221 insertions(+), 287 deletions(-) diff --git a/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClient.h b/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClient.h index 837210d1110..fc7e5752a6c 100644 --- a/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClient.h +++ b/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClient.h @@ -51,34 +51,6 @@ namespace DynamoDB static const char* GetServiceName(); static const char* GetAllocationTag(); inline const char* GetServiceClientName() const override { return "DynamoDB"; } - - DynamoDBClient(const DynamoDBClient& other); - - DynamoDBClient(DynamoDBClient&& other); - - DynamoDBClient& operator=(const DynamoDBClient& other) - { - if(this == &other) - { - return *this; - } - AwsSmithyClientT::operator=(other); - Aws::Client::ClientWithAsyncTemplateMethods::operator=(other); - init(m_clientConfiguration); - return *this; - } - - DynamoDBClient& operator=(DynamoDBClient&& other) - { - if(this == &other) - { - return *this; - } - AwsSmithyClientT::operator=(std::move(other)); - Aws::Client::ClientWithAsyncTemplateMethods::operator=(std::move(other)); - init(m_clientConfiguration); - return *this; - } typedef DynamoDBClientConfiguration ClientConfigurationType; typedef DynamoDBEndpointProvider EndpointProviderType; @@ -2316,7 +2288,6 @@ namespace DynamoDB std::shared_ptr& accessEndpointProvider(); private: friend class Aws::Client::ClientWithAsyncTemplateMethods; - void init(const DynamoDBClientConfiguration& clientConfiguration); void OptionallyUpdateDescribeEndpointsCache(Aws::Endpoint::AWSEndpoint& resolvedEndpoint, const Aws::String& operationName, diff --git a/generated/src/aws-cpp-sdk-dynamodb/source/DynamoDBClient.cpp b/generated/src/aws-cpp-sdk-dynamodb/source/DynamoDBClient.cpp index 9f1a0884390..da4cef3baa5 100644 --- a/generated/src/aws-cpp-sdk-dynamodb/source/DynamoDBClient.cpp +++ b/generated/src/aws-cpp-sdk-dynamodb/source/DynamoDBClient.cpp @@ -116,9 +116,7 @@ DynamoDBClient::DynamoDBClient(const DynamoDB::DynamoDBClientConfiguration& clie { {smithy::SigV4AuthSchemeOption::sigV4AuthSchemeOption.schemeId, smithy::SigV4AuthScheme{GetServiceName(), clientConfiguration.region}}, }) -{ - init(m_clientConfiguration); -} +{} DynamoDBClient::DynamoDBClient(const AWSCredentials& credentials, std::shared_ptr endpointProvider, @@ -132,9 +130,7 @@ DynamoDBClient::DynamoDBClient(const AWSCredentials& credentials, { {smithy::SigV4AuthSchemeOption::sigV4AuthSchemeOption.schemeId, smithy::SigV4AuthScheme{Aws::MakeShared(ALLOCATION_TAG, credentials), GetServiceName(), clientConfiguration.region}}, }) -{ - init(m_clientConfiguration); -} +{} DynamoDBClient::DynamoDBClient(const std::shared_ptr& credentialsProvider, std::shared_ptr endpointProvider, @@ -148,9 +144,7 @@ DynamoDBClient::DynamoDBClient(const std::shared_ptr& cr { {smithy::SigV4AuthSchemeOption::sigV4AuthSchemeOption.schemeId, smithy::SigV4AuthScheme{ Aws::MakeShared(ALLOCATION_TAG, credentialsProvider), GetServiceName(), clientConfiguration.region}} }) -{ - init(m_clientConfiguration); -} +{} /* Legacy constructors due deprecation */ DynamoDBClient::DynamoDBClient(const Client::ClientConfiguration& clientConfiguration) : @@ -163,9 +157,7 @@ DynamoDBClient::DynamoDBClient(const Client::ClientConfiguration& clientConfigur { {smithy::SigV4AuthSchemeOption::sigV4AuthSchemeOption.schemeId, smithy::SigV4AuthScheme{Aws::MakeShared(ALLOCATION_TAG), GetServiceName(), clientConfiguration.region}} }) -{ - init(m_clientConfiguration); -} +{} DynamoDBClient::DynamoDBClient(const AWSCredentials& credentials, const Client::ClientConfiguration& clientConfiguration) : @@ -178,9 +170,7 @@ DynamoDBClient::DynamoDBClient(const AWSCredentials& credentials, { {smithy::SigV4AuthSchemeOption::sigV4AuthSchemeOption.schemeId, smithy::SigV4AuthScheme{Aws::MakeShared(ALLOCATION_TAG, credentials), GetServiceName(), clientConfiguration.region}} }) -{ - init(m_clientConfiguration); -} +{} DynamoDBClient::DynamoDBClient(const std::shared_ptr& credentialsProvider, const Client::ClientConfiguration& clientConfiguration) : @@ -193,9 +183,7 @@ DynamoDBClient::DynamoDBClient(const std::shared_ptr& cr { {smithy::SigV4AuthSchemeOption::sigV4AuthSchemeOption.schemeId, smithy::SigV4AuthScheme{Aws::MakeShared(ALLOCATION_TAG, credentialsProvider), GetServiceName(), clientConfiguration.region}} }) -{ - init(m_clientConfiguration); -} +{} /* End of legacy constructors due deprecation */ DynamoDBClient::~DynamoDBClient() @@ -208,47 +196,12 @@ std::shared_ptr& DynamoDBClient::accessEndpointPro return m_endpointProvider; } -void DynamoDBClient::init(const DynamoDB::DynamoDBClientConfiguration& config) -{ - if (!m_clientConfiguration.executor) { - if (!m_clientConfiguration.configFactories.executorCreateFn()) { - AWS_LOGSTREAM_FATAL(ALLOCATION_TAG, "Failed to initialize client: config is missing Executor or executorCreateFn"); - m_isInitialized = false; - return; - } - m_clientConfiguration.executor = m_clientConfiguration.configFactories.executorCreateFn(); - } - AWS_CHECK_PTR(SERVICE_NAME, m_endpointProvider); - m_endpointProvider->InitBuiltInParameters(config); -} - void DynamoDBClient::OverrideEndpoint(const Aws::String& endpoint) { AWS_CHECK_PTR(SERVICE_NAME, m_endpointProvider); m_endpointProvider->OverrideEndpoint(endpoint); } -DynamoDBClient::DynamoDBClient(const DynamoDBClient& other): - AwsSmithyClientT( - *other.m_clientConfig, - GetServiceName(), - Aws::Http::CreateHttpClient(other.m_clientConfiguration), - Aws::MakeShared(ALLOCATION_TAG), - other.m_endpointProvider, - Aws::MakeShared>(ALLOCATION_TAG), - other.m_authSchemes), - Aws::Client::ClientWithAsyncTemplateMethods(other) -{ - init(m_clientConfiguration); -} - -DynamoDBClient::DynamoDBClient(DynamoDBClient&& other): - AwsSmithyClientT(std::move(other)), - Aws::Client::ClientWithAsyncTemplateMethods(std::move(other)) -{ - init(m_clientConfiguration); -} - BatchExecuteStatementOutcome DynamoDBClient::BatchExecuteStatement(const BatchExecuteStatementRequest& request) const { AWS_OPERATION_GUARD(BatchExecuteStatement); 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 e4cfe9c2bb3..b643ee7ac91 100644 --- a/src/aws-cpp-sdk-core/include/smithy/client/AwsSmithyClient.h +++ b/src/aws-cpp-sdk-core/include/smithy/client/AwsSmithyClient.h @@ -30,13 +30,11 @@ namespace client typename EndpointProviderT, typename SerializerT, typename ResponseT, - typename MarshallerT> + typename ErrorMarshallerT> class AwsSmithyClientT : public AwsSmithyClientBase { - private: - public: - static_assert(std::is_base_of::value, "MarshallerT must be derived from class Aws::Client::AWSErrorMarshaller"); + static_assert(std::is_base_of::value, "MarshallerT must be derived from class Aws::Client::AWSErrorMarshaller"); explicit AwsSmithyClientT(const ServiceClientConfigurationT& clientConfig, const Aws::String& serviceName, const std::shared_ptr& httpClient, @@ -44,40 +42,48 @@ namespace client const std::shared_ptr endpointProvider, const std::shared_ptr& authSchemeResolver, const Aws::UnorderedMap& authSchemes) - : AwsSmithyClientBase(Aws::MakeShared(ServiceNameT, clientConfig), serviceName, httpClient, errorMarshaller), + : AwsSmithyClientBase(Aws::MakeUnique(ServiceNameT, clientConfig), serviceName, httpClient, errorMarshaller), m_clientConfiguration(*static_cast(AwsSmithyClientBase::m_clientConfig.get())), m_endpointProvider(endpointProvider), m_authSchemeResolver(authSchemeResolver), m_authSchemes(authSchemes), m_serializer(Aws::MakeShared(ServiceNameT, m_clientConfiguration.telemetryProvider)) { - m_serviceName = ServiceNameT; + m_serviceName = ServiceNameT; + initClient(); } AwsSmithyClientT(const AwsSmithyClientT& other): - AwsSmithyClientBase(Aws::MakeShared(ServiceNameT, other.m_clientConfig), other.m_serviceName, Aws::Http::CreateHttpClient(*other.m_clientConfig), Aws::MakeShared(other.m_serviceName.c_str())), - m_clientConfiguration{*static_cast(AwsSmithyClientBase::m_clientConfig.get())}, + AwsSmithyClientBase(other, + Aws::MakeUnique(ServiceNameT, other.m_clientConfiguration), + ServiceNameT, + Aws::Http::CreateHttpClient(other.m_clientConfiguration), + Aws::MakeShared(ServiceNameT)), + m_clientConfiguration{*static_cast(m_clientConfig.get())}, m_endpointProvider{other.m_endpointProvider}, - m_authSchemeResolver{other.m_authSchemeResolver}, + m_authSchemeResolver{Aws::MakeShared(ServiceNameT)}, m_authSchemes{other.m_authSchemes}, m_serializer{Aws::MakeShared(ServiceNameT, m_clientConfiguration.telemetryProvider)} { + initClient(); } - AwsSmithyClientT& operator=(const AwsSmithyClientT& other) { if(this != &other) { - AwsSmithyClientBase::operator=(other); - m_clientConfiguration = *static_cast(AwsSmithyClientBase::m_clientConfig.get()); + AwsSmithyClientBase::deepCopy(Aws::MakeUnique(ServiceNameT, other.m_clientConfiguration), + ServiceNameT, + Aws::Http::CreateHttpClient(other.m_clientConfiguration), + Aws::MakeShared(ServiceNameT)); + m_clientConfiguration = *static_cast(m_clientConfig.get()); m_endpointProvider = other.m_endpointProvider; - m_authSchemeResolver = other.m_authSchemeResolver; + m_authSchemeResolver = Aws::MakeShared(ServiceNameT); m_authSchemes = other.m_authSchemes; - m_serializer = Aws::MakeShared(other.m_serviceName.c_str(), m_clientConfiguration.telemetryProvider); - m_errorMarshaller = Aws::MakeShared(other.m_serviceName.c_str()); + m_serializer = Aws::MakeShared(ServiceNameT, m_clientConfiguration.telemetryProvider); + m_errorMarshaller = Aws::MakeShared(ServiceNameT); + initClient(); } - return *this; } @@ -88,6 +94,10 @@ namespace client virtual ~AwsSmithyClientT() = default; protected: + void initClient() { + m_endpointProvider->InitBuiltInParameters(m_clientConfiguration); + } + inline const char* GetServiceClientName() const override { return m_serviceName.c_str(); } ResolveEndpointOutcome ResolveEndpoint(const Aws::Endpoint::EndpointParameters& endpointParameters, EndpointUpdateCallback&& epCallback) const override @@ -166,7 +176,6 @@ namespace client return m_serializer->Deserialize(std::move(httpResponseOutcome), GetServiceClientName(), requestName); } - protected: ServiceClientConfigurationT& m_clientConfiguration; std::shared_ptr m_endpointProvider{}; std::shared_ptr m_authSchemeResolver{}; 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 fdf9effba07..34554c0b52e 100644 --- a/src/aws-cpp-sdk-core/include/smithy/client/AwsSmithyClientBase.h +++ b/src/aws-cpp-sdk-core/include/smithy/client/AwsSmithyClientBase.h @@ -20,6 +20,8 @@ #include #include +#include + namespace Aws { namespace Utils @@ -67,33 +69,6 @@ namespace client /* Non-template base client class that contains main Aws Client Request pipeline logic */ class SMITHY_API AwsSmithyClientBase { - private: - const char* ALLOC_TAG{"AwsSmithyClientBase"}; - - - void deepCopyClientConfiguration(const AwsSmithyClientBase& target) - { - //first create copy from target - m_clientConfig = Aws::MakeShared(target.m_serviceName.c_str(), *target.m_clientConfig); - - //then reinitialize appropriate fields unconditionally - assert(m_clientConfig->configFactories.retryStrategyCreateFn); - m_clientConfig->retryStrategy = m_clientConfig->configFactories.retryStrategyCreateFn(); - - assert(m_clientConfig->configFactories.executorCreateFn); - m_clientConfig->executor = m_clientConfig->configFactories.executorCreateFn(); - - assert(m_clientConfig->configFactories.writeRateLimiterCreateFn); - m_clientConfig->writeRateLimiter = m_clientConfig->configFactories.writeRateLimiterCreateFn(); - - assert(m_clientConfig->configFactories.readRateLimiterCreateFn); - m_clientConfig->readRateLimiter = m_clientConfig->configFactories.readRateLimiterCreateFn(); - - assert(m_clientConfig->configFactories.telemetryProviderCreateFn); - m_clientConfig->telemetryProvider = m_clientConfig->configFactories.telemetryProviderCreateFn(); - - } - public: using HttpRequest = Aws::Http::HttpRequest; using HttpResponse = Aws::Http::HttpResponse; @@ -108,7 +83,7 @@ namespace client using SelectAuthSchemeOptionOutcome = Aws::Utils::Outcome; using ResolveEndpointOutcome = Aws::Utils::Outcome; - AwsSmithyClientBase(std::shared_ptr&& clientConfig, + AwsSmithyClientBase(Aws::UniquePtr&& clientConfig, Aws::String serviceName, std::shared_ptr httpClient, std::shared_ptr errorMarshaller) : @@ -119,61 +94,28 @@ namespace client m_errorMarshaller(std::move(errorMarshaller)), m_interceptors{Aws::MakeShared("AwsSmithyClientBase")} { - if (!m_clientConfig->retryStrategy) - { - assert(m_clientConfig->configFactories.retryStrategyCreateFn); - m_clientConfig->retryStrategy = m_clientConfig->configFactories.retryStrategyCreateFn(); - } - if (!m_clientConfig->executor) - { - assert(m_clientConfig->configFactories.executorCreateFn); - m_clientConfig->executor = m_clientConfig->configFactories.executorCreateFn(); - } - if (!m_clientConfig->writeRateLimiter) - { - assert(m_clientConfig->configFactories.writeRateLimiterCreateFn); - m_clientConfig->writeRateLimiter = m_clientConfig->configFactories.writeRateLimiterCreateFn(); - } - if (!m_clientConfig->readRateLimiter) - { - assert(m_clientConfig->configFactories.readRateLimiterCreateFn); - m_clientConfig->readRateLimiter = m_clientConfig->configFactories.readRateLimiterCreateFn(); - } - if (!m_clientConfig->telemetryProvider) - { - assert(m_clientConfig->configFactories.telemetryProviderCreateFn); - m_clientConfig->telemetryProvider = m_clientConfig->configFactories.telemetryProviderCreateFn(); - } - - m_userAgent = Aws::Client::ComputeUserAgentString(m_clientConfig.get()); + baseInit(); } - - AwsSmithyClientBase& operator=(const AwsSmithyClientBase& target) - { - if (this != &target) - { - deepCopyClientConfiguration(target); - m_serviceName = target.m_serviceName; - m_userAgent = target.m_userAgent; - m_httpClient = Aws::Http::CreateHttpClient(*target.m_clientConfig); - m_interceptors = {Aws::MakeShared(ALLOC_TAG)}; - m_userAgent = Aws::Client::ComputeUserAgentString(m_clientConfig.get()); - } - return *this; - } - - AwsSmithyClientBase(const AwsSmithyClientBase& target): - m_serviceName{target.m_serviceName}, - m_userAgent{target.m_userAgent}, - m_httpClient{Aws::Http::CreateHttpClient(*target.m_clientConfig)}, - m_interceptors{Aws::MakeShared(ALLOC_TAG)} + AwsSmithyClientBase(const AwsSmithyClientBase& other, + Aws::UniquePtr&& clientConfig, + Aws::String serviceName, + std::shared_ptr httpClient, + std::shared_ptr errorMarshaller) : + m_clientConfig(std::move(clientConfig)), + m_serviceName(std::move(serviceName)), + m_userAgent(), + m_httpClient(std::move(httpClient)), + m_errorMarshaller(std::move(errorMarshaller)), + m_interceptors{Aws::MakeShared("AwsSmithyClientBase")} { - deepCopyClientConfiguration(target); + AWS_UNREFERENCED_PARAM(other); + baseCopyInit(); } + AwsSmithyClientBase(AwsSmithyClientBase& target) = delete; + AwsSmithyClientBase& operator=(AwsSmithyClientBase& target) = delete; AwsSmithyClientBase(AwsSmithyClientBase&& target) = default; - AwsSmithyClientBase& operator=(AwsSmithyClientBase&& target) = default; virtual ~AwsSmithyClientBase() = default; @@ -191,6 +133,32 @@ namespace client EndpointUpdateCallback&& endpointCallback) const; protected: + void deepCopy(Aws::UniquePtr&& clientConfig, + const Aws::String& serviceName, + std::shared_ptr httpClient, + std::shared_ptr errorMarshaller) + { + m_clientConfig = std::move(clientConfig); + m_serviceName = serviceName; + m_httpClient = std::move(httpClient); + m_errorMarshaller = std::move(errorMarshaller); + m_interceptors = Aws::Vector>{Aws::MakeShared("AwsSmithyClientBase")}; + baseCopyInit(); + } + + /** + * 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 + * factory method. + */ + void baseInit(); + + /** + * Initialize client configuration on copy, if there is a factory use it, otherwise use the already present + * shared configuration. + */ + void baseCopyInit(); + /** * Transforms the AmazonWebServicesResult object into an HttpRequest. */ @@ -211,7 +179,6 @@ namespace client virtual SigningOutcome SignRequest(std::shared_ptr httpRequest, const AuthSchemeOption& targetAuthSchemeOption) const = 0; virtual bool AdjustClockSkew(HttpResponseOutcome& outcome, const AuthSchemeOption& authSchemeOption) const = 0; - protected: std::shared_ptr m_clientConfig; Aws::String m_serviceName; Aws::String m_userAgent; diff --git a/src/aws-cpp-sdk-core/source/smithy/client/AwsSmithyClientBase.cpp b/src/aws-cpp-sdk-core/source/smithy/client/AwsSmithyClientBase.cpp index 27f0304a6bf..c09d2144748 100644 --- a/src/aws-cpp-sdk-core/source/smithy/client/AwsSmithyClientBase.cpp +++ b/src/aws-cpp-sdk-core/source/smithy/client/AwsSmithyClientBase.cpp @@ -24,14 +24,50 @@ using namespace smithy::components::tracing; static const char AWS_SMITHY_CLIENT_LOG[] = "AwsSmithyClient"; - +namespace { void AddHeadersToRequest(const std::shared_ptr& httpRequest, const Aws::Http::HeaderValueCollection& headerValues) { - for (auto const& headerValue : headerValues) - { - httpRequest->SetHeaderValue(headerValue.first, headerValue.second); - } + for (auto const& headerValue : headerValues) + { + httpRequest->SetHeaderValue(headerValue.first, headerValue.second); + } +} + +template +void createFromFactories(T& entity, std::function& factory) { + if (!entity) { + assert(factory); + entity = factory(); + } else { + factory = nullptr; + } +} + +template +void createFromFactoriesIfPresent(T& entity, std::function& factory) { + if (entity && factory) { + entity = factory(); + } +} +} // namespace + +void AwsSmithyClientBase::baseInit() { + createFromFactories(m_clientConfig->retryStrategy, m_clientConfig->configFactories.retryStrategyCreateFn); + createFromFactories(m_clientConfig->executor, m_clientConfig->configFactories.executorCreateFn); + createFromFactories(m_clientConfig->writeRateLimiter, m_clientConfig->configFactories.writeRateLimiterCreateFn); + createFromFactories(m_clientConfig->readRateLimiter, m_clientConfig->configFactories.readRateLimiterCreateFn); + createFromFactories(m_clientConfig->telemetryProvider, m_clientConfig->configFactories.telemetryProviderCreateFn); + m_userAgent = Aws::Client::ComputeUserAgentString(m_clientConfig.get()); +} + +void AwsSmithyClientBase::baseCopyInit() { + createFromFactoriesIfPresent(m_clientConfig->retryStrategy, m_clientConfig->configFactories.retryStrategyCreateFn); + createFromFactoriesIfPresent(m_clientConfig->executor, m_clientConfig->configFactories.executorCreateFn); + createFromFactoriesIfPresent(m_clientConfig->writeRateLimiter, m_clientConfig->configFactories.writeRateLimiterCreateFn); + createFromFactoriesIfPresent(m_clientConfig->readRateLimiter, m_clientConfig->configFactories.readRateLimiterCreateFn); + createFromFactoriesIfPresent(m_clientConfig->telemetryProvider, m_clientConfig->configFactories.telemetryProviderCreateFn); + m_userAgent = Aws::Client::ComputeUserAgentString(m_clientConfig.get()); } std::shared_ptr diff --git a/tests/aws-cpp-sdk-core-tests/smithy/client/SmithyClientTest.cpp b/tests/aws-cpp-sdk-core-tests/smithy/client/SmithyClientTest.cpp index 2200612c1b7..94296efb44a 100644 --- a/tests/aws-cpp-sdk-core-tests/smithy/client/SmithyClientTest.cpp +++ b/tests/aws-cpp-sdk-core-tests/smithy/client/SmithyClientTest.cpp @@ -1,36 +1,50 @@ /** -* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ -#include -#include -#include -#include - -#include -#include +#include +#include #include - -#include -#include -#include - #include -#include #include -#include #include +#include +#include +#include +#include +#include #include +#include #include -#include - -#include -#include +#include +#include +#include +#include +#include +#include +#include static const char ALLOC_TAG[] = "SmithyClientTest"; -class TestEndPointProvider : public Aws::Endpoint::EndpointProviderBase<> +struct TestEndPointProvider : public Aws::Endpoint::EndpointProviderBase<> { +public: + void InitBuiltInParameters(const Aws::Client::GenericClientConfiguration& config) override { AWS_UNREFERENCED_PARAM(config); } + + void OverrideEndpoint(const Aws::String& endpoint) override { AWS_UNREFERENCED_PARAM(endpoint); } + + ClientContextParameters& AccessClientContextParameters() override { return m_clientContext; } + + const ClientContextParameters& GetClientContextParameters() const override { return m_clientContext; } + + Aws::Endpoint::ResolveEndpointOutcome ResolveEndpoint(const Aws::Endpoint::EndpointParameters& endpointParameters) const override { + AWS_UNREFERENCED_PARAM(endpointParameters); + return Aws::Endpoint::AWSEndpoint{}; + } + + ~TestEndPointProvider() override = default; +private: + ClientContextParameters m_clientContext; }; @@ -101,6 +115,7 @@ class SmithyClientTest : public Aws::Testing::AwsCppSdkGTestSuite { httpClient = Aws::MakeShared(ALLOCATION_TAG); errorMarshaller = Aws::MakeShared(ALLOCATION_TAG); credsProviderChain = Aws::MakeShared(ALLOCATION_TAG); + endPointProvider = Aws::MakeShared(ALLOCATION_TAG); //add mock credentials provider for the test to the credentials provider chain AddCredentialsProvider(Aws::MakeShared("TestCredentialsProviderChain")); @@ -349,4 +364,66 @@ TEST_F(SmithyClientTest, bearer) EXPECT_EQ(res2.GetResult()->GetHeaderValue("authorization"), "Bearer testBearerToken"); +} + +struct SampleConfiguration: public Aws::Client::ClientConfiguration { + Aws::String localToService{"whatever"}; +}; + +struct SampleConfigurationAuthSchemeOption { + static smithy::AuthSchemeOption schemeOption; +}; + +struct SampleEndpointProvider : public Aws::Endpoint::EndpointProviderBase<> +{ +public: + void InitBuiltInParameters(const Aws::Client::GenericClientConfiguration& config) override { AWS_UNREFERENCED_PARAM(config); } + + void OverrideEndpoint(const Aws::String& endpoint) override { AWS_UNREFERENCED_PARAM(endpoint); } + + ClientContextParameters& AccessClientContextParameters() override { return m_clientContext; } + + const ClientContextParameters& GetClientContextParameters() const override { return m_clientContext; } + + Aws::Endpoint::ResolveEndpointOutcome ResolveEndpoint(const Aws::Endpoint::EndpointParameters& endpointParameters) const override { + AWS_UNREFERENCED_PARAM(endpointParameters); + return Aws::Endpoint::AWSEndpoint{}; + } + + ~SampleEndpointProvider() override = default; +private: + ClientContextParameters m_clientContext; +}; + +static constexpr char SampleServiceName[] = "SampleService"; +class SampleClient: public smithy::client::AwsSmithyClientT, + Aws::Crt::Variant, + SampleEndpointProvider, + smithy::client::JsonOutcomeSerializer, + smithy::client::JsonOutcome, + Aws::Client::JsonErrorMarshaller> +{ +public: + SampleClient(): AwsSmithyClientT(SampleConfiguration{}, + SampleServiceName, + Aws::MakeShared(SampleServiceName), + Aws::MakeShared(SampleServiceName), + Aws::MakeShared(SampleServiceName), + Aws::MakeShared>(SampleServiceName), + {}) + {} +}; + +TEST_F(SmithyClientTest, SmithyClientShouldCopyAssignAndMove) { + SampleClient client{}; + SampleClient copy{client}; + AWS_UNREFERENCED_PARAM(copy); + SampleClient assign = client; + AWS_UNREFERENCED_PARAM(assign); + SampleClient move{client}; + AWS_UNREFERENCED_PARAM(copy); + SampleClient moveAssign = std::move(client); + AWS_UNREFERENCED_PARAM(assign); } \ No newline at end of file diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientHeader.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientHeader.vm index e69ffb30625..3260b29122b 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientHeader.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientHeader.vm @@ -51,34 +51,6 @@ namespace ${serviceNamespace} static const char* GetServiceName(); static const char* GetAllocationTag(); inline const char* GetServiceClientName() const override { return "${metadata.serviceId}"; } - - ${className}(const ${className}& other); - - ${className}(${className}&& other); - - ${className}& operator=(const ${className}& other) - { - if(this == &other) - { - return *this; - } - AwsSmithyClientT::operator=(other); - Aws::Client::ClientWithAsyncTemplateMethods<${className}>::operator=(other); - init(m_clientConfiguration); - return *this; - } - - ${className}& operator=(${className}&& other) - { - if(this == &other) - { - return *this; - } - AwsSmithyClientT::operator=(std::move(other)); - Aws::Client::ClientWithAsyncTemplateMethods<${className}>::operator=(std::move(other)); - init(m_clientConfiguration); - return *this; - } #parse("com/amazonaws/util/awsclientgenerator/velocity/cpp/ServiceClientHeaderConfigTypeDeclarations.vm") #parse("com/amazonaws/util/awsclientgenerator/velocity/cpp/ServiceClientHeaderConstructors.vm") @@ -88,7 +60,6 @@ namespace ${serviceNamespace} std::shared_ptr<${metadata.classNamePrefix}EndpointProviderBase>& accessEndpointProvider(); private: friend class ${rootNamespace}::Client::ClientWithAsyncTemplateMethods<${className}>; - void init(const ${metadata.classNamePrefix}ClientConfiguration& clientConfiguration); #if($metadata.hasEndpointDiscoveryTrait) void OptionallyUpdateDescribeEndpointsCache(${rootNamespace}::Endpoint::AWSEndpoint& resolvedEndpoint, 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 6381a47b2a0..439256ea5ce 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 @@ -12,9 +12,7 @@ ${className}::${className}(const ${clientConfiguration}& clientConfiguration, {${entry}{GetServiceName(), clientConfiguration.region}}, #end }) -{ - init(m_clientConfiguration); -} +{} ${className}::${className}(const AWSCredentials& credentials, std::shared_ptr<${metadata.classNamePrefix}EndpointProviderBase> endpointProvider, @@ -30,9 +28,7 @@ ${className}::${className}(const AWSCredentials& credentials, {${entry}{Aws::MakeShared(ALLOCATION_TAG, credentials), GetServiceName(), clientConfiguration.region}}, #end }) -{ - init(m_clientConfiguration); -} +{} ${className}::${className}(const std::shared_ptr& credentialsProvider, std::shared_ptr<${metadata.classNamePrefix}EndpointProviderBase> endpointProvider, @@ -48,9 +44,7 @@ ${className}::${className}(const std::shared_ptr& creden {${entry}{ Aws::MakeShared(ALLOCATION_TAG, credentialsProvider), GetServiceName(), clientConfiguration.region}} #end }) -{ - init(m_clientConfiguration); -} +{} /* Legacy constructors due deprecation */ ${className}::${className}(const Client::ClientConfiguration& clientConfiguration) : @@ -65,9 +59,7 @@ ${className}::${className}(const Client::ClientConfiguration& clientConfiguratio {$entry{Aws::MakeShared(ALLOCATION_TAG), GetServiceName(), clientConfiguration.region}} #end }) -{ - init(m_clientConfiguration); -} +{} ${className}::${className}(const AWSCredentials& credentials, const Client::ClientConfiguration& clientConfiguration) : @@ -82,9 +74,7 @@ ${className}::${className}(const AWSCredentials& credentials, {$entry{Aws::MakeShared(ALLOCATION_TAG, credentials), GetServiceName(), clientConfiguration.region}} #end }) -{ - init(m_clientConfiguration); -} +{} ${className}::${className}(const std::shared_ptr& credentialsProvider, const Client::ClientConfiguration& clientConfiguration) : @@ -99,9 +89,7 @@ ${className}::${className}(const std::shared_ptr& creden {$entry{Aws::MakeShared(ALLOCATION_TAG, credentialsProvider), GetServiceName(), clientConfiguration.region}} #end }) -{ - init(m_clientConfiguration); -} +{} /* End of legacy constructors due deprecation */ ${className}::~${className}() @@ -114,46 +102,8 @@ std::shared_ptr<${metadata.classNamePrefix}EndpointProviderBase>& ${className}:: return m_endpointProvider; } -void ${className}::init(const ${clientConfiguration}& config) -{ - if (!m_clientConfiguration.executor) { - if (!m_clientConfiguration.configFactories.executorCreateFn()) { - AWS_LOGSTREAM_FATAL(ALLOCATION_TAG, "Failed to initialize client: config is missing Executor or executorCreateFn"); - m_isInitialized = false; - return; - } - m_clientConfiguration.executor = m_clientConfiguration.configFactories.executorCreateFn(); - } - AWS_CHECK_PTR(SERVICE_NAME, m_endpointProvider); - m_endpointProvider->InitBuiltInParameters(config); -#if($AdditionalServiceSpecificConfigLoadString) - ${AdditionalServiceSpecificConfigLoadString} -#end##if($AdditionalServiceSpecificConfigLoadString) -} - void ${className}::OverrideEndpoint(const Aws::String& endpoint) { AWS_CHECK_PTR(SERVICE_NAME, m_endpointProvider); m_endpointProvider->OverrideEndpoint(endpoint); } - -${className}::${className}(const ${className}& other): - AwsSmithyClientT( - *other.m_clientConfig, - GetServiceName(), - Aws::Http::CreateHttpClient(other.m_clientConfiguration), - Aws::MakeShared<${metadata.classNamePrefix}ErrorMarshaller>(ALLOCATION_TAG), - other.m_endpointProvider, - Aws::MakeShared>(ALLOCATION_TAG), - other.m_authSchemes), - Aws::Client::ClientWithAsyncTemplateMethods<${className}>(other) -{ - init(m_clientConfiguration); -} - -${className}::${className}(${className}&& other): - AwsSmithyClientT(std::move(other)), - Aws::Client::ClientWithAsyncTemplateMethods<${className}>(std::move(other)) -{ - init(m_clientConfiguration); -}