Skip to content

Commit 649274f

Browse files
authored
6238 cpp s3 getobject custom response stream (#6442)
* customizations for C++ sdk
1 parent 01b1eff commit 649274f

11 files changed

+878
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
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.13)
6+
7+
set(PROJECT_NAME sdk_customization)
8+
set(SERVICE_COMPONENTS s3)
9+
10+
# Set this project's name.
11+
project("${PROJECT_NAME}-examples")
12+
13+
# Set the C++ standard to use to build this target.
14+
set(CMAKE_CXX_STANDARD 11)
15+
16+
# Use the MSVC variable to determine if this is a Windows build.
17+
set(WINDOWS_BUILD ${MSVC})
18+
19+
# Set the location of where Windows can find the installed libraries of the SDK.
20+
if (WINDOWS_BUILD)
21+
string(REPLACE ";" "/aws-cpp-sdk-all;" SYSTEM_MODULE_PATH "${CMAKE_SYSTEM_PREFIX_PATH}/aws-cpp-sdk-all")
22+
list(APPEND CMAKE_PREFIX_PATH ${SYSTEM_MODULE_PATH})
23+
endif ()
24+
25+
# Find the AWS SDK for C++ package.
26+
find_package(AWSSDK REQUIRED COMPONENTS ${SERVICE_COMPONENTS})
27+
28+
29+
if (WINDOWS_BUILD AND AWSSDK_INSTALL_AS_SHARED_LIBS)
30+
# Copy relevant AWS SDK for C++ libraries into the current binary directory for running and debugging.
31+
32+
# set(BIN_SUB_DIR "/Debug") # If you are building from the command line, you may need to uncomment this
33+
# and set the proper subdirectory to the executables' location.
34+
35+
AWSSDK_CPY_DYN_LIBS(SERVICE_COMPONENTS "" ${CMAKE_CURRENT_BINARY_DIR}${BIN_SUB_DIR})
36+
endif ()
37+
38+
39+
# AWSDOC_SOURCE can be defined in the command line to limit the files in a build. For example,
40+
# you can limit files to one action.
41+
if (NOT DEFINED AWSDOC_SOURCE)
42+
file(GLOB AWSDOC_SOURCE
43+
"*.cpp"
44+
)
45+
endif ()
46+
47+
foreach (file ${AWSDOC_SOURCE})
48+
get_filename_component(EXAMPLE ${file} NAME_WE)
49+
50+
# Build the code example executables.
51+
set(EXAMPLE_EXE run_${EXAMPLE})
52+
53+
add_executable(${EXAMPLE_EXE} ${file})
54+
55+
target_link_libraries(${EXAMPLE_EXE} ${AWSSDK_LINK_LIBRARIES}
56+
${AWSSDK_PLATFORM_DEPS})
57+
58+
endforeach ()
59+
60+
61+
if (BUILD_TESTS)
62+
add_subdirectory(tests)
63+
endif ()
64+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Customization code examples for the SDK for C++
2+
3+
## Overview
4+
5+
Shows how to customize the behavior of the AWS SDK for C++.
6+
7+
8+
## ⚠ Important
9+
10+
* Running this code might result in charges to your AWS account. For more details, see [AWS Pricing](https://aws.amazon.com/pricing/) and [Free Tier](https://aws.amazon.com/free/).
11+
* Running the tests might result in charges to your AWS account.
12+
* We recommend that you grant your code least privilege. At most, grant only the minimum permissions required to perform the task. For more information, see [Grant least privilege](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege).
13+
* This code is not tested in every AWS Region. For more information, see [AWS Regional Services](https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services).
14+
15+
16+
## Code examples
17+
18+
### Prerequisites
19+
20+
21+
22+
Before using the code examples, first complete the installation and setup steps
23+
for [Getting started](https://docs.aws.amazon.com/sdk-for-cpp/v1/developer-guide/getting-started.html) in the AWS SDK for
24+
C++ Developer Guide.
25+
26+
Next, for information on code example structures and how to build and run the examples, see [Getting started with the AWS SDK for C++ code examples](https://docs.aws.amazon.com/sdk-for-cpp/v1/developer-guide/getting-started-code-examples.html).
27+
28+
29+
30+
### Customizations
31+
32+
Code excerpts that show you how to customize the behavior of the AWS C++ SDK.
33+
34+
- [Create a custom response stream](custom_response_stream.cpp)
35+
- [Override the default logger](override_default_logger.cpp)
36+
37+
38+
## Run the examples
39+
40+
### Instructions
41+
42+
An executable is built for each source file in this folder. These executables are located in the build folder and have
43+
"run_" prepended to the source file name, minus the suffix. See the "main" function in the source file for further instructions.
44+
45+
For example, to run the action in the source file "my_customization.cpp", execute the following command from within the build folder. The command
46+
will display any required arguments.
47+
48+
```
49+
./run_my_customization
50+
```
51+
52+
### Tests
53+
54+
⚠ Running tests might result in charges to your AWS account.
55+
56+
57+
58+
```sh
59+
cd <BUILD_DIR>
60+
cmake <path-to-root-of-this-source-code> -DBUILD_TESTS=ON
61+
make
62+
ctest
63+
```
64+
65+
66+
<!--custom.tests.start-->
67+
<!--custom.tests.end-->
68+
69+
## Additional resources
70+
71+
- [SDK for C++ Amazon S3 reference](https://sdk.amazonaws.com/cpp/api/LATEST/aws-cpp-sdk-s3/html/annotated.html)
72+
73+
74+
---
75+
76+
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
77+
78+
SPDX-License-Identifier: Apache-2.0
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
/**
5+
* Before running this C++ code example, set up your development environment, including your credentials.
6+
*
7+
* For more information, see the following documentation topic:
8+
*
9+
* https://docs.aws.amazon.com/sdk-for-cpp/v1/developer-guide/getting-started.html
10+
*
11+
* For information on the structure of the code examples and how to build and run the examples, see
12+
* https://docs.aws.amazon.com/sdk-for-cpp/v1/developer-guide/getting-started-code-examples.html.
13+
*
14+
**/
15+
16+
#include <iostream>
17+
#include <fstream>
18+
#include <aws/core/Aws.h>
19+
#include <aws/s3/S3Client.h>
20+
#include <aws/s3/model/GetObjectRequest.h>
21+
#include "sdk_customization_samples.h"
22+
23+
// snippet-start:[cpp.example_code.sdk_customization.CustomResponseStream]
24+
//! Use a custom response stream when downloading an object from an Amazon Simple
25+
//! Storage Service (Amazon S3) bucket.
26+
/*!
27+
\param bucketName: The Amazon S3 bucket name.
28+
\param objectKey: The object key.
29+
\param filePath: File path for custom response stream.
30+
\param clientConfiguration: AWS client configuration.
31+
\return bool: Function succeeded.
32+
*/
33+
34+
bool AwsDoc::SdkCustomization::customResponseStream(const Aws::String &bucketName,
35+
const Aws::String &objectKey,
36+
const Aws::String &filePath,
37+
const Aws::Client::ClientConfiguration &clientConfiguration) {
38+
39+
Aws::S3::S3Client s3_client(clientConfiguration);
40+
41+
Aws::S3::Model::GetObjectRequest getObjectRequest;
42+
getObjectRequest.WithBucket(bucketName).WithKey(objectKey);
43+
44+
getObjectRequest.SetResponseStreamFactory([filePath]() {
45+
return Aws::New<Aws::FStream>(
46+
"FStreamAllocationTag", filePath, std::ios_base::out);
47+
});
48+
49+
Aws::S3::Model::GetObjectOutcome getObjectOutcome = s3_client.GetObject(
50+
getObjectRequest);
51+
52+
if (getObjectOutcome.IsSuccess()) {
53+
std::cout << "Successfully retrieved object to file " << filePath << std::endl;
54+
}
55+
else {
56+
std::cerr << "Error getting object. "
57+
<< getObjectOutcome.GetError().GetMessage() << std::endl;
58+
}
59+
60+
return getObjectOutcome.IsSuccess();
61+
}
62+
// snippet-end:[cpp.example_code.sdk_customization.CustomResponseStream]
63+
64+
65+
/*
66+
*
67+
* main function
68+
*
69+
* Usage: 'run_custom_response_stream <bucket_name> <object_key> <file_name>'
70+
*
71+
* Prerequisites: An Amazon S3 bucket containing an object.
72+
*
73+
*/
74+
75+
#ifndef TESTING_BUILD
76+
77+
int main(int argc, char **argv) {
78+
if (argc != 4) {
79+
std::cout << "Usage: run_custom_response_stream <bucket_name> <object_key> <file_name>" << std::endl;
80+
return 1;
81+
}
82+
83+
Aws::String bucketName = argv[1];
84+
Aws::String keyName = argv[2];
85+
Aws::String fileName = argv[3];
86+
87+
Aws::SDKOptions options;
88+
options.loggingOptions.logLevel = Aws::Utils::Logging::LogLevel::Trace;
89+
Aws::InitAPI(options);
90+
{
91+
Aws::Client::ClientConfiguration clientConfig;
92+
// Optional: Set to the AWS Region (overrides config file).
93+
// clientConfig.region = "us-east-1";
94+
95+
AwsDoc::SdkCustomization::customResponseStream(bucketName, keyName, fileName, clientConfig);
96+
}
97+
98+
Aws::ShutdownAPI(options);
99+
100+
return 0;
101+
}
102+
103+
#endif // TESTING_BUILD
104+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
/**
5+
* Before running this C++ code example, set up your development environment, including your credentials.
6+
*
7+
* For more information, see the following documentation topic:
8+
*
9+
* https://docs.aws.amazon.com/sdk-for-cpp/v1/developer-guide/getting-started.html
10+
*
11+
* For information on the structure of the code examples and how to build and run the examples, see
12+
* https://docs.aws.amazon.com/sdk-for-cpp/v1/developer-guide/getting-started-code-examples.html.
13+
*
14+
**/
15+
16+
#include <iostream>
17+
#include <fstream>
18+
#include <aws/core/Aws.h>
19+
#include <aws/s3/S3Client.h>
20+
#include <aws/core/utils/logging/DefaultLogSystem.h>
21+
#include <aws/core/utils/stream/SimpleStreamBuf.h>
22+
23+
/*
24+
* This class overrides the default log system and allows temporary logging to a
25+
* 'SimpleStreamBuf'.
26+
*/
27+
28+
class LogSystemOverride : public Aws::Utils::Logging::DefaultLogSystem {
29+
public:
30+
explicit LogSystemOverride(Aws::Utils::Logging::LogLevel logLevel,
31+
const Aws::String &logPrefix)
32+
: DefaultLogSystem(logLevel, logPrefix), m_OverrideLog(false) {}
33+
34+
const Aws::Utils::Stream::SimpleStreamBuf &GetStreamBuf() const {
35+
return m_StreamBuf;
36+
}
37+
38+
void setOverrideLog(bool overrideLog) {
39+
m_OverrideLog = overrideLog;
40+
}
41+
42+
protected:
43+
44+
virtual void ProcessFormattedStatement(Aws::String &&statement) override {
45+
if (m_OverrideLog) {
46+
std::lock_guard<std::mutex> lock(m_StreamMutex);
47+
m_StreamBuf.sputn(statement.c_str(), statement.length());
48+
}
49+
else {
50+
DefaultLogSystem::ProcessFormattedStatement(std::move(statement));
51+
}
52+
}
53+
54+
private:
55+
Aws::Utils::Stream::SimpleStreamBuf m_StreamBuf;
56+
// Use a mutex when writing to the buffer because
57+
// ProcessFormattedStatement can be called from multiple threads.
58+
std::mutex m_StreamMutex;
59+
std::atomic<bool> m_OverrideLog;
60+
};
61+
62+
/*
63+
*
64+
* main function
65+
*
66+
* Usage: 'run_override_default_logger'
67+
*
68+
*/
69+
70+
int main(int argc, char **argv) {
71+
72+
Aws::SDKOptions options;
73+
options.loggingOptions.logLevel = Aws::Utils::Logging::LogLevel::Trace;
74+
auto logSystemOverride = Aws::MakeShared<LogSystemOverride>("AllocationTag",
75+
options.loggingOptions.logLevel,
76+
options.loggingOptions.defaultLogPrefix);
77+
options.loggingOptions.logger_create_fn = [logSystemOverride]() {
78+
return logSystemOverride;
79+
};
80+
81+
Aws::InitAPI(options);
82+
{
83+
Aws::Client::ClientConfiguration clientConfig;
84+
// Optional: Set to the AWS Region (overrides config file).
85+
// clientConfig.region = "us-east-1";
86+
87+
Aws::S3::S3Client s3Client(clientConfig);
88+
89+
logSystemOverride->setOverrideLog(true);
90+
auto outcome = s3Client.ListBuckets();
91+
if (outcome.IsSuccess()) {
92+
std::cout << "ListBuckets succeeded:" << std::endl;
93+
}
94+
logSystemOverride->setOverrideLog(false);
95+
96+
std::cout << "Log for ListBuckets" << std::endl;
97+
std::cout << logSystemOverride->GetStreamBuf().str() << std::endl;
98+
}
99+
100+
Aws::ShutdownAPI(options);
101+
102+
return 0;
103+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
5+
#pragma once
6+
#ifndef SDK_CUSTOMIZATION_EXAMPLES_SDK_CUSTOMIZATION_SAMPLES_H
7+
#define SDK_CUSTOMIZATION_EXAMPLES_SDK_CUSTOMIZATION_SAMPLES_H
8+
9+
#include <aws/core/client/ClientConfiguration.h>
10+
11+
namespace AwsDoc {
12+
namespace SdkCustomization {
13+
//! Use a custom response stream when downloading an object from an Amazon Simple
14+
//! Storage Service (Amazon S3) bucket.
15+
/*!
16+
\param bucketName: The Amazon S3 bucket name.
17+
\param objectKey: The object key.
18+
\param filePath: File path for custom response stream.
19+
\param clientConfiguration: AWS client configuration.
20+
\return bool: Function succeeded.
21+
*/
22+
bool customResponseStream(const Aws::String &bucketName,
23+
const Aws::String &objectKey,
24+
const Aws::String &filePath,
25+
const Aws::Client::ClientConfiguration &clientConfiguration);
26+
} // namespace SES
27+
} // namespace AwsDoc
28+
#endif //SDK_CUSTOMIZATION_EXAMPLES_SDK_CUSTOMIZATION_SAMPLES_H

0 commit comments

Comments
 (0)