-   Notifications  You must be signed in to change notification settings 
- Fork 5.8k
Add examples for S3 CRT client in AWS SDK for C++. #1614
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
   Merged  
     Merged  
 Changes from all commits
 Commits 
  Show all changes 
  7 commits   Select commit Hold shift + click to select a range 
 2fe76e4  Add examples for S3 CRT client in AWS SDK for C++. 
  8c41a58  Update snippet-end tag. 
  44b7e11  Address Review. 
  abbd68f  Fix type. 
  e4bca66  Address reviews. 
  cc7eb76  Update s3-crt-demo.cpp 
  brmur c5d9e34  Update s3-crt-demo.cpp 
  brmur File filter
Filter by extension
Conversations
 Failed to load comments.  
    Loading  
 Jump to
  Jump to file  
  Failed to load files.  
    Loading  
 Diff view
Diff view
There are no files selected for viewing
   This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters   
     | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|  | ||
| # Set the minimum required version of CMake for this project. | ||
| cmake_minimum_required(VERSION 3.8) | ||
|  | ||
| # Set this project's name. | ||
| project("s3-crt-examples") | ||
|  | ||
| # Set the C++ standard to use to build this target. | ||
| set(CMAKE_CXX_STANDARD 11) | ||
|  | ||
| # Enable CTest for testing these code examples. | ||
| include(CTest) | ||
|  | ||
| # Build shared libraries by default. | ||
| if(NOT BUILD_SHARED_LIBS) | ||
| set(BUILD_SHARED_LIBS ON) | ||
| endif() | ||
|  | ||
| # Find the AWS SDK for C++ package. | ||
| find_package(AWSSDK REQUIRED COMPONENTS s3-crt) | ||
|  | ||
| # If the compiler is some version of Microsoft Visual C++, | ||
| # and building as shared libraries, then dynamically link to those shared libraries. | ||
| if(MSVC AND BUILD_SHARED_LIBS) | ||
| add_definitions(-DUSE_IMPORT_EXPORT) | ||
| # Copy relevant AWS SDK for C++ libraries into the current binary directory for running and debugging. | ||
| list(APPEND SERVICE_LIST s3-crt) | ||
| AWSSDK_CPY_DYN_LIBS(SERVICE_LIST "" ${CMAKE_CURRENT_BINARY_DIR}) | ||
| endif() | ||
|  | ||
| # Add the code example-specific header files. | ||
| file(GLOB AWSDOC_S3CRT_HEADERS | ||
| "include/awsdoc/s3-crt/*.h" | ||
| ) | ||
|  | ||
| # Add the code example-specific source files. | ||
| file(GLOB AWSDOC_S3CRT_SOURCE | ||
| "*.cpp" | ||
| ) | ||
|  | ||
| # Check whether the target system is Windows, including Win64. | ||
| if(WIN32) | ||
| # Check whether the compiler is some version of Microsoft Visual C++, or another compiler simulating C++. | ||
| if(MSVC) | ||
| source_group("Header Files\\awsdoc\\s3-crt" FILES ${AWSDOC_S3CRT_HEADERS}) | ||
| source_group("Source Files" FILES ${AWSDOC_S3CRT_SOURCE}) | ||
| endif(MSVC) | ||
| endif() | ||
|  | ||
| foreach(file ${AWSDOC_S3CRT_SOURCE}) | ||
| get_filename_component(EXAMPLE ${file} NAME_WE) | ||
|  | ||
| # Build the code example executables. | ||
| set(EXAMPLE_EXE run_${EXAMPLE}) | ||
|  | ||
| add_executable(${EXAMPLE_EXE} ${AWSDOC_S3CRT_HEADERS} ${file}) | ||
|  | ||
| if(MSVC AND BUILD_SHARED_LIBS) | ||
| target_compile_definitions(${EXAMPLE_EXE} PUBLIC "USE_IMPORT_EXPORT") | ||
| target_compile_definitions(${EXAMPLE_EXE} PRIVATE "AWSDOC_S3CRT_EXPORTS") | ||
| endif() | ||
|  | ||
| target_include_directories(${EXAMPLE_EXE} PUBLIC | ||
| $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> | ||
| $<INSTALL_INTERFACE:include>) | ||
| target_link_libraries(${EXAMPLE_EXE} ${AWSSDK_LINK_LIBRARIES} | ||
| ${AWSSDK_PLATFORM_DEPS}) | ||
|  | ||
| if(BUILD_TESTING) | ||
| # Enable testing for this directory and below. | ||
| enable_testing() | ||
|  | ||
| # Build the code example libraries. | ||
| set(EXAMPLE_LIB ${EXAMPLE}) | ||
|  | ||
| add_library(${EXAMPLE_LIB} ${AWSDOC_S3CRT_HEADERS} ${file} ) | ||
|  | ||
| if(MSVC AND BUILD_SHARED_LIBS) | ||
| target_compile_definitions(${EXAMPLE_LIB} PUBLIC "USE_IMPORT_EXPORT") | ||
| target_compile_definitions(${EXAMPLE_LIB} PRIVATE "AWSDOC_S3CRT_EXPORTS") | ||
| endif() | ||
|  | ||
| target_include_directories(${EXAMPLE_LIB} PUBLIC | ||
| $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> | ||
| $<INSTALL_INTERFACE:include>) | ||
| target_link_libraries(${EXAMPLE_LIB} ${AWSSDK_LINK_LIBRARIES} | ||
| ${AWSSDK_PLATFORM_DEPS}) | ||
|  | ||
| # Build the code example unit tests. | ||
| set(EXAMPLE_TEST test_${EXAMPLE}) | ||
| set(EXAMPLE_TEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/tests/test_${EXAMPLE}.cpp) | ||
|  | ||
| if(EXISTS ${EXAMPLE_TEST_FILE}) | ||
| add_executable(${EXAMPLE_TEST} ${EXAMPLE_TEST_FILE} ) | ||
|  | ||
| target_include_directories(${EXAMPLE_TEST} PUBLIC | ||
| $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> | ||
| $<INSTALL_INTERFACE:include>) | ||
| target_link_libraries(${EXAMPLE_TEST} ${EXAMPLE_LIB} ) | ||
| add_test(${EXAMPLE_TEST} ${EXAMPLE_TEST}) | ||
| endif() | ||
|  | ||
| endif() | ||
| endforeach() | 
   27 changes: 27 additions & 0 deletions  27   cpp/example_code/s3-crt/include/awsdoc/s3-crt/S3Crt_EXPORTS.h          
     This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters   
     | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
|  | ||
| #pragma once | ||
|  | ||
| #ifdef _MSC_VER | ||
| // Disable Windows complaining about max template size. | ||
| #pragma warning (disable : 4503) | ||
| #endif // _MSC_VER | ||
|  | ||
| #ifdef _WIN32 | ||
| #ifdef _MSC_VER | ||
| #pragma warning (disable : 4251) | ||
| #endif // _MSC_VER | ||
|  | ||
| #ifdef USE_IMPORT_EXPORT | ||
| #ifdef AWSDOC_S3CRT_EXPORTS | ||
| #define AWSDOC_S3CRT_API __declspec(dllexport) | ||
| #else | ||
| #define AWSDOC_S3CRT_API __declspec(dllimport) | ||
| #endif // AWSDOC_S3CRT_EXPORTS | ||
| #else | ||
| #define AWSDOC_S3CRT_API | ||
| #endif // USE_IMPORT_EXPORT | ||
| #else // _WIN32 | ||
| #define AWSDOC_S3CRT_API | ||
| #endif // _WIN32 | 
   23 changes: 23 additions & 0 deletions  23   cpp/example_code/s3-crt/include/awsdoc/s3-crt/s3-crt-demo.h          
     This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters   
     | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| // SPDX - License - Identifier: Apache - 2.0 | ||
|  | ||
| // Enables test_s3-crt-demo.cpp to test the functionality in s3-crt-demo.cpp. | ||
|  | ||
| #pragma once | ||
|  | ||
| #include <aws/core/Aws.h> | ||
| #include <aws/s3-crt/S3CrtClient.h> | ||
| #include <awsdoc/s3-crt/S3Crt_EXPORTS.h> | ||
|  | ||
| AWSDOC_S3CRT_API bool ListBuckets(const Aws::S3Crt::S3CrtClient& s3CrtClient, | ||
| const Aws::String& bucketName); | ||
| AWSDOC_S3CRT_API bool CreateBucket(const Aws::S3Crt::S3CrtClient& s3CrtClient, | ||
| const Aws::String& bucketName); | ||
| AWSDOC_S3CRT_API bool DeleteBucket(const Aws::S3Crt::S3CrtClient& s3CrtClient, | ||
| const Aws::String& bucketName); | ||
| AWSDOC_S3CRT_API bool PutObject(const Aws::S3Crt::S3CrtClient& s3CrtClient, | ||
| const Aws::String& bucketName, const Aws::String& objectKey, const Aws::String& fileName); | ||
| AWSDOC_S3CRT_API bool GetObject(const Aws::S3Crt::S3CrtClient& s3CrtClient, | ||
| const Aws::String& bucketName, const Aws::String& objectKey); | ||
| AWSDOC_S3CRT_API bool DeleteObject(const Aws::S3Crt::S3CrtClient& s3CrtClient, | ||
| const Aws::String& bucketName, const Aws::String& objectKey); | 
   This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters   
     | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| # Disregard this file. AWS uses it internally to | ||
| # track code coverage and unit test coverage | ||
| # within this repository. | ||
| --- | ||
| files: | ||
| - path: s3-crt-demo.cpp | ||
| services: | ||
| - s3-crt | ||
| ... | 
   This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters   
     | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,225 @@ | ||
| // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| // SPDX - License - Identifier: Apache - 2.0 | ||
|  | ||
| #include <awsdoc/s3-crt/s3-crt-demo.h> | ||
| // snippet-start:[s3-crt.cpp.bucket_operations.list_create_delete] | ||
| #include <iostream> | ||
| #include <fstream> | ||
| #include <aws/core/Aws.h> | ||
| #include <aws/core/utils/memory/stl/AWSStringStream.h> | ||
| #include <aws/core/utils/logging/CRTLogSystem.h> | ||
| #include <aws/s3-crt/S3CrtClient.h> | ||
| #include <aws/s3-crt/model/CreateBucketRequest.h> | ||
| #include <aws/s3-crt/model/DeleteBucketRequest.h> | ||
| #include <aws/s3-crt/model/PutObjectRequest.h> | ||
| #include <aws/s3-crt/model/GetObjectRequest.h> | ||
| #include <aws/s3-crt/model/DeleteObjectRequest.h> | ||
|  | ||
| static const char ALLOCATION_TAG[] = "s3-crt-demo"; | ||
|  | ||
| // List all Amazon Simple Storage Service (Amazon S3) buckets under the account. | ||
| bool ListBuckets(const Aws::S3Crt::S3CrtClient& s3CrtClient, const Aws::String& bucketName) { | ||
|  | ||
| Aws::S3Crt::Model::ListBucketsOutcome outcome = s3CrtClient.ListBuckets(); | ||
|  | ||
| if (outcome.IsSuccess()) { | ||
| std::cout << "All buckets under my account:" << std::endl; | ||
|  | ||
| for (auto const& bucket : outcome.GetResult().GetBuckets()) | ||
| { | ||
| std::cout << " * " << bucket.GetName() << std::endl; | ||
| } | ||
| std::cout << std::endl; | ||
|  | ||
| return true; | ||
| } | ||
| else { | ||
| std::cout << "ListBuckets error:\n"<< outcome.GetError() << std::endl << std::endl; | ||
|  | ||
| return false; | ||
| } | ||
| } | ||
|  | ||
| // Create an Amazon Simple Storage Service (Amazon S3) bucket. | ||
| bool CreateBucket(const Aws::S3Crt::S3CrtClient& s3CrtClient, const Aws::String& bucketName) { | ||
|  | ||
| std::cout << "Creating bucket: \"" << bucketName << "\" ..." << std::endl; | ||
|  | ||
| Aws::S3Crt::Model::CreateBucketRequest request; | ||
| request.SetBucket(bucketName); | ||
|  | ||
| Aws::S3Crt::Model::CreateBucketOutcome outcome = s3CrtClient.CreateBucket(request); | ||
|  | ||
| if (outcome.IsSuccess()) { | ||
| std::cout << "Bucket created." << std::endl << std::endl; | ||
|  | ||
| return true; | ||
| } | ||
| else { | ||
| std::cout << "CreateBucket error:\n" << outcome.GetError() << std::endl << std::endl; | ||
|  | ||
| return false; | ||
| } | ||
| } | ||
|  | ||
| // Delete an existing Amazon S3 bucket. | ||
| bool DeleteBucket(const Aws::S3Crt::S3CrtClient& s3CrtClient, const Aws::String& bucketName) { | ||
|  | ||
| std::cout << "Deleting bucket: \"" << bucketName << "\" ..." << std::endl; | ||
|  | ||
| Aws::S3Crt::Model::DeleteBucketRequest request; | ||
| request.SetBucket(bucketName); | ||
|  | ||
| Aws::S3Crt::Model::DeleteBucketOutcome outcome = s3CrtClient.DeleteBucket(request); | ||
|  | ||
| if (outcome.IsSuccess()) { | ||
| std::cout << "Bucket deleted." << std::endl << std::endl; | ||
|  | ||
| return true; | ||
| } | ||
| else { | ||
| std::cout << "DeleteBucket error:\n" << outcome.GetError() << std::endl << std::endl; | ||
|  | ||
| return false; | ||
| } | ||
| } | ||
|  | ||
| // Put an Amazon S3 object to the bucket. | ||
| bool PutObject(const Aws::S3Crt::S3CrtClient& s3CrtClient, const Aws::String& bucketName, const Aws::String& objectKey, const Aws::String& fileName) { | ||
|  | ||
| std::cout << "Putting object: \"" << objectKey << "\" to bucket: \"" << bucketName << "\" ..." << std::endl; | ||
|  | ||
| Aws::S3Crt::Model::PutObjectRequest request; | ||
| request.SetBucket(bucketName); | ||
| request.SetKey(objectKey); | ||
| std::shared_ptr<Aws::IOStream> bodyStream = Aws::MakeShared<Aws::FStream>(ALLOCATION_TAG, fileName.c_str(), std::ios_base::in | std::ios_base::binary); | ||
| if (!bodyStream->good()) { | ||
| std::cout << "Failed to open file: \"" << fileName << "\"." << std::endl << std::endl; | ||
| return false; | ||
| } | ||
| request.SetBody(bodyStream); | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [opinion] The existing s3 demo uploads a file from disk. That seems more interesting than uploading the string "s3-crt-demo" | ||
|  | ||
| Aws::S3Crt::Model::PutObjectOutcome outcome = s3CrtClient.PutObject(request); | ||
|  | ||
| if (outcome.IsSuccess()) { | ||
| std::cout << "Object added." << std::endl << std::endl; | ||
|  | ||
| return true; | ||
| } | ||
| else { | ||
| std::cout << "PutObject error:\n" << outcome.GetError() << std::endl << std::endl; | ||
|  | ||
| return false; | ||
| } | ||
| } | ||
|  | ||
| // Get the Amazon S3 object from the bucket. | ||
| bool GetObject(const Aws::S3Crt::S3CrtClient& s3CrtClient, const Aws::String& bucketName, const Aws::String& objectKey) { | ||
|  | ||
| std::cout << "Getting object: \"" << objectKey << "\" from bucket: \"" << bucketName << "\" ..." << std::endl; | ||
|  | ||
| Aws::S3Crt::Model::GetObjectRequest request; | ||
| request.SetBucket(bucketName); | ||
| request.SetKey(objectKey); | ||
|  | ||
| Aws::S3Crt::Model::GetObjectOutcome outcome = s3CrtClient.GetObject(request); | ||
|  | ||
| if (outcome.IsSuccess()) { | ||
| std::cout << "Object content: " << outcome.GetResult().GetBody().rdbuf() << std::endl << std::endl; | ||
|  | ||
| return true; | ||
| } | ||
| else { | ||
| std::cout << "GetObject error:\n" << outcome.GetError() << std::endl << std::endl; | ||
|  | ||
| return false; | ||
| } | ||
| } | ||
|  | ||
| // Delete the Amazon S3 object from the bucket. | ||
| bool DeleteObject(const Aws::S3Crt::S3CrtClient& s3CrtClient, const Aws::String& bucketName, const Aws::String& objectKey) { | ||
|  | ||
| std::cout << "Deleting object: \"" << objectKey << "\" from bucket: \"" << bucketName << "\" ..." << std::endl; | ||
|  | ||
| Aws::S3Crt::Model::DeleteObjectRequest request; | ||
| request.SetBucket(bucketName); | ||
| request.SetKey(objectKey); | ||
|  | ||
| Aws::S3Crt::Model::DeleteObjectOutcome outcome = s3CrtClient.DeleteObject(request); | ||
|  | ||
| if (outcome.IsSuccess()) { | ||
| std::cout << "Object deleted." << std::endl << std::endl; | ||
|  | ||
| return true; | ||
| } | ||
| else { | ||
| std::cout << "DeleteObject error:\n" << outcome.GetError() << std::endl << std::endl; | ||
|  | ||
| return false; | ||
| } | ||
| } | ||
|  | ||
| // 1. List all buckets under the account | ||
| // 2. Create an Amazon S3 bucket | ||
| // 3. Put an object to the bucket | ||
| // 4. Get the object | ||
| // 5. Delete the object | ||
| // 6. Delete the bucket | ||
| int main(int argc, char* argv[]) { | ||
|  | ||
| Aws::SDKOptions options; | ||
|  | ||
| // Override default log level for AWS common runtime libraries to prevent from being overwhelmed by logs from them. | ||
| options.loggingOptions.crt_logger_create_fn = []() { | ||
| return Aws::MakeShared<Aws::Utils::Logging::DefaultCRTLogSystem>(ALLOCATION_TAG, Aws::Utils::Logging::LogLevel::Warn); | ||
| }; | ||
|  | ||
| // Uncomment the following code to override default global client bootstrap for AWS common runtime libraries. | ||
| // options.ioOptions.clientBootstrap_create_fn = []() { | ||
| // Aws::Crt::Io::EventLoopGroup eventLoopGroup(0 /* cpuGroup */, 18 /* threadCount */); | ||
| // Aws::Crt::Io::DefaultHostResolver defaultHostResolver(eventLoopGroup, 8 /* maxHosts */, 300 /* maxTTL */); | ||
| // auto clientBootstrap = Aws::MakeShared<Aws::Crt::Io::ClientBootstrap>(ALLOCATION_TAG, eventLoopGroup, defaultHostResolver); | ||
| // clientBootstrap->EnableBlockingShutdown(); | ||
| // return clientBootstrap; | ||
| // }; | ||
|  | ||
| // Uncomment the following code to override default global TLS connection options for AWS common runtime libraries. | ||
| // options.ioOptions.tlsConnectionOptions_create_fn = []() { | ||
| // Aws::Crt::Io::TlsContextOptions tlsCtxOptions = Aws::Crt::Io::TlsContextOptions::InitDefaultClient(); | ||
| // Aws::Crt::Io::TlsContext tlsContext(tlsCtxOptions, Aws::Crt::Io::TlsMode::CLIENT); | ||
| // return Aws::MakeShared<Aws::Crt::Io::TlsConnectionOptions>(ALLOCATION_TAG, tlsContext.NewConnectionOptions()); | ||
| // }; | ||
|  | ||
| Aws::InitAPI(options); | ||
| { | ||
| Aws::String bucket_name = "my-bucket"; | ||
| Aws::String object_key = "my-object"; | ||
| Aws::String file_name = "my-file"; | ||
| Aws::String region = Aws::Region::US_EAST_1; | ||
| const double throughput_target_gbps = 5; | ||
| const uint64_t part_size = 8 * 1024 * 1024; // 8 MB. | ||
|  | ||
| Aws::S3Crt::ClientConfiguration config; | ||
| config.region = region; | ||
| config.throughputTargetGbps = throughput_target_gbps; | ||
| config.partSize = part_size; | ||
|  | ||
| Aws::S3Crt::S3CrtClient s3_crt_client(config); | ||
|  | ||
| ListBuckets(s3_crt_client, bucket_name); | ||
|  | ||
| CreateBucket(s3_crt_client, bucket_name); | ||
|  | ||
| PutObject(s3_crt_client, bucket_name, object_key, file_name); | ||
|  | ||
| GetObject(s3_crt_client, bucket_name, object_key); | ||
|  | ||
| DeleteObject(s3_crt_client, bucket_name, object_key); | ||
|  | ||
| DeleteBucket(s3_crt_client, bucket_name); | ||
| } | ||
| Aws::ShutdownAPI(options); | ||
|  | ||
| return 0; | ||
| } | ||
| // snippet-end:[s3-crt.cpp.bucket_operations.list_create_delete] | ||
  Oops, something went wrong.  
  Add this suggestion to a batch that can be applied as a single commit. This suggestion is invalid because no changes were made to the code. Suggestions cannot be applied while the pull request is closed. Suggestions cannot be applied while viewing a subset of changes. Only one suggestion per line can be applied in a batch. Add this suggestion to a batch that can be applied as a single commit. Applying suggestions on deleted lines is not supported. You must change the existing code in this line in order to create a valid suggestion. Outdated suggestions cannot be applied. This suggestion has been applied or marked resolved. Suggestions cannot be applied from pending reviews. Suggestions cannot be applied on multi-line comments. Suggestions cannot be applied while the pull request is queued to merge. Suggestion cannot be applied right now. Please check back later.    
 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't follow the whole flow for this, but at a first glance it doesn't look like you sharing the ownership of this object. Could it be a unique_ptr?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.