/** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include namespace smithy { namespace client { template class AwsSmithyClientT : public AwsSmithyClientBase { public: explicit AwsSmithyClientT(const ServiceClientConfigurationT& clientConfig, const Aws::String& serviceName, const std::shared_ptr& httpClient, const std::shared_ptr& errorMarshaller, const std::shared_ptr endpointProvider, const std::shared_ptr& authSchemeResolver, const Aws::UnorderedMap& authSchemes) : AwsSmithyClientBase(Aws::MakeUnique(ServiceNameT, clientConfig), serviceName, httpClient, errorMarshaller), m_clientConfiguration(*static_cast(AwsSmithyClientBase::m_clientConfig.get())), m_endpointProvider(endpointProvider), m_authSchemeResolver(authSchemeResolver), m_authSchemes(authSchemes), m_serializer(Aws::MakeUnique(ServiceNameT, m_clientConfiguration.telemetryProvider)) { m_serviceName = ServiceNameT; } virtual ~AwsSmithyClientT() = default; protected: inline const char* GetServiceClientName() const override { return m_serviceName.c_str(); } ResolveEndpointOutcome ResolveEndpoint(const Aws::Endpoint::EndpointParameters& endpointParameters, EndpointUpdateCallback&& epCallback) const override { assert(m_endpointProvider); ResolveEndpointOutcome resolveEndpointOutcome = m_endpointProvider->ResolveEndpoint(endpointParameters); if (resolveEndpointOutcome.IsSuccess()) { epCallback(resolveEndpointOutcome.GetResult()); } return resolveEndpointOutcome; } SelectAuthSchemeOptionOutcome SelectAuthSchemeOption(const AwsSmithyClientAsyncRequestContext& ctx) const override { assert(m_authSchemeResolver); typename ServiceAuthSchemeResolverT::ServiceAuthSchemeParameters identityParams; identityParams.serviceName = m_serviceName; identityParams.operation = ctx.m_requestName; identityParams.region = m_clientConfiguration.region; if (ctx.m_pRequest) { // refactor once auth scheme resolver will use it's own rule set const auto& epParams = ctx.m_pRequest->GetEndpointContextParams(); for (const auto& epParam : epParams) { using ParameterType = Aws::Endpoint::EndpointParameter::ParameterType; if(epParam.GetStoredType() == ParameterType::STRING) identityParams.additionalProperties.insert({epParam.GetName(), epParam.GetStrValueNoCheck()}); else if (epParam.GetStoredType() == ParameterType::BOOLEAN) identityParams.additionalProperties.insert({epParam.GetName(), epParam.GetBoolValueNoCheck()}); else assert(!"Unknown endpoint parameter!"); } const auto& serviceParams = ctx.m_pRequest->GetServiceSpecificParameters(); if (serviceParams) { for (const auto& serviceParam : serviceParams->parameterMap) { identityParams.additionalProperties.insert({serviceParam.first, serviceParam.second}); } } } Aws::Vector authSchemeOptions = m_authSchemeResolver->resolveAuthScheme(identityParams); auto authSchemeOptionIt = std::find_if(authSchemeOptions.begin(), authSchemeOptions.end(), [this](const AuthSchemeOption& opt) { return m_authSchemes.find(opt.schemeId) != m_authSchemes.end(); }); assert(authSchemeOptionIt != authSchemeOptions.end()); if (authSchemeOptionIt != authSchemeOptions.end()) { return SelectAuthSchemeOptionOutcome(*authSchemeOptionIt); } return AWSError(Aws::Client::CoreErrors::CLIENT_SIGNING_FAILURE, "", "Failed to select an auth scheme", false/*retryable*/); } SigningOutcome SignRequest(std::shared_ptr httpRequest, const AuthSchemeOption& targetAuthSchemeOption) const override { return AwsClientRequestSigning::SignRequest(httpRequest, targetAuthSchemeOption, m_authSchemes); } bool AdjustClockSkew(HttpResponseOutcome& outcome, const AuthSchemeOption& authSchemeOption) const override { return AwsClientRequestSigning::AdjustClockSkew(outcome, authSchemeOption, m_authSchemes); } ResponseT MakeRequestDeserialize(Aws::AmazonWebServiceRequest const * const request, const char* requestName, Aws::Http::HttpMethod method, EndpointUpdateCallback&& endpointCallback) const { auto httpResponseOutcome = MakeRequestSync(request, requestName, method, std::move(endpointCallback)); return m_serializer->Deserialize(std::move(httpResponseOutcome), GetServiceClientName(), requestName); } protected: ServiceClientConfigurationT& m_clientConfiguration; std::shared_ptr m_endpointProvider{}; std::shared_ptr m_authSchemeResolver{}; Aws::UnorderedMap m_authSchemes{}; Aws::UniquePtr m_serializer{}; }; } // namespace client } // namespace smithy