Skip to content

Commit

Permalink
Add codegen for crt copy object
Browse files Browse the repository at this point in the history
  • Loading branch information
sbiscigl committed Jul 5, 2023
1 parent 6544c01 commit 7dcc651
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 112 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -391,14 +391,6 @@ namespace Aws
*/
virtual Model::CopyObjectOutcome CopyObject(const Model::CopyObjectRequest& request) const;

/**
* A Callable wrapper for CopyObject that returns a future to the operation so that it can be executed in parallel to other requests.
*/
template<typename CopyObjectRequestT = Model::CopyObjectRequest>
Model::CopyObjectOutcomeCallable CopyObjectCallable(const CopyObjectRequestT& request) const
{
return SubmitCallable(&S3CrtClient::CopyObject, request);
}

/**
* An Async wrapper for CopyObject that queues the request into a thread executor and triggers associated callback when operation has finished.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,6 @@ namespace Aws
/* Service model Outcome callable definitions */
typedef std::future<AbortMultipartUploadOutcome> AbortMultipartUploadOutcomeCallable;
typedef std::future<CompleteMultipartUploadOutcome> CompleteMultipartUploadOutcomeCallable;
typedef std::future<CopyObjectOutcome> CopyObjectOutcomeCallable;
typedef std::future<CreateBucketOutcome> CreateBucketOutcomeCallable;
typedef std::future<CreateMultipartUploadOutcome> CreateMultipartUploadOutcomeCallable;
typedef std::future<DeleteBucketOutcome> DeleteBucketOutcomeCallable;
Expand Down
193 changes: 100 additions & 93 deletions generated/src/aws-cpp-sdk-s3-crt/source/S3CrtClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,13 +390,13 @@ static void S3CrtRequestFinishCallback(struct aws_s3_meta_request *meta_request,
{
AWS_UNREFERENCED_PARAM(meta_request);
auto *userData = static_cast<S3CrtClient::CrtRequestCallbackUserData*>(user_data);

if (meta_request_result->error_code != AWS_ERROR_SUCCESS && meta_request_result->response_status == 0) {
/* client side error */
userData->response->SetClientErrorType(CoreErrors::NETWORK_CONNECTION);
Aws::StringStream ss;
ss << "crtCode: " << meta_request_result->error_code
<< ", " << aws_error_name(meta_request_result->error_code)
ss << "crtCode: " << meta_request_result->error_code
<< ", " << aws_error_name(meta_request_result->error_code)
<< " - " << aws_error_str(meta_request_result->error_code);
userData->response->SetClientErrorMessage(ss.str());
userData->response->SetResponseCode(HttpResponseCode::REQUEST_NOT_MADE);
Expand Down Expand Up @@ -527,6 +527,103 @@ void S3CrtClient::InitCommonCrtRequestOption(CrtRequestCallbackUserData *userDat
aws_uri_init_parse(options->endpoint, Aws::get_aws_allocator(), &endpointCursor);
}

static void CopyObjectRequestShutdownCallback(void *user_data)
{
auto *userData = static_cast<S3CrtClient::CrtRequestCallbackUserData*>(user_data);
// call user callback and release user_data
S3Crt::Model::CopyObjectOutcome outcome(userData->s3CrtClient->GenerateXmlOutcome(userData->response));
userData->copyResponseHandler(userData->s3CrtClient, *(reinterpret_cast<const CopyObjectRequest*>(userData->originalRequest)), std::move(outcome), userData->asyncCallerContext);

Aws::Delete(userData);
}

void S3CrtClient::CopyObjectAsync(const CopyObjectRequest& request, const CopyObjectResponseReceivedHandler& handler, const std::shared_ptr<const Aws::Client::AsyncCallerContext>& handlerContext) const
{
if (!m_endpointProvider) {
return handler(this, request, CopyObjectOutcome(Aws::Client::AWSError<S3CrtErrors>(S3CrtErrors::INTERNAL_FAILURE, "INTERNAL_FAILURE", "Endpoint provider is not initialized", false)), handlerContext);
}
if (!request.BucketHasBeenSet())
{
AWS_LOGSTREAM_ERROR("CopyObject", "Required field: Bucket, is not set");
return handler(this, request, CopyObjectOutcome(Aws::Client::AWSError<S3CrtErrors>(S3CrtErrors::MISSING_PARAMETER, "MISSING_PARAMETER", "Missing required field [Bucket]", false)), handlerContext);
}
if (!request.CopySourceHasBeenSet())
{
AWS_LOGSTREAM_ERROR("CopyObject", "Required field: CopySource, is not set");
return handler(this, request, CopyObjectOutcome(Aws::Client::AWSError<S3CrtErrors>(S3CrtErrors::MISSING_PARAMETER, "MISSING_PARAMETER", "Missing required field [CopySource]", false)), handlerContext);
}
if (!request.KeyHasBeenSet())
{
AWS_LOGSTREAM_ERROR("CopyObject", "Required field: Key, is not set");
return handler(this, request, CopyObjectOutcome(Aws::Client::AWSError<S3CrtErrors>(S3CrtErrors::MISSING_PARAMETER, "MISSING_PARAMETER", "Missing required field [Key]", false)), handlerContext);
}
ResolveEndpointOutcome endpointResolutionOutcome = m_endpointProvider->ResolveEndpoint(request.GetEndpointContextParams());
if (!endpointResolutionOutcome.IsSuccess()) {
handler(this, request, CopyObjectOutcome(Aws::Client::AWSError<CoreErrors>(
CoreErrors::ENDPOINT_RESOLUTION_FAILURE, "ENDPOINT_RESOLUTION_FAILURE", endpointResolutionOutcome.GetError().GetMessage(), false)), handlerContext);
return;
}
endpointResolutionOutcome.GetResult().AddPathSegments(request.GetKey());

// make aws_s3_meta_request with callbacks
CrtRequestCallbackUserData *userData = Aws::New<CrtRequestCallbackUserData>(ALLOCATION_TAG);
aws_s3_meta_request_options options;
AWS_ZERO_STRUCT(options);
aws_uri endpoint;
AWS_ZERO_STRUCT(endpoint);
options.endpoint = &endpoint;
std::unique_ptr<aws_uri, void(*)(aws_uri*)> endpointCleanup { options.endpoint, &aws_uri_clean_up };

userData->copyResponseHandler = handler;
userData->asyncCallerContext = handlerContext;
InitCommonCrtRequestOption(userData, &options, &request, endpointResolutionOutcome.GetResult().GetURI(), Aws::Http::HttpMethod::HTTP_PUT);
if (userData != nullptr &&
userData->request != nullptr &&
userData->request->GetContentBody() != nullptr &&
userData->request->GetContentBody()->fail())
{
return handler(this, request, CopyObjectOutcome(Aws::Client::AWSError<S3CrtErrors>(S3CrtErrors::INTERNAL_FAILURE, "INTERNAL_FAILURE", "Unable to create s3 meta request", false)), handlerContext);
}
options.shutdown_callback = CopyObjectRequestShutdownCallback;
options.type = AWS_S3_META_REQUEST_TYPE_COPY_OBJECT;
struct aws_signing_config_aws signing_config_override = m_s3CrtSigningConfig;
if (endpointResolutionOutcome.GetResult().GetAttributes() && endpointResolutionOutcome.GetResult().GetAttributes()->authScheme.GetSigningRegion()) {
signing_config_override.region = Aws::Crt::ByteCursorFromCString(endpointResolutionOutcome.GetResult().GetAttributes()->authScheme.GetSigningRegion()->c_str());
}
if (endpointResolutionOutcome.GetResult().GetAttributes() && endpointResolutionOutcome.GetResult().GetAttributes()->authScheme.GetSigningRegionSet()) {
signing_config_override.region = Aws::Crt::ByteCursorFromCString(endpointResolutionOutcome.GetResult().GetAttributes()->authScheme.GetSigningRegionSet()->c_str());
}
if (endpointResolutionOutcome.GetResult().GetAttributes() && endpointResolutionOutcome.GetResult().GetAttributes()->authScheme.GetSigningName()) {
signing_config_override.service = Aws::Crt::ByteCursorFromCString(endpointResolutionOutcome.GetResult().GetAttributes()->authScheme.GetSigningName()->c_str());
}
options.signing_config = &signing_config_override;

std::shared_ptr<Aws::Crt::Http::HttpRequest> crtHttpRequest = userData->request->ToCrtHttpRequest();
options.message= crtHttpRequest->GetUnderlyingMessage();
userData->crtHttpRequest = crtHttpRequest;

if (aws_s3_client_make_meta_request(m_s3CrtClient, &options) == nullptr)
{
return handler(this, request, CopyObjectOutcome(Aws::Client::AWSError<S3CrtErrors>(S3CrtErrors::INTERNAL_FAILURE, "INTERNAL_FAILURE", "Unable to create s3 meta request", false)), handlerContext);
}
}

CopyObjectOutcome S3CrtClient::CopyObject(const CopyObjectRequest& request) const
{
AWS_OPERATION_GUARD(CopyObject);
Aws::Utils::Threading::Semaphore sem(0, 1);
CopyObjectOutcome res;

auto handler = CopyObjectResponseReceivedHandler{[&](const S3CrtClient*, const CopyObjectRequest&, const CopyObjectOutcome& outcome, const std::shared_ptr<const Aws::Client::AsyncCallerContext> &) {
res = std::move(outcome);
sem.ReleaseAll();
}};

S3CrtClient::CopyObjectAsync(request, handler, nullptr);
sem.WaitOne();
return res;
}

static void GetObjectRequestShutdownCallback(void *user_data)
{
auto *userData = static_cast<S3CrtClient::CrtRequestCallbackUserData*>(user_data);
Expand Down Expand Up @@ -761,96 +858,6 @@ CompleteMultipartUploadOutcome S3CrtClient::CompleteMultipartUpload(const Comple
return CompleteMultipartUploadOutcome(MakeRequest(request, endpointResolutionOutcome.GetResult(), Aws::Http::HttpMethod::HTTP_POST));
}

static void CopyObjectRequestShutdownCallback(void *user_data)
{
auto *userData = static_cast<S3CrtClient::CrtRequestCallbackUserData*>(user_data);
S3Crt::Model::CopyObjectOutcome outcome(userData->s3CrtClient->GenerateXmlOutcome(userData->response));

userData->copyResponseHandler(userData->s3CrtClient, *(reinterpret_cast<const CopyObjectRequest*>(userData->originalRequest)), std::move(outcome), userData->asyncCallerContext);
Aws::Delete(userData);
}

void S3CrtClient::CopyObjectAsync(const Model::CopyObjectRequest& request, const CopyObjectResponseReceivedHandler& handler, const std::shared_ptr<const Aws::Client::AsyncCallerContext>& handlerContext) const
{
if (!m_endpointProvider) {
return handler(this, request, CopyObjectOutcome(Aws::Client::AWSError<S3CrtErrors>(S3CrtErrors::INTERNAL_FAILURE, "INTERNAL_FAILURE", "Endpoint provider is not initialized", false)), handlerContext);
}
if (!request.BucketHasBeenSet())
{
AWS_LOGSTREAM_ERROR("CopyObject", "Required field: Bucket, is not set");
return handler(this, request, CopyObjectOutcome(Aws::Client::AWSError<S3CrtErrors>(S3CrtErrors::MISSING_PARAMETER, "MISSING_PARAMETER", "Missing required field [Bucket]", false)), handlerContext);
}
if (!request.CopySourceHasBeenSet())
{
AWS_LOGSTREAM_ERROR("CopyObject", "Required field: CopySource, is not set");
return handler(this, request, CopyObjectOutcome(Aws::Client::AWSError<S3CrtErrors>(S3CrtErrors::MISSING_PARAMETER, "MISSING_PARAMETER", "Missing required field [CopySource]", false)), handlerContext);
}
if (!request.KeyHasBeenSet())
{
AWS_LOGSTREAM_ERROR("CopyObject", "Required field: Key, is not set");
return handler(this, request, CopyObjectOutcome(Aws::Client::AWSError<S3CrtErrors>(S3CrtErrors::MISSING_PARAMETER, "MISSING_PARAMETER", "Missing required field [Key]", false)), handlerContext);
}

ResolveEndpointOutcome endpointResolutionOutcome = m_endpointProvider->ResolveEndpoint(request.GetEndpointContextParams());
if (!endpointResolutionOutcome.IsSuccess()) {
handler(this, request, CopyObjectOutcome(Aws::Client::AWSError<CoreErrors>(
CoreErrors::ENDPOINT_RESOLUTION_FAILURE, "ENDPOINT_RESOLUTION_FAILURE", endpointResolutionOutcome.GetError().GetMessage(), false)), handlerContext);
return;
}
endpointResolutionOutcome.GetResult().AddPathSegments(request.GetKey());

CrtRequestCallbackUserData *userData = Aws::New<CrtRequestCallbackUserData>(ALLOCATION_TAG);
aws_s3_meta_request_options options;
AWS_ZERO_STRUCT(options);
aws_uri endpoint;
AWS_ZERO_STRUCT(endpoint);
options.endpoint = &endpoint;
std::unique_ptr<aws_uri, void(*)(aws_uri*)> endpointCleanup { options.endpoint, &aws_uri_clean_up };

userData->copyResponseHandler = handler;
userData->asyncCallerContext = handlerContext;
InitCommonCrtRequestOption(userData, &options, &request, endpointResolutionOutcome.GetResult().GetURI(), Aws::Http::HttpMethod::HTTP_PUT);
options.shutdown_callback = CopyObjectRequestShutdownCallback;
options.type = AWS_S3_META_REQUEST_TYPE_COPY_OBJECT;

struct aws_signing_config_aws signing_config_override = m_s3CrtSigningConfig;
if (endpointResolutionOutcome.GetResult().GetAttributes() && endpointResolutionOutcome.GetResult().GetAttributes()->authScheme.GetSigningRegion()) {
signing_config_override.region = Aws::Crt::ByteCursorFromCString(endpointResolutionOutcome.GetResult().GetAttributes()->authScheme.GetSigningRegion()->c_str());
}
if (endpointResolutionOutcome.GetResult().GetAttributes() && endpointResolutionOutcome.GetResult().GetAttributes()->authScheme.GetSigningRegionSet()) {
signing_config_override.region = Aws::Crt::ByteCursorFromCString(endpointResolutionOutcome.GetResult().GetAttributes()->authScheme.GetSigningRegionSet()->c_str());
}
if (endpointResolutionOutcome.GetResult().GetAttributes() && endpointResolutionOutcome.GetResult().GetAttributes()->authScheme.GetSigningName()) {
signing_config_override.service = Aws::Crt::ByteCursorFromCString(endpointResolutionOutcome.GetResult().GetAttributes()->authScheme.GetSigningName()->c_str());
}
options.signing_config = &signing_config_override;

std::shared_ptr<Aws::Crt::Http::HttpRequest> crtHttpRequest = userData->request->ToCrtHttpRequest();
options.message= crtHttpRequest->GetUnderlyingMessage();
userData->crtHttpRequest = crtHttpRequest;

if (aws_s3_client_make_meta_request(m_s3CrtClient, &options) == nullptr)
{
return handler(this, request, CopyObjectOutcome(Aws::Client::AWSError<S3CrtErrors>(S3CrtErrors::INTERNAL_FAILURE, "INTERNAL_FAILURE", "Unable to create s3 meta request", false)), handlerContext);
}
}

CopyObjectOutcome S3CrtClient::CopyObject(const CopyObjectRequest& request) const
{
AWS_OPERATION_GUARD(CopyObject);
Aws::Utils::Threading::Semaphore sem(0, 1);
CopyObjectOutcome res;

auto handler = CopyObjectResponseReceivedHandler{[&](const S3CrtClient*, const CopyObjectRequest&, CopyObjectOutcome outcome, const std::shared_ptr<const Aws::Client::AsyncCallerContext> &) {
res = std::move(outcome);
sem.ReleaseAll();
}};

S3CrtClient::CopyObjectAsync(request, handler, nullptr);
sem.WaitOne();
return res;
}

CreateBucketOutcome S3CrtClient::CreateBucket(const CreateBucketRequest& request) const
{
AWS_OPERATION_GUARD(CreateBucket);
Expand Down
12 changes: 2 additions & 10 deletions generated/src/aws-cpp-sdk-s3/include/aws/s3/S3Client.h
Original file line number Diff line number Diff line change
Expand Up @@ -408,20 +408,12 @@ namespace Aws
/**
* A Callable wrapper for CopyObject that returns a future to the operation so that it can be executed in parallel to other requests.
*/
template<typename CopyObjectRequestT = Model::CopyObjectRequest>
Model::CopyObjectOutcomeCallable CopyObjectCallable(const CopyObjectRequestT& request) const
{
return SubmitCallable(&S3Client::CopyObject, request);
}
virtual Model::CopyObjectOutcomeCallable CopyObjectCallable(const Model::CopyObjectRequest& request) const;

/**
* An Async wrapper for CopyObject that queues the request into a thread executor and triggers associated callback when operation has finished.
*/
template<typename CopyObjectRequestT = Model::CopyObjectRequest>
void CopyObjectAsync(const CopyObjectRequestT& request, const CopyObjectResponseReceivedHandler& handler, const std::shared_ptr<const Aws::Client::AsyncCallerContext>& context = nullptr) const
{
return SubmitAsync(&S3Client::CopyObject, request, handler, context);
}
virtual void CopyObjectAsync(const Model::CopyObjectRequest& request, const CopyObjectResponseReceivedHandler& handler, const std::shared_ptr<const Aws::Client::AsyncCallerContext>& context = nullptr) const;

/**
* <p>Creates a new S3 bucket. To create a bucket, you must register with Amazon S3
Expand Down
16 changes: 16 additions & 0 deletions generated/src/aws-cpp-sdk-s3/source/S3Client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,22 @@ CopyObjectOutcome S3Client::CopyObject(const CopyObjectRequest& request) const
return CopyObjectOutcome(MakeRequest(request, endpointResolutionOutcome.GetResult(), Aws::Http::HttpMethod::HTTP_PUT));
}

CopyObjectOutcomeCallable S3Client::CopyObjectCallable(const CopyObjectRequest& request) const
{
auto task = Aws::MakeShared< std::packaged_task< CopyObjectOutcome() > >(ALLOCATION_TAG, [this, request](){ return this->CopyObject(request); } );
auto packagedFunction = [task]() { (*task)(); };
m_executor->Submit(packagedFunction);
return task->get_future();
}

void S3Client::CopyObjectAsync(const CopyObjectRequest& request, const CopyObjectResponseReceivedHandler& handler, const std::shared_ptr<const Aws::Client::AsyncCallerContext>& context) const
{
m_executor->Submit( [this, request, handler, context]()
{
handler(this, request, CopyObject(request), context);
} );
}

CreateBucketOutcome S3Client::CreateBucket(const CreateBucketRequest& request) const
{
AWS_OPERATION_GUARD(CreateBucket);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public class S3RestXmlCppClientGenerator extends RestXmlCppClientGenerator {

s3CrtEnabledOps.add("GetObject");
s3CrtEnabledOps.add("PutObject");
s3CrtEnabledOps.add("CopyObject");

bucketLocationConstraints.add("us-east-1");
bucketLocationConstraints.add("us-east-2");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ namespace ${rootNamespace}
const S3CrtClient *s3CrtClient;
GetObjectResponseReceivedHandler getResponseHandler;
PutObjectResponseReceivedHandler putResponseHandler;
CopyObjectResponseReceivedHandler copyResponseHandler;
std::shared_ptr<const Aws::Client::AsyncCallerContext> asyncCallerContext;
const Aws::AmazonWebServiceRequest *originalRequest;
std::shared_ptr<Aws::Http::HttpRequest> request;
Expand Down
Loading

0 comments on commit 7dcc651

Please sign in to comment.