Skip to content

Commit d83d567

Browse files
authored
Pre-requisite Changes Enable smithy query + rest-xml clients (#3321)
1 parent 9c57cd5 commit d83d567

File tree

18 files changed

+833
-204
lines changed

18 files changed

+833
-204
lines changed

src/aws-cpp-sdk-core/include/smithy/client/AwsLegacyClient.h

Lines changed: 304 additions & 0 deletions
Large diffs are not rendered by default.

src/aws-cpp-sdk-core/include/smithy/client/AwsSmithyClient.h

Lines changed: 82 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ namespace client
228228
auto httpResponseOutcome = MakeRequestSync(request, requestName, method, std::move(endpointCallback));
229229
return m_serializer->Deserialize(std::move(httpResponseOutcome), GetServiceClientName(), requestName);
230230
}
231-
231+
232232
Aws::String GeneratePresignedUrl(
233233
EndpointUpdateCallback&& endpointCallback,
234234
Aws::Http::HttpMethod method,
@@ -238,110 +238,66 @@ namespace client
238238
const Aws::Http::HeaderValueCollection& customizedHeaders,
239239
const std::shared_ptr<Aws::Http::ServiceSpecificParameters> serviceSpecificParameters) const
240240
{
241-
AwsSmithyClientAsyncRequestContext ctx;
242-
auto authSchemeOptionOutcome = SelectAuthSchemeOption( ctx);
243-
auto authSchemeOption = std::move(authSchemeOptionOutcome.GetResultWithOwnership());
244-
245-
Aws::Endpoint::EndpointParameters epParams = Aws::Endpoint::EndpointParameters();
246-
const auto authSchemeEpParams = authSchemeOption.endpointParameters();
247-
epParams.insert(epParams.end(), authSchemeEpParams.begin(), authSchemeEpParams.end());
248-
if(serviceSpecificParameters)
249-
{
250-
auto bucketIt = serviceSpecificParameters->parameterMap.find("bucketName");
251-
if(bucketIt != serviceSpecificParameters->parameterMap.end())
241+
ExtractUriCallback getUriCallback = [&](Aws::Http::URI& uri, Aws::String& signerRegionOverride,
242+
Aws::String& signerServiceNameOverride, const AuthSchemeOption& authSchemeOption) -> bool{
243+
244+
Aws::Endpoint::EndpointParameters epParams = Aws::Endpoint::EndpointParameters();
245+
const auto authSchemeEpParams = authSchemeOption.endpointParameters();
246+
epParams.insert(epParams.end(), authSchemeEpParams.begin(), authSchemeEpParams.end());
247+
if(serviceSpecificParameters)
252248
{
253-
auto bucket = bucketIt->second;
254-
epParams.emplace_back(Aws::String("Bucket"), bucket);
249+
auto bucketIt = serviceSpecificParameters->parameterMap.find("bucketName");
250+
if(bucketIt != serviceSpecificParameters->parameterMap.end())
251+
{
252+
auto bucket = bucketIt->second;
253+
epParams.emplace_back(Aws::String("Bucket"), bucket);
254+
}
255255
}
256-
}
257256

258-
auto epResolutionOutcome = this->ResolveEndpoint(std::move(epParams), std::move(endpointCallback));
259-
if (!epResolutionOutcome.IsSuccess())
260-
{
261-
AWS_LOGSTREAM_ERROR(ServiceNameT, "Presigned URL generating failed. Encountered error: " << epResolutionOutcome.GetError().GetMessage());
262-
return {};
263-
}
264-
auto endpoint = std::move(epResolutionOutcome.GetResultWithOwnership());
265-
const Aws::Http::URI& uri = endpoint.GetURI();
266-
auto signerRegionOverride = region;
267-
auto signerServiceNameOverride = serviceName;
268-
//signer name is needed for some identity resolvers
269-
if (endpoint.GetAttributes()) {
270-
if (endpoint.GetAttributes()->authScheme.GetSigningRegion()) {
271-
signerRegionOverride = endpoint.GetAttributes()->authScheme.GetSigningRegion()->c_str();
272-
}
273-
if (endpoint.GetAttributes()->authScheme.GetSigningRegionSet()) {
274-
signerRegionOverride = endpoint.GetAttributes()->authScheme.GetSigningRegionSet()->c_str();
257+
auto epResolutionOutcome = this->ResolveEndpoint(std::move(epParams), std::move(endpointCallback));
258+
if (!epResolutionOutcome.IsSuccess())
259+
{
260+
AWS_LOGSTREAM_ERROR(ServiceNameT, "Presigned URL generating failed. Encountered error: " << epResolutionOutcome.GetError().GetMessage());
261+
return false;
275262
}
276-
if (endpoint.GetAttributes()->authScheme.GetSigningName()) {
277-
signerServiceNameOverride = endpoint.GetAttributes()->authScheme.GetSigningName()->c_str();
263+
auto endpoint = std::move(epResolutionOutcome.GetResultWithOwnership());
264+
uri = endpoint.GetURI();
265+
signerRegionOverride = region;
266+
signerServiceNameOverride = serviceName;
267+
//signer name is needed for some identity resolvers
268+
if (endpoint.GetAttributes()) {
269+
if (endpoint.GetAttributes()->authScheme.GetSigningRegion()) {
270+
signerRegionOverride = endpoint.GetAttributes()->authScheme.GetSigningRegion()->c_str();
271+
}
272+
if (endpoint.GetAttributes()->authScheme.GetSigningRegionSet()) {
273+
signerRegionOverride = endpoint.GetAttributes()->authScheme.GetSigningRegionSet()->c_str();
274+
}
275+
if (endpoint.GetAttributes()->authScheme.GetSigningName()) {
276+
signerServiceNameOverride = endpoint.GetAttributes()->authScheme.GetSigningName()->c_str();
277+
}
278278
}
279-
}
280-
std::shared_ptr<HttpRequest> request = CreateHttpRequest(uri, method, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod);
281-
request->SetServiceSpecificParameters(serviceSpecificParameters);
282-
for (const auto& it: customizedHeaders)
283-
{
284-
request->SetHeaderValue(it.first.c_str(), it.second);
285-
}
286-
if (AwsClientRequestSigning<AuthSchemesVariantT>::PreSignRequest(request, authSchemeOption, m_authSchemes, signerRegionOverride, signerServiceNameOverride, expirationInSeconds).IsSuccess())
287-
{
288-
return request->GetURIString();
289-
}
290-
return {};
291-
}
279+
return true;
280+
};
292281

293-
//legacy
294-
Aws::String GeneratePresignedUrl(const Aws::Http::URI& uri,
295-
Aws::Http::HttpMethod method,
296-
const Aws::String& region,
297-
const Aws::String& serviceName,
298-
long long expirationInSeconds,
299-
const Aws::Http::HeaderValueCollection& customizedHeaders,
300-
const std::shared_ptr<Aws::Http::ServiceSpecificParameters> serviceSpecificParameters) const
301-
{
302-
std::shared_ptr<HttpRequest> request = CreateHttpRequest(uri, method, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod);
303-
request->SetServiceSpecificParameters(serviceSpecificParameters);
304-
for (const auto& it: customizedHeaders)
305-
{
306-
request->SetHeaderValue(it.first.c_str(), it.second);
307-
}
308-
AwsSmithyClientAsyncRequestContext ctx;
309-
auto authSchemeOptionOutcome = SelectAuthSchemeOption( ctx);
310-
auto authSchemeOption = std::move(authSchemeOptionOutcome.GetResultWithOwnership());
311-
if (AwsClientRequestSigning<AuthSchemesVariantT>::PreSignRequest(request, authSchemeOption, m_authSchemes, region, serviceName, expirationInSeconds).IsSuccess())
312-
{
313-
return request->GetURIString();
314-
}
315-
return {};
316-
}
317-
318-
319-
Aws::String GeneratePresignedUrl(const Aws::Endpoint::AWSEndpoint& endpoint,
320-
Aws::Http::HttpMethod method,
321-
const Aws::String& region,
322-
const Aws::String& serviceName,
323-
long long expirationInSeconds,
324-
const Aws::Http::HeaderValueCollection& customizedHeaders,
325-
const std::shared_ptr<Aws::Http::ServiceSpecificParameters> serviceSpecificParameters) const
326-
{
327-
const Aws::Http::URI& uri = endpoint.GetURI();
328-
auto signerRegionOverride = region;
329-
auto signerServiceNameOverride = serviceName;
330-
// signer name is needed for some identity resolvers
331-
if (endpoint.GetAttributes()) {
332-
if (endpoint.GetAttributes()->authScheme.GetSigningRegion()) {
333-
signerRegionOverride = endpoint.GetAttributes()->authScheme.GetSigningRegion()->c_str();
334-
}
335-
if (endpoint.GetAttributes()->authScheme.GetSigningRegionSet()) {
336-
signerRegionOverride = endpoint.GetAttributes()->authScheme.GetSigningRegionSet()->c_str();
337-
}
338-
if (endpoint.GetAttributes()->authScheme.GetSigningName()) {
339-
signerServiceNameOverride = endpoint.GetAttributes()->authScheme.GetSigningName()->c_str();
282+
CreateHttpRequestCallback createHttpRequestCallback = [&customizedHeaders, &serviceSpecificParameters](const Aws::Http::URI& uri, const Aws::Http::HttpMethod& method) -> std::shared_ptr<HttpRequest> {
283+
std::shared_ptr<HttpRequest> request = CreateHttpRequest(uri, method, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod);
284+
request->SetServiceSpecificParameters(serviceSpecificParameters);
285+
for (const auto& it: customizedHeaders)
286+
{
287+
request->SetHeaderValue(it.first.c_str(), it.second);
340288
}
341-
}
342-
return GeneratePresignedUrl(uri, method, signerRegionOverride, signerServiceNameOverride, expirationInSeconds, customizedHeaders, serviceSpecificParameters);
289+
return request;
290+
};
291+
292+
return GeneratePresignedUrl(
293+
std::move(getUriCallback),
294+
std::move(createHttpRequestCallback),
295+
method,
296+
region,
297+
serviceName,
298+
expirationInSeconds);
343299
}
344-
300+
345301
/* Service client specific config, the actual object is stored in AwsSmithyClientBase by pointer
346302
* In order to avoid config object duplication, smithy template client access it by a reference.
347303
* So that base client has it by base config pointer, child smithy client has it by child config reference.
@@ -352,6 +308,35 @@ namespace client
352308
Aws::UnorderedMap<Aws::String, AuthSchemesVariantT> m_authSchemes{};
353309
std::shared_ptr<SerializerT> m_serializer{};
354310
private:
311+
using ExtractUriCallback = std::function<bool (Aws::Http::URI&, Aws::String& region, Aws::String& serviceName,const AuthSchemeOption&)>;
312+
using CreateHttpRequestCallback = std::function<std::shared_ptr<HttpRequest> (const Aws::Http::URI&, const Aws::Http::HttpMethod&)>;
313+
314+
Aws::String GeneratePresignedUrl(
315+
ExtractUriCallback&& getUriCallback,
316+
CreateHttpRequestCallback&& createHttpRequestCallback,
317+
Aws::Http::HttpMethod method,
318+
const Aws::String& region,
319+
const Aws::String& serviceName,
320+
long long expirationInSeconds) const
321+
{
322+
AwsSmithyClientAsyncRequestContext ctx;
323+
auto authSchemeOptionOutcome = SelectAuthSchemeOption( ctx);
324+
auto authSchemeOption = std::move(authSchemeOptionOutcome.GetResultWithOwnership());
325+
Aws::Http::URI uri;
326+
Aws::String signerRegionOverride = region;
327+
Aws::String signerServiceNameOverride = serviceName;
328+
if(!getUriCallback(uri , signerRegionOverride, signerServiceNameOverride, authSchemeOption))
329+
{
330+
return {};
331+
}
332+
std::shared_ptr<HttpRequest> request = createHttpRequestCallback(uri, method);
333+
if (AwsClientRequestSigning<AuthSchemesVariantT>::PreSignRequest(request, authSchemeOption, m_authSchemes, signerRegionOverride, signerServiceNameOverride, expirationInSeconds).IsSuccess())
334+
{
335+
return request->GetURIString();
336+
}
337+
return {};
338+
}
339+
355340
friend class AwsLegacyClientT<ServiceNameT, ResponseT, AwsSmithyClientT<ServiceNameT,
356341
ServiceClientConfigurationT,
357342
ServiceAuthSchemeResolverT,

src/aws-cpp-sdk-core/include/smithy/identity/signer/built-in/SigV4Signer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ namespace smithy {
8585
}
8686
return {identity.accessKeyId(), identity.secretAccessKey()};
8787
}();
88-
auto result = legacySigner.PresignRequest(*httpRequest, legacyCreds, region.c_str(), serviceName.c_str(), expirationTimeInSeconds);
88+
auto result = legacySigner.PresignRequest(*httpRequest, legacyCreds, region.empty() ? nullptr : region.c_str(), serviceName.empty() ? nullptr : serviceName.c_str(), expirationTimeInSeconds);
8989

9090
return (result ? SigningFutureOutcome(std::move(httpRequest)) :
9191
SigningError(Aws::Client::CoreErrors::CLIENT_SIGNING_FAILURE, "", "presign failed",

tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/generators/cpp/CppClientGenerator.java

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -718,40 +718,43 @@ protected SdkFileEntry generateClientSmithyHeaderFile(final ServiceModel service
718718
VelocityContext context = createContext(serviceModel);
719719
context.put("CppViewHelper", CppViewHelper.class);
720720
context.put("RequestlessOperations", requestlessOperations);
721-
Optional<String> firstAuthScheme = serviceModel.getAuthSchemes().stream().filter(entry->ResolverMapping.containsKey(entry)).findFirst();
722-
if(firstAuthScheme.isPresent())
721+
selectAuthschemeResolver(serviceModel, context);
722+
String fileName = String.format("include/aws/%s/%sClient.h", serviceModel.getMetadata().getProjectName(),
723+
serviceModel.getMetadata().getClassNamePrefix());
724+
725+
return makeFile(template, context, fileName, true);
726+
}
727+
728+
private void selectAuthschemeResolver(final ServiceModel serviceModel, VelocityContext context)
729+
{
730+
if(serviceModel.getAuthSchemes().size() > 1)
723731
{
724-
context.put("AuthSchemeResolver", ResolverMapping.get(firstAuthScheme.get()));
732+
context.put("AuthSchemeResolver", "SigV4MultiAuthSchemeResolver");
725733
}
726734
else
727735
{
728-
throw new RuntimeException(String.format("authSchemes '%s'",serviceModel.getAuthSchemes().stream().collect(Collectors.toList())
729-
));
736+
Optional<String> firstAuthScheme = serviceModel.getAuthSchemes().stream().filter(entry->ResolverMapping.containsKey(entry)).findFirst();
737+
738+
if(firstAuthScheme.isPresent())
739+
{
740+
context.put("AuthSchemeResolver", ResolverMapping.get(firstAuthScheme.get()));
741+
}
742+
else
743+
{
744+
throw new RuntimeException(String.format("authSchemes '%s'",serviceModel.getAuthSchemes().stream().collect(Collectors.toList())));
745+
}
730746
}
731747
context.put("AuthSchemeVariants", serviceModel.getAuthSchemes().stream().map(this::mapAuthSchemes).collect(Collectors.joining(",")));
732-
733-
String fileName = String.format("include/aws/%s/%sClient.h", serviceModel.getMetadata().getProjectName(),
734-
serviceModel.getMetadata().getClassNamePrefix());
735-
736-
return makeFile(template, context, fileName, true);
737748
}
738749

739-
protected SdkFileEntry GenerateSmithyClientSourceFile(final ServiceModel serviceModel, int i) {
750+
protected SdkFileEntry GenerateSmithyClientSourceFile(final ServiceModel serviceModel, int i, Optional<String> templateFile) {
740751

741-
Template template = velocityEngine.getTemplate("/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientSource.vm", StandardCharsets.UTF_8.name());
752+
String templatePath = templateFile.orElse("/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientSource.vm");
753+
Template template = velocityEngine.getTemplate(templatePath, StandardCharsets.UTF_8.name());
742754

743755
VelocityContext context = createContext(serviceModel);
744756
context.put("CppViewHelper", CppViewHelper.class);
745-
Optional<String> firstAuthScheme = serviceModel.getAuthSchemes().stream().filter(entry->ResolverMapping.containsKey(entry)).findFirst();
746-
if(firstAuthScheme.isPresent())
747-
{
748-
context.put("AuthSchemeResolver", ResolverMapping.get(firstAuthScheme.get()));
749-
}
750-
else
751-
{
752-
throw new RuntimeException(String.format("authSchemes '%s'",serviceModel.getAuthSchemes().stream().collect(Collectors.toList())
753-
));
754-
}
757+
selectAuthschemeResolver(serviceModel, context);
755758
context.put("AuthSchemeMapEntries", createAuthSchemeMapEntries(serviceModel));
756759

757760
final String fileName;
@@ -788,7 +791,8 @@ protected SdkFileEntry GenerateLegacyClientSourceFile(final ServiceModel service
788791
"aws.auth#sigv4a", "smithy::SigV4aAuthScheme",
789792
"bearer", "smithy::BearerTokenAuthScheme",
790793
"v4","smithy::SigV4AuthScheme",
791-
"sigv4-s3express","S3::S3ExpressSigV4AuthScheme"
794+
"sigv4-s3express","S3::S3ExpressSigV4AuthScheme",
795+
"v2","smithy::SigV4AuthScheme"
792796
);
793797

794798
protected String mapAuthSchemes(final String authSchemeName) {
@@ -804,14 +808,16 @@ protected String mapAuthSchemes(final String authSchemeName) {
804808
"aws.auth#sigv4a", "smithy::SigV4aAuthSchemeOption::sigV4aAuthSchemeOption",
805809
"bearer", "smithy::BearerTokenAuthSchemeOption::bearerTokenAuthSchemeOption",
806810
"v4", "smithy::SigV4AuthSchemeOption::sigV4AuthSchemeOption",
807-
"sigv4-s3express", "S3::S3ExpressSigV4AuthSchemeOption::s3ExpressSigV4AuthSchemeOption"
811+
"sigv4-s3express", "S3::S3ExpressSigV4AuthSchemeOption::s3ExpressSigV4AuthSchemeOption",
812+
"v2", "smithy::SigV4AuthSchemeOption::sigV4AuthSchemeOption"
808813
);
809814

810-
private static final Map<String, String> ResolverMapping = ImmutableMap.of(
815+
protected static final Map<String, String> ResolverMapping = ImmutableMap.of(
811816
"aws.auth#sigv4", "SigV4AuthSchemeResolver",
812817
"aws.auth#sigv4a", "SigV4aAuthSchemeResolver",
813818
"bearer", "BearerTokenAuthSchemeResolver",
814-
"v4", "SigV4AuthSchemeResolver"
819+
"v4", "SigV4AuthSchemeResolver",
820+
"v2", "SigV4AuthSchemeResolver"
815821
);
816822

817823

tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/generators/cpp/JsonCppClientGenerator.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.HashMap;
2121
import java.util.List;
2222
import java.util.Map;
23+
import java.util.Optional;
2324
import java.util.stream.Collectors;
2425
import java.util.stream.IntStream;
2526

@@ -176,7 +177,7 @@ protected List<SdkFileEntry> generateClientSourceFile( List<ServiceModel> servic
176177
{
177178
if(serviceModels.get(index).isUseSmithyClient() && !serviceModels.get(index).hasEventStreamingRequestShapes())
178179
{
179-
return GenerateSmithyClientSourceFile(serviceModels.get(index), index);
180+
return GenerateSmithyClientSourceFile(serviceModels.get(index), index, Optional.empty());
180181
}
181182
else
182183
{

0 commit comments

Comments
 (0)