feat(hos_client_create, hos_client_destory): 多次调用destory不会导致重复释放

This commit is contained in:
彭宣正
2020-12-14 17:24:58 +08:00
parent 505d529c32
commit 10b370e486
55976 changed files with 8544395 additions and 2 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,180 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#include <aws/core/client/AWSErrorMarshaller.h>
#include <aws/core/utils/logging/LogMacros.h>
#include <aws/core/utils/json/JsonSerializer.h>
#include <aws/core/utils/xml/XmlSerializer.h>
#include <aws/core/utils/StringUtils.h>
#include <aws/core/client/AWSError.h>
#include <aws/core/client/CoreErrors.h>
using namespace Aws::Utils::Logging;
using namespace Aws::Utils::Json;
using namespace Aws::Utils::Xml;
using namespace Aws::Http;
using namespace Aws::Utils;
using namespace Aws::Client;
static const char AWS_ERROR_MARSHALLER_LOG_TAG[] = "AWSErrorMarshaller";
AWS_CORE_API extern const char MESSAGE_LOWER_CASE[] = "message";
AWS_CORE_API extern const char MESSAGE_CAMEL_CASE[] = "Message";
AWS_CORE_API extern const char ERROR_TYPE_HEADER[] = "x-amzn-ErrorType";
AWS_CORE_API extern const char REQUEST_ID_HEADER[] = "x-amzn-RequestId";
AWS_CORE_API extern const char TYPE[] = "__type";
AWSError<CoreErrors> JsonErrorMarshaller::Marshall(const Aws::Http::HttpResponse& httpResponse) const
{
JsonValue exceptionPayload(httpResponse.GetResponseBody());
JsonView payloadView(exceptionPayload);
AWSError<CoreErrors> error;
if (exceptionPayload.WasParseSuccessful())
{
AWS_LOGSTREAM_TRACE(AWS_ERROR_MARSHALLER_LOG_TAG, "Error response is " << payloadView.WriteReadable());
Aws::String message(payloadView.ValueExists(MESSAGE_CAMEL_CASE) ? payloadView.GetString(MESSAGE_CAMEL_CASE) :
payloadView.ValueExists(MESSAGE_LOWER_CASE) ? payloadView.GetString(MESSAGE_LOWER_CASE) : "");
if (httpResponse.HasHeader(ERROR_TYPE_HEADER))
{
error = Marshall(httpResponse.GetHeader(ERROR_TYPE_HEADER), message);
}
else if (payloadView.ValueExists(TYPE))
{
error = Marshall(payloadView.GetString(TYPE), message);
}
else
{
error = FindErrorByHttpResponseCode(httpResponse.GetResponseCode());
error.SetMessage(message);
}
}
else
{
error = AWSError<CoreErrors>(CoreErrors::UNKNOWN, "", "Failed to parse error payload", false);
}
error.SetRequestId(httpResponse.HasHeader(REQUEST_ID_HEADER) ? httpResponse.GetHeader(REQUEST_ID_HEADER) : "");
error.SetJsonPayload(std::move(exceptionPayload));
return error;
}
const JsonValue& JsonErrorMarshaller::GetJsonPayloadFromError(const AWSError<CoreErrors>& error) const
{
return error.GetJsonPayload();
}
AWSError<CoreErrors> XmlErrorMarshaller::Marshall(const Aws::Http::HttpResponse& httpResponse) const
{
XmlDocument doc = XmlDocument::CreateFromXmlStream(httpResponse.GetResponseBody());
AWS_LOGSTREAM_TRACE(AWS_ERROR_MARSHALLER_LOG_TAG, "Error response is " << doc.ConvertToString());
bool errorParsed = false;
AWSError<CoreErrors> error;
if (doc.WasParseSuccessful())
{
XmlNode errorNode = doc.GetRootElement();
Aws::String requestId(!errorNode.FirstChild("RequestId").IsNull() ? errorNode.FirstChild("RequestId").GetText() :
!errorNode.FirstChild("RequestID").IsNull() ? errorNode.FirstChild("RequestID").GetText() : "");
if (errorNode.GetName() != "Error")
{
errorNode = doc.GetRootElement().FirstChild("Error");
}
if (errorNode.IsNull())
{
errorNode = doc.GetRootElement().FirstChild("Errors");
if(!errorNode.IsNull())
{
errorNode = errorNode.FirstChild("Error");
}
}
if (!errorNode.IsNull())
{
requestId = !requestId.empty() ? requestId : !errorNode.FirstChild("RequestId").IsNull() ? errorNode.FirstChild("RequestId").GetText() :
!errorNode.FirstChild("RequestID").IsNull() ? errorNode.FirstChild("RequestID").GetText() : "";
XmlNode codeNode = errorNode.FirstChild("Code");
XmlNode messageNode = errorNode.FirstChild("Message");
if (!codeNode.IsNull())
{
error = Marshall(StringUtils::Trim(codeNode.GetText().c_str()),
StringUtils::Trim(messageNode.GetText().c_str()));
errorParsed = true;
}
}
error.SetRequestId(requestId);
}
if(!errorParsed)
{
// An error occurred attempting to parse the httpResponse as an XML stream, so we're just
// going to dump the XML parsing error and the http response code as a string
AWS_LOGSTREAM_WARN(AWS_ERROR_MARSHALLER_LOG_TAG, "Unable to generate a proper httpResponse from the response "
"stream. Response code: " << static_cast< uint32_t >(httpResponse.GetResponseCode()));
error = FindErrorByHttpResponseCode(httpResponse.GetResponseCode());
}
error.SetXmlPayload(std::move(doc));
return error;
}
const XmlDocument& XmlErrorMarshaller::GetXmlPayloadFromError(const AWSError<CoreErrors>& error) const
{
return error.GetXmlPayload();
}
AWSError<CoreErrors> AWSErrorMarshaller::Marshall(const Aws::String& exceptionName, const Aws::String& message) const
{
if(exceptionName.empty())
{
return AWSError<CoreErrors>(CoreErrors::UNKNOWN, "", message, false);
}
auto locationOfPound = exceptionName.find_first_of('#');
auto locationOfColon = exceptionName.find_first_of(':');
Aws::String formalExceptionName;
if (locationOfPound != Aws::String::npos)
{
formalExceptionName = exceptionName.substr(locationOfPound + 1);
}
else if (locationOfColon != Aws::String::npos)
{
formalExceptionName = exceptionName.substr(0, locationOfColon);
}
else
{
formalExceptionName = exceptionName;
}
AWSError<CoreErrors> error = FindErrorByName(formalExceptionName.c_str());
if (error.GetErrorType() != CoreErrors::UNKNOWN)
{
AWS_LOGSTREAM_WARN(AWS_ERROR_MARSHALLER_LOG_TAG, "Encountered AWSError '" << formalExceptionName.c_str() <<
"': " << message.c_str());
error.SetExceptionName(formalExceptionName);
error.SetMessage(message);
return error;
}
AWS_LOGSTREAM_WARN(AWS_ERROR_MARSHALLER_LOG_TAG, "Encountered Unknown AWSError '" << exceptionName.c_str() <<
"': " << message.c_str());
return AWSError<CoreErrors>(CoreErrors::UNKNOWN, exceptionName, "Unable to parse ExceptionName: " + exceptionName + " Message: " + message, false);
}
AWSError<CoreErrors> AWSErrorMarshaller::FindErrorByName(const char* errorName) const
{
return CoreErrorsMapper::GetErrorForName(errorName);
}
AWSError<CoreErrors> AWSErrorMarshaller::FindErrorByHttpResponseCode(Aws::Http::HttpResponseCode code) const
{
return CoreErrorsMapper::GetErrorForHttpResponseCode(code);
}

View File

@@ -0,0 +1,16 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#include <aws/core/client/AsyncCallerContext.h>
#include <aws/core/utils/UUID.h>
namespace Aws
{
namespace Client
{
AsyncCallerContext::AsyncCallerContext() : m_uuid(Aws::Utils::UUID::RandomUUID())
{}
}
}

View File

@@ -0,0 +1,160 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#include <aws/core/client/ClientConfiguration.h>
#include <aws/core/auth/AWSCredentialsProvider.h>
#include <aws/core/client/DefaultRetryStrategy.h>
#include <aws/core/platform/Environment.h>
#include <aws/core/platform/OSVersionInfo.h>
#include <aws/core/utils/memory/AWSMemory.h>
#include <aws/core/utils/StringUtils.h>
#include <aws/core/utils/threading/Executor.h>
#include <aws/core/utils/memory/stl/AWSStringStream.h>
#include <aws/core/Version.h>
#include <aws/core/config/AWSProfileConfigLoader.h>
#include <aws/core/utils/logging/LogMacros.h>
namespace Aws
{
namespace Auth
{
AWS_CORE_API Aws::String GetConfigProfileFilename();
}
namespace Client
{
static const char* CLIENT_CONFIG_TAG = "ClientConfiguration";
AWS_CORE_API Aws::String ComputeUserAgentString()
{
Aws::StringStream ss;
ss << "aws-sdk-cpp/" << Version::GetVersionString() << " " << Aws::OSVersionInfo::ComputeOSVersionString()
<< " " << Version::GetCompilerVersionString();
return ss.str();
}
ClientConfiguration::ClientConfiguration() :
scheme(Aws::Http::Scheme::HTTPS),
useDualStack(false),
maxConnections(25),
httpRequestTimeoutMs(0),
requestTimeoutMs(3000),
connectTimeoutMs(1000),
enableTcpKeepAlive(true),
tcpKeepAliveIntervalMs(30000),
lowSpeedLimit(1),
proxyScheme(Aws::Http::Scheme::HTTP),
proxyPort(0),
executor(Aws::MakeShared<Aws::Utils::Threading::DefaultExecutor>(CLIENT_CONFIG_TAG)),
verifySSL(true),
writeRateLimiter(nullptr),
readRateLimiter(nullptr),
httpLibOverride(Aws::Http::TransferLibType::DEFAULT_CLIENT),
followRedirects(FollowRedirectsPolicy::DEFAULT),
disableExpectHeader(false),
enableClockSkewAdjustment(true),
enableHostPrefixInjection(true),
enableEndpointDiscovery(false),
profileName(Aws::Auth::GetConfigProfileName())
{
AWS_LOGSTREAM_DEBUG(CLIENT_CONFIG_TAG, "ClientConfiguration will use SDK Auto Resolved profile: [" << profileName << "] if not specified by users.");
// Initialize Retry Strategy
int maxAttempts;
Aws::String maxAttemptsString = Aws::Environment::GetEnv("AWS_MAX_ATTEMPTS");
if (maxAttemptsString.empty())
{
maxAttemptsString = Aws::Config::GetCachedConfigValue("max_attempts");
}
// In case users specify 0 explicitly to disable retry.
if (maxAttemptsString == "0")
{
maxAttempts = 0;
}
else
{
maxAttempts = static_cast<int>(Aws::Utils::StringUtils::ConvertToInt32(maxAttemptsString.c_str()));
if (maxAttempts == 0)
{
AWS_LOGSTREAM_WARN(CLIENT_CONFIG_TAG, "Retry Strategy will use the default max attempts.");
maxAttempts = -1;
}
}
Aws::String retryMode = Aws::Environment::GetEnv("AWS_RETRY_MODE");
if (retryMode.empty())
{
retryMode = Aws::Config::GetCachedConfigValue("retry_mode");
}
if (retryMode == "standard")
{
if (maxAttempts < 0)
{
retryStrategy = Aws::MakeShared<StandardRetryStrategy>(CLIENT_CONFIG_TAG);
}
else
{
retryStrategy = Aws::MakeShared<StandardRetryStrategy>(CLIENT_CONFIG_TAG, maxAttempts);
}
}
else
{
retryStrategy = Aws::MakeShared<DefaultRetryStrategy>(CLIENT_CONFIG_TAG);
}
// Automatically determine the AWS region from environment variables, configuration file and EC2 metadata.
region = Aws::Environment::GetEnv("AWS_DEFAULT_REGION");
if (!region.empty())
{
return;
}
region = Aws::Environment::GetEnv("AWS_REGION");
if (!region.empty())
{
return;
}
region = Aws::Config::GetCachedConfigValue("region");
if (!region.empty())
{
return;
}
if (Aws::Utils::StringUtils::ToLower(Aws::Environment::GetEnv("AWS_EC2_METADATA_DISABLED").c_str()) != "true")
{
auto client = Aws::Internal::GetEC2MetadataClient();
if (client)
{
region = client->GetCurrentRegion();
}
}
if (!region.empty())
{
return;
}
region = Aws::String(Aws::Region::US_EAST_1);
}
ClientConfiguration::ClientConfiguration(const char* profileName) : ClientConfiguration()
{
if (profileName && Aws::Config::HasCachedConfigProfile(profileName))
{
this->profileName = Aws::String(profileName);
AWS_LOGSTREAM_DEBUG(CLIENT_CONFIG_TAG, "Use user specified profile: [" << this->profileName << "] for ClientConfiguration.");
auto tmpRegion = Aws::Config::GetCachedConfigProfile(this->profileName).GetRegion();
if (!tmpRegion.empty())
{
region = tmpRegion;
}
return;
}
AWS_LOGSTREAM_WARN(CLIENT_CONFIG_TAG, "User specified profile: [" << profileName << "] is not found, will use the SDK resolved one.");
}
} // namespace Client
} // namespace Aws

View File

@@ -0,0 +1,151 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#include <aws/core/client/AWSError.h>
#include <aws/core/client/CoreErrors.h>
#include <aws/core/utils/memory/stl/AWSMap.h>
#include <aws/core/utils/HashingUtils.h>
using namespace Aws::Client;
using namespace Aws::Utils;
using namespace Aws::Http;
#ifdef _MSC_VER
#pragma warning(push)
// VS2015 compiler's bug, warning s_CoreErrorsMapper: symbol will be dynamically initialized (implementation limitation)
#pragma warning(disable : 4592)
#endif
static Aws::UniquePtr<Aws::Map<Aws::String, AWSError<CoreErrors> > > s_CoreErrorsMapper(nullptr);
#ifdef _MSC_VER
#pragma warning(pop)
#endif
void CoreErrorsMapper::InitCoreErrorsMapper()
{
if (s_CoreErrorsMapper)
{
return;
}
s_CoreErrorsMapper = Aws::MakeUnique<Aws::Map<Aws::String, AWSError<CoreErrors> > >("InitCoreErrorsMapper");
s_CoreErrorsMapper->emplace("IncompleteSignature", AWSError<CoreErrors>(CoreErrors::INCOMPLETE_SIGNATURE, false));
s_CoreErrorsMapper->emplace("IncompleteSignatureException", AWSError<CoreErrors>(CoreErrors::INCOMPLETE_SIGNATURE, false));
s_CoreErrorsMapper->emplace("InvalidSignatureException", AWSError<CoreErrors>(CoreErrors::INVALID_SIGNATURE, false));
s_CoreErrorsMapper->emplace("InvalidSignature", AWSError<CoreErrors>(CoreErrors::INVALID_SIGNATURE, false));
s_CoreErrorsMapper->emplace("InternalFailureException", AWSError<CoreErrors>(CoreErrors::INTERNAL_FAILURE, true));
s_CoreErrorsMapper->emplace("InternalFailure", AWSError<CoreErrors>(CoreErrors::INTERNAL_FAILURE, true));
s_CoreErrorsMapper->emplace("InternalServerError", AWSError<CoreErrors>(CoreErrors::INTERNAL_FAILURE, true));
s_CoreErrorsMapper->emplace("InternalError", AWSError<CoreErrors>(CoreErrors::INTERNAL_FAILURE, true));
s_CoreErrorsMapper->emplace("InvalidActionException", AWSError<CoreErrors>(CoreErrors::INVALID_ACTION, false));
s_CoreErrorsMapper->emplace("InvalidAction", AWSError<CoreErrors>(CoreErrors::INVALID_ACTION, false));
s_CoreErrorsMapper->emplace("InvalidClientTokenIdException", AWSError<CoreErrors>(CoreErrors::INVALID_CLIENT_TOKEN_ID, false));
s_CoreErrorsMapper->emplace("InvalidClientTokenId", AWSError<CoreErrors>(CoreErrors::INVALID_CLIENT_TOKEN_ID, false));
s_CoreErrorsMapper->emplace("InvalidParameterCombinationException", AWSError<CoreErrors>(CoreErrors::INVALID_PARAMETER_COMBINATION, false));
s_CoreErrorsMapper->emplace("InvalidParameterCombination", AWSError<CoreErrors>(CoreErrors::INVALID_PARAMETER_COMBINATION, false));
s_CoreErrorsMapper->emplace("InvalidParameterValueException", AWSError<CoreErrors>(CoreErrors::INVALID_PARAMETER_VALUE, false));
s_CoreErrorsMapper->emplace("InvalidParameterValue", AWSError<CoreErrors>(CoreErrors::INVALID_PARAMETER_VALUE, false));
s_CoreErrorsMapper->emplace("InvalidQueryParameterException", AWSError<CoreErrors>(CoreErrors::INVALID_QUERY_PARAMETER, false));
s_CoreErrorsMapper->emplace("InvalidQueryParameter", AWSError<CoreErrors>(CoreErrors::INVALID_QUERY_PARAMETER, false));
s_CoreErrorsMapper->emplace("MalformedQueryStringException", AWSError<CoreErrors>(CoreErrors::MALFORMED_QUERY_STRING, false));
s_CoreErrorsMapper->emplace("MalformedQueryString", AWSError<CoreErrors>(CoreErrors::MALFORMED_QUERY_STRING, false));
s_CoreErrorsMapper->emplace("MissingActionException", AWSError<CoreErrors>(CoreErrors::MISSING_ACTION, false));
s_CoreErrorsMapper->emplace("MissingAction", AWSError<CoreErrors>(CoreErrors::MISSING_ACTION, false));
s_CoreErrorsMapper->emplace("MissingAuthenticationTokenException", AWSError<CoreErrors>(CoreErrors::MISSING_AUTHENTICATION_TOKEN, false));
s_CoreErrorsMapper->emplace("MissingAuthenticationToken", AWSError<CoreErrors>(CoreErrors::MISSING_AUTHENTICATION_TOKEN, false));
s_CoreErrorsMapper->emplace("MissingParameterException", AWSError<CoreErrors>(CoreErrors::MISSING_PARAMETER, false));
s_CoreErrorsMapper->emplace("MissingParameter", AWSError<CoreErrors>(CoreErrors::MISSING_PARAMETER, false));
s_CoreErrorsMapper->emplace("OptInRequired", AWSError<CoreErrors>(CoreErrors::OPT_IN_REQUIRED, false));
s_CoreErrorsMapper->emplace("RequestExpiredException", AWSError<CoreErrors>(CoreErrors::REQUEST_EXPIRED, true));
s_CoreErrorsMapper->emplace("RequestExpired", AWSError<CoreErrors>(CoreErrors::REQUEST_EXPIRED, true));
s_CoreErrorsMapper->emplace("ServiceUnavailableException", AWSError<CoreErrors>(CoreErrors::SERVICE_UNAVAILABLE, true));
s_CoreErrorsMapper->emplace("ServiceUnavailableError", AWSError<CoreErrors>(CoreErrors::SERVICE_UNAVAILABLE, true));
s_CoreErrorsMapper->emplace("ServiceUnavailable", AWSError<CoreErrors>(CoreErrors::SERVICE_UNAVAILABLE, true));
s_CoreErrorsMapper->emplace("RequestThrottledException", AWSError<CoreErrors>(CoreErrors::THROTTLING, true));
s_CoreErrorsMapper->emplace("RequestThrottled", AWSError<CoreErrors>(CoreErrors::THROTTLING, true));
s_CoreErrorsMapper->emplace("ThrottlingException", AWSError<CoreErrors>(CoreErrors::THROTTLING, true));
s_CoreErrorsMapper->emplace("ThrottledException", AWSError<CoreErrors>(CoreErrors::THROTTLING, true));
s_CoreErrorsMapper->emplace("Throttling", AWSError<CoreErrors>(CoreErrors::THROTTLING, true));
s_CoreErrorsMapper->emplace("ValidationErrorException", AWSError<CoreErrors>(CoreErrors::VALIDATION, false));
s_CoreErrorsMapper->emplace("ValidationException", AWSError<CoreErrors>(CoreErrors::VALIDATION, false));
s_CoreErrorsMapper->emplace("ValidationError", AWSError<CoreErrors>(CoreErrors::VALIDATION, false));
s_CoreErrorsMapper->emplace("AccessDeniedException", AWSError<CoreErrors>(CoreErrors::ACCESS_DENIED, false));
s_CoreErrorsMapper->emplace("AccessDenied", AWSError<CoreErrors>(CoreErrors::ACCESS_DENIED, false));
s_CoreErrorsMapper->emplace("ResourceNotFoundException", AWSError<CoreErrors>(CoreErrors::RESOURCE_NOT_FOUND, false));
s_CoreErrorsMapper->emplace("ResourceNotFound", AWSError<CoreErrors>(CoreErrors::RESOURCE_NOT_FOUND, false));
s_CoreErrorsMapper->emplace("UnrecognizedClientException", AWSError<CoreErrors>(CoreErrors::UNRECOGNIZED_CLIENT, false));
s_CoreErrorsMapper->emplace("UnrecognizedClient", AWSError<CoreErrors>(CoreErrors::UNRECOGNIZED_CLIENT, false));
s_CoreErrorsMapper->emplace("SlowDownException", AWSError<CoreErrors>(CoreErrors::SLOW_DOWN, true));
s_CoreErrorsMapper->emplace("SlowDown", AWSError<CoreErrors>(CoreErrors::SLOW_DOWN, true));
s_CoreErrorsMapper->emplace("SignatureDoesNotMatchException", AWSError<CoreErrors>(CoreErrors::SIGNATURE_DOES_NOT_MATCH, false));
s_CoreErrorsMapper->emplace("SignatureDoesNotMatch", AWSError<CoreErrors>(CoreErrors::SIGNATURE_DOES_NOT_MATCH, false));
s_CoreErrorsMapper->emplace("InvalidAccessKeyIdException", AWSError<CoreErrors>(CoreErrors::INVALID_ACCESS_KEY_ID, false));
s_CoreErrorsMapper->emplace("InvalidAccessKeyId", AWSError<CoreErrors>(CoreErrors::INVALID_ACCESS_KEY_ID, false));
s_CoreErrorsMapper->emplace("RequestTimeTooSkewedException", AWSError<CoreErrors>(CoreErrors::REQUEST_TIME_TOO_SKEWED, true));
s_CoreErrorsMapper->emplace("RequestTimeTooSkewed", AWSError<CoreErrors>(CoreErrors::REQUEST_TIME_TOO_SKEWED, true));
s_CoreErrorsMapper->emplace("RequestTimeoutException", AWSError<CoreErrors>(CoreErrors::REQUEST_TIMEOUT, true));
s_CoreErrorsMapper->emplace("RequestTimeout", AWSError<CoreErrors>(CoreErrors::REQUEST_TIMEOUT, true));
}
void CoreErrorsMapper::CleanupCoreErrorsMapper()
{
if (s_CoreErrorsMapper)
{
s_CoreErrorsMapper = nullptr;
}
}
AWSError<CoreErrors> CoreErrorsMapper::GetErrorForName(const char* errorName)
{
auto iter = s_CoreErrorsMapper->find(errorName);
if (iter != s_CoreErrorsMapper->end())
{
return iter->second;
}
return AWSError<CoreErrors>(CoreErrors::UNKNOWN, false);
}
AWS_CORE_API AWSError<CoreErrors> CoreErrorsMapper::GetErrorForHttpResponseCode(HttpResponseCode code)
{
// best effort attempt to map HTTP response codes to CoreErrors
bool retryable = IsRetryableHttpResponseCode(code);
AWSError<CoreErrors> error;
switch (code)
{
case HttpResponseCode::UNAUTHORIZED:
case HttpResponseCode::FORBIDDEN:
error = AWSError<CoreErrors>(CoreErrors::ACCESS_DENIED, retryable);
break;
case HttpResponseCode::NOT_FOUND:
error = AWSError<CoreErrors>(CoreErrors::RESOURCE_NOT_FOUND, retryable);
break;
case HttpResponseCode::TOO_MANY_REQUESTS:
error = AWSError<CoreErrors>(CoreErrors::SLOW_DOWN, retryable);
break;
case HttpResponseCode::INTERNAL_SERVER_ERROR:
error = AWSError<CoreErrors>(CoreErrors::INTERNAL_FAILURE, retryable);
break;
case HttpResponseCode::BANDWIDTH_LIMIT_EXCEEDED:
error = AWSError<CoreErrors>(CoreErrors::THROTTLING, retryable);
break;
case HttpResponseCode::SERVICE_UNAVAILABLE:
error = AWSError<CoreErrors>(CoreErrors::SERVICE_UNAVAILABLE, retryable);
break;
case HttpResponseCode::REQUEST_TIMEOUT:
case HttpResponseCode::AUTHENTICATION_TIMEOUT:
case HttpResponseCode::LOGIN_TIMEOUT:
case HttpResponseCode::GATEWAY_TIMEOUT:
case HttpResponseCode::NETWORK_READ_TIMEOUT:
case HttpResponseCode::NETWORK_CONNECT_TIMEOUT:
error = AWSError<CoreErrors>(CoreErrors::REQUEST_TIMEOUT, retryable);
break;
default:
int codeValue = static_cast<int>(code);
error = AWSError<CoreErrors>(CoreErrors::UNKNOWN, codeValue >= 500 && codeValue < 600);
}
error.SetResponseCode(code);
return error;
}

View File

@@ -0,0 +1,32 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#include <aws/core/client/DefaultRetryStrategy.h>
#include <aws/core/client/AWSError.h>
#include <aws/core/utils/UnreferencedParam.h>
using namespace Aws;
using namespace Aws::Client;
bool DefaultRetryStrategy::ShouldRetry(const AWSError<CoreErrors>& error, long attemptedRetries) const
{
if (attemptedRetries >= m_maxRetries)
return false;
return error.ShouldRetry();
}
long DefaultRetryStrategy::CalculateDelayBeforeNextRetry(const AWSError<CoreErrors>& error, long attemptedRetries) const
{
AWS_UNREFERENCED_PARAM(error);
if (attemptedRetries == 0)
{
return 0;
}
return (1 << attemptedRetries) * m_scaleFactor;
}

View File

@@ -0,0 +1,102 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#include <aws/core/client/RetryStrategy.h>
#include <aws/core/client/AWSError.h>
#include <aws/core/client/CoreErrors.h>
#include <aws/core/utils/Outcome.h>
using namespace Aws::Utils::Threading;
namespace Aws
{
namespace Client
{
static const int INITIAL_RETRY_TOKENS = 500;
static const int RETRY_COST = 5;
static const int NO_RETRY_INCREMENT = 1;
static const int TIMEOUT_RETRY_COST = 10;
StandardRetryStrategy::StandardRetryStrategy(long maxAttempts) :
m_retryQuotaContainer(Aws::MakeShared<DefaultRetryQuotaContainer>("StandardRetryStrategy")),
m_maxAttempts(maxAttempts)
{}
StandardRetryStrategy::StandardRetryStrategy(std::shared_ptr<RetryQuotaContainer> retryQuotaContainer, long maxAttempts) :
m_retryQuotaContainer(retryQuotaContainer),
m_maxAttempts(maxAttempts)
{}
void StandardRetryStrategy::RequestBookkeeping(const HttpResponseOutcome& httpResponseOutcome)
{
if (httpResponseOutcome.IsSuccess())
{
m_retryQuotaContainer->ReleaseRetryQuota(NO_RETRY_INCREMENT);
}
}
void StandardRetryStrategy::RequestBookkeeping(const HttpResponseOutcome& httpResponseOutcome, const AWSError<CoreErrors>& lastError)
{
if (httpResponseOutcome.IsSuccess())
{
m_retryQuotaContainer->ReleaseRetryQuota(lastError);
}
}
bool StandardRetryStrategy::ShouldRetry(const AWSError<CoreErrors>& error, long attemptedRetries) const
{
if (!error.ShouldRetry())
return false;
if (attemptedRetries + 1 >= m_maxAttempts)
return false;
return m_retryQuotaContainer->AcquireRetryQuota(error);
}
long StandardRetryStrategy::CalculateDelayBeforeNextRetry(const AWSError<CoreErrors>& error, long attemptedRetries) const
{
AWS_UNREFERENCED_PARAM(error);
return (std::min)(rand() % 1000 * (1 << attemptedRetries), 20000);
}
DefaultRetryQuotaContainer::DefaultRetryQuotaContainer() : m_retryQuota(INITIAL_RETRY_TOKENS)
{}
bool DefaultRetryQuotaContainer::AcquireRetryQuota(int capacityAmount)
{
WriterLockGuard guard(m_retryQuotaLock);
if (capacityAmount > m_retryQuota)
{
return false;
}
else
{
m_retryQuota -= capacityAmount;
return true;
}
}
bool DefaultRetryQuotaContainer::AcquireRetryQuota(const AWSError<CoreErrors>& error)
{
int capacityAmount = error.GetErrorType() == CoreErrors::REQUEST_TIMEOUT ? TIMEOUT_RETRY_COST : RETRY_COST;
return AcquireRetryQuota(capacityAmount);
}
void DefaultRetryQuotaContainer::ReleaseRetryQuota(int capacityAmount)
{
WriterLockGuard guard(m_retryQuotaLock);
m_retryQuota = (std::min)(m_retryQuota + capacityAmount, INITIAL_RETRY_TOKENS);
}
void DefaultRetryQuotaContainer::ReleaseRetryQuota(const AWSError<CoreErrors>& error)
{
int capacityAmount = error.GetErrorType() == CoreErrors::REQUEST_TIMEOUT ? TIMEOUT_RETRY_COST : RETRY_COST;
ReleaseRetryQuota(capacityAmount);
}
}
}

View File

@@ -0,0 +1,28 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#include <aws/core/client/SpecifiedRetryableErrorsRetryStrategy.h>
#include <aws/core/client/AWSError.h>
using namespace Aws;
using namespace Aws::Client;
bool SpecifiedRetryableErrorsRetryStrategy::ShouldRetry(const AWSError<CoreErrors>& error, long attemptedRetries) const
{
if (attemptedRetries >= m_maxRetries)
{
return false;
}
for (const auto& err: m_specifiedRetryableErrors)
{
if (error.GetExceptionName() == err)
{
return true;
}
}
return error.ShouldRetry();
}