I am trying to use AWS SDK C++ S3 on Ceph Rados Object Gateway, called RGW.
My Environment
- Ceph 17.2.6 (Quincy)
- g++ (GCC) 11.2.1 20220127 (Red Hat 11.2.1-9)
- AWS SDK C++ S3 latest version (Maybe.. 1.11.209 ??)
- CentOS 8 Stream
Problem
CreateBucket
works. But CreateBucketOutcome
doesn't work. Threrfore, I can't be aware even it creates bucket well or not.
Aws::S3::Model::CreateBucketOutcome::IsSuccess()
doesn't work properly.
It always response the error, Xml Parse Error
.
Aws::S3::Model::CreateBucketOutcome::GetError().GetExceptionName()
: Xml Parse ErrorAws::S3::Model::CreateBucketOutcome::GetError().GetMessage()
: XML_ERROR_PARSING_TEXT
The problem is that, I can't get raw xml message because the function is protected
.
Code
I wrote the example code, for creating 2 buckets, listing buckets, deleting 1 bucket, and listing buckets in serial order.
Aws::S3::S3Client::CreateBucket
is work as you can see on bucket list. However, Aws::S3::Model::CreateBucketOutcome
doesn't work properly.
(Of course, DeleteBucket
is working properly without any trouble.)
Create Bucket
void CreateBucket(std::string bucketName) {
Aws::Client::ClientConfiguration clientConfig;
clientConfig.endpointOverride = "XXX.XXX.XXX.XXX:PORT";
clientConfig.scheme = Aws::Http::Scheme::HTTP;
clientConfig.verifySSL = false;
Aws::Auth::AWSCredentials credentials;
credentials.SetAWSAccessKeyId("____________________");
credentials.SetAWSSecretKey("________________________________________");
Aws::S3::S3Client client = Aws::S3::S3Client(credentials, clientConfig, Aws::Client::AWSAuthV4Signer::PayloadSigningPolicy::Never, false);
Aws::S3::Model::CreateBucketRequest request;
request.SetBucket(bucketName);
Aws::S3::Model::CreateBucketConfiguration createBucketConfig;
Aws::String region("default"); // Empty string for default region (https://docs.ceph.com/en/quincy/radosgw/s3/bucketops/#response-entities)
createBucketConfig.SetLocationConstraint(Aws::S3::Model::BucketLocationConstraintMapper::GetBucketLocationConstraintForName(region));
std::cout << "My region: " << region << std::endl;
request.SetCreateBucketConfiguration(createBucketConfig);
std::cout << "BEFORE!" << std::endl;
Aws::S3::Model::CreateBucketOutcome outcome = client.CreateBucket(request);
std::cout << "AFTER! " << std::to_string(outcome.IsSuccess()) << std::endl;
if (outcome.IsSuccess()) {
std::cout << "SUCCESS!" << std::endl;
} else {
auto err = outcome.GetError();
std::cerr << "===========ERROR===========" << std::endl;
std::cerr << "Error: CreateBucket: " <<
err.GetExceptionName() << ": " << err.GetMessage() << std::endl;
std::cerr << err << std::endl;
std::cerr << "===========================" << std::endl;
}
}
ListBucket
void ListBucket() {
Aws::Client::ClientConfiguration clientConfig;
clientConfig.endpointOverride = "XXX.XXX.XXX.XXX:PORT";
clientConfig.scheme = Aws::Http::Scheme::HTTP;
clientConfig.verifySSL = false;
Aws::Auth::AWSCredentials credentials;
credentials.SetAWSAccessKeyId("____________________");
credentials.SetAWSSecretKey("________________________________________");
Aws::S3::S3Client client = Aws::S3::S3Client(credentials, clientConfig, Aws::Client::AWSAuthV4Signer::PayloadSigningPolicy::Never, false);
auto outcome = client.ListBuckets();
if (outcome.IsSuccess()) {
for (auto&& b : outcome.GetResult().GetBuckets()) {
std::cout << b.GetName().c_str() << std::endl;
}
} else {
auto err = outcome.GetError();
std::cerr << "Error: ListBucket: " <<
err.GetExceptionName() << ": " << err.GetMessage() << std::endl;
}
}
DeleteBucket
void DeleteBucket(std::string bucketName) {
Aws::Client::ClientConfiguration clientConfig;
clientConfig.endpointOverride = "XXX.XXX.XXX.XXX:PORT";
clientConfig.scheme = Aws::Http::Scheme::HTTP;
clientConfig.verifySSL = false;
Aws::Auth::AWSCredentials credentials;
credentials.SetAWSAccessKeyId("____________________");
credentials.SetAWSSecretKey("________________________________________");
Aws::S3::S3Client client = Aws::S3::S3Client(credentials, clientConfig, Aws::Client::AWSAuthV4Signer::PayloadSigningPolicy::Never, false);
Aws::S3::Model::DeleteBucketRequest request;
request.SetBucket(bucketName);
Aws::S3::Model::DeleteBucketOutcome outcome = client.DeleteBucket(request);
if (outcome.IsSuccess()) {
std::cout << "SUCCESS!" << std::endl;
} else {
auto err = outcome.GetError();
std::cerr << "===========ERROR===========" << std::endl;
std::cerr << "Error: CreateBucket: " <<
err.GetExceptionName() << ": " << err.GetMessage() << std::endl;
std::cerr << err << std::endl;
std::cerr << "===========================" << std::endl;
}
}
main function
int main() {
Aws::SDKOptions options;
options.loggingOptions.logLevel = Aws::Utils::Logging::LogLevel::Debug;
Aws::InitAPI(options);
CreateBucket("bucket1");
CreateBucket("bucket2");
ListBucket();
DeleteBucket("bucket1");
ListBucket();
Aws::ShutdownAPI(options);
}
Running results (terminal)
[ 50%] Building CXX object CMakeFiles/AWSS3Test.dir/src/main.cc.o
[100%] Linking CXX executable AWSS3Test
[100%] Built target AWSS3Test
My region: default
BEFORE!
AFTER! 0
===========ERROR===========
Error: CreateBucket: Xml Parse Error: XML_ERROR_PARSING_TEXT
HTTP response code: -1
Resolved remote host IP address:
Request ID:
Exception name: Xml Parse Error
Error message: XML_ERROR_PARSING_TEXT
0 response headers:
===========================
My region: default
BEFORE!
AFTER! 0
===========ERROR===========
Error: CreateBucket: Xml Parse Error: XML_ERROR_PARSING_TEXT
HTTP response code: -1
Resolved remote host IP address:
Request ID:
Exception name: Xml Parse Error
Error message: XML_ERROR_PARSING_TEXT
0 response headers:
===========================
bucket1
bucket2
SUCCESS!
bucket2
Conclusion
Please let me know how to solve this problem.
- Should I contact with Ceph engineer? If so, how can I report this problem?
- Is there any available options for not S3 but Ceph RGW ? (Like changing outcome style or etc.)
- Do I misuse AWS SDK C++ S3? (I guess not. It is on official documents.)