blob: d209057eb14dd9a1767567ef302c7c2e3fe4cf23 [file]
/**
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <map>
#include <optional>
#include <string>
#include <sstream>
#include <utility>
#include <vector>
#include "s3/S3RequestSender.h"
#include "aws/core/utils/DateTime.h"
const std::string S3_VERSION_1 = "1.2.3";
const std::string S3_VERSION_2 = "1.2.4";
const std::string S3_ETAG = "\"tag-123\"";
const std::string S3_ETAG_UNQUOTED = "tag-123";
const std::string S3_EXPIRATION = "expiry-date=\"Wed, 28 Oct 2020 00:00:00 GMT\", rule-id=\"my_expiration_rule\"";
const std::string S3_EXPIRATION_DATE = "Wed, 28 Oct 2020 00:00:00 GMT";
const std::string S3_EXPIRATION_TIME_RULE_ID = "my_expiration_rule";
const Aws::S3Crt::Model::ServerSideEncryption S3_SSEALGORITHM = Aws::S3Crt::Model::ServerSideEncryption::aws_kms;
const std::string S3_SSEALGORITHM_STR = "aws_kms";
const std::string S3_CONTENT_TYPE = "application/octet-stream";
const std::string S3_CONTENT = "INPUT_DATA";
const std::string S3_KEY_PREFIX = "KEY_";
const std::string S3_ETAG_PREFIX = "ETAG_";
const std::size_t S3_OBJECT_COUNT = 10;
const int64_t S3_OBJECT_SIZE = 1024;
const int64_t S3_OBJECT_OLD_AGE_MILLISECONDS = 652924800;
const std::string S3_STORAGE_CLASS_STR = "Standard";
const std::map<std::string, std::string> S3_OBJECT_TAGS {
std::make_pair("tag1", "value1"),
std::make_pair("tag2", "value2")
};
const std::map<std::string, std::string> S3_OBJECT_USER_METADATA {
std::make_pair("metadata_key_1", "metadata_value_1"),
std::make_pair("metadata_key_2", "metadata_value_2")
};
const std::string S3_KEY_MARKER = "continue_key";
const std::string S3_VERSION_ID_MARKER = "continue_version";
const std::string S3_CONTINUATION_TOKEN = "continue";
const std::string S3_UPLOAD_ID = "test_upload_id";
class MockS3RequestSender : public minifi::aws::s3::S3RequestSender {
public:
MockS3RequestSender() {
for (std::size_t i = 0; i < S3_OBJECT_COUNT; ++i) {
Aws::S3Crt::Model::ObjectVersion version;
version.SetKey(S3_KEY_PREFIX + std::to_string(i));
version.SetETag(S3_ETAG_PREFIX + std::to_string(i));
version.SetIsLatest(false);
version.SetStorageClass(Aws::S3Crt::Model::ObjectVersionStorageClass::STANDARD);
version.SetVersionId(S3_VERSION_1);
version.SetSize(S3_OBJECT_SIZE);
version.SetLastModified(Aws::Utils::DateTime(S3_OBJECT_OLD_AGE_MILLISECONDS));
listed_versions_.push_back(version);
version.SetVersionId(S3_VERSION_2);
version.SetIsLatest(true);
version.SetLastModified(Aws::Utils::DateTime::CurrentTimeMillis());
listed_versions_.push_back(version);
}
for (std::size_t i = 0; i < S3_OBJECT_COUNT; ++i) {
Aws::S3Crt::Model::Object object;
object.SetKey(S3_KEY_PREFIX + std::to_string(i));
object.SetETag(S3_ETAG_PREFIX + std::to_string(i));
object.SetStorageClass(Aws::S3Crt::Model::ObjectStorageClass::STANDARD);
object.SetSize(S3_OBJECT_SIZE);
if (i % 2 == 0) {
object.SetLastModified(Aws::Utils::DateTime(S3_OBJECT_OLD_AGE_MILLISECONDS));
} else {
object.SetLastModified(Aws::Utils::DateTime::CurrentTimeMillis());
}
listed_objects_.push_back(object);
}
}
void setCredentials(const Aws::Auth::AWSCredentials& credentials) {
credentials_ = credentials;
}
void setClientConfig(const Aws::Client::ClientConfiguration& client_config) {
client_config_ = client_config;
}
void setUseVirtualAddressing(bool use_virtual_addressing) {
use_virtual_addressing_ = use_virtual_addressing;
}
std::optional<Aws::S3Crt::Model::PutObjectResult> sendPutObjectRequest(const Aws::S3Crt::Model::PutObjectRequest& request) override {
put_object_request = request;
Aws::S3Crt::Model::PutObjectResult put_s3_result;
if (!return_empty_result_) {
put_s3_result.SetVersionId(S3_VERSION_1);
put_s3_result.SetETag(S3_ETAG);
put_s3_result.SetExpiration(S3_EXPIRATION);
put_s3_result.SetServerSideEncryption(S3_SSEALGORITHM);
}
return put_s3_result;
}
bool sendDeleteObjectRequest(const Aws::S3Crt::Model::DeleteObjectRequest& request) override {
delete_object_request = request;
return delete_object_result_;
}
std::optional<Aws::S3Crt::Model::GetObjectResult> sendGetObjectRequest(const Aws::S3Crt::Model::GetObjectRequest& request) override {
get_object_request = request;
Aws::S3Crt::Model::GetObjectResult get_s3_result;
if (!return_empty_result_) {
get_s3_result.SetVersionId(S3_VERSION_1);
get_s3_result.SetETag(S3_ETAG);
get_s3_result.SetExpiration(S3_EXPIRATION);
get_s3_result.SetServerSideEncryption(S3_SSEALGORITHM);
get_s3_result.SetContentType(S3_CONTENT_TYPE);
get_s3_result.ReplaceBody(new std::stringstream(S3_CONTENT));
get_s3_result.SetContentLength(S3_CONTENT.size());
get_s3_result.SetMetadata(S3_OBJECT_USER_METADATA);
}
return std::make_optional(std::move(get_s3_result));
}
std::optional<Aws::S3Crt::Model::ListObjectsV2Result> sendListObjectsRequest(const Aws::S3Crt::Model::ListObjectsV2Request& request) override {
list_object_request = request;
Aws::S3Crt::Model::ListObjectsV2Result list_object_result;
if (!is_listing_truncated_) {
for (std::size_t i = 0; i < listed_objects_.size(); ++i) {
list_object_result.AddContents(listed_objects_[i]);
}
return list_object_result;
}
if (request.GetContinuationToken().empty()) {
list_object_result.SetNextContinuationToken(S3_CONTINUATION_TOKEN);
list_object_result.SetIsTruncated(true);
for (std::size_t i = 0; i < listed_objects_.size() / 2; ++i) {
list_object_result.AddContents(listed_objects_[i]);
}
} else {
list_object_result.SetIsTruncated(false);
for (auto i = listed_objects_.size() / 2; i < listed_objects_.size(); ++i) {
list_object_result.AddContents(listed_objects_[i]);
}
}
return list_object_result;
}
std::optional<Aws::S3Crt::Model::ListObjectVersionsResult> sendListVersionsRequest(const Aws::S3Crt::Model::ListObjectVersionsRequest& request) override {
list_version_request = request;
Aws::S3Crt::Model::ListObjectVersionsResult list_version_result;
if (!is_listing_truncated_) {
for (std::size_t i = 0; i < listed_versions_.size(); ++i) {
list_version_result.AddVersions(listed_versions_[i]);
}
return list_version_result;
}
if (request.GetKeyMarker().empty() && request.GetVersionIdMarker().empty()) {
list_version_result.SetNextKeyMarker(S3_KEY_MARKER);
list_version_result.SetNextVersionIdMarker(S3_VERSION_ID_MARKER);
list_version_result.SetIsTruncated(true);
for (std::size_t i = 0; i < listed_versions_.size() / 2; ++i) {
list_version_result.AddVersions(listed_versions_[i]);
}
} else {
list_version_result.SetIsTruncated(false);
for (auto i = listed_versions_.size() / 2; i < listed_versions_.size(); ++i) {
list_version_result.AddVersions(listed_versions_[i]);
}
}
return list_version_result;
}
std::optional<Aws::S3Crt::Model::GetObjectTaggingResult> sendGetObjectTaggingRequest(const Aws::S3Crt::Model::GetObjectTaggingRequest& request) override {
get_object_tagging_request = request;
Aws::S3Crt::Model::GetObjectTaggingResult result;
for (const auto& tag_pair : S3_OBJECT_TAGS) {
Aws::S3Crt::Model::Tag tag;
tag.SetKey(tag_pair.first);
tag.SetValue(tag_pair.second);
result.AddTagSet(tag);
}
return result;
}
std::optional<Aws::S3Crt::Model::HeadObjectResult> sendHeadObjectRequest(const Aws::S3Crt::Model::HeadObjectRequest& request) override {
head_object_request = request;
Aws::S3Crt::Model::HeadObjectResult head_s3_result;
if (!return_empty_result_) {
head_s3_result.SetVersionId(S3_VERSION_1);
head_s3_result.SetETag(S3_ETAG);
head_s3_result.SetExpiration(S3_EXPIRATION);
head_s3_result.SetServerSideEncryption(S3_SSEALGORITHM);
head_s3_result.SetContentType(S3_CONTENT_TYPE);
head_s3_result.SetContentLength(S3_CONTENT.size());
head_s3_result.SetMetadata(S3_OBJECT_USER_METADATA);
}
return std::make_optional(std::move(head_s3_result));
}
std::optional<Aws::S3Crt::Model::CreateMultipartUploadResult> sendCreateMultipartUploadRequest(const Aws::S3Crt::Model::CreateMultipartUploadRequest& request) override {
create_multipart_upload_request = request;
Aws::S3Crt::Model::CreateMultipartUploadResult result;
result.SetUploadId(S3_UPLOAD_ID);
return std::make_optional(std::move(result));
}
std::optional<Aws::S3Crt::Model::UploadPartResult> sendUploadPartRequest(const Aws::S3Crt::Model::UploadPartRequest& request) override {
if (etag_counter_ == fail_on_part_) {
fail_on_part_ = 0;
return std::nullopt;
}
upload_part_requests.push_back(request);
Aws::S3Crt::Model::UploadPartResult result;
result.SetETag("etag" + std::to_string(etag_counter_));
++etag_counter_;
return std::make_optional(std::move(result));
}
std::optional<Aws::S3Crt::Model::CompleteMultipartUploadResult> sendCompleteMultipartUploadRequest(const Aws::S3Crt::Model::CompleteMultipartUploadRequest& request) override {
complete_multipart_upload_request = request;
Aws::S3Crt::Model::CompleteMultipartUploadResult result;
if (!return_empty_result_) {
result.SetVersionId(S3_VERSION_1);
result.SetETag(S3_ETAG);
result.SetExpiration(S3_EXPIRATION);
result.SetServerSideEncryption(S3_SSEALGORITHM);
}
return std::make_optional(std::move(result));
}
std::optional<Aws::S3Crt::Model::ListMultipartUploadsResult> sendListMultipartUploadsRequest(const Aws::S3Crt::Model::ListMultipartUploadsRequest& request) override {
list_multipart_upload_request = request;
Aws::S3Crt::Model::ListMultipartUploadsResult result;
Aws::Vector<Aws::S3Crt::Model::MultipartUpload> uploads;
Aws::S3Crt::Model::MultipartUpload upload1;
upload1.SetKey("resumable_key");
upload1.SetUploadId("upload1");
upload1.SetInitiated(Aws::Utils::DateTime::CurrentTimeMillis());
uploads.push_back(upload1);
Aws::S3Crt::Model::MultipartUpload upload2;
upload2.SetKey("old_key");
upload2.SetUploadId("upload2");
upload2.SetInitiated(Aws::Utils::DateTime("1980-05-31T15:55:55Z", Aws::Utils::DateFormat::AutoDetect));
uploads.push_back(upload2);
result.SetUploads(uploads);
return std::make_optional(std::move(result));
}
bool sendAbortMultipartUploadRequest(const Aws::S3Crt::Model::AbortMultipartUploadRequest& request) override {
abort_multipart_upload_requests.push_back(request);
Aws::S3Crt::Model::AbortMultipartUploadResult result;
return true;
}
Aws::Auth::AWSCredentials getCredentials() const {
return credentials_;
}
Aws::Client::ClientConfiguration getClientConfig() const {
return client_config_;
}
bool getUseVirtualAddressing() const {
return use_virtual_addressing_;
}
std::string getPutObjectRequestBody() const {
std::istreambuf_iterator<char> buf_it;
return std::string(std::istreambuf_iterator<char>(*put_object_request.GetBody()), buf_it);
}
static std::string getUploadPartRequestBody(const Aws::S3Crt::Model::UploadPartRequest& upload_part_request) {
std::istreambuf_iterator<char> buf_it;
return std::string(std::istreambuf_iterator<char>(*upload_part_request.GetBody()), buf_it);
}
void returnEmptyS3Result(bool return_empty_result = true) {
return_empty_result_ = return_empty_result;
}
void setDeleteObjectResult(bool delete_object_result) {
delete_object_result_ = delete_object_result;
}
std::vector<Aws::S3Crt::Model::ObjectVersion> getListedVersion() const {
return listed_versions_;
}
std::vector<Aws::S3Crt::Model::Object> getListedObjects() const {
return listed_objects_;
}
void setListingTruncated(bool is_listing_truncated) {
is_listing_truncated_ = is_listing_truncated;
}
void failOnPartOnce(uint32_t fail_on_part) {
fail_on_part_ = fail_on_part;
}
Aws::S3Crt::Model::PutObjectRequest put_object_request;
Aws::S3Crt::Model::DeleteObjectRequest delete_object_request;
Aws::S3Crt::Model::GetObjectRequest get_object_request;
Aws::S3Crt::Model::ListObjectsV2Request list_object_request;
Aws::S3Crt::Model::ListObjectVersionsRequest list_version_request;
Aws::S3Crt::Model::GetObjectTaggingRequest get_object_tagging_request;
Aws::S3Crt::Model::HeadObjectRequest head_object_request;
Aws::S3Crt::Model::CreateMultipartUploadRequest create_multipart_upload_request;
std::vector<Aws::S3Crt::Model::UploadPartRequest> upload_part_requests;
Aws::S3Crt::Model::CompleteMultipartUploadRequest complete_multipart_upload_request;
Aws::S3Crt::Model::ListMultipartUploadsRequest list_multipart_upload_request;
std::vector<Aws::S3Crt::Model::AbortMultipartUploadRequest> abort_multipart_upload_requests;
private:
std::vector<Aws::S3Crt::Model::ObjectVersion> listed_versions_;
std::vector<Aws::S3Crt::Model::Object> listed_objects_;
bool delete_object_result_ = true;
bool return_empty_result_ = false;
bool is_listing_truncated_ = false;
Aws::Auth::AWSCredentials credentials_;
Aws::Client::ClientConfiguration client_config_;
bool use_virtual_addressing_ = true;
uint32_t etag_counter_ = 1;
uint32_t fail_on_part_ = 0;
};