From 692c95c2fede3cbd119fef9e83dbaab0e2d29ce2 Mon Sep 17 00:00:00 2001 From: SergeyRyabinin Date: Thu, 30 Jan 2025 21:02:27 +0000 Subject: [PATCH] Fix non-streaming request with non-structured (not xml) plain string/blob payload serialization --- .../cpp/queryxml/QueryXmlSubObjectHeader.vm | 3 +++ .../xml/ModelClassMemberSingleXmlizeSource.vm | 4 ++++ .../velocity/cpp/xml/XmlRequestSource.vm | 19 ++++++++++++++++++- .../cpp/xml/rest/RestXmlSubObjectHeader.vm | 3 +++ tools/scripts/codegen/protocol_tests_gen.py | 10 +++++----- 5 files changed, 33 insertions(+), 6 deletions(-) diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/queryxml/QueryXmlSubObjectHeader.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/queryxml/QueryXmlSubObjectHeader.vm index 7cf7452553a..1fb5ec8a0c5 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/queryxml/QueryXmlSubObjectHeader.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/queryxml/QueryXmlSubObjectHeader.vm @@ -29,6 +29,9 @@ namespace ${serviceNamespace} { namespace Model { +#foreach($forwardDeclaration in $typeInfo.forwardDeclarations) + class $forwardDeclaration; +#end #set($xmlRef = "${typeInfo.xmlNodeType}&") #set($classNameRef = "${typeInfo.className}&") diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/ModelClassMemberSingleXmlizeSource.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/ModelClassMemberSingleXmlizeSource.vm index 1138cee91d9..238400e6d88 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/ModelClassMemberSingleXmlizeSource.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/ModelClassMemberSingleXmlizeSource.vm @@ -4,8 +4,12 @@ #if($shapeMember.shape.enum) ${shapeMember.shape.name}Mapper::GetNameFor${shapeMember.shape.name}(${memberVarName})## #elseif($shapeMember.shape.timeStamp) +#if($member.shape.timestampFormat != "unixTimestamp") #set($timestamptFormatStr = $CppViewHelper.computeTimestampFormatInXml($shapeMember.shape)) ${memberVarName}.ToGmtString(Aws::Utils::DateFormat::${timestamptFormatStr})## +#else +StringUtils::to_string(${memberVarName}.Seconds())## +#end #elseif($shapeMember.shape.boolean) std::boolalpha << ${memberVarName}## #elseif($shapeMember.shape.blob) diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/XmlRequestSource.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/XmlRequestSource.vm index 7d0d3c26479..099f66012fc 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/XmlRequestSource.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/XmlRequestSource.vm @@ -69,6 +69,7 @@ Aws::String ${typeInfo.className}::SerializePayload() const #set($xmlNamespace = ${payloadMember.xmlNamespace}) #set($locationName = $payloadMember.locationName) #end +#if(!$payloadMember || !$payloadMember.shape.enum && !$payloadMember.shape.string && !$payloadMember.shape.string)##if payload is structured #if($locationName) XmlDocument payloadDoc = XmlDocument::CreateWithRootNode("${locationName}"); #else @@ -76,6 +77,7 @@ Aws::String ${typeInfo.className}::SerializePayload() const #end XmlNode parentNode = payloadDoc.GetRootElement(); +#end #if($xmlNamespace) #if($xmlNamespace.prefix) #set($xmlnsKey = "xmlns:${xmlNamespace.prefix}") @@ -85,7 +87,21 @@ Aws::String ${typeInfo.className}::SerializePayload() const parentNode.SetAttributeValue("${xmlnsKey}", "${xmlNamespace.uri}"); #end -#if($payloadMember && !$member.shape.enum) +#if($payloadMember) +#if($payloadMember.shape.enum || $payloadMember.shape.string || $payloadMember.shape.string) +##payload member is "streamed", i.e. payload doc is not the XML, but the enum string/string/blob itself +##and CPP SDK did not generate legacy "streaming" request for some modelling quirks) - we need to set the payload to just a string/buffer. +#if($payloadMember.shape.enum) + if ($payloadMember.shape.name::NOT_SET != ${CppViewHelper.computeMemberVariableName($shape.payload)}) { + return ${payloadMember.shape.name}Mapper::GetNameFor${payloadMember.shape.name}(${CppViewHelper.computeMemberVariableName($shape.payload)}); + } + return {}; +#elseif($payloadMember.shape.string) + return ${CppViewHelper.computeMemberVariableName($shape.payload)}; +#else + static_assert(false, "Failed to generate code to serialize non-streaming request with non-structured (not xml) plain string/blob payload" /*payloadMember: $payloadMember*/); +#end +#else ${CppViewHelper.computeMemberVariableName($shape.payload)}.AddToNode(parentNode); if(parentNode.HasChildren()) { @@ -93,6 +109,7 @@ Aws::String ${typeInfo.className}::SerializePayload() const } return {}; +#end #else #set($useRequiredField = true) #set($callFromRequestShape = true) diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/rest/RestXmlSubObjectHeader.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/rest/RestXmlSubObjectHeader.vm index 919ae5c67f3..33489947c02 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/rest/RestXmlSubObjectHeader.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/rest/RestXmlSubObjectHeader.vm @@ -28,6 +28,9 @@ namespace ${serviceNamespace} { namespace Model { +#foreach($forwardDeclaration in $typeInfo.forwardDeclarations) + class $forwardDeclaration; +#end #set($xmlRef = "${typeInfo.xmlNodeType}&") #set($classNameRef = "${typeInfo.className}&") diff --git a/tools/scripts/codegen/protocol_tests_gen.py b/tools/scripts/codegen/protocol_tests_gen.py index 42f427a14a3..d817255d686 100644 --- a/tools/scripts/codegen/protocol_tests_gen.py +++ b/tools/scripts/codegen/protocol_tests_gen.py @@ -157,10 +157,10 @@ def _collect_test_client_models(self) -> dict: PROTOCOL_TESTS_ENDPOINT_RULES, None, use_smithy) return service_models - def _get_client_models_metadata(self) -> set: - models = set() + def _get_client_models_metadata(self) -> list: + models = list() model_files = os.listdir(self.client_models_dir) - for filename in model_files: + for filename in sorted(model_files): if not os.path.isfile("/".join([self.client_models_dir, filename])): continue model_abspath = str(pathlib.Path(f"{self.client_models_dir}/{filename}").resolve()) @@ -169,7 +169,7 @@ def _get_client_models_metadata(self) -> set: c2j_model = json.load(file_content) model_metadata = self.ProtoTestC2jClientModelMetadata(filename, model_abspath, c2j_model.get("metadata")) - models.add(model_metadata) + models.append(model_metadata) except Exception as exc: print(f"ERROR: unexpected file content in protocol tests clients dir {self.client_models_dir}. " f"Expected c2j client model, but json metadata kew is missing: {exc}") @@ -194,7 +194,7 @@ def _collect_test_definition_models(self) -> dict: test_def_path = str(pathlib.Path(f"{self.test_definitions_dir}/{test_def_group}/{filename}").resolve()) - def _get_corresponding_test_client(test_clients_md: set, test_path: str) -> list: + def _get_corresponding_test_client(test_clients_md: list, test_path: str) -> list: # Get c2j client models matching the test suite # more than 1 is possible (ex: xml and xml with namespace clients for a single test suite) result = list()