Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ namespace Aws
public:
typedef AWSClient BASECLASS;

typedef OutcomeType OUTCOME;
typedef ResponseType RESPONSE;

AWSProtocolClient(const Aws::Client::ClientConfiguration& configuration,
const std::shared_ptr<Aws::Client::AWSAuthSigner>& signer,
const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller)
Expand Down
3 changes: 3 additions & 0 deletions src/aws-cpp-sdk-core/include/aws/core/client/AWSXmlClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ namespace Aws
public:
typedef AWSClient BASECLASS;

typedef XmlOutcome OUTCOME;
typedef Utils::Xml::XmlDocument RESPONSE;

AWSXMLClient(const Aws::Client::ClientConfiguration& configuration,
const std::shared_ptr<Aws::Client::AWSAuthSigner>& signer,
const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller);
Expand Down
2 changes: 2 additions & 0 deletions src/aws-cpp-sdk-core/include/aws/core/utils/Outcome.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ namespace Aws
class Outcome
{
public:
typedef R RESULT;
typedef E ERROR;

Outcome() : result(), error(), success(false)
{
Expand Down
27 changes: 27 additions & 0 deletions src/aws-cpp-sdk-core/include/aws/core/utils/logging/ErrorMacros.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@ do { \
} \
} while (0)

#define AWS_OPERATION_CHECK_PTR_DYNAMIC(PTR, OPERATION, ERROR_TYPE, ERROR) \
do { \
if (PTR == nullptr) \
{ \
AWS_LOGSTREAM_FATAL(OPERATION, "Unexpected nullptr: " #PTR); \
return Aws::Client::AWSError<ERROR_TYPE>(ERROR, #ERROR, "Unexpected nullptr: " #PTR, false); \
} \
} while (0)


#define AWS_CHECK(LOG_TAG, CONDITION, ERROR_MESSAGE, RETURN) \
do { \
if (!(CONDITION)) \
Expand Down Expand Up @@ -49,6 +59,15 @@ do { \
} \
} while (0)

#define AWS_OPERATION_CHECK_SUCCESS_DYNAMIC(OUTCOME, OPERATION, ERROR_TYPE, ERROR, ERROR_MESSAGE) \
do { \
if (!OUTCOME.IsSuccess()) \
{ \
AWS_LOGSTREAM_ERROR(OPERATION, ERROR_MESSAGE); \
return Aws::Client::AWSError<ERROR_TYPE>(ERROR, #ERROR, ERROR_MESSAGE, false); \
} \
} while (0)

#define AWS_OPERATION_CHECK_PARAMETER_PRESENT(REQUEST, FIELD, OPERATION, CLIENT_NAMESPACE) \
do { \
if (!REQUEST##.##FIELD##HasBeenSet()) \
Expand All @@ -66,6 +85,14 @@ if(!m_isInitialized) \
} \
Aws::Utils::RAIICounter raiiGuard(this->m_operationsProcessed, &this->m_shutdownSignal)

#define AWS_OPERATION_GUARD_DYNAMIC(OPERATION) \
if(!m_isInitialized) \
{ \
AWS_LOGSTREAM_ERROR(OPERATION, "Unable to call " << OPERATION << ": client is not initialized (or already terminated)"); \
return Aws::Client::AWSError<CoreErrors>(CoreErrors::NOT_INITIALIZED, "NOT_INITIALIZED", "Client is not initialized or already terminated", false); \
} \
Aws::Utils::RAIICounter raiiGuard(this->m_operationsProcessed, &this->m_shutdownSignal)

#define AWS_ASYNC_OPERATION_GUARD(OPERATION) \
if(!m_isInitialized) \
{ \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ ${cbor_virtual}std::shared_ptr<${metadata.classNamePrefix}EndpointProviderBase>&
void Load${metadata.classNamePrefix}SpecificConfig(const Aws::Client::ClientConfiguration& clientConfiguration);
#end

#parse("com/amazonaws/util/awsclientgenerator/velocity/cpp/common/ServiceInvokeOperationHeader.vm")

#if(!$serviceModel.endpointRules)
#if($metadata.hasEndpointTrait)
Aws::String m_baseUri;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,6 @@ const char* ${className}::GetAllocationTag() {return ALLOCATION_TAG;}
#parseOverrideOrDefault( "ServiceClientSourceInit_template" "com/amazonaws/util/awsclientgenerator/velocity/cpp/ServiceClientSourceInit.vm")
#end

#parse("com/amazonaws/util/awsclientgenerator/velocity/cpp/common/ServiceInvokeOperationSource.vm")

#parse("com/amazonaws/util/awsclientgenerator/velocity/cpp/json/serviceoperations/JsonServiceOperationsSource.vm")
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
return handler(this, ${operation.name}Outcome(Aws::Client::AWSError<${metadata.classNamePrefix}Errors>(${metadata.classNamePrefix}Errors::INTERNAL_FAILURE, "INTERNAL_FAILURE", "Endpoint provider is not initialized", false)), handlerContext);
}
#end
#else
#elseif(!$emitGenericOperation)
AWS_OPERATION_CHECK_PTR(m_endpointProvider, ${operation.name}, CoreErrors, CoreErrors::ENDPOINT_RESOLUTION_FAILURE);
#end
#else##-#if(!$operation.request.shape.hasEventStreamMembers())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

## Be careful to not have this outcome name clash with an operation outcome name (specifically lambda:Invoke)
typedef Aws::Utils::Outcome<Aws::AmazonWebServiceResult<RESPONSE>, ${metadata.classNamePrefix}Error> InvokeOperationOutcome;

InvokeOperationOutcome InvokeServiceOperation(
const AmazonWebServiceRequest& request,
#if($metadata.protocol == "rest-json" || $metadata.protocol == "rest-xml")
const std::function<void(Aws::Endpoint::ResolveEndpointOutcome&)>& resolveUri,
#end
#if($serviceModel.metadata.namespace == "S3" || $serviceModel.metadata.namespace == "S3Crt")
Aws::String bucketName,
#end
Aws::Http::HttpMethod httpMethod
) const;
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#set($emitGenericOperation = true)
#parse("com/amazonaws/util/awsclientgenerator/velocity/cpp/common/ServiceClientOperationRequestRequiredMemberValidate.vm")
#set($emitGenericOperation = false)

#if($serviceModel.metadata.serviceId == "EC2")
#set($presignSpelling = "PresignedUrl")
#set($shouldGenerateUrl = "request.SourceRegionHasBeenSet()")
#else
#set($presignSpelling = "PreSignedUrl")
#set($shouldGenerateUrl = "request.SourceRegionHasBeenSet() && !request.${presignSpelling}HasBeenSet()")
#end

##
## Handle presigned URL generation if the operation requires it
##

#if($operation.hasPreSignedUrl)
if (${shouldGenerateUrl}) {
${operation.request.shape.name} newRequest = request;
Aws::Endpoint::EndpointParameters endpointParameters;
#if($operation.staticContextParams)
#foreach($staticParamPair in $operation.staticContextParams.entrySet())
parameters.emplace_back(Aws::String("${staticParamPair.key}"), ${staticParamPair.value.get("value").getValue()});
#end
#end
endpointParameters.emplace_back(Aws::Endpoint::EndpointParameter("Region", request.GetSourceRegion()));
ResolveEndpointOutcome presignedEndpointResolutionOutcome = m_endpointProvider->ResolveEndpoint(endpointParameters);
AWS_OPERATION_CHECK_SUCCESS(presignedEndpointResolutionOutcome, ${operation.name}, CoreErrors, CoreErrors::ENDPOINT_RESOLUTION_FAILURE, presignedEndpointResolutionOutcome.GetError().GetMessage());
newRequest.Set${presignSpelling}(GeneratePresignedUrl(request, presignedEndpointResolutionOutcome.GetResult().GetURI(),
Aws::Http::HttpMethod::HTTP_GET, request.GetSourceRegion().c_str(),
{{ "DestinationRegion", m_region }}, 3600));

return ${operation.name}Outcome{InvokeServiceOperation(newRequest, Aws::Http::HttpMethod::HTTP_${operation.http.method})};
}
#end

#if($metadata.protocol == "ec2" || $metadata.protocol == "json" || $metadata.protocol == "query" || $metadata.protocol == "smithy-rpc-v2-cbor")
return ${operation.name}Outcome{InvokeServiceOperation(request, Aws::Http::HttpMethod::HTTP_${operation.http.method})};
#elseif($metadata.protocol == "rest-json" || $metadata.protocol == "rest-xml")
auto uriResolver = [&](Aws::Endpoint::ResolveEndpointOutcome& endpointResolutionOutcome) {
(void)endpointResolutionOutcome;
#parse("com/amazonaws/util/awsclientgenerator/velocity/cpp/common/UriRequestPathSegments.vm")
};

#if($serviceModel.metadata.namespace == "S3" || $serviceModel.metadata.namespace == "S3Crt")
#if(($serviceModel.metadata.namespace == "S3" || ($serviceModel.metadata.namespace == "S3Crt" && !$operation.s3CrtEnabled)) && $operation.shouldUsePropertyBag)
return ${operation.name}Outcome{InvokeServiceOperation(request, uriResolver, request.GetBucket(), Aws::Http::HttpMethod::HTTP_${operation.http.method})};
#else
return ${operation.name}Outcome{InvokeServiceOperation(request, uriResolver, "", Aws::Http::HttpMethod::HTTP_${operation.http.method})};
#end
#else
return ${operation.name}Outcome{InvokeServiceOperation(request, uriResolver, Aws::Http::HttpMethod::HTTP_${operation.http.method})};
#end
#end
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
${className}::InvokeOperationOutcome ${className}::InvokeServiceOperation(
const AmazonWebServiceRequest& request,
#if($metadata.protocol == "rest-json" || $metadata.protocol == "rest-xml")
const std::function<void(Aws::Endpoint::ResolveEndpointOutcome&)>& resolveUri,
#end
#if($serviceModel.metadata.namespace == "S3" || $serviceModel.metadata.namespace == "S3Crt")
Aws::String bucketName,
#end
Aws::Http::HttpMethod httpMethod
) const
{
auto operationName = request.GetServiceRequestName();
auto serviceName = GetServiceClientName();

AWS_OPERATION_GUARD_DYNAMIC(operationName);

AWS_OPERATION_CHECK_PTR_DYNAMIC(m_endpointProvider, operationName, CoreErrors, CoreErrors::ENDPOINT_RESOLUTION_FAILURE);
AWS_OPERATION_CHECK_PTR_DYNAMIC(m_telemetryProvider, operationName, CoreErrors, CoreErrors::NOT_INITIALIZED);

auto tracer = m_telemetryProvider->getTracer(serviceName, {});
auto meter = m_telemetryProvider->getMeter(serviceName, {});
AWS_OPERATION_CHECK_PTR_DYNAMIC(meter, operationName, CoreErrors, CoreErrors::NOT_INITIALIZED);

auto span = tracer->CreateSpan(Aws::String(serviceName) + "." + operationName,
{{TracingUtils::SMITHY_METHOD_DIMENSION, operationName},
{TracingUtils::SMITHY_SERVICE_DIMENSION, serviceName},
{TracingUtils::SMITHY_SYSTEM_DIMENSION, TracingUtils::SMITHY_METHOD_AWS_VALUE}},
smithy::components::tracing::SpanKind::CLIENT);

#if($serviceModel.metadata.namespace == "S3" || $serviceModel.metadata.namespace == "S3Crt")
if (!bucketName.empty()) {
request.SetServiceSpecificParameters([bucketName]() -> std::shared_ptr<Http::ServiceSpecificParameters> {
Aws::Map<Aws::String, Aws::String> params;
params.emplace("bucketName", bucketName);
ServiceSpecificParameters serviceSpecificParameters{params};
return Aws::MakeShared<ServiceSpecificParameters>(ALLOCATION_TAG, serviceSpecificParameters);
}());
}
#end

return TracingUtils::MakeCallWithTiming<InvokeOperationOutcome>(
[&]() -> InvokeOperationOutcome {
auto endpointResolutionOutcome = TracingUtils::MakeCallWithTiming<ResolveEndpointOutcome>(
[&]() -> ResolveEndpointOutcome { return m_endpointProvider->ResolveEndpoint(request.GetEndpointContextParams()); },
TracingUtils::SMITHY_CLIENT_ENDPOINT_RESOLUTION_METRIC, *meter,
{{TracingUtils::SMITHY_METHOD_DIMENSION, operationName},
{TracingUtils::SMITHY_SERVICE_DIMENSION, serviceName}});

AWS_OPERATION_CHECK_SUCCESS_DYNAMIC(endpointResolutionOutcome, operationName, CoreErrors,
CoreErrors::ENDPOINT_RESOLUTION_FAILURE, endpointResolutionOutcome.GetError().GetMessage());

#if($metadata.findFirstSupportedProtocol() == "smithy-rpc-v2-cbor")
endpointResolutionOutcome.GetResult().AddPathSegments("/service/${serviceModel.metadata.targetPrefix}/operation/");
endpointResolutionOutcome.GetResult().AddPathSegment(operationName);
#end

#if($metadata.protocol == "rest-json" || $metadata.protocol == "rest-xml")
resolveUri(endpointResolutionOutcome);
#end

return InvokeOperationOutcome{MakeRequest(request, endpointResolutionOutcome.GetResult(), httpMethod, Aws::Auth::SIGV4_SIGNER)};
},
TracingUtils::SMITHY_CLIENT_DURATION_METRIC, *meter,
{{TracingUtils::SMITHY_METHOD_DIMENSION, operationName},
{TracingUtils::SMITHY_SERVICE_DIMENSION, serviceName}});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#if(($serviceNamespace == "S3Crt" && $operation.s3CrtEnabled) || $operation.getRequest().getShape().hasEventStreamMembers())
#set($meterNeeded = true)
#set($indent = "")
#else
#set($meterNeeded = false)
#set($indent = " ")
#end
#if($metadata.findFirstSupportedProtocol() == "smithy-rpc-v2-cbor")
${indent} endpointResolutionOutcome.GetResult().AddPathSegments("/service/${serviceModel.metadata.targetPrefix}/operation/${operation.name}");
#end
#if($operation.http.requestUri.contains("?"))
${indent} Aws::StringStream ss;
#end
#set($uriParts = $operation.http.requestUriParts)
#set($uriVars = $operation.http.requestParameters)
#if(!$startIndex)
#set($startIndex = 0)
#end
#set($partIndex = 1)
#set($queryStart = false)
#if($uriParts.size() > $startIndex)
#set($uriPartString = ${uriParts.get($startIndex)})
#if($uriPartString.contains("?"))## if (request uri contains query) ----------
#set($queryStart = true)
#set($pathAndQuery = $operation.http.splitUriPartIntoPathAndQuery($uriPartString))
#if(!$pathAndQuery.get(0).isEmpty())
#if($pathAndQuery.get(0).toLowerCase().contains("resourcearn"))
${indent} endpointResolutionOutcome.GetResult().SetRfc3986Encoded(true);
#end
${indent} endpointResolutionOutcome.GetResult().AddPathSegments("${pathAndQuery.get(0)}");
#end
${indent} ss.str("${pathAndQuery.get(1)}");
#elseif(!$uriPartString.equals("/"))
#if($uriPartString.get(0).toLowerCase().contains("resourcearn"))
${indent} endpointResolutionOutcome.GetResult().SetRfc3986Encoded(true);
#end
${indent} endpointResolutionOutcome.GetResult().AddPathSegments("$uriPartString");
#end## ---------------------------- if (request uri contains query) end ------
#foreach($var in $uriVars)## for (parameter in request uri parameters) -------
#set($varIndex = $partIndex - 1)
#set($uriVar = $uriVars.get($varIndex).replace('+', ''))
#set($greedySyntax = $uriVars.get($varIndex).contains("+"))
#if(!$skipFirst)
#set($partShapeMember = $operation.request.shape.getMemberByLocationName($uriVar))
#if($partShapeMember.shape.enum)
#set($parameter = "${partShapeMember.shape.name}Mapper::GetNameFor${partShapeMember.shape.name}(request.Get${CppViewHelper.convertToUpperCamel($operation.request.shape.getMemberNameByLocationName($uriVar))}())")
#elseif($partShapeMember.shape.timeStamp)
#if($partShapeMember.shape.timestampFormat != "unixTimestamp")
#set($parameter = "request.Get${CppViewHelper.convertToUpperCamel($operation.request.shape.getMemberNameByLocationName($uriVar))}().ToGmtString(Aws::Utils::DateFormat::$CppViewHelper.computeTimestampFormatInQueryString($partShapeMember.shape))")
#else
#set($parameter = "request.Get${CppViewHelper.convertToUpperCamel($operation.request.shape.getMemberNameByLocationName($uriVar))}().Seconds()")
#end
#else
#set($parameter = "request.Get${CppViewHelper.convertToUpperCamel($operation.request.shape.getMemberNameByLocationName($uriVar))}()")
#end
#if($queryStart)
${indent} ss << $parameter;
#else
#if($greedySyntax)
#if($parameter.toLowerCase().contains("resourcearn"))
${indent} endpointResolutionOutcome.GetResult().SetRfc3986Encoded(true);
#end
${indent} endpointResolutionOutcome.GetResult().AddPathSegments($parameter);
#else
${indent} endpointResolutionOutcome.GetResult().AddPathSegment($parameter);
#end
#end
#if($uriParts.size() > $partIndex)
#set($uriPartString = "${uriParts.get($partIndex)}")
#if(!$queryStart && $uriPartString.contains("?"))
#set($queryStart = true)
#set($pathAndQuery = $operation.http.splitUriPartIntoPathAndQuery($uriPartString))
#if(!$pathAndQuery.get(0).isEmpty())
#if($pathAndQuery.get(0).toLowerCase().contains("resourcearn"))
${indent} endpointResolutionOutcome.GetResult().SetRfc3986Encoded(true);
#end
${indent} endpointResolutionOutcome.GetResult().AddPathSegments("${pathAndQuery.get(0)}");
#end
${indent} ss.str("${pathAndQuery.get(1)}");
#elseif(!$uriPartString.equals("/"))
#if($uriPartString.toLowerCase().contains("resourcearn"))
${indent} endpointResolutionOutcome.GetResult().SetRfc3986Encoded(true);
#end
${indent} endpointResolutionOutcome.GetResult().AddPathSegments("$uriPartString");
#end
#end
#end## --------------------- if !skipFirst end ---
#set($partIndex = $partIndex + 1)
#set($skipFirst = false)
#end## --------------------- if uriParts.size() > startIndex end ---
#end## --------------------- for (parameter in request uri parameters) end ---
#if($queryStart)
${indent} endpointResolutionOutcome.GetResult().SetQueryString(ss.str());
#end
Loading
Loading