Skip to content

Commit fbb568b

Browse files
authored
Merge pull request #1614 from wps132230/s3-crt-demo
Add examples for S3 CRT client in AWS SDK for C++.
2 parents 2648721 + c5d9e34 commit fbb568b

File tree

6 files changed

+528
-0
lines changed

6 files changed

+528
-0
lines changed
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
# Set the minimum required version of CMake for this project.
5+
cmake_minimum_required(VERSION 3.8)
6+
7+
# Set this project's name.
8+
project("s3-crt-examples")
9+
10+
# Set the C++ standard to use to build this target.
11+
set(CMAKE_CXX_STANDARD 11)
12+
13+
# Enable CTest for testing these code examples.
14+
include(CTest)
15+
16+
# Build shared libraries by default.
17+
if(NOT BUILD_SHARED_LIBS)
18+
set(BUILD_SHARED_LIBS ON)
19+
endif()
20+
21+
# Find the AWS SDK for C++ package.
22+
find_package(AWSSDK REQUIRED COMPONENTS s3-crt)
23+
24+
# If the compiler is some version of Microsoft Visual C++,
25+
# and building as shared libraries, then dynamically link to those shared libraries.
26+
if(MSVC AND BUILD_SHARED_LIBS)
27+
add_definitions(-DUSE_IMPORT_EXPORT)
28+
# Copy relevant AWS SDK for C++ libraries into the current binary directory for running and debugging.
29+
list(APPEND SERVICE_LIST s3-crt)
30+
AWSSDK_CPY_DYN_LIBS(SERVICE_LIST "" ${CMAKE_CURRENT_BINARY_DIR})
31+
endif()
32+
33+
# Add the code example-specific header files.
34+
file(GLOB AWSDOC_S3CRT_HEADERS
35+
"include/awsdoc/s3-crt/*.h"
36+
)
37+
38+
# Add the code example-specific source files.
39+
file(GLOB AWSDOC_S3CRT_SOURCE
40+
"*.cpp"
41+
)
42+
43+
# Check whether the target system is Windows, including Win64.
44+
if(WIN32)
45+
# Check whether the compiler is some version of Microsoft Visual C++, or another compiler simulating C++.
46+
if(MSVC)
47+
source_group("Header Files\\awsdoc\\s3-crt" FILES ${AWSDOC_S3CRT_HEADERS})
48+
source_group("Source Files" FILES ${AWSDOC_S3CRT_SOURCE})
49+
endif(MSVC)
50+
endif()
51+
52+
foreach(file ${AWSDOC_S3CRT_SOURCE})
53+
get_filename_component(EXAMPLE ${file} NAME_WE)
54+
55+
# Build the code example executables.
56+
set(EXAMPLE_EXE run_${EXAMPLE})
57+
58+
add_executable(${EXAMPLE_EXE} ${AWSDOC_S3CRT_HEADERS} ${file})
59+
60+
if(MSVC AND BUILD_SHARED_LIBS)
61+
target_compile_definitions(${EXAMPLE_EXE} PUBLIC "USE_IMPORT_EXPORT")
62+
target_compile_definitions(${EXAMPLE_EXE} PRIVATE "AWSDOC_S3CRT_EXPORTS")
63+
endif()
64+
65+
target_include_directories(${EXAMPLE_EXE} PUBLIC
66+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
67+
$<INSTALL_INTERFACE:include>)
68+
target_link_libraries(${EXAMPLE_EXE} ${AWSSDK_LINK_LIBRARIES}
69+
${AWSSDK_PLATFORM_DEPS})
70+
71+
if(BUILD_TESTING)
72+
# Enable testing for this directory and below.
73+
enable_testing()
74+
75+
# Build the code example libraries.
76+
set(EXAMPLE_LIB ${EXAMPLE})
77+
78+
add_library(${EXAMPLE_LIB} ${AWSDOC_S3CRT_HEADERS} ${file} )
79+
80+
if(MSVC AND BUILD_SHARED_LIBS)
81+
target_compile_definitions(${EXAMPLE_LIB} PUBLIC "USE_IMPORT_EXPORT")
82+
target_compile_definitions(${EXAMPLE_LIB} PRIVATE "AWSDOC_S3CRT_EXPORTS")
83+
endif()
84+
85+
target_include_directories(${EXAMPLE_LIB} PUBLIC
86+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
87+
$<INSTALL_INTERFACE:include>)
88+
target_link_libraries(${EXAMPLE_LIB} ${AWSSDK_LINK_LIBRARIES}
89+
${AWSSDK_PLATFORM_DEPS})
90+
91+
# Build the code example unit tests.
92+
set(EXAMPLE_TEST test_${EXAMPLE})
93+
set(EXAMPLE_TEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/tests/test_${EXAMPLE}.cpp)
94+
95+
if(EXISTS ${EXAMPLE_TEST_FILE})
96+
add_executable(${EXAMPLE_TEST} ${EXAMPLE_TEST_FILE} )
97+
98+
target_include_directories(${EXAMPLE_TEST} PUBLIC
99+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
100+
$<INSTALL_INTERFACE:include>)
101+
target_link_libraries(${EXAMPLE_TEST} ${EXAMPLE_LIB} )
102+
add_test(${EXAMPLE_TEST} ${EXAMPLE_TEST})
103+
endif()
104+
105+
endif()
106+
endforeach()
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
#pragma once
5+
6+
#ifdef _MSC_VER
7+
// Disable Windows complaining about max template size.
8+
#pragma warning (disable : 4503)
9+
#endif // _MSC_VER
10+
11+
#ifdef _WIN32
12+
#ifdef _MSC_VER
13+
#pragma warning (disable : 4251)
14+
#endif // _MSC_VER
15+
16+
#ifdef USE_IMPORT_EXPORT
17+
#ifdef AWSDOC_S3CRT_EXPORTS
18+
#define AWSDOC_S3CRT_API __declspec(dllexport)
19+
#else
20+
#define AWSDOC_S3CRT_API __declspec(dllimport)
21+
#endif // AWSDOC_S3CRT_EXPORTS
22+
#else
23+
#define AWSDOC_S3CRT_API
24+
#endif // USE_IMPORT_EXPORT
25+
#else // _WIN32
26+
#define AWSDOC_S3CRT_API
27+
#endif // _WIN32
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX - License - Identifier: Apache - 2.0
3+
4+
// Enables test_s3-crt-demo.cpp to test the functionality in s3-crt-demo.cpp.
5+
6+
#pragma once
7+
8+
#include <aws/core/Aws.h>
9+
#include <aws/s3-crt/S3CrtClient.h>
10+
#include <awsdoc/s3-crt/S3Crt_EXPORTS.h>
11+
12+
AWSDOC_S3CRT_API bool ListBuckets(const Aws::S3Crt::S3CrtClient& s3CrtClient,
13+
const Aws::String& bucketName);
14+
AWSDOC_S3CRT_API bool CreateBucket(const Aws::S3Crt::S3CrtClient& s3CrtClient,
15+
const Aws::String& bucketName);
16+
AWSDOC_S3CRT_API bool DeleteBucket(const Aws::S3Crt::S3CrtClient& s3CrtClient,
17+
const Aws::String& bucketName);
18+
AWSDOC_S3CRT_API bool PutObject(const Aws::S3Crt::S3CrtClient& s3CrtClient,
19+
const Aws::String& bucketName, const Aws::String& objectKey, const Aws::String& fileName);
20+
AWSDOC_S3CRT_API bool GetObject(const Aws::S3Crt::S3CrtClient& s3CrtClient,
21+
const Aws::String& bucketName, const Aws::String& objectKey);
22+
AWSDOC_S3CRT_API bool DeleteObject(const Aws::S3Crt::S3CrtClient& s3CrtClient,
23+
const Aws::String& bucketName, const Aws::String& objectKey);
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Disregard this file. AWS uses it internally to
2+
# track code coverage and unit test coverage
3+
# within this repository.
4+
---
5+
files:
6+
- path: s3-crt-demo.cpp
7+
services:
8+
- s3-crt
9+
...
Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX - License - Identifier: Apache - 2.0
3+
4+
#include <awsdoc/s3-crt/s3-crt-demo.h>
5+
// snippet-start:[s3-crt.cpp.bucket_operations.list_create_delete]
6+
#include <iostream>
7+
#include <fstream>
8+
#include <aws/core/Aws.h>
9+
#include <aws/core/utils/memory/stl/AWSStringStream.h>
10+
#include <aws/core/utils/logging/CRTLogSystem.h>
11+
#include <aws/s3-crt/S3CrtClient.h>
12+
#include <aws/s3-crt/model/CreateBucketRequest.h>
13+
#include <aws/s3-crt/model/DeleteBucketRequest.h>
14+
#include <aws/s3-crt/model/PutObjectRequest.h>
15+
#include <aws/s3-crt/model/GetObjectRequest.h>
16+
#include <aws/s3-crt/model/DeleteObjectRequest.h>
17+
18+
static const char ALLOCATION_TAG[] = "s3-crt-demo";
19+
20+
// List all Amazon Simple Storage Service (Amazon S3) buckets under the account.
21+
bool ListBuckets(const Aws::S3Crt::S3CrtClient& s3CrtClient, const Aws::String& bucketName) {
22+
23+
Aws::S3Crt::Model::ListBucketsOutcome outcome = s3CrtClient.ListBuckets();
24+
25+
if (outcome.IsSuccess()) {
26+
std::cout << "All buckets under my account:" << std::endl;
27+
28+
for (auto const& bucket : outcome.GetResult().GetBuckets())
29+
{
30+
std::cout << " * " << bucket.GetName() << std::endl;
31+
}
32+
std::cout << std::endl;
33+
34+
return true;
35+
}
36+
else {
37+
std::cout << "ListBuckets error:\n"<< outcome.GetError() << std::endl << std::endl;
38+
39+
return false;
40+
}
41+
}
42+
43+
// Create an Amazon Simple Storage Service (Amazon S3) bucket.
44+
bool CreateBucket(const Aws::S3Crt::S3CrtClient& s3CrtClient, const Aws::String& bucketName) {
45+
46+
std::cout << "Creating bucket: \"" << bucketName << "\" ..." << std::endl;
47+
48+
Aws::S3Crt::Model::CreateBucketRequest request;
49+
request.SetBucket(bucketName);
50+
51+
Aws::S3Crt::Model::CreateBucketOutcome outcome = s3CrtClient.CreateBucket(request);
52+
53+
if (outcome.IsSuccess()) {
54+
std::cout << "Bucket created." << std::endl << std::endl;
55+
56+
return true;
57+
}
58+
else {
59+
std::cout << "CreateBucket error:\n" << outcome.GetError() << std::endl << std::endl;
60+
61+
return false;
62+
}
63+
}
64+
65+
// Delete an existing Amazon S3 bucket.
66+
bool DeleteBucket(const Aws::S3Crt::S3CrtClient& s3CrtClient, const Aws::String& bucketName) {
67+
68+
std::cout << "Deleting bucket: \"" << bucketName << "\" ..." << std::endl;
69+
70+
Aws::S3Crt::Model::DeleteBucketRequest request;
71+
request.SetBucket(bucketName);
72+
73+
Aws::S3Crt::Model::DeleteBucketOutcome outcome = s3CrtClient.DeleteBucket(request);
74+
75+
if (outcome.IsSuccess()) {
76+
std::cout << "Bucket deleted." << std::endl << std::endl;
77+
78+
return true;
79+
}
80+
else {
81+
std::cout << "DeleteBucket error:\n" << outcome.GetError() << std::endl << std::endl;
82+
83+
return false;
84+
}
85+
}
86+
87+
// Put an Amazon S3 object to the bucket.
88+
bool PutObject(const Aws::S3Crt::S3CrtClient& s3CrtClient, const Aws::String& bucketName, const Aws::String& objectKey, const Aws::String& fileName) {
89+
90+
std::cout << "Putting object: \"" << objectKey << "\" to bucket: \"" << bucketName << "\" ..." << std::endl;
91+
92+
Aws::S3Crt::Model::PutObjectRequest request;
93+
request.SetBucket(bucketName);
94+
request.SetKey(objectKey);
95+
std::shared_ptr<Aws::IOStream> bodyStream = Aws::MakeShared<Aws::FStream>(ALLOCATION_TAG, fileName.c_str(), std::ios_base::in | std::ios_base::binary);
96+
if (!bodyStream->good()) {
97+
std::cout << "Failed to open file: \"" << fileName << "\"." << std::endl << std::endl;
98+
return false;
99+
}
100+
request.SetBody(bodyStream);
101+
102+
Aws::S3Crt::Model::PutObjectOutcome outcome = s3CrtClient.PutObject(request);
103+
104+
if (outcome.IsSuccess()) {
105+
std::cout << "Object added." << std::endl << std::endl;
106+
107+
return true;
108+
}
109+
else {
110+
std::cout << "PutObject error:\n" << outcome.GetError() << std::endl << std::endl;
111+
112+
return false;
113+
}
114+
}
115+
116+
// Get the Amazon S3 object from the bucket.
117+
bool GetObject(const Aws::S3Crt::S3CrtClient& s3CrtClient, const Aws::String& bucketName, const Aws::String& objectKey) {
118+
119+
std::cout << "Getting object: \"" << objectKey << "\" from bucket: \"" << bucketName << "\" ..." << std::endl;
120+
121+
Aws::S3Crt::Model::GetObjectRequest request;
122+
request.SetBucket(bucketName);
123+
request.SetKey(objectKey);
124+
125+
Aws::S3Crt::Model::GetObjectOutcome outcome = s3CrtClient.GetObject(request);
126+
127+
if (outcome.IsSuccess()) {
128+
std::cout << "Object content: " << outcome.GetResult().GetBody().rdbuf() << std::endl << std::endl;
129+
130+
return true;
131+
}
132+
else {
133+
std::cout << "GetObject error:\n" << outcome.GetError() << std::endl << std::endl;
134+
135+
return false;
136+
}
137+
}
138+
139+
// Delete the Amazon S3 object from the bucket.
140+
bool DeleteObject(const Aws::S3Crt::S3CrtClient& s3CrtClient, const Aws::String& bucketName, const Aws::String& objectKey) {
141+
142+
std::cout << "Deleting object: \"" << objectKey << "\" from bucket: \"" << bucketName << "\" ..." << std::endl;
143+
144+
Aws::S3Crt::Model::DeleteObjectRequest request;
145+
request.SetBucket(bucketName);
146+
request.SetKey(objectKey);
147+
148+
Aws::S3Crt::Model::DeleteObjectOutcome outcome = s3CrtClient.DeleteObject(request);
149+
150+
if (outcome.IsSuccess()) {
151+
std::cout << "Object deleted." << std::endl << std::endl;
152+
153+
return true;
154+
}
155+
else {
156+
std::cout << "DeleteObject error:\n" << outcome.GetError() << std::endl << std::endl;
157+
158+
return false;
159+
}
160+
}
161+
162+
// 1. List all buckets under the account
163+
// 2. Create an Amazon S3 bucket
164+
// 3. Put an object to the bucket
165+
// 4. Get the object
166+
// 5. Delete the object
167+
// 6. Delete the bucket
168+
int main(int argc, char* argv[]) {
169+
170+
Aws::SDKOptions options;
171+
172+
// Override default log level for AWS common runtime libraries to prevent from being overwhelmed by logs from them.
173+
options.loggingOptions.crt_logger_create_fn = []() {
174+
return Aws::MakeShared<Aws::Utils::Logging::DefaultCRTLogSystem>(ALLOCATION_TAG, Aws::Utils::Logging::LogLevel::Warn);
175+
};
176+
177+
// Uncomment the following code to override default global client bootstrap for AWS common runtime libraries.
178+
// options.ioOptions.clientBootstrap_create_fn = []() {
179+
// Aws::Crt::Io::EventLoopGroup eventLoopGroup(0 /* cpuGroup */, 18 /* threadCount */);
180+
// Aws::Crt::Io::DefaultHostResolver defaultHostResolver(eventLoopGroup, 8 /* maxHosts */, 300 /* maxTTL */);
181+
// auto clientBootstrap = Aws::MakeShared<Aws::Crt::Io::ClientBootstrap>(ALLOCATION_TAG, eventLoopGroup, defaultHostResolver);
182+
// clientBootstrap->EnableBlockingShutdown();
183+
// return clientBootstrap;
184+
// };
185+
186+
// Uncomment the following code to override default global TLS connection options for AWS common runtime libraries.
187+
// options.ioOptions.tlsConnectionOptions_create_fn = []() {
188+
// Aws::Crt::Io::TlsContextOptions tlsCtxOptions = Aws::Crt::Io::TlsContextOptions::InitDefaultClient();
189+
// Aws::Crt::Io::TlsContext tlsContext(tlsCtxOptions, Aws::Crt::Io::TlsMode::CLIENT);
190+
// return Aws::MakeShared<Aws::Crt::Io::TlsConnectionOptions>(ALLOCATION_TAG, tlsContext.NewConnectionOptions());
191+
// };
192+
193+
Aws::InitAPI(options);
194+
{
195+
Aws::String bucket_name = "my-bucket";
196+
Aws::String object_key = "my-object";
197+
Aws::String file_name = "my-file";
198+
Aws::String region = Aws::Region::US_EAST_1;
199+
const double throughput_target_gbps = 5;
200+
const uint64_t part_size = 8 * 1024 * 1024; // 8 MB.
201+
202+
Aws::S3Crt::ClientConfiguration config;
203+
config.region = region;
204+
config.throughputTargetGbps = throughput_target_gbps;
205+
config.partSize = part_size;
206+
207+
Aws::S3Crt::S3CrtClient s3_crt_client(config);
208+
209+
ListBuckets(s3_crt_client, bucket_name);
210+
211+
CreateBucket(s3_crt_client, bucket_name);
212+
213+
PutObject(s3_crt_client, bucket_name, object_key, file_name);
214+
215+
GetObject(s3_crt_client, bucket_name, object_key);
216+
217+
DeleteObject(s3_crt_client, bucket_name, object_key);
218+
219+
DeleteBucket(s3_crt_client, bucket_name);
220+
}
221+
Aws::ShutdownAPI(options);
222+
223+
return 0;
224+
}
225+
// snippet-end:[s3-crt.cpp.bucket_operations.list_create_delete]

0 commit comments

Comments
 (0)