From 1973f2576c3bf217c78c5e648fd380ffa1f07d6a Mon Sep 17 00:00:00 2001 From: Muhammad Othman Date: Thu, 19 Jun 2025 19:36:24 -0400 Subject: [PATCH 1/2] Add CBOR Tests and update Protocol test models to 1.0.5931.0 and Smithy Version 1.58.0 --- extensions/AWSSDK.Extensions.sln | 21 + .../CborProtocol.Tests.NetFramework.csproj | 30 ++ .../CborProtocol.Tests/WriteDateTimeTests.cs | 45 ++ .../WriteOptimizedNumberTests.cs | 55 +++ .../settings.gradle.kts | 5 +- .../codegen/HttpProtocolTestGenerator.java | 25 +- .../ProtocolTestCustomizations.java | 8 + .../build.gradle.kts | 1 + .../smithy-build.json | 18 + .../rest-json-protocol-2019-12-16.normal.json | 41 ++ .../rest-xml-protocol-2019-12-16.normal.json | 73 +++- ...-protocol-namespace-2019-12-16.normal.json | 53 ++- .../metadata.json | 5 + .../rpcv2protocol-2020-07-14.normal.json | 390 ++++++++++++++++++ .../rpcv2protocol.customizations.json | 14 + sdk/src/Core/Amazon.Util/AWSSDKUtils.cs | 16 +- .../AWSSDK.ProtocolTests.NetFramework.csproj | 1 + .../AWSSDK.ProtocolTests.NetFramework.sln | 12 + .../AWSSDK.ProtocolTests.NetStandard.csproj | 2 + .../AWSSDK.ProtocolTests.NetStandard.sln | 12 + .../ProtocolTests/Custom/CborProtocolUtils.cs | 181 ++++++++ 21 files changed, 984 insertions(+), 24 deletions(-) create mode 100644 extensions/test/CborProtocol.Tests/CborProtocol.Tests.NetFramework.csproj create mode 100644 extensions/test/CborProtocol.Tests/WriteDateTimeTests.cs create mode 100644 extensions/test/CborProtocol.Tests/WriteOptimizedNumberTests.cs create mode 100644 generator/TestServiceModels/smithyrpcv2cbor-tests-client/metadata.json create mode 100644 generator/TestServiceModels/smithyrpcv2cbor-tests-client/rpcv2protocol-2020-07-14.normal.json create mode 100644 generator/TestServiceModels/smithyrpcv2cbor-tests-client/rpcv2protocol.customizations.json create mode 100644 sdk/test/ProtocolTests/Custom/CborProtocolUtils.cs diff --git a/extensions/AWSSDK.Extensions.sln b/extensions/AWSSDK.Extensions.sln index 3b45806eb294..c2d06ce0e53b 100644 --- a/extensions/AWSSDK.Extensions.sln +++ b/extensions/AWSSDK.Extensions.sln @@ -74,6 +74,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AWSSDK.CommonTest", "..\sdk EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AWSSDK.S3.NetFramework", "..\sdk\src\Services\S3\AWSSDK.S3.NetFramework.csproj", "{1A313326-988F-4FF2-992E-6D7E50DCF598}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AWSSDK.Extensions.CborProtocol.NetFramework", "src\AWSSDK.Extensions.CborProtocol\AWSSDK.Extensions.CborProtocol.NetFramework.csproj", "{4FCCBD72-8E9B-D74B-6538-D8684D181230}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AWSSDK.Extensions.CborProtocol.NetStandard", "src\AWSSDK.Extensions.CborProtocol\AWSSDK.Extensions.CborProtocol.NetStandard.csproj", "{24CBBC97-409E-BAC8-0553-D260AB0B8C6A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CborProtocol.Tests.NetFramework", "test\CborProtocol.Tests\CborProtocol.Tests.NetFramework.csproj", "{9FFDECAB-94D6-7EB1-1A5B-487492600755}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -204,6 +210,18 @@ Global {1A313326-988F-4FF2-992E-6D7E50DCF598}.Debug|Any CPU.Build.0 = Debug|Any CPU {1A313326-988F-4FF2-992E-6D7E50DCF598}.Release|Any CPU.ActiveCfg = Release|Any CPU {1A313326-988F-4FF2-992E-6D7E50DCF598}.Release|Any CPU.Build.0 = Release|Any CPU + {4FCCBD72-8E9B-D74B-6538-D8684D181230}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4FCCBD72-8E9B-D74B-6538-D8684D181230}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4FCCBD72-8E9B-D74B-6538-D8684D181230}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4FCCBD72-8E9B-D74B-6538-D8684D181230}.Release|Any CPU.Build.0 = Release|Any CPU + {24CBBC97-409E-BAC8-0553-D260AB0B8C6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {24CBBC97-409E-BAC8-0553-D260AB0B8C6A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {24CBBC97-409E-BAC8-0553-D260AB0B8C6A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {24CBBC97-409E-BAC8-0553-D260AB0B8C6A}.Release|Any CPU.Build.0 = Release|Any CPU + {9FFDECAB-94D6-7EB1-1A5B-487492600755}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9FFDECAB-94D6-7EB1-1A5B-487492600755}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9FFDECAB-94D6-7EB1-1A5B-487492600755}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9FFDECAB-94D6-7EB1-1A5B-487492600755}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -240,6 +258,9 @@ Global {58BD3C7A-087C-4ECB-87C6-A3445025BEF5} = {A960D001-40B3-4B1A-A890-D1049FB7586E} {AF5B5402-7C9A-4E5E-B0C2-9278BAE0435C} = {A960D001-40B3-4B1A-A890-D1049FB7586E} {1A313326-988F-4FF2-992E-6D7E50DCF598} = {0BA39F07-84D6-420B-82D3-6DC3AF016C65} + {4FCCBD72-8E9B-D74B-6538-D8684D181230} = {3D822DC2-ED2E-4434-BC4F-CE7FCD846B02} + {24CBBC97-409E-BAC8-0553-D260AB0B8C6A} = {3D822DC2-ED2E-4434-BC4F-CE7FCD846B02} + {9FFDECAB-94D6-7EB1-1A5B-487492600755} = {A960D001-40B3-4B1A-A890-D1049FB7586E} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {949367A4-5683-4FD3-93F4-A2CEA6EECB21} diff --git a/extensions/test/CborProtocol.Tests/CborProtocol.Tests.NetFramework.csproj b/extensions/test/CborProtocol.Tests/CborProtocol.Tests.NetFramework.csproj new file mode 100644 index 000000000000..c32accb1f826 --- /dev/null +++ b/extensions/test/CborProtocol.Tests/CborProtocol.Tests.NetFramework.csproj @@ -0,0 +1,30 @@ + + + net472 + CborProtocol.Tests + CborProtocol.Tests + false + false + false + false + false + false + false + false + true + Latest + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + \ No newline at end of file diff --git a/extensions/test/CborProtocol.Tests/WriteDateTimeTests.cs b/extensions/test/CborProtocol.Tests/WriteDateTimeTests.cs new file mode 100644 index 000000000000..56425f34162f --- /dev/null +++ b/extensions/test/CborProtocol.Tests/WriteDateTimeTests.cs @@ -0,0 +1,45 @@ +using System; +using System.Formats.Cbor; +using Xunit; +using AWSSDK.Extensions.CborProtocol; + +namespace Amazon.CborProtocol.Tests; + +public class WriteDateTimeTests +{ + [Theory] + [InlineData("1969-12-31T23:59:59Z", -1.0, CborReaderState.NegativeInteger, 2)] + [InlineData("1970-01-01T00:00:01Z", 1.0, CborReaderState.UnsignedInteger, 2)] + [InlineData("1970-01-01T00:00:00.500Z", 0.5, CborReaderState.SinglePrecisionFloat, 6)] + [InlineData("2025-01-01T00:00:00Z", 1735689600.0, CborReaderState.UnsignedInteger, 6)] + [InlineData("2025-06-19T20:15:28.468Z", 1750364128.468, CborReaderState.DoublePrecisionFloat, 10)] + public void WriteDateTime_EncodesCorrectly(string isoDate, double expectedUnixEpoch, CborReaderState expectedState, int expectedTotalBytes) + { + var dt = DateTime.Parse(isoDate).ToUniversalTime(); + var writer = new CborWriter(); + writer.WriteDateTime(dt); + + var encoded = writer.Encode(); + var reader = new CborReader(encoded); + var tag = reader.ReadTag(); + + Assert.Equal(CborTag.UnixTimeSeconds, tag); + Assert.Equal(expectedState, reader.PeekState()); + + double value = 0; + + if (expectedState == CborReaderState.SinglePrecisionFloat) + value = reader.ReadSingle(); + else if (expectedState == CborReaderState.DoublePrecisionFloat) + value = reader.ReadDouble(); + else if (expectedState == CborReaderState.UnsignedInteger) + value = reader.ReadUInt64(); + else if (expectedState == CborReaderState.NegativeInteger) + value = reader.ReadInt64(); + else + Assert.Fail($"CBOR state not found: ${reader.PeekState()}"); + + Assert.Equal(expectedUnixEpoch, value); + Assert.Equal(expectedTotalBytes, encoded.Length); + } +} diff --git a/extensions/test/CborProtocol.Tests/WriteOptimizedNumberTests.cs b/extensions/test/CborProtocol.Tests/WriteOptimizedNumberTests.cs new file mode 100644 index 000000000000..dec08da0cb49 --- /dev/null +++ b/extensions/test/CborProtocol.Tests/WriteOptimizedNumberTests.cs @@ -0,0 +1,55 @@ +using System.Formats.Cbor; +using Xunit; +using AWSSDK.Extensions.CborProtocol; + +namespace Amazon.CborProtocol.Tests; + +public class WriteOptimizedNumberTests +{ + [Theory] + [InlineData(0, 1)] // Fits in initial byte (major type + value) + [InlineData(23, 1)] // Still in initial byte + [InlineData(24, 2)] // One additional byte for UInt8 + [InlineData(255, 2)] // UInt8 + [InlineData(256, 3)] // UInt16 + [InlineData(65535, 3)] // UInt16 max + [InlineData(65536, 5)] // UInt32 + [InlineData(uint.MaxValue, 5)] // UInt32 + [InlineData((long)uint.MaxValue + 1, 9)] // UInt64 + public void WriteOptimizedNumber_UsesExpectedEncodingLength_ForUInt64(double value, int expectedBytes) + { + var writer = new CborWriter(); + writer.WriteOptimizedNumber((double)value); + var encoded = writer.Encode(); + + Assert.Equal(expectedBytes, encoded.Length); + } + + [Theory] + [InlineData(-1, 1)] // Negative integers encoded compactly + [InlineData(-24, 1)] + [InlineData(-25, 2)] // Beyond negative byte range + [InlineData(int.MinValue, 5)] // Should require full 32 bits + [InlineData(long.MinValue, 9)] // Full 64-bit negative integer + public void WriteOptimizedNumber_UsesExpectedEncodingLength_ForNegativeIntegers(long value, int expectedBytes) + { + var writer = new CborWriter(); + writer.WriteOptimizedNumber((double)value); + var encoded = writer.Encode(); + + Assert.Equal(expectedBytes, encoded.Length); + } + + [Theory] + [InlineData(1.5, 5, 0xFA)] // float32 marker + 4 bytes + [InlineData(123456789.12345, 9, 0xFB)] // Doesn't fit in float32 + public void WriteOptimizedNumber_Float32_IsManuallyEncodedAsFiveBytes(double value, int expectedBytes, byte floatMarker) + { + var writer = new CborWriter(); + writer.WriteOptimizedNumber(value); + var encoded = writer.Encode(); + + Assert.Equal(expectedBytes, encoded.Length); + Assert.Equal(floatMarker, encoded[0]); // Check float32 CBOR marker + } +} diff --git a/generator/ProtocolTestsGenerator/settings.gradle.kts b/generator/ProtocolTestsGenerator/settings.gradle.kts index 0c14cf8100c8..f57af9125985 100644 --- a/generator/ProtocolTestsGenerator/settings.gradle.kts +++ b/generator/ProtocolTestsGenerator/settings.gradle.kts @@ -12,8 +12,9 @@ pluginManagement { dependencyResolutionManagement { versionCatalogs { create("codegen") { - version("smithy", "1.54.0") - library("protocol-tests", "software.amazon.smithy", "smithy-aws-protocol-tests").versionRef("smithy") + version("smithy", "1.58.0") + library("protocol-tests", "software.amazon.smithy", "smithy-protocol-tests").versionRef("smithy") + library("protocol-aws-tests", "software.amazon.smithy", "smithy-aws-protocol-tests").versionRef("smithy") library("codegen-core", "software.amazon.smithy", "smithy-codegen-core").versionRef("smithy") library("protocol-tests-traits", "software.amazon.smithy", "smithy-protocol-test-traits").versionRef("smithy") library("aws-traits", "software.amazon.smithy", "smithy-aws-traits").versionRef("smithy") diff --git a/generator/ProtocolTestsGenerator/smithy-dotnet-codegen/src/main/java/software/amazon/smithy/dotnet/codegen/HttpProtocolTestGenerator.java b/generator/ProtocolTestsGenerator/smithy-dotnet-codegen/src/main/java/software/amazon/smithy/dotnet/codegen/HttpProtocolTestGenerator.java index c8e4315db0b5..14a9049d064c 100644 --- a/generator/ProtocolTestsGenerator/smithy-dotnet-codegen/src/main/java/software/amazon/smithy/dotnet/codegen/HttpProtocolTestGenerator.java +++ b/generator/ProtocolTestsGenerator/smithy-dotnet-codegen/src/main/java/software/amazon/smithy/dotnet/codegen/HttpProtocolTestGenerator.java @@ -16,6 +16,7 @@ package software.amazon.smithy.dotnet.codegen; import software.amazon.smithy.aws.traits.ServiceTrait; +import software.amazon.smithy.model.traits.TitleTrait; import software.amazon.smithy.codegen.core.CodegenException; import software.amazon.smithy.dotnet.codegen.utils.ProtocolTestUtils; import software.amazon.smithy.model.Model; @@ -51,7 +52,14 @@ public HttpProtocolTestGenerator( this.model = context.model(); this.service = settings.getService(model); this.context = context; - this.serviceNamespace = service.getTrait(ServiceTrait.class).get().getSdkId().replace(" ", ""); + + String serviceNamespace = null; + if(service.getTrait(ServiceTrait.class).isPresent()) + serviceNamespace = service.getTrait(ServiceTrait.class).get().getSdkId(); + else if(service.getTrait(TitleTrait.class).isPresent()) + serviceNamespace = service.getTrait(TitleTrait.class).get().getValue().replace("Service", ""); + + this.serviceNamespace = serviceNamespace.replace(" ", ""); } @Override @@ -60,6 +68,8 @@ public void run() { OperationIndex operationIndex = OperationIndex.of(model); for (OperationShape operation : new TreeSet<>(topDownIndex.getContainedOperations(service))) { var operationName = operation.getId().getName(); + if (ProtocolTestCustomizations.OperationsToSkip.contains(operationName)) + continue; context.writerDelegator().useFileWriter(operationName + ".cs", serviceName, writer -> { this.writer = writer; addServiceProtocolSpecificImports(); @@ -87,6 +97,8 @@ private void addServiceProtocolSpecificImports() { } else if (this.serviceName.toLowerCase().contains("xml")) { writer.addImport(serviceName, "System.Xml"); writer.addImport(serviceName, "System.Xml.Linq"); + } else if (this.serviceName.toLowerCase().contains("rpcv2")) { + writer.addImport(serviceName, "AWSSDK.Extensions.CborProtocol.Internal"); } } @@ -94,7 +106,8 @@ private void generateErrorResponseTests(OperationShape operation, OperationIndex for (StructureShape error : index.getErrors(operation, service)) { error.getTrait(HttpResponseTestsTrait.class).ifPresent(trait -> { for (HttpResponseTestCase httpResponseTestCase : trait.getTestCasesFor(AppliesTo.CLIENT)) { - generateErrorResponseTest(operation, error, httpResponseTestCase); + if(!trait.getTestCasesFor(AppliesTo.CLIENT).getFirst().getProtocol().getName().toLowerCase().contains("cbor")) // Skip CBOR response tests until the unmarshallers are ready + generateErrorResponseTest(operation, error, httpResponseTestCase); } }); } @@ -283,6 +296,9 @@ private void assertRequestBody(HttpRequestTestCase httpRequestTestCase) { } else if (httpRequestTestCase.getProtocol().getName().equals("restXml")) { writer.write("var expectedBody = $S;", httpRequestTestCase.getBody()); writer.write("XmlTestUtils.AssertBody(marshalledRequest,expectedBody);"); + } else if (this.marshallerType.equals("Cbor")) { + writer.write("var expectedBody = $S;", httpRequestTestCase.getBody()); + writer.write("CborProtocolUtils.AssertBody(marshalledRequest, expectedBody);"); } else { throw new CodegenException("Unsupported protocol detected while generating request test block."); } @@ -294,7 +310,8 @@ private void generateResponseTests(OperationShape operation) { setMarshallerType(trait.getTestCasesFor(AppliesTo.CLIENT).getFirst().getProtocol().getName()); } for (HttpResponseTestCase httpResponseTestCase : trait.getTestCasesFor(AppliesTo.CLIENT)) { - if (ProtocolTestCustomizations.TestsToSkip.contains(httpResponseTestCase.getId()) || httpResponseTestCase.hasTag("defaults")) + if (ProtocolTestCustomizations.TestsToSkip.contains(httpResponseTestCase.getId()) || httpResponseTestCase.hasTag("defaults") + || trait.getTestCasesFor(AppliesTo.CLIENT).getFirst().getProtocol().getName().toLowerCase().contains("cbor")) // Skip CBOR response tests until the unmarshallers are ready continue; generateResponseTest(operation, httpResponseTestCase); } @@ -343,6 +360,8 @@ private void setMarshallerType(String protocol) { this.marshallerType = "Json"; } else if (protocol.toLowerCase().contains("xml") || protocol.toLowerCase().contains("query")) { this.marshallerType = "Xml"; + } else if (protocol.toLowerCase().contains("cbor")) { + this.marshallerType = "Cbor"; } } diff --git a/generator/ProtocolTestsGenerator/smithy-dotnet-codegen/src/main/java/software/amazon/smithy/dotnet/codegen/customizations/ProtocolTestCustomizations.java b/generator/ProtocolTestsGenerator/smithy-dotnet-codegen/src/main/java/software/amazon/smithy/dotnet/codegen/customizations/ProtocolTestCustomizations.java index 0cc7a2df9fd3..e8a7438727cf 100644 --- a/generator/ProtocolTestsGenerator/smithy-dotnet-codegen/src/main/java/software/amazon/smithy/dotnet/codegen/customizations/ProtocolTestCustomizations.java +++ b/generator/ProtocolTestsGenerator/smithy-dotnet-codegen/src/main/java/software/amazon/smithy/dotnet/codegen/customizations/ProtocolTestCustomizations.java @@ -20,6 +20,14 @@ private ProtocolTestCustomizations() { "SparseBooleanMap", "SparseNumberMap" ); + + // These operations don't exist in C2J + public static final List OperationsToSkip = Arrays.asList( + "RpcV2CborSparseMaps", + "OperationWithDefaults", + "SparseNullsOperation" + ); + //The rename is written in smithy and since we're generating from the C2J structures we will skip this test. public static final List TestsToSkip = Arrays.asList( "RestJsonSerializeRenamedStructureUnionValue", diff --git a/generator/ProtocolTestsGenerator/smithy-dotnet-protocol-test/build.gradle.kts b/generator/ProtocolTestsGenerator/smithy-dotnet-protocol-test/build.gradle.kts index 5ae891f3ea15..874b34ae93b3 100644 --- a/generator/ProtocolTestsGenerator/smithy-dotnet-protocol-test/build.gradle.kts +++ b/generator/ProtocolTestsGenerator/smithy-dotnet-protocol-test/build.gradle.kts @@ -27,6 +27,7 @@ repositories { dependencies { implementation(project(":smithy-dotnet-codegen")) + implementation(codegen.protocol.aws.tests) implementation(codegen.protocol.tests) } diff --git a/generator/ProtocolTestsGenerator/smithy-dotnet-protocol-test/smithy-build.json b/generator/ProtocolTestsGenerator/smithy-dotnet-protocol-test/smithy-build.json index 520ca34ea199..bdd22d6e4a06 100644 --- a/generator/ProtocolTestsGenerator/smithy-dotnet-protocol-test/smithy-build.json +++ b/generator/ProtocolTestsGenerator/smithy-dotnet-protocol-test/smithy-build.json @@ -127,6 +127,24 @@ "packageVersion": "0.0.1" } } + }, + "RpcV2Protocol": { + "transforms": [ + { + "name": "includeServices", + "args": { + "services": [ + "smithy.protocoltests.rpcv2Cbor#RpcV2Protocol" + ] + } + } + ], + "plugins": { + "dotnet-protocol-test-codegen": { + "service": "smithy.protocoltests.rpcv2Cbor#RpcV2Protocol", + "packageVersion": "0.0.1" + } + } } } } \ No newline at end of file diff --git a/generator/TestServiceModels/restjson-tests-client/rest-json-protocol-2019-12-16.normal.json b/generator/TestServiceModels/restjson-tests-client/rest-json-protocol-2019-12-16.normal.json index 1b52f0baf5e1..229326a898d7 100644 --- a/generator/TestServiceModels/restjson-tests-client/rest-json-protocol-2019-12-16.normal.json +++ b/generator/TestServiceModels/restjson-tests-client/rest-json-protocol-2019-12-16.normal.json @@ -176,6 +176,17 @@ "documentation":"

This example tests httpChecksumRequired trait

", "httpChecksumRequired":true }, + "HttpEmptyPrefixHeaders":{ + "name":"HttpEmptyPrefixHeaders", + "http":{ + "method":"GET", + "requestUri":"/HttpEmptyPrefixHeaders", + "responseCode":200 + }, + "input":{"shape":"HttpEmptyPrefixHeadersInput"}, + "output":{"shape":"HttpEmptyPrefixHeadersOutput"}, + "documentation":"

Clients that perform this test extract all headers from the response.

" + }, "HttpEnumPayload":{ "name":"HttpEnumPayload", "http":{ @@ -1030,6 +1041,36 @@ "type":"timestamp", "timestampFormat":"rfc822" }, + "HttpEmptyPrefixHeadersInput":{ + "type":"structure", + "members":{ + "prefixHeaders":{ + "shape":"StringMap", + "location":"headers", + "locationName":"" + }, + "specificHeader":{ + "shape":"String", + "location":"header", + "locationName":"hello" + } + } + }, + "HttpEmptyPrefixHeadersOutput":{ + "type":"structure", + "members":{ + "prefixHeaders":{ + "shape":"StringMap", + "location":"headers", + "locationName":"" + }, + "specificHeader":{ + "shape":"String", + "location":"header", + "locationName":"hello" + } + } + }, "HttpPayloadTraitsInputOutput":{ "type":"structure", "members":{ diff --git a/generator/TestServiceModels/restxml-tests-client/rest-xml-protocol-2019-12-16.normal.json b/generator/TestServiceModels/restxml-tests-client/rest-xml-protocol-2019-12-16.normal.json index 57c47de1a677..5d91859fd83e 100644 --- a/generator/TestServiceModels/restxml-tests-client/rest-xml-protocol-2019-12-16.normal.json +++ b/generator/TestServiceModels/restxml-tests-client/rest-xml-protocol-2019-12-16.normal.json @@ -229,6 +229,21 @@ "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A BadRequest error.

Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the

", "idempotent": true }, + "HttpEmptyPrefixHeaders": { + "name": "HttpEmptyPrefixHeaders", + "http": { + "method": "GET", + "requestUri": "/HttpEmptyPrefixHeaders", + "responseCode": 200 + }, + "input": { + "shape": "HttpEmptyPrefixHeadersInput" + }, + "output": { + "shape": "HttpEmptyPrefixHeadersOutput" + }, + "documentation": "

Clients that perform this test extract all headers from the response.

" + }, "HttpEnumPayload": { "name": "HttpEnumPayload", "http": { @@ -476,11 +491,11 @@ "responseCode": 200 }, "input": { - "shape": "NestedXmlMapWithXmlNameInputOutput", + "shape": "NestedXmlMapWithXmlNameRequest", "locationName": "NestedXmlMapWithXmlNameRequest" }, "output": { - "shape": "NestedXmlMapWithXmlNameInputOutput" + "shape": "NestedXmlMapWithXmlNameResponse" }, "documentation": "

Nested Xml Maps with key/values with @xmlName

" }, @@ -1337,6 +1352,36 @@ "type": "timestamp", "timestampFormat": "rfc822" }, + "HttpEmptyPrefixHeadersInput": { + "type": "structure", + "members": { + "prefixHeaders": { + "shape": "StringMap", + "location": "headers", + "locationName": "" + }, + "specificHeader": { + "shape": "String", + "location": "header", + "locationName": "hello" + } + } + }, + "HttpEmptyPrefixHeadersOutput": { + "type": "structure", + "members": { + "prefixHeaders": { + "shape": "StringMap", + "location": "headers", + "locationName": "" + }, + "specificHeader": { + "shape": "String", + "location": "header", + "locationName": "hello" + } + } + }, "HttpPayloadTraitsInputOutput": { "type": "structure", "members": { @@ -1786,14 +1831,6 @@ "locationName": "InnerValue" } }, - "NestedXmlMapWithXmlNameInputOutput": { - "type": "structure", - "members": { - "nestedXmlMapWithXmlNameMap": { - "shape": "NestedXmlMapWithXmlNameMap" - } - } - }, "NestedXmlMapWithXmlNameMap": { "type": "map", "key": { @@ -1804,6 +1841,22 @@ "shape": "NestedXmlMapWithXmlNameInnerMap" } }, + "NestedXmlMapWithXmlNameRequest": { + "type": "structure", + "members": { + "nestedXmlMapWithXmlNameMap": { + "shape": "NestedXmlMapWithXmlNameMap" + } + } + }, + "NestedXmlMapWithXmlNameResponse": { + "type": "structure", + "members": { + "nestedXmlMapWithXmlNameMap": { + "shape": "NestedXmlMapWithXmlNameMap" + } + } + }, "NestedXmlMapsRequest": { "type": "structure", "members": { diff --git a/generator/TestServiceModels/restxmlwithnamespace-tests-client/rest-xml-protocol-namespace-2019-12-16.normal.json b/generator/TestServiceModels/restxmlwithnamespace-tests-client/rest-xml-protocol-namespace-2019-12-16.normal.json index 65b7e98c25e4..c1f945c604c8 100644 --- a/generator/TestServiceModels/restxmlwithnamespace-tests-client/rest-xml-protocol-namespace-2019-12-16.normal.json +++ b/generator/TestServiceModels/restxmlwithnamespace-tests-client/rest-xml-protocol-namespace-2019-12-16.normal.json @@ -25,14 +25,14 @@ "responseCode": 200 }, "input": { - "shape": "SimpleScalarPropertiesInputOutput", + "shape": "SimpleScalarPropertiesRequest", "locationName": "SimpleScalarPropertiesRequest", "xmlNamespace": { "uri": "https://example.com" } }, "output": { - "shape": "SimpleScalarPropertiesInputOutput" + "shape": "SimpleScalarPropertiesResponse" }, "idempotent": true } @@ -68,7 +68,7 @@ } } }, - "SimpleScalarPropertiesInputOutput": { + "SimpleScalarPropertiesRequest": { "type": "structure", "members": { "foo": { @@ -102,10 +102,49 @@ }, "Nested": { "shape": "NestedWithNamespace", - "xmlNamespace": { - "prefix": "xsi", - "uri": "https://example.com" - } + "xmlNamespace": "https://example.com" + }, + "doubleValue": { + "shape": "Double", + "locationName": "DoubleDribble" + } + } + }, + "SimpleScalarPropertiesResponse": { + "type": "structure", + "members": { + "foo": { + "shape": "String", + "location": "header", + "locationName": "X-Foo" + }, + "stringValue": { + "shape": "String" + }, + "trueBooleanValue": { + "shape": "Boolean" + }, + "falseBooleanValue": { + "shape": "Boolean" + }, + "byteValue": { + "shape": "Integer" + }, + "shortValue": { + "shape": "Integer" + }, + "integerValue": { + "shape": "Integer" + }, + "longValue": { + "shape": "Long" + }, + "floatValue": { + "shape": "Float" + }, + "Nested": { + "shape": "NestedWithNamespace", + "xmlNamespace": "https://example.com" }, "doubleValue": { "shape": "Double", diff --git a/generator/TestServiceModels/smithyrpcv2cbor-tests-client/metadata.json b/generator/TestServiceModels/smithyrpcv2cbor-tests-client/metadata.json new file mode 100644 index 000000000000..a50503b0f2d7 --- /dev/null +++ b/generator/TestServiceModels/smithyrpcv2cbor-tests-client/metadata.json @@ -0,0 +1,5 @@ +{ + "active": true, + "test-service": true, + "synopsis": "RpcV2Protocol test service" +} \ No newline at end of file diff --git a/generator/TestServiceModels/smithyrpcv2cbor-tests-client/rpcv2protocol-2020-07-14.normal.json b/generator/TestServiceModels/smithyrpcv2cbor-tests-client/rpcv2protocol-2020-07-14.normal.json new file mode 100644 index 000000000000..dff3518f7447 --- /dev/null +++ b/generator/TestServiceModels/smithyrpcv2cbor-tests-client/rpcv2protocol-2020-07-14.normal.json @@ -0,0 +1,390 @@ +{ + "version":"2.0", + "metadata":{ + "apiVersion":"2020-07-14", + "auth":["aws.auth#sigv4"], + "endpointPrefix":"rpcv2protocol", + "protocol":"smithy-rpc-v2-cbor", + "protocols":["smithy-rpc-v2-cbor"], + "serviceFullName":"RpcV2 Protocol Service", + "serviceId":"RpcV2Protocol", + "signatureVersion":"v4", + "signingName":"rpcv2protocol", + "targetPrefix":"RpcV2Protocol", + "uid":"rpcv2protocol-2020-07-14" + }, + "operations":{ + "EmptyInputOutput":{ + "name":"EmptyInputOutput", + "http":{ + "method":"POST", + "requestUri":"/" + }, + "input":{"shape":"EmptyStructure"}, + "output":{"shape":"EmptyStructure"} + }, + "Float16":{ + "name":"Float16", + "http":{ + "method":"POST", + "requestUri":"/" + }, + "output":{"shape":"Float16Output"} + }, + "FractionalSeconds":{ + "name":"FractionalSeconds", + "http":{ + "method":"POST", + "requestUri":"/" + }, + "output":{"shape":"FractionalSecondsOutput"} + }, + "GreetingWithErrors":{ + "name":"GreetingWithErrors", + "http":{ + "method":"POST", + "requestUri":"/" + }, + "output":{"shape":"GreetingWithErrorsOutput"}, + "errors":[ + {"shape":"ComplexError"}, + {"shape":"InvalidGreeting"} + ], + "documentation":"

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A ComplexError error.

Implementations must be able to successfully take a response and properly deserialize successful and error responses.

", + "idempotent":true + }, + "NoInputOutput":{ + "name":"NoInputOutput", + "http":{ + "method":"POST", + "requestUri":"/" + } + }, + "OptionalInputOutput":{ + "name":"OptionalInputOutput", + "http":{ + "method":"POST", + "requestUri":"/" + }, + "input":{"shape":"SimpleStructure"}, + "output":{"shape":"SimpleStructure"} + }, + "RecursiveShapes":{ + "name":"RecursiveShapes", + "http":{ + "method":"POST", + "requestUri":"/" + }, + "input":{"shape":"RecursiveShapesInputOutput"}, + "output":{"shape":"RecursiveShapesInputOutput"} + }, + "RpcV2CborDenseMaps":{ + "name":"RpcV2CborDenseMaps", + "http":{ + "method":"POST", + "requestUri":"/" + }, + "input":{"shape":"RpcV2CborDenseMapsInputOutput"}, + "output":{"shape":"RpcV2CborDenseMapsInputOutput"}, + "errors":[ + {"shape":"ValidationException"} + ], + "documentation":"

The example tests basic map serialization.

" + }, + "RpcV2CborLists":{ + "name":"RpcV2CborLists", + "http":{ + "method":"POST", + "requestUri":"/" + }, + "input":{"shape":"RpcV2CborListInputOutput"}, + "output":{"shape":"RpcV2CborListInputOutput"}, + "errors":[ + {"shape":"ValidationException"} + ], + "documentation":"

This test case serializes JSON lists for the following cases for both input and output:

  1. Normal lists.
  2. Normal sets.
  3. Lists of lists.
  4. Lists of structures.
", + "idempotent":true + }, + "SimpleScalarProperties":{ + "name":"SimpleScalarProperties", + "http":{ + "method":"POST", + "requestUri":"/" + }, + "input":{"shape":"SimpleScalarStructure"}, + "output":{"shape":"SimpleScalarStructure"} + } + }, + "shapes":{ + "Blob":{"type":"blob"}, + "BlobList":{ + "type":"list", + "member":{"shape":"Blob"} + }, + "Boolean":{ + "type":"boolean", + "box":true + }, + "BooleanList":{ + "type":"list", + "member":{"shape":"Boolean"} + }, + "ComplexError":{ + "type":"structure", + "members":{ + "TopLevel":{"shape":"String"}, + "Nested":{"shape":"ComplexNestedErrorData"} + }, + "documentation":"

This error is thrown when a request is invalid.

", + "exception":true + }, + "ComplexNestedErrorData":{ + "type":"structure", + "members":{ + "Foo":{"shape":"String"} + } + }, + "DateTime":{ + "type":"timestamp", + "timestampFormat":"iso8601" + }, + "DenseBooleanMap":{ + "type":"map", + "key":{"shape":"String"}, + "value":{"shape":"Boolean"} + }, + "DenseNumberMap":{ + "type":"map", + "key":{"shape":"String"}, + "value":{"shape":"Integer"} + }, + "DenseSetMap":{ + "type":"map", + "key":{"shape":"String"}, + "value":{"shape":"StringSet"} + }, + "DenseStringMap":{ + "type":"map", + "key":{"shape":"String"}, + "value":{"shape":"String"} + }, + "DenseStructMap":{ + "type":"map", + "key":{"shape":"String"}, + "value":{"shape":"GreetingStruct"} + }, + "Double":{ + "type":"double", + "box":true + }, + "EmptyStructure":{ + "type":"structure", + "members":{ + } + }, + "Float":{ + "type":"float", + "box":true + }, + "Float16Output":{ + "type":"structure", + "members":{ + "value":{"shape":"Double"} + } + }, + "FooEnum":{ + "type":"string", + "enum":[ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "FooEnumList":{ + "type":"list", + "member":{"shape":"FooEnum"} + }, + "FractionalSecondsOutput":{ + "type":"structure", + "members":{ + "datetime":{"shape":"DateTime"} + } + }, + "GreetingStruct":{ + "type":"structure", + "members":{ + "hi":{"shape":"String"} + } + }, + "GreetingWithErrorsOutput":{ + "type":"structure", + "members":{ + "greeting":{"shape":"String"} + } + }, + "Integer":{ + "type":"integer", + "box":true + }, + "IntegerEnum":{ + "type":"integer", + "box":true + }, + "IntegerEnumList":{ + "type":"list", + "member":{"shape":"IntegerEnum"} + }, + "IntegerList":{ + "type":"list", + "member":{"shape":"Integer"} + }, + "InvalidGreeting":{ + "type":"structure", + "members":{ + "Message":{"shape":"String"} + }, + "documentation":"

This error is thrown when an invalid greeting value is provided.

", + "exception":true + }, + "Long":{ + "type":"long", + "box":true + }, + "NestedStringList":{ + "type":"list", + "member":{"shape":"StringList"}, + "documentation":"

A list of lists of strings.

" + }, + "RecursiveShapesInputOutput":{ + "type":"structure", + "members":{ + "nested":{"shape":"RecursiveShapesInputOutputNested1"} + } + }, + "RecursiveShapesInputOutputNested1":{ + "type":"structure", + "members":{ + "foo":{"shape":"String"}, + "nested":{"shape":"RecursiveShapesInputOutputNested2"} + } + }, + "RecursiveShapesInputOutputNested2":{ + "type":"structure", + "members":{ + "bar":{"shape":"String"}, + "recursiveMember":{"shape":"RecursiveShapesInputOutputNested1"} + } + }, + "RpcV2CborDenseMapsInputOutput":{ + "type":"structure", + "members":{ + "denseStructMap":{"shape":"DenseStructMap"}, + "denseNumberMap":{"shape":"DenseNumberMap"}, + "denseBooleanMap":{"shape":"DenseBooleanMap"}, + "denseStringMap":{"shape":"DenseStringMap"}, + "denseSetMap":{"shape":"DenseSetMap"} + } + }, + "RpcV2CborListInputOutput":{ + "type":"structure", + "members":{ + "stringList":{"shape":"StringList"}, + "stringSet":{"shape":"StringSet"}, + "integerList":{"shape":"IntegerList"}, + "booleanList":{"shape":"BooleanList"}, + "timestampList":{"shape":"TimestampList"}, + "enumList":{"shape":"FooEnumList"}, + "intEnumList":{"shape":"IntegerEnumList"}, + "nestedStringList":{"shape":"NestedStringList"}, + "structureList":{"shape":"StructureList"}, + "blobList":{"shape":"BlobList"} + } + }, + "SimpleScalarStructure":{ + "type":"structure", + "members":{ + "trueBooleanValue":{"shape":"Boolean"}, + "falseBooleanValue":{"shape":"Boolean"}, + "byteValue":{"shape":"Integer"}, + "doubleValue":{"shape":"Double"}, + "floatValue":{"shape":"Float"}, + "integerValue":{"shape":"Integer"}, + "longValue":{"shape":"Long"}, + "shortValue":{"shape":"Integer"}, + "stringValue":{"shape":"String"}, + "blobValue":{"shape":"Blob"} + } + }, + "SimpleStructure":{ + "type":"structure", + "members":{ + "value":{"shape":"String"} + } + }, + "String":{"type":"string"}, + "StringList":{ + "type":"list", + "member":{"shape":"String"} + }, + "StringSet":{ + "type":"list", + "member":{"shape":"String"} + }, + "StructureList":{ + "type":"list", + "member":{"shape":"StructureListMember"} + }, + "StructureListMember":{ + "type":"structure", + "members":{ + "a":{"shape":"String"}, + "b":{"shape":"String"} + } + }, + "Timestamp":{"type":"timestamp"}, + "TimestampList":{ + "type":"list", + "member":{"shape":"Timestamp"} + }, + "ValidationException":{ + "type":"structure", + "required":["message"], + "members":{ + "message":{ + "shape":"String", + "documentation":"

A summary of the validation failure.

" + }, + "fieldList":{ + "shape":"ValidationExceptionFieldList", + "documentation":"

A list of specific failures encountered while validating the input. A member can appear in this list more than once if it failed to satisfy multiple constraints.

" + } + }, + "documentation":"

A standard error for input validation failures. This should be thrown by services when a member of the input structure falls outside of the modeled or documented constraints.

", + "exception":true + }, + "ValidationExceptionField":{ + "type":"structure", + "required":[ + "path", + "message" + ], + "members":{ + "path":{ + "shape":"String", + "documentation":"

A JSONPointer expression to the structure member whose value failed to satisfy the modeled constraints.

" + }, + "message":{ + "shape":"String", + "documentation":"

A detailed description of the validation failure.

" + } + }, + "documentation":"

Describes one specific validation failure for an input member.

" + }, + "ValidationExceptionFieldList":{ + "type":"list", + "member":{"shape":"ValidationExceptionField"} + } + } +} diff --git a/generator/TestServiceModels/smithyrpcv2cbor-tests-client/rpcv2protocol.customizations.json b/generator/TestServiceModels/smithyrpcv2cbor-tests-client/rpcv2protocol.customizations.json new file mode 100644 index 000000000000..0dd56516f2b9 --- /dev/null +++ b/generator/TestServiceModels/smithyrpcv2cbor-tests-client/rpcv2protocol.customizations.json @@ -0,0 +1,14 @@ +{ + "shapeModifiers": { + "FooEnum": { + "modify": [ + { + "0": { "emitPropertyName": "Num_0" } + }, + { + "1": { "emitPropertyName": "Num_1" } + } + ] + } + } +} diff --git a/sdk/src/Core/Amazon.Util/AWSSDKUtils.cs b/sdk/src/Core/Amazon.Util/AWSSDKUtils.cs index 826a3ca44047..136553f77a6f 100644 --- a/sdk/src/Core/Amazon.Util/AWSSDKUtils.cs +++ b/sdk/src/Core/Amazon.Util/AWSSDKUtils.cs @@ -72,6 +72,7 @@ public static partial class AWSSDKUtils private const int DefaultMaxIdleTime = 50 * 1000; // 50 seconds private const int MaxIsSetMethodsCacheSize = 50; + private const long TicksPerSecond = 10_000_000; public static readonly DateTime EPOCH_START = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); @@ -600,7 +601,7 @@ public static string DetermineService(string url) /// Converted DateTime structure public static DateTime ConvertFromUnixEpochSeconds(int seconds) { - return new DateTime(seconds * 10000000L + EPOCH_START.Ticks, DateTimeKind.Utc); + return new DateTime(seconds * TicksPerSecond + EPOCH_START.Ticks, DateTimeKind.Utc); } /// @@ -610,7 +611,18 @@ public static DateTime ConvertFromUnixEpochSeconds(int seconds) /// Converted DateTime structure public static DateTime ConvertFromUnixLongEpochSeconds(long seconds) { - return new DateTime(seconds * 10000000L + EPOCH_START.Ticks, DateTimeKind.Utc); + return new DateTime(seconds * TicksPerSecond + EPOCH_START.Ticks, DateTimeKind.Utc); + } + + /// + /// Utility method for converting Unix epoch seconds to DateTime structure. + /// + /// The number of seconds since January 1, 1970. + /// Converted DateTime structure + public static DateTime ConvertFromUnixDoubleEpochSeconds(double seconds) + { + var ticksSinceEpoch = (long)(seconds * TicksPerSecond); + return new DateTime(ticksSinceEpoch + EPOCH_START.Ticks, DateTimeKind.Utc); } /// diff --git a/sdk/test/ProtocolTests/AWSSDK.ProtocolTests.NetFramework.csproj b/sdk/test/ProtocolTests/AWSSDK.ProtocolTests.NetFramework.csproj index bc103b18b1c4..2eacc9e0dd55 100644 --- a/sdk/test/ProtocolTests/AWSSDK.ProtocolTests.NetFramework.csproj +++ b/sdk/test/ProtocolTests/AWSSDK.ProtocolTests.NetFramework.csproj @@ -39,6 +39,7 @@ + diff --git a/sdk/test/ProtocolTests/AWSSDK.ProtocolTests.NetFramework.sln b/sdk/test/ProtocolTests/AWSSDK.ProtocolTests.NetFramework.sln index 42c421a877ae..1d491e0dcf36 100644 --- a/sdk/test/ProtocolTests/AWSSDK.ProtocolTests.NetFramework.sln +++ b/sdk/test/ProtocolTests/AWSSDK.ProtocolTests.NetFramework.sln @@ -31,6 +31,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AWSSDK.JsonProtocol.NetFram EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AWSSDK.S3.NetFramework", "..\..\src\Services\S3\AWSSDK.S3.NetFramework.csproj", "{6C0E771C-5B37-4781-B251-4D7FC14B4A98}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AWSSDK.RpcV2Protocol.NetFramework", "..\Services\RpcV2Protocol\AWSSDK.RpcV2Protocol.NetFramework.csproj", "{693BD7C1-E732-E013-2D87-1763030BC50D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AWSSDK.Extensions.CborProtocol.NetFramework", "..\..\..\extensions\src\AWSSDK.Extensions.CborProtocol\AWSSDK.Extensions.CborProtocol.NetFramework.csproj", "{97F1A3EB-F3F8-CD33-75A4-DB6465F32512}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -93,6 +97,14 @@ Global {6C0E771C-5B37-4781-B251-4D7FC14B4A98}.Debug|Any CPU.Build.0 = Debug|Any CPU {6C0E771C-5B37-4781-B251-4D7FC14B4A98}.Release|Any CPU.ActiveCfg = Release|Any CPU {6C0E771C-5B37-4781-B251-4D7FC14B4A98}.Release|Any CPU.Build.0 = Release|Any CPU + {693BD7C1-E732-E013-2D87-1763030BC50D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {693BD7C1-E732-E013-2D87-1763030BC50D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {693BD7C1-E732-E013-2D87-1763030BC50D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {693BD7C1-E732-E013-2D87-1763030BC50D}.Release|Any CPU.Build.0 = Release|Any CPU + {97F1A3EB-F3F8-CD33-75A4-DB6465F32512}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {97F1A3EB-F3F8-CD33-75A4-DB6465F32512}.Debug|Any CPU.Build.0 = Debug|Any CPU + {97F1A3EB-F3F8-CD33-75A4-DB6465F32512}.Release|Any CPU.ActiveCfg = Release|Any CPU + {97F1A3EB-F3F8-CD33-75A4-DB6465F32512}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/sdk/test/ProtocolTests/AWSSDK.ProtocolTests.NetStandard.csproj b/sdk/test/ProtocolTests/AWSSDK.ProtocolTests.NetStandard.csproj index e639058d534a..8c2f64fcfa9a 100644 --- a/sdk/test/ProtocolTests/AWSSDK.ProtocolTests.NetStandard.csproj +++ b/sdk/test/ProtocolTests/AWSSDK.ProtocolTests.NetStandard.csproj @@ -16,6 +16,7 @@ false false false + true true CS1591,CS1570,NU1701 @@ -39,6 +40,7 @@ + diff --git a/sdk/test/ProtocolTests/AWSSDK.ProtocolTests.NetStandard.sln b/sdk/test/ProtocolTests/AWSSDK.ProtocolTests.NetStandard.sln index 79f0a875cd7c..c5b7441b3461 100644 --- a/sdk/test/ProtocolTests/AWSSDK.ProtocolTests.NetStandard.sln +++ b/sdk/test/ProtocolTests/AWSSDK.ProtocolTests.NetStandard.sln @@ -31,6 +31,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AWSSDK.CommonTest.NetStanda EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AWSSDK.UnitTestUtilities.Netstandard", "..\UnitTests\Custom\AWSSDK.UnitTestUtilities.Netstandard.csproj", "{A267E3F2-38CC-4659-B9C9-1BBB3058C88B}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AWSSDK.RpcV2Protocol.NetStandard", "..\Services\RpcV2Protocol\AWSSDK.RpcV2Protocol.NetStandard.csproj", "{5416C5A8-2446-0BD3-C670-B15344172326}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AWSSDK.Extensions.CborProtocol.NetStandard", "..\..\..\extensions\src\AWSSDK.Extensions.CborProtocol\AWSSDK.Extensions.CborProtocol.NetStandard.csproj", "{81474FD0-7BA6-F9DD-3C62-C8D954A57425}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -93,6 +97,14 @@ Global {A267E3F2-38CC-4659-B9C9-1BBB3058C88B}.Debug|Any CPU.Build.0 = Debug|Any CPU {A267E3F2-38CC-4659-B9C9-1BBB3058C88B}.Release|Any CPU.ActiveCfg = Release|Any CPU {A267E3F2-38CC-4659-B9C9-1BBB3058C88B}.Release|Any CPU.Build.0 = Release|Any CPU + {5416C5A8-2446-0BD3-C670-B15344172326}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5416C5A8-2446-0BD3-C670-B15344172326}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5416C5A8-2446-0BD3-C670-B15344172326}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5416C5A8-2446-0BD3-C670-B15344172326}.Release|Any CPU.Build.0 = Release|Any CPU + {81474FD0-7BA6-F9DD-3C62-C8D954A57425}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {81474FD0-7BA6-F9DD-3C62-C8D954A57425}.Debug|Any CPU.Build.0 = Debug|Any CPU + {81474FD0-7BA6-F9DD-3C62-C8D954A57425}.Release|Any CPU.ActiveCfg = Release|Any CPU + {81474FD0-7BA6-F9DD-3C62-C8D954A57425}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/sdk/test/ProtocolTests/Custom/CborProtocolUtils.cs b/sdk/test/ProtocolTests/Custom/CborProtocolUtils.cs new file mode 100644 index 000000000000..17adafebbadb --- /dev/null +++ b/sdk/test/ProtocolTests/Custom/CborProtocolUtils.cs @@ -0,0 +1,181 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +using System; +using System.Collections.Generic; +using System.Formats.Cbor; +using System.Linq; +using Amazon.Runtime.Internal; +using Amazon.Util; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace AWSSDK.ProtocolTests.Utils +{ + internal static class CborProtocolUtils + { + public static void AssertBody(IRequest actualRequest, string expectedBody) + { + var expectedCbor = Convert.FromBase64String(expectedBody); + var expectedObj = CborToNativeObject(expectedCbor); + var actualObj = CborToNativeObject(actualRequest.Content); + + AssertObjectsEqual(expectedObj, actualObj); + } + + private static object CborToNativeObject(byte[] cborBytes) + { + var reader = new CborReader(cborBytes); + return ReadCborValue(reader); + } + + private static object ReadCborValue(CborReader reader) + { + switch (reader.PeekState()) + { + case CborReaderState.StartMap: + var map = new Dictionary(); + reader.ReadStartMap(); + while (reader.PeekState() != CborReaderState.EndMap) + { + var key = ReadCborValue(reader).ToString(); + var value = ReadCborValue(reader); + map[key] = value; + } + reader.ReadEndMap(); + return map; + + case CborReaderState.StartArray: + var list = new List(); + reader.ReadStartArray(); + while (reader.PeekState() != CborReaderState.EndArray) + { + list.Add(ReadCborValue(reader)); + } + reader.ReadEndArray(); + return list; + + case CborReaderState.TextString: + return reader.ReadTextString(); + + case CborReaderState.ByteString: + return reader.ReadByteString(); + + case CborReaderState.UnsignedInteger: + return reader.ReadUInt64(); + + case CborReaderState.NegativeInteger: + return reader.ReadInt64(); + + case CborReaderState.Boolean: + return reader.ReadBoolean(); + + case CborReaderState.Null: + reader.ReadNull(); + return null; + + case CborReaderState.DoublePrecisionFloat: + return reader.ReadDouble(); + + case CborReaderState.SinglePrecisionFloat: + case CborReaderState.HalfPrecisionFloat: + return (double)reader.ReadSingle(); + + case CborReaderState.Tag: + var tag = reader.ReadTag(); + if (tag == CborTag.UnixTimeSeconds) + { + var epochSeconds = Convert.ToDouble(ReadCborValue(reader)); + return AWSSDKUtils.ConvertFromUnixDoubleEpochSeconds(epochSeconds); + } + throw new NotSupportedException($"Unsupported CBOR tag: {tag}"); + + default: + throw new NotSupportedException($"Unsupported CBOR state: {reader.PeekState()}"); + } + } + + private static void AssertObjectsEqual(object expected, object actual) + { + if (expected == null || actual == null) + { + Assert.AreEqual(expected, actual); + return; + } + + var expectedType = expected.GetType(); + var actualType = actual.GetType(); + + Assert.AreEqual(expectedType, actualType); + + if (expectedType == typeof(byte[])) + { + var expectedBytes = (byte[])expected; + var actualBytes = (byte[])actual; + Assert.IsTrue(expectedBytes.SequenceEqual(actualBytes)); + } + else if (expectedType == typeof(Dictionary)) + { + var expectedDict = (Dictionary)expected; + var actualDict = (Dictionary)actual; + + Assert.AreEqual(expectedDict.Count, actualDict.Count); + + foreach (var key in expectedDict.Keys) + { + Assert.IsTrue(actualDict.ContainsKey(key)); + AssertObjectsEqual(expectedDict[key], actualDict[key]); + } + } + else if (expectedType == typeof(List)) + { + var expectedList = (List)expected; + var actualList = (List)actual; + + Assert.AreEqual(expectedList.Count, actualList.Count); + + for (int i = 0; i < expectedList.Count; i++) + { + AssertObjectsEqual(expectedList[i], actualList[i]); + } + } + else if (IsNumericType(expectedType)) + { + // Normalize numeric types by converting both to double for comparison + var expectedDouble = Convert.ToDouble(expected); + var actualDouble = Convert.ToDouble(actual); + Assert.AreEqual(expectedDouble, actualDouble); + } + else + { + Assert.AreEqual(expected, actual); + } + } + + private static bool IsNumericType(Type type) + { + return type == typeof(byte) + || type == typeof(sbyte) + || type == typeof(short) + || type == typeof(ushort) + || type == typeof(int) + || type == typeof(uint) + || type == typeof(long) + || type == typeof(ulong) + || type == typeof(float) + || type == typeof(double) + || type == typeof(decimal); + } + } +} From ecde7e63da260ee12764ddbe19c70ae3dd537360 Mon Sep 17 00:00:00 2001 From: Muhammad Othman Date: Fri, 27 Jun 2025 15:32:22 -0400 Subject: [PATCH 2/2] Generate CBOR Protocol Tests along with other models for v1.0.5931.0 and Smithy v1.58.0 --- .../CborProtocol.Tests/WriteDateTimeTests.cs | 2 +- .../6a90e4df-251e-45f8-808a-1a088cf0b25e.json | 10 + .../codegen/HttpProtocolTestGenerator.java | 6 +- .../Marshallers/CborExceptionUnmarshaller.cs | 238 ++++++ .../Marshallers/CborExceptionUnmarshaller.tt | 95 +++ .../Marshallers/CborResponseUnmarshaller.cs | 533 +++++++++++++ .../Marshallers/CborResponseUnmarshaller.tt | 245 ++++++ .../Marshallers/CborStructureUnmarshaller.cs | 266 +++++++ .../Marshallers/CborStructureUnmarshaller.tt | 103 +++ .../SourceFiles/EventStreamOutputGenerator.cs | 114 +-- .../SourceFiles/EventStreamOutputGenerator.tt | 10 + generator/ServiceClientGeneratorLib/Member.cs | 23 +- sdk/AWSSDK.NetFramework.sln | 10 + sdk/AWSSDK.NetStandard.sln | 10 + .../AWSSDK.ProtocolTests.NetFramework.csproj | 16 +- .../GreetingWithErrors.cs | 92 +-- .../GreetingWithErrors.cs | 30 +- .../GreetingWithErrors.cs | 140 ++-- .../HttpEmptyPrefixHeaders.cs | 119 +++ .../HttpEmptyPrefixHeaders.cs | 119 +++ .../NestedXmlMapWithXmlName.cs | 4 +- .../SimpleScalarProperties.cs | 4 +- .../EmptyInputOutput.cs | 76 ++ .../dotnet-protocol-test-codegen/Float16.cs | 42 ++ .../FractionalSeconds.cs | 42 ++ .../GreetingWithErrors.cs | 42 ++ .../NoInputOutput.cs | 74 ++ .../OptionalInputOutput.cs | 76 ++ .../RecursiveShapes.cs | 91 +++ .../RpcV2CborDenseMaps.cs | 176 +++++ .../RpcV2CborLists.cs | 213 ++++++ .../SimpleScalarProperties.cs | 224 ++++++ .../Model/HttpEmptyPrefixHeadersRequest.cs | 77 ++ .../Model/HttpEmptyPrefixHeadersResponse.cs | 76 ++ ...HttpEmptyPrefixHeadersRequestMarshaller.cs | 102 +++ ...pEmptyPrefixHeadersResponseUnmarshaller.cs | 118 +++ .../_bcl/AmazonRestJsonProtocolClient.cs | 41 + .../Generated/_bcl/IAmazonRestJsonProtocol.cs | 28 + .../AmazonRestJsonProtocolClient.cs | 33 + .../_netstandard/IAmazonRestJsonProtocol.cs | 18 + .../Model/HttpEmptyPrefixHeadersRequest.cs | 77 ++ .../Model/HttpEmptyPrefixHeadersResponse.cs | 76 ++ ...HttpEmptyPrefixHeadersRequestMarshaller.cs | 100 +++ ...pEmptyPrefixHeadersResponseUnmarshaller.cs | 116 +++ ...estedXmlMapWithXmlNameRequestMarshaller.cs | 2 +- .../_bcl/AmazonRestXmlProtocolClient.cs | 41 + .../Generated/_bcl/IAmazonRestXmlProtocol.cs | 28 + .../AmazonRestXmlProtocolClient.cs | 33 + .../_netstandard/IAmazonRestXmlProtocol.cs | 18 + ...SimpleScalarPropertiesRequestMarshaller.cs | 2 +- .../AWSSDK.RpcV2Protocol.NetFramework.csproj | 85 +++ .../AWSSDK.RpcV2Protocol.NetStandard.csproj | 95 +++ .../Generated/AmazonRpcV2ProtocolConfig.cs | 106 +++ ...AmazonRpcV2ProtocolDefaultConfiguration.cs | 126 ++++ .../Generated/AmazonRpcV2ProtocolException.cs | 105 +++ .../AmazonRpcV2ProtocolAuthResolver.cs | 79 ++ .../Internal/AmazonRpcV2ProtocolMetadata.cs | 55 ++ .../Model/AmazonRpcV2ProtocolRequest.cs | 30 + .../Generated/Model/ComplexErrorException.cs | 156 ++++ .../Generated/Model/ComplexNestedErrorData.cs | 55 ++ .../Model/EmptyInputOutputRequest.cs | 40 + .../Model/EmptyInputOutputResponse.cs | 39 + .../Generated/Model/Float16Request.cs | 35 +- .../Generated/Model/Float16Response.cs | 55 ++ .../Model/FractionalSecondsRequest.cs | 40 + .../Model/FractionalSecondsResponse.cs | 55 ++ .../Generated/Model/GreetingStruct.cs | 55 ++ .../Model/GreetingWithErrorsRequest.cs | 47 ++ .../Model/GreetingWithErrorsResponse.cs | 55 ++ .../ComplexErrorExceptionUnmarshaller.cs | 106 +++ .../ComplexNestedErrorDataUnmarshaller.cs | 83 +++ .../EmptyInputOutputRequestMarshaller.cs | 101 +++ .../EmptyInputOutputResponseUnmarshaller.cs | 97 +++ .../Float16RequestMarshaller.cs | 87 +++ .../Float16ResponseUnmarshaller.cs | 109 +++ .../FractionalSecondsRequestMarshaller.cs | 87 +++ .../FractionalSecondsResponseUnmarshaller.cs | 109 +++ .../GreetingStructMarshaller.cs | 66 ++ .../GreetingStructUnmarshaller.cs | 83 +++ .../GreetingWithErrorsRequestMarshaller.cs | 87 +++ .../GreetingWithErrorsResponseUnmarshaller.cs | 117 +++ .../InvalidGreetingExceptionUnmarshaller.cs | 94 +++ .../NoInputOutputRequestMarshaller.cs | 87 +++ .../NoInputOutputResponseUnmarshaller.cs | 97 +++ .../OptionalInputOutputRequestMarshaller.cs | 106 +++ ...OptionalInputOutputResponseUnmarshaller.cs | 109 +++ ...rsiveShapesInputOutputNested1Marshaller.cs | 76 ++ ...iveShapesInputOutputNested1Unmarshaller.cs | 89 +++ ...rsiveShapesInputOutputNested2Marshaller.cs | 76 ++ ...iveShapesInputOutputNested2Unmarshaller.cs | 89 +++ .../RecursiveShapesRequestMarshaller.cs | 111 +++ .../RecursiveShapesResponseUnmarshaller.cs | 109 +++ .../RpcV2CborDenseMapsRequestMarshaller.cs | 176 +++++ .../RpcV2CborDenseMapsResponseUnmarshaller.cs | 137 ++++ .../RpcV2CborListsRequestMarshaller.cs | 211 ++++++ .../RpcV2CborListsResponseUnmarshaller.cs | 167 +++++ ...SimpleScalarPropertiesRequestMarshaller.cs | 151 ++++ ...pleScalarPropertiesResponseUnmarshaller.cs | 163 ++++ .../StructureListMemberMarshaller.cs | 71 ++ .../StructureListMemberUnmarshaller.cs | 89 +++ .../ValidationExceptionFieldUnmarshaller.cs | 89 +++ .../ValidationExceptionUnmarshaller.cs | 100 +++ .../Model/InvalidGreetingException.cs | 120 +++ .../Generated/Model/NoInputOutputRequest.cs | 40 + .../Generated/Model/NoInputOutputResponse.cs | 39 + .../Model/OptionalInputOutputRequest.cs | 56 ++ .../Model/OptionalInputOutputResponse.cs | 55 ++ .../RecursiveShapesInputOutputNested1.cs | 71 ++ .../RecursiveShapesInputOutputNested2.cs | 71 ++ .../Generated/Model/RecursiveShapesRequest.cs | 56 ++ .../Model/RecursiveShapesResponse.cs | 55 ++ .../Model/RpcV2CborDenseMapsRequest.cs | 145 ++++ .../Model/RpcV2CborDenseMapsResponse.cs | 144 ++++ .../Generated/Model/RpcV2CborListsRequest.cs | 253 +++++++ .../Generated/Model/RpcV2CborListsResponse.cs | 249 +++++++ .../Model/SimpleScalarPropertiesRequest.cs | 200 +++++ .../Model/SimpleScalarPropertiesResponse.cs | 199 +++++ .../Generated/Model/StructureListMember.cs | 71 ++ .../Generated/Model/ValidationException.cs | 148 ++++ .../Model/ValidationExceptionField.cs | 80 ++ .../Generated/ServiceEnumerations.cs | 88 +++ .../_bcl/AmazonRpcV2ProtocolClient.cs | 703 ++++++++++++++++++ .../Generated/_bcl/IAmazonRpcV2Protocol.cs | 371 +++++++++ .../_netstandard/AmazonRpcV2ProtocolClient.cs | 601 +++++++++++++++ .../_netstandard/IAmazonRpcV2Protocol.cs | 273 +++++++ .../RpcV2Protocol/Properties/AssemblyInfo.cs | 45 ++ ...nitTests.RpcV2Protocol.NetFramework.csproj | 79 ++ 127 files changed, 13067 insertions(+), 218 deletions(-) create mode 100644 generator/.DevConfigs/6a90e4df-251e-45f8-808a-1a088cf0b25e.json create mode 100644 generator/ServiceClientGeneratorLib/Generators/Marshallers/CborExceptionUnmarshaller.cs create mode 100644 generator/ServiceClientGeneratorLib/Generators/Marshallers/CborExceptionUnmarshaller.tt create mode 100644 generator/ServiceClientGeneratorLib/Generators/Marshallers/CborResponseUnmarshaller.cs create mode 100644 generator/ServiceClientGeneratorLib/Generators/Marshallers/CborResponseUnmarshaller.tt create mode 100644 generator/ServiceClientGeneratorLib/Generators/Marshallers/CborStructureUnmarshaller.cs create mode 100644 generator/ServiceClientGeneratorLib/Generators/Marshallers/CborStructureUnmarshaller.tt create mode 100644 sdk/test/ProtocolTests/Generated/RestJsonProtocol/dotnet-protocol-test-codegen/HttpEmptyPrefixHeaders.cs create mode 100644 sdk/test/ProtocolTests/Generated/RestXmlProtocol/dotnet-protocol-test-codegen/HttpEmptyPrefixHeaders.cs create mode 100644 sdk/test/ProtocolTests/Generated/RpcV2Protocol/dotnet-protocol-test-codegen/EmptyInputOutput.cs create mode 100644 sdk/test/ProtocolTests/Generated/RpcV2Protocol/dotnet-protocol-test-codegen/Float16.cs create mode 100644 sdk/test/ProtocolTests/Generated/RpcV2Protocol/dotnet-protocol-test-codegen/FractionalSeconds.cs create mode 100644 sdk/test/ProtocolTests/Generated/RpcV2Protocol/dotnet-protocol-test-codegen/GreetingWithErrors.cs create mode 100644 sdk/test/ProtocolTests/Generated/RpcV2Protocol/dotnet-protocol-test-codegen/NoInputOutput.cs create mode 100644 sdk/test/ProtocolTests/Generated/RpcV2Protocol/dotnet-protocol-test-codegen/OptionalInputOutput.cs create mode 100644 sdk/test/ProtocolTests/Generated/RpcV2Protocol/dotnet-protocol-test-codegen/RecursiveShapes.cs create mode 100644 sdk/test/ProtocolTests/Generated/RpcV2Protocol/dotnet-protocol-test-codegen/RpcV2CborDenseMaps.cs create mode 100644 sdk/test/ProtocolTests/Generated/RpcV2Protocol/dotnet-protocol-test-codegen/RpcV2CborLists.cs create mode 100644 sdk/test/ProtocolTests/Generated/RpcV2Protocol/dotnet-protocol-test-codegen/SimpleScalarProperties.cs create mode 100644 sdk/test/Services/RestJsonProtocol/Generated/Model/HttpEmptyPrefixHeadersRequest.cs create mode 100644 sdk/test/Services/RestJsonProtocol/Generated/Model/HttpEmptyPrefixHeadersResponse.cs create mode 100644 sdk/test/Services/RestJsonProtocol/Generated/Model/Internal/MarshallTransformations/HttpEmptyPrefixHeadersRequestMarshaller.cs create mode 100644 sdk/test/Services/RestJsonProtocol/Generated/Model/Internal/MarshallTransformations/HttpEmptyPrefixHeadersResponseUnmarshaller.cs create mode 100644 sdk/test/Services/RestXmlProtocol/Generated/Model/HttpEmptyPrefixHeadersRequest.cs create mode 100644 sdk/test/Services/RestXmlProtocol/Generated/Model/HttpEmptyPrefixHeadersResponse.cs create mode 100644 sdk/test/Services/RestXmlProtocol/Generated/Model/Internal/MarshallTransformations/HttpEmptyPrefixHeadersRequestMarshaller.cs create mode 100644 sdk/test/Services/RestXmlProtocol/Generated/Model/Internal/MarshallTransformations/HttpEmptyPrefixHeadersResponseUnmarshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/AWSSDK.RpcV2Protocol.NetFramework.csproj create mode 100644 sdk/test/Services/RpcV2Protocol/AWSSDK.RpcV2Protocol.NetStandard.csproj create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/AmazonRpcV2ProtocolConfig.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/AmazonRpcV2ProtocolDefaultConfiguration.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/AmazonRpcV2ProtocolException.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Internal/AmazonRpcV2ProtocolAuthResolver.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Internal/AmazonRpcV2ProtocolMetadata.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/AmazonRpcV2ProtocolRequest.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/ComplexErrorException.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/ComplexNestedErrorData.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/EmptyInputOutputRequest.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/EmptyInputOutputResponse.cs rename extensions/src/AWSSDK.Extensions.CborProtocol/Internal/CborMarshallerContext.cs => sdk/test/Services/RpcV2Protocol/Generated/Model/Float16Request.cs (60%) create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Float16Response.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/FractionalSecondsRequest.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/FractionalSecondsResponse.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/GreetingStruct.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/GreetingWithErrorsRequest.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/GreetingWithErrorsResponse.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Internal/MarshallTransformations/ComplexErrorExceptionUnmarshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Internal/MarshallTransformations/ComplexNestedErrorDataUnmarshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Internal/MarshallTransformations/EmptyInputOutputRequestMarshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Internal/MarshallTransformations/EmptyInputOutputResponseUnmarshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Internal/MarshallTransformations/Float16RequestMarshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Internal/MarshallTransformations/Float16ResponseUnmarshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Internal/MarshallTransformations/FractionalSecondsRequestMarshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Internal/MarshallTransformations/FractionalSecondsResponseUnmarshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Internal/MarshallTransformations/GreetingStructMarshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Internal/MarshallTransformations/GreetingStructUnmarshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Internal/MarshallTransformations/GreetingWithErrorsRequestMarshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Internal/MarshallTransformations/GreetingWithErrorsResponseUnmarshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Internal/MarshallTransformations/InvalidGreetingExceptionUnmarshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Internal/MarshallTransformations/NoInputOutputRequestMarshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Internal/MarshallTransformations/NoInputOutputResponseUnmarshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Internal/MarshallTransformations/OptionalInputOutputRequestMarshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Internal/MarshallTransformations/OptionalInputOutputResponseUnmarshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Internal/MarshallTransformations/RecursiveShapesInputOutputNested1Marshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Internal/MarshallTransformations/RecursiveShapesInputOutputNested1Unmarshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Internal/MarshallTransformations/RecursiveShapesInputOutputNested2Marshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Internal/MarshallTransformations/RecursiveShapesInputOutputNested2Unmarshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Internal/MarshallTransformations/RecursiveShapesRequestMarshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Internal/MarshallTransformations/RecursiveShapesResponseUnmarshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Internal/MarshallTransformations/RpcV2CborDenseMapsRequestMarshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Internal/MarshallTransformations/RpcV2CborDenseMapsResponseUnmarshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Internal/MarshallTransformations/RpcV2CborListsRequestMarshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Internal/MarshallTransformations/RpcV2CborListsResponseUnmarshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Internal/MarshallTransformations/SimpleScalarPropertiesRequestMarshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Internal/MarshallTransformations/SimpleScalarPropertiesResponseUnmarshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Internal/MarshallTransformations/StructureListMemberMarshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Internal/MarshallTransformations/StructureListMemberUnmarshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Internal/MarshallTransformations/ValidationExceptionFieldUnmarshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/Internal/MarshallTransformations/ValidationExceptionUnmarshaller.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/InvalidGreetingException.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/NoInputOutputRequest.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/NoInputOutputResponse.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/OptionalInputOutputRequest.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/OptionalInputOutputResponse.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/RecursiveShapesInputOutputNested1.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/RecursiveShapesInputOutputNested2.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/RecursiveShapesRequest.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/RecursiveShapesResponse.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/RpcV2CborDenseMapsRequest.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/RpcV2CborDenseMapsResponse.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/RpcV2CborListsRequest.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/RpcV2CborListsResponse.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/SimpleScalarPropertiesRequest.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/SimpleScalarPropertiesResponse.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/StructureListMember.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/ValidationException.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/Model/ValidationExceptionField.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/ServiceEnumerations.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/_bcl/AmazonRpcV2ProtocolClient.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/_bcl/IAmazonRpcV2Protocol.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/_netstandard/AmazonRpcV2ProtocolClient.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Generated/_netstandard/IAmazonRpcV2Protocol.cs create mode 100644 sdk/test/Services/RpcV2Protocol/Properties/AssemblyInfo.cs create mode 100644 sdk/test/Services/RpcV2Protocol/UnitTests/AWSSDK.UnitTests.RpcV2Protocol.NetFramework.csproj diff --git a/extensions/test/CborProtocol.Tests/WriteDateTimeTests.cs b/extensions/test/CborProtocol.Tests/WriteDateTimeTests.cs index 56425f34162f..4df476f4849f 100644 --- a/extensions/test/CborProtocol.Tests/WriteDateTimeTests.cs +++ b/extensions/test/CborProtocol.Tests/WriteDateTimeTests.cs @@ -15,7 +15,7 @@ public class WriteDateTimeTests [InlineData("2025-06-19T20:15:28.468Z", 1750364128.468, CborReaderState.DoublePrecisionFloat, 10)] public void WriteDateTime_EncodesCorrectly(string isoDate, double expectedUnixEpoch, CborReaderState expectedState, int expectedTotalBytes) { - var dt = DateTime.Parse(isoDate).ToUniversalTime(); + var dt = DateTime.Parse(isoDate); var writer = new CborWriter(); writer.WriteDateTime(dt); diff --git a/generator/.DevConfigs/6a90e4df-251e-45f8-808a-1a088cf0b25e.json b/generator/.DevConfigs/6a90e4df-251e-45f8-808a-1a088cf0b25e.json new file mode 100644 index 000000000000..0dc87396474b --- /dev/null +++ b/generator/.DevConfigs/6a90e4df-251e-45f8-808a-1a088cf0b25e.json @@ -0,0 +1,10 @@ + +{ + "core": { + "changeLogMessages": [ + "Cbor protocol temp message" + ], + "type": "patch", + "updateMinimum": true + } +} \ No newline at end of file diff --git a/generator/ProtocolTestsGenerator/smithy-dotnet-codegen/src/main/java/software/amazon/smithy/dotnet/codegen/HttpProtocolTestGenerator.java b/generator/ProtocolTestsGenerator/smithy-dotnet-codegen/src/main/java/software/amazon/smithy/dotnet/codegen/HttpProtocolTestGenerator.java index 14a9049d064c..d9a879e88045 100644 --- a/generator/ProtocolTestsGenerator/smithy-dotnet-codegen/src/main/java/software/amazon/smithy/dotnet/codegen/HttpProtocolTestGenerator.java +++ b/generator/ProtocolTestsGenerator/smithy-dotnet-codegen/src/main/java/software/amazon/smithy/dotnet/codegen/HttpProtocolTestGenerator.java @@ -54,9 +54,9 @@ public HttpProtocolTestGenerator( this.context = context; String serviceNamespace = null; - if(service.getTrait(ServiceTrait.class).isPresent()) + if (service.getTrait(ServiceTrait.class).isPresent()) serviceNamespace = service.getTrait(ServiceTrait.class).get().getSdkId(); - else if(service.getTrait(TitleTrait.class).isPresent()) + else if (service.getTrait(TitleTrait.class).isPresent()) serviceNamespace = service.getTrait(TitleTrait.class).get().getValue().replace("Service", ""); this.serviceNamespace = serviceNamespace.replace(" ", ""); @@ -106,7 +106,7 @@ private void generateErrorResponseTests(OperationShape operation, OperationIndex for (StructureShape error : index.getErrors(operation, service)) { error.getTrait(HttpResponseTestsTrait.class).ifPresent(trait -> { for (HttpResponseTestCase httpResponseTestCase : trait.getTestCasesFor(AppliesTo.CLIENT)) { - if(!trait.getTestCasesFor(AppliesTo.CLIENT).getFirst().getProtocol().getName().toLowerCase().contains("cbor")) // Skip CBOR response tests until the unmarshallers are ready + if (!trait.getTestCasesFor(AppliesTo.CLIENT).getFirst().getProtocol().getName().toLowerCase().contains("cbor")) // Skip CBOR response tests until the unmarshallers are ready generateErrorResponseTest(operation, error, httpResponseTestCase); } }); diff --git a/generator/ServiceClientGeneratorLib/Generators/Marshallers/CborExceptionUnmarshaller.cs b/generator/ServiceClientGeneratorLib/Generators/Marshallers/CborExceptionUnmarshaller.cs new file mode 100644 index 000000000000..4b43859b25e2 --- /dev/null +++ b/generator/ServiceClientGeneratorLib/Generators/Marshallers/CborExceptionUnmarshaller.cs @@ -0,0 +1,238 @@ +// ------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version: 17.0.0.0 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +// ------------------------------------------------------------------------------ +namespace ServiceClientGenerator.Generators.Marshallers +{ + using System.Linq; + using System.Text; + using System.Collections.Generic; + using System; + + /// + /// Class to produce the template output + /// + + #line 1 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborExceptionUnmarshaller.tt" + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")] + public partial class CborExceptionUnmarshaller : BaseResponseUnmarshaller + { +#line hidden + /// + /// Create the template output + /// + public override string TransformText() + { + + #line 6 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborExceptionUnmarshaller.tt" + + AddLicenseHeader(); + + AddCommonUsingStatements(); + + + #line default + #line hidden + this.Write("using System.Text.Json;\r\nusing Amazon.Util;\r\n#pragma warning disable CS0612,CS061" + + "8\r\nnamespace "); + + #line 14 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborExceptionUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(this.Config.Namespace)); + + #line default + #line hidden + this.Write(".Model.Internal.MarshallTransformations\r\n{\r\n /// \r\n /// Response U" + + "nmarshaller for "); + + #line 17 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborExceptionUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(this.UnmarshallerBaseName)); + + #line default + #line hidden + this.Write(" Object\r\n /// \r\n public class "); + + #line 19 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborExceptionUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(this.UnmarshallerBaseName)); + + #line default + #line hidden + this.Write("Unmarshaller : IJsonErrorResponseUnmarshaller<"); + + #line 19 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborExceptionUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(this.UnmarshallerBaseName)); + + #line default + #line hidden + this.Write(@", JsonUnmarshallerContext> + { + /// + /// Unmarshaller the response from the service to the response class. + /// + /// + /// + /// + public "); + + #line 27 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborExceptionUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(this.UnmarshallerBaseName)); + + #line default + #line hidden + this.Write(@" Unmarshall(JsonUnmarshallerContext context, ref StreamingUtf8JsonReader reader) + { + return this.Unmarshall(context, new Amazon.Runtime.Internal.ErrorResponse(), ref reader); + } + + /// + /// Unmarshaller the response from the service to the response class. + /// + /// + /// + /// + /// + public "); + + #line 39 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborExceptionUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(this.UnmarshallerBaseName)); + + #line default + #line hidden + this.Write(@" Unmarshall(JsonUnmarshallerContext context, Amazon.Runtime.Internal.ErrorResponse errorResponse, ref StreamingUtf8JsonReader reader) + { + if (context.Stream.Length > 0) + { + context.Read(ref reader); + } + +"); + + #line 46 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborExceptionUnmarshaller.tt" + + if (this.Config.ServiceModel.IsAwsQueryCompatible) + { + GenerateAWSQueryCompatibleBlock(); + + + #line default + #line hidden + this.Write(" "); + + #line 51 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborExceptionUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(this.UnmarshallerBaseName)); + + #line default + #line hidden + this.Write(" unmarshalledObject = new "); + + #line 51 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborExceptionUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(this.UnmarshallerBaseName)); + + #line default + #line hidden + this.Write("(errorResponse.Message, errorResponse.InnerException,\r\n errorType," + + " errorCode, errorResponse.RequestId, errorResponse.StatusCode);\r\n"); + + #line 53 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborExceptionUnmarshaller.tt" + + } + else + { + + + #line default + #line hidden + this.Write(" "); + + #line 58 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborExceptionUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(this.UnmarshallerBaseName)); + + #line default + #line hidden + this.Write(" unmarshalledObject = new "); + + #line 58 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborExceptionUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(this.UnmarshallerBaseName)); + + #line default + #line hidden + this.Write("(errorResponse.Message, errorResponse.InnerException,\r\n errorRespo" + + "nse.Type, errorResponse.Code, errorResponse.RequestId, errorResponse.StatusCode)" + + ";\r\n"); + + #line 60 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborExceptionUnmarshaller.tt" + + } + + + #line default + #line hidden + this.Write(" \r\n int targetDepth = context.CurrentDepth;\r\n if (co" + + "ntext.Stream.Length > 0)\r\n {\r\n while (context.ReadAtDe" + + "pth(targetDepth, ref reader))\r\n {\r\n"); + + #line 69 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborExceptionUnmarshaller.tt" + + if(this.Structure != null) + { + foreach (var member in this.Structure.Members) + { + + + #line default + #line hidden + this.Write(" if (context.TestExpression(\""); + + #line 75 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborExceptionUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(member.MarshallName)); + + #line default + #line hidden + this.Write("\", targetDepth))\r\n {\r\n var unmarshaller" + + " = "); + + #line 77 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborExceptionUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(member.DetermineTypeUnmarshallerInstantiate())); + + #line default + #line hidden + this.Write(";\r\n unmarshalledObject."); + + #line 78 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborExceptionUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(member.PropertyName)); + + #line default + #line hidden + this.Write(" = unmarshaller.Unmarshall(context, ref reader);\r\n continu" + + "e;\r\n }\r\n"); + + #line 81 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborExceptionUnmarshaller.tt" + + } + } + + + #line default + #line hidden + this.Write(" }\r\n }\r\n \r\n return unmarshalledObje" + + "ct;\r\n }\r\n\r\n"); + + #line 91 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborExceptionUnmarshaller.tt" + + this.AddStructureSingletonMethod(); + + + #line default + #line hidden + this.Write(" }\r\n}"); + return this.GenerationEnvironment.ToString(); + } + } + + #line default + #line hidden +} diff --git a/generator/ServiceClientGeneratorLib/Generators/Marshallers/CborExceptionUnmarshaller.tt b/generator/ServiceClientGeneratorLib/Generators/Marshallers/CborExceptionUnmarshaller.tt new file mode 100644 index 000000000000..fc262f8ce25f --- /dev/null +++ b/generator/ServiceClientGeneratorLib/Generators/Marshallers/CborExceptionUnmarshaller.tt @@ -0,0 +1,95 @@ +<#@ template language="C#" inherits="BaseResponseUnmarshaller"#> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<# + AddLicenseHeader(); + + AddCommonUsingStatements(); +#> +using System.Text.Json; +using Amazon.Util; +#pragma warning disable CS0612,CS0618 +namespace <#=this.Config.Namespace #>.Model.Internal.MarshallTransformations +{ + /// + /// Response Unmarshaller for <#=this.UnmarshallerBaseName #> Object + /// + public class <#=this.UnmarshallerBaseName #>Unmarshaller : IJsonErrorResponseUnmarshaller<<#=this.UnmarshallerBaseName #>, JsonUnmarshallerContext> + { + /// + /// Unmarshaller the response from the service to the response class. + /// + /// + /// + /// + public <#=this.UnmarshallerBaseName #> Unmarshall(JsonUnmarshallerContext context, ref StreamingUtf8JsonReader reader) + { + return this.Unmarshall(context, new Amazon.Runtime.Internal.ErrorResponse(), ref reader); + } + + /// + /// Unmarshaller the response from the service to the response class. + /// + /// + /// + /// + /// + public <#=this.UnmarshallerBaseName #> Unmarshall(JsonUnmarshallerContext context, Amazon.Runtime.Internal.ErrorResponse errorResponse, ref StreamingUtf8JsonReader reader) + { + if (context.Stream.Length > 0) + { + context.Read(ref reader); + } + +<# + if (this.Config.ServiceModel.IsAwsQueryCompatible) + { + GenerateAWSQueryCompatibleBlock(); +#> + <#=this.UnmarshallerBaseName #> unmarshalledObject = new <#=this.UnmarshallerBaseName #>(errorResponse.Message, errorResponse.InnerException, + errorType, errorCode, errorResponse.RequestId, errorResponse.StatusCode); +<# + } + else + { +#> + <#=this.UnmarshallerBaseName #> unmarshalledObject = new <#=this.UnmarshallerBaseName #>(errorResponse.Message, errorResponse.InnerException, + errorResponse.Type, errorResponse.Code, errorResponse.RequestId, errorResponse.StatusCode); +<# + } +#> + + int targetDepth = context.CurrentDepth; + if (context.Stream.Length > 0) + { + while (context.ReadAtDepth(targetDepth, ref reader)) + { +<# + if(this.Structure != null) + { + foreach (var member in this.Structure.Members) + { +#> + if (context.TestExpression("<#=member.MarshallName#>", targetDepth)) + { + var unmarshaller = <#= member.DetermineTypeUnmarshallerInstantiate() #>; + unmarshalledObject.<#=member.PropertyName#> = unmarshaller.Unmarshall(context, ref reader); + continue; + } +<# + } + } +#> + } + } + + return unmarshalledObject; + } + +<# + this.AddStructureSingletonMethod(); +#> + } +} \ No newline at end of file diff --git a/generator/ServiceClientGeneratorLib/Generators/Marshallers/CborResponseUnmarshaller.cs b/generator/ServiceClientGeneratorLib/Generators/Marshallers/CborResponseUnmarshaller.cs new file mode 100644 index 000000000000..0b40a4eff320 --- /dev/null +++ b/generator/ServiceClientGeneratorLib/Generators/Marshallers/CborResponseUnmarshaller.cs @@ -0,0 +1,533 @@ +// ------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version: 17.0.0.0 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +// ------------------------------------------------------------------------------ +namespace ServiceClientGenerator.Generators.Marshallers +{ + using System.Linq; + using System.Text; + using System.Collections.Generic; + using System; + + /// + /// Class to produce the template output + /// + + #line 1 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")] + public partial class CborResponseUnmarshaller : BaseResponseUnmarshaller + { +#line hidden + /// + /// Create the template output + /// + public override string TransformText() + { + + #line 6 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + + AddLicenseHeader(); + + AddCommonUsingStatements(); + + + #line default + #line hidden + this.Write("using System.Text.Json;\r\nusing Amazon.Util;\r\n#pragma warning disable CS0612,CS061" + + "8\r\nnamespace "); + + #line 14 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(this.Config.Namespace)); + + #line default + #line hidden + this.Write(".Model.Internal.MarshallTransformations\r\n{\r\n /// \r\n /// Response U" + + "nmarshaller for "); + + #line 17 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(this.UnmarshallerBaseName)); + + #line default + #line hidden + this.Write(" operation\r\n /// \r\n public class "); + + #line 19 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(this.UnmarshallerBaseName)); + + #line default + #line hidden + this.Write(@"ResponseUnmarshaller : JsonResponseUnmarshaller + { + /// + /// Unmarshaller the response from the service to the response class. + /// + /// + /// + public override AmazonWebServiceResponse Unmarshall(JsonUnmarshallerContext context) + { + "); + + #line 28 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(this.UnmarshallerBaseName)); + + #line default + #line hidden + this.Write("Response response = new "); + + #line 28 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(this.Operation.Name)); + + #line default + #line hidden + this.Write("Response();\r\n"); + + #line 29 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + + var payload = this.Operation.ResponsePayloadMember; + var unmarshallPayload = payload != null && payload.IsStructure; + var payloadIsStream = payload != null && !unmarshallPayload; + bool isEventStreamOutput = this.Operation.IsEventStreamOutput; + if (this.Operation.ResponseHasBodyMembers || payload != null) + { + if (this.Operation.AllowEmptyResult) + { + throw new NotImplementedException("AllowEmptyResult is not implemented for JSON unmarshallers"); + } + if (isEventStreamOutput) + { + if(payload == null) + { + payload = this.Structure.Members.Where(m => m.ModelShape.IsEventStream).FirstOrDefault(); + //if payload is still null after we search for a member that is of eventStream then the operation is not modeled correctly + + if(payload == null) + throw new InvalidOperationException("An eventstream operation's response must have at least one member that is marked with the eventStream trait"); + } + + + #line default + #line hidden + this.Write(" response."); + + #line 51 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(payload.PropertyName)); + + #line default + #line hidden + this.Write(" = new "); + + #line 51 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(payload.Shape.Name)); + + #line default + #line hidden + this.Write("(context.Stream);\r\n"); + + #line 52 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + + } + else if (payloadIsStream) + { + if (payload.Shape.IsStreaming) + { + + + #line default + #line hidden + this.Write(" response."); + + #line 59 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(payload.PropertyName)); + + #line default + #line hidden + this.Write(" = context.Stream;\r\n"); + + #line 60 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + + } + else if (payload.ModelShape.IsString) + { + + + #line default + #line hidden + this.Write(" using (var sr = new StreamReader(context.Stream))\r\n {\r\n " + + " response."); + + #line 67 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(payload.PropertyName)); + + #line default + #line hidden + this.Write(" = sr.ReadToEnd();\r\n }\r\n"); + + #line 69 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + + } + else if (payload.ModelShape.IsMemoryStream) + { + + + #line default + #line hidden + this.Write(" var ms = new MemoryStream();\r\n Amazon.Util.AWSSDKUtils.Cop" + + "yStream(context.Stream, ms);\r\n ms.Seek(0, SeekOrigin.Begin);\r\n " + + " if (ms.Length > 0)\r\n response."); + + #line 78 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(payload.PropertyName)); + + #line default + #line hidden + this.Write(" = ms;\r\n"); + + #line 79 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + + } + else + { + // At this point, all valid configurations have been handled. Valid use of payload is defined: + // https://awslabs.github.io/smithy/1.0/spec/core/http-traits.html#httppayload-trait + throw new Exception( + $"{payload.PropertyName} can not be a Payload as Type {payload.Shape.Type} is not a valid target for the httpPayload trait. " + + "The httpPayload trait can be applied to structure members that target a string, blob, structure, union, document, set, map, or list."); + } + } + else if (unmarshallPayload) + { + + + #line default + #line hidden + this.Write(" StreamingUtf8JsonReader reader = new StreamingUtf8JsonReader(context." + + "Stream);\r\n var unmarshaller = "); + + #line 94 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(payload.DetermineTypeUnmarshallerInstantiate())); + + #line default + #line hidden + this.Write(";\r\n response."); + + #line 95 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(payload.PropertyName)); + + #line default + #line hidden + this.Write(" = unmarshaller.Unmarshall(context, ref reader);\r\n"); + + #line 96 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + + } + else if (this.IsWrapped) + { + + + #line default + #line hidden + this.Write(" StreamingUtf8JsonReader reader = new StreamingUtf8JsonReader(context." + + "Stream);\r\n\t\t\tresponse."); + + #line 102 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(this.WrappedResultMember)); + + #line default + #line hidden + this.Write(" = "); + + #line 102 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(this.Structure.Name)); + + #line default + #line hidden + this.Write("Unmarshaller.Instance.Unmarshall(context, ref reader);\r\n"); + + #line 103 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + + } + else + { + + + #line default + #line hidden + this.Write(@" StreamingUtf8JsonReader reader = new StreamingUtf8JsonReader(context.Stream); + context.Read(ref reader); + int targetDepth = context.CurrentDepth; + while (context.ReadAtDepth(targetDepth, ref reader)) + { +"); + + #line 113 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + + + foreach (var member in this.Operation.ResponseBodyMembers) + { + + + #line default + #line hidden + this.Write(" if (context.TestExpression(\""); + + #line 118 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(member.MarshallName)); + + #line default + #line hidden + this.Write("\", targetDepth))\r\n {\r\n var unmarshaller = "); + + #line 120 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(member.DetermineTypeUnmarshallerInstantiate())); + + #line default + #line hidden + this.Write(";\r\n response."); + + #line 121 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(member.PropertyName)); + + #line default + #line hidden + this.Write(" = unmarshaller.Unmarshall(context, ref reader);\r\n continue;\r\n" + + " }\r\n"); + + #line 124 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + + } + + + #line default + #line hidden + this.Write(" }\r\n"); + + #line 128 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + + } + } + UnmarshallHeaders(); + ProcessStatusCode(); + + + #line default + #line hidden + this.Write(@" + return response; + } + + /// + /// Unmarshaller error response to exception. + /// + /// + /// + /// + /// + public override AmazonServiceException UnmarshallException(JsonUnmarshallerContext context, Exception innerException, HttpStatusCode statusCode) + { + StreamingUtf8JsonReader reader = new StreamingUtf8JsonReader(context.Stream); + var errorResponse = JsonErrorResponseUnmarshaller.GetInstance().Unmarshall(context, ref reader); + errorResponse.InnerException = innerException; + errorResponse.StatusCode = statusCode; + + var responseBodyBytes = context.GetResponseBodyBytes(); + + using (var streamCopy = new MemoryStream(responseBodyBytes)) +"); + + #line 155 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + + if (this.Config.ServiceModel.IsAwsQueryCompatible) + { + + + #line default + #line hidden + + #line 159 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + // Create a copy of context with headers in the response + + + + #line default + #line hidden + this.Write(" using (var contextCopy = new JsonUnmarshallerContext(streamCopy, true" + + ", context.ResponseData))\r\n"); + + #line 163 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + + } + else + { + + + #line default + #line hidden + this.Write(" using (var contextCopy = new JsonUnmarshallerContext(streamCopy, fals" + + "e, context.ResponseData))\r\n"); + + #line 169 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + + // Create a new reader because the stream has been read already in the original context + } + + + #line default + #line hidden + this.Write(" {\r\n StreamingUtf8JsonReader readerCopy = new Streaming" + + "Utf8JsonReader(streamCopy);\r\n"); + + #line 175 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + + foreach (var exception in this.Operation.Exceptions) + { + + + #line default + #line hidden + this.Write(" if (errorResponse.Code != null && errorResponse.Code.Equals(\""); + + #line 179 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(exception.Code)); + + #line default + #line hidden + this.Write("\"))\r\n {\r\n return "); + + #line 181 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(exception.Name)); + + #line default + #line hidden + this.Write("Unmarshaller.Instance.Unmarshall(contextCopy, errorResponse, ref readerCopy);\r\n " + + " }\r\n"); + + #line 183 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + + } + + + #line default + #line hidden + this.Write(" }\r\n"); + + #line 187 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + + if (this.Config.ServiceModel.IsAwsQueryCompatible) + { + GenerateAWSQueryCompatibleBlock(); + + + #line default + #line hidden + this.Write(" return new "); + + #line 192 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(this.BaseException)); + + #line default + #line hidden + this.Write("(errorResponse.Message, errorResponse.InnerException, errorType, errorCode, error" + + "Response.RequestId, errorResponse.StatusCode);\r\n"); + + #line 193 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + + } + else + { + + + #line default + #line hidden + this.Write(" return new "); + + #line 198 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(this.BaseException)); + + #line default + #line hidden + this.Write("(errorResponse.Message, errorResponse.InnerException, errorResponse.Type, errorRe" + + "sponse.Code, errorResponse.RequestId, errorResponse.StatusCode);\r\n"); + + #line 199 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + + } + + + #line default + #line hidden + this.Write(" }\r\n\r\n"); + + #line 204 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + + if (payload != null && payload.Shape.IsStreaming) + { + + + #line default + #line hidden + this.Write(@" /// + /// Overriden to return true indicating the response contains streaming data. + /// + public override bool HasStreamingProperty + { + get + { + return true; + } + } + +"); + + #line 219 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + + } + this.AddResponseSingletonMethod(); + + + #line default + #line hidden + + #line 223 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + + if(isEventStreamOutput) + { + + + #line default + #line hidden + this.Write(@" /// + /// Return false for reading the entire response + /// + /// + /// + /// + protected override bool ShouldReadEntireResponse(IWebResponseData response, bool readEntireResponse) + { + return false; + } + /// + /// Specifies that the response should be streamed + /// + public override bool HasStreamingProperty => true; +"); + + #line 241 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborResponseUnmarshaller.tt" + + } + + + #line default + #line hidden + this.Write(" }\r\n}"); + return this.GenerationEnvironment.ToString(); + } + } + + #line default + #line hidden +} diff --git a/generator/ServiceClientGeneratorLib/Generators/Marshallers/CborResponseUnmarshaller.tt b/generator/ServiceClientGeneratorLib/Generators/Marshallers/CborResponseUnmarshaller.tt new file mode 100644 index 000000000000..0b6fa34d8f41 --- /dev/null +++ b/generator/ServiceClientGeneratorLib/Generators/Marshallers/CborResponseUnmarshaller.tt @@ -0,0 +1,245 @@ +<#@ template language="C#" inherits="BaseResponseUnmarshaller"#> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<# + AddLicenseHeader(); + + AddCommonUsingStatements(); +#> +using System.Text.Json; +using Amazon.Util; +#pragma warning disable CS0612,CS0618 +namespace <#=this.Config.Namespace #>.Model.Internal.MarshallTransformations +{ + /// + /// Response Unmarshaller for <#=this.UnmarshallerBaseName #> operation + /// + public class <#=this.UnmarshallerBaseName #>ResponseUnmarshaller : JsonResponseUnmarshaller + { + /// + /// Unmarshaller the response from the service to the response class. + /// + /// + /// + public override AmazonWebServiceResponse Unmarshall(JsonUnmarshallerContext context) + { + <#=this.UnmarshallerBaseName #>Response response = new <#=this.Operation.Name #>Response(); +<# + var payload = this.Operation.ResponsePayloadMember; + var unmarshallPayload = payload != null && payload.IsStructure; + var payloadIsStream = payload != null && !unmarshallPayload; + bool isEventStreamOutput = this.Operation.IsEventStreamOutput; + if (this.Operation.ResponseHasBodyMembers || payload != null) + { + if (this.Operation.AllowEmptyResult) + { + throw new NotImplementedException("AllowEmptyResult is not implemented for JSON unmarshallers"); + } + if (isEventStreamOutput) + { + if(payload == null) + { + payload = this.Structure.Members.Where(m => m.ModelShape.IsEventStream).FirstOrDefault(); + //if payload is still null after we search for a member that is of eventStream then the operation is not modeled correctly + + if(payload == null) + throw new InvalidOperationException("An eventstream operation's response must have at least one member that is marked with the eventStream trait"); + } +#> + response.<#=payload.PropertyName#> = new <#=payload.Shape.Name#>(context.Stream); +<# + } + else if (payloadIsStream) + { + if (payload.Shape.IsStreaming) + { +#> + response.<#=payload.PropertyName#> = context.Stream; +<# + } + else if (payload.ModelShape.IsString) + { +#> + using (var sr = new StreamReader(context.Stream)) + { + response.<#=payload.PropertyName#> = sr.ReadToEnd(); + } +<# + } + else if (payload.ModelShape.IsMemoryStream) + { +#> + var ms = new MemoryStream(); + Amazon.Util.AWSSDKUtils.CopyStream(context.Stream, ms); + ms.Seek(0, SeekOrigin.Begin); + if (ms.Length > 0) + response.<#=payload.PropertyName#> = ms; +<# + } + else + { + // At this point, all valid configurations have been handled. Valid use of payload is defined: + // https://awslabs.github.io/smithy/1.0/spec/core/http-traits.html#httppayload-trait + throw new Exception( + $"{payload.PropertyName} can not be a Payload as Type {payload.Shape.Type} is not a valid target for the httpPayload trait. " + + "The httpPayload trait can be applied to structure members that target a string, blob, structure, union, document, set, map, or list."); + } + } + else if (unmarshallPayload) + { +#> + StreamingUtf8JsonReader reader = new StreamingUtf8JsonReader(context.Stream); + var unmarshaller = <#= payload.DetermineTypeUnmarshallerInstantiate() #>; + response.<#=payload.PropertyName#> = unmarshaller.Unmarshall(context, ref reader); +<# + } + else if (this.IsWrapped) + { +#> + StreamingUtf8JsonReader reader = new StreamingUtf8JsonReader(context.Stream); + response.<#=this.WrappedResultMember#> = <#=this.Structure.Name#>Unmarshaller.Instance.Unmarshall(context, ref reader); +<# + } + else + { +#> + StreamingUtf8JsonReader reader = new StreamingUtf8JsonReader(context.Stream); + context.Read(ref reader); + int targetDepth = context.CurrentDepth; + while (context.ReadAtDepth(targetDepth, ref reader)) + { +<# + + foreach (var member in this.Operation.ResponseBodyMembers) + { +#> + if (context.TestExpression("<#=member.MarshallName#>", targetDepth)) + { + var unmarshaller = <#= member.DetermineTypeUnmarshallerInstantiate() #>; + response.<#=member.PropertyName#> = unmarshaller.Unmarshall(context, ref reader); + continue; + } +<# + } +#> + } +<# + } + } + UnmarshallHeaders(); + ProcessStatusCode(); +#> + + return response; + } + + /// + /// Unmarshaller error response to exception. + /// + /// + /// + /// + /// + public override AmazonServiceException UnmarshallException(JsonUnmarshallerContext context, Exception innerException, HttpStatusCode statusCode) + { + StreamingUtf8JsonReader reader = new StreamingUtf8JsonReader(context.Stream); + var errorResponse = JsonErrorResponseUnmarshaller.GetInstance().Unmarshall(context, ref reader); + errorResponse.InnerException = innerException; + errorResponse.StatusCode = statusCode; + + var responseBodyBytes = context.GetResponseBodyBytes(); + + using (var streamCopy = new MemoryStream(responseBodyBytes)) +<# + if (this.Config.ServiceModel.IsAwsQueryCompatible) + { +#> +<# // Create a copy of context with headers in the response + +#> + using (var contextCopy = new JsonUnmarshallerContext(streamCopy, true, context.ResponseData)) +<# + } + else + { +#> + using (var contextCopy = new JsonUnmarshallerContext(streamCopy, false, context.ResponseData)) +<# + // Create a new reader because the stream has been read already in the original context + } +#> + { + StreamingUtf8JsonReader readerCopy = new StreamingUtf8JsonReader(streamCopy); +<# + foreach (var exception in this.Operation.Exceptions) + { +#> + if (errorResponse.Code != null && errorResponse.Code.Equals("<#=exception.Code #>")) + { + return <#=exception.Name#>Unmarshaller.Instance.Unmarshall(contextCopy, errorResponse, ref readerCopy); + } +<# + } +#> + } +<# + if (this.Config.ServiceModel.IsAwsQueryCompatible) + { + GenerateAWSQueryCompatibleBlock(); +#> + return new <#=this.BaseException#>(errorResponse.Message, errorResponse.InnerException, errorType, errorCode, errorResponse.RequestId, errorResponse.StatusCode); +<# + } + else + { +#> + return new <#=this.BaseException#>(errorResponse.Message, errorResponse.InnerException, errorResponse.Type, errorResponse.Code, errorResponse.RequestId, errorResponse.StatusCode); +<# + } +#> + } + +<# + if (payload != null && payload.Shape.IsStreaming) + { +#> + /// + /// Overriden to return true indicating the response contains streaming data. + /// + public override bool HasStreamingProperty + { + get + { + return true; + } + } + +<# + } + this.AddResponseSingletonMethod(); +#> +<# + if(isEventStreamOutput) + { +#> + /// + /// Return false for reading the entire response + /// + /// + /// + /// + protected override bool ShouldReadEntireResponse(IWebResponseData response, bool readEntireResponse) + { + return false; + } + /// + /// Specifies that the response should be streamed + /// + public override bool HasStreamingProperty => true; +<# + } +#> + } +} \ No newline at end of file diff --git a/generator/ServiceClientGeneratorLib/Generators/Marshallers/CborStructureUnmarshaller.cs b/generator/ServiceClientGeneratorLib/Generators/Marshallers/CborStructureUnmarshaller.cs new file mode 100644 index 000000000000..e88fe2577d0c --- /dev/null +++ b/generator/ServiceClientGeneratorLib/Generators/Marshallers/CborStructureUnmarshaller.cs @@ -0,0 +1,266 @@ +// ------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version: 17.0.0.0 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +// ------------------------------------------------------------------------------ +namespace ServiceClientGenerator.Generators.Marshallers +{ + using System.Linq; + using System.Text; + using System.Collections.Generic; + using System; + + /// + /// Class to produce the template output + /// + + #line 1 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborStructureUnmarshaller.tt" + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")] + public partial class CborStructureUnmarshaller : BaseResponseUnmarshaller + { +#line hidden + /// + /// Create the template output + /// + public override string TransformText() + { + + #line 6 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborStructureUnmarshaller.tt" + + AddLicenseHeader(); + + AddCommonUsingStatements(); + + + #line default + #line hidden + this.Write("using System.Text.Json;\r\n#pragma warning disable CS0612,CS0618\r\nnamespace "); + + #line 13 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborStructureUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(this.Config.Namespace)); + + #line default + #line hidden + this.Write(".Model.Internal.MarshallTransformations\r\n{\r\n /// \r\n /// Response U" + + "nmarshaller for "); + + #line 16 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborStructureUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(this.UnmarshallerBaseName)); + + #line default + #line hidden + this.Write(" Object\r\n /// \r\n public class "); + + #line 18 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborStructureUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(this.UnmarshallerBaseName)); + + #line default + #line hidden + this.Write("Unmarshaller : IJsonUnmarshaller<"); + + #line 18 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborStructureUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(this.UnmarshallerBaseName)); + + #line default + #line hidden + this.Write(@", JsonUnmarshallerContext> + { + /// + /// Unmarshaller the response from the service to the response class. + /// + /// + /// + /// The unmarshalled object + public "); + + #line 26 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborStructureUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(this.UnmarshallerBaseName)); + + #line default + #line hidden + this.Write(" Unmarshall(JsonUnmarshallerContext context, ref StreamingUtf8JsonReader reader)\r" + + "\n {\r\n "); + + #line 28 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborStructureUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(this.UnmarshallerBaseName)); + + #line default + #line hidden + this.Write(" unmarshalledObject = new "); + + #line 28 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborStructureUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(this.UnmarshallerBaseName)); + + #line default + #line hidden + this.Write("();\r\n if (context.IsEmptyResponse)\r\n return null;\r\n"); + + #line 31 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborStructureUnmarshaller.tt" + + //HasImplicitEventPayloadMembers means that the structure does not have a member with the EventPayload trait + if(this.Structure != null && this.Structure.IsEvent && !this.Structure.HasImplicitEventPayloadMembers()) + { + Member eventPayloadMember = this.Structure.GetExplicitEventPayloadMember(); + if(eventPayloadMember.ModelShape.IsString) + { + + + #line default + #line hidden + this.Write(" using (var sr = new StreamReader(context.Stream))\r\n {\r\n " + + " unmarshalledObject."); + + #line 41 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborStructureUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(eventPayloadMember.PropertyName)); + + #line default + #line hidden + this.Write(" = sr.ReadToEnd();\r\n }\r\n"); + + #line 43 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborStructureUnmarshaller.tt" + + } + + + #line default + #line hidden + + #line 46 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborStructureUnmarshaller.tt" + + else + { + + + #line default + #line hidden + this.Write(" unmarshalledObject."); + + #line 50 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborStructureUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(eventPayloadMember.PropertyName)); + + #line default + #line hidden + this.Write(" = context.Stream as MemoryStream;\r\n"); + + #line 51 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborStructureUnmarshaller.tt" + + } + + + #line default + #line hidden + + #line 54 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborStructureUnmarshaller.tt" + + } + + + #line default + #line hidden + + #line 57 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborStructureUnmarshaller.tt" + + if(this.Structure != null && (this.Structure.HasImplicitEventPayloadMembers() || !this.Structure.IsEvent)) + { + + + #line default + #line hidden + this.Write(@" context.Read(ref reader); + if (context.CurrentTokenType == JsonTokenType.Null) + return null; + + int targetDepth = context.CurrentDepth; + while (context.ReadAtDepth(targetDepth, ref reader)) + { +"); + + #line 68 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborStructureUnmarshaller.tt" + + } + + + #line default + #line hidden + + #line 71 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborStructureUnmarshaller.tt" + + if(this.Structure != null && (!this.Structure.IsEvent || this.Structure.HasImplicitEventPayloadMembers())) + { + foreach (var member in this.Structure.Members) + { + + + #line default + #line hidden + this.Write(" if (context.TestExpression(\""); + + #line 77 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborStructureUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(member.MarshallName)); + + #line default + #line hidden + this.Write("\", targetDepth))\r\n {\r\n var unmarshaller = "); + + #line 79 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborStructureUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(member.DetermineTypeUnmarshallerInstantiate())); + + #line default + #line hidden + this.Write(";\r\n unmarshalledObject."); + + #line 80 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborStructureUnmarshaller.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(member.PropertyName)); + + #line default + #line hidden + this.Write(" = unmarshaller.Unmarshall(context, ref reader);\r\n continue;\r\n" + + " }\r\n"); + + #line 83 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborStructureUnmarshaller.tt" + + } + } + + + #line default + #line hidden + + #line 87 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborStructureUnmarshaller.tt" + + if(this.Structure != null && (!this.Structure.IsEvent || this.Structure.HasImplicitEventPayloadMembers())) + { + + + #line default + #line hidden + this.Write(" }\r\n"); + + #line 92 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborStructureUnmarshaller.tt" + + } + + + #line default + #line hidden + this.Write(" return unmarshalledObject;\r\n }\r\n\r\n\r\n"); + + #line 99 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\Marshallers\CborStructureUnmarshaller.tt" + + this.AddStructureSingletonMethod(); + + + #line default + #line hidden + this.Write(" }\r\n}"); + return this.GenerationEnvironment.ToString(); + } + } + + #line default + #line hidden +} diff --git a/generator/ServiceClientGeneratorLib/Generators/Marshallers/CborStructureUnmarshaller.tt b/generator/ServiceClientGeneratorLib/Generators/Marshallers/CborStructureUnmarshaller.tt new file mode 100644 index 000000000000..f46be03f43a3 --- /dev/null +++ b/generator/ServiceClientGeneratorLib/Generators/Marshallers/CborStructureUnmarshaller.tt @@ -0,0 +1,103 @@ +<#@ template language="C#" inherits="BaseResponseUnmarshaller"#> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<# + AddLicenseHeader(); + + AddCommonUsingStatements(); +#> +using System.Text.Json; +#pragma warning disable CS0612,CS0618 +namespace <#=this.Config.Namespace #>.Model.Internal.MarshallTransformations +{ + /// + /// Response Unmarshaller for <#=this.UnmarshallerBaseName #> Object + /// + public class <#=this.UnmarshallerBaseName #>Unmarshaller : IJsonUnmarshaller<<#=this.UnmarshallerBaseName #>, JsonUnmarshallerContext> + { + /// + /// Unmarshaller the response from the service to the response class. + /// + /// + /// + /// The unmarshalled object + public <#=this.UnmarshallerBaseName #> Unmarshall(JsonUnmarshallerContext context, ref StreamingUtf8JsonReader reader) + { + <#=this.UnmarshallerBaseName #> unmarshalledObject = new <#=this.UnmarshallerBaseName #>(); + if (context.IsEmptyResponse) + return null; +<# + //HasImplicitEventPayloadMembers means that the structure does not have a member with the EventPayload trait + if(this.Structure != null && this.Structure.IsEvent && !this.Structure.HasImplicitEventPayloadMembers()) + { + Member eventPayloadMember = this.Structure.GetExplicitEventPayloadMember(); + if(eventPayloadMember.ModelShape.IsString) + { +#> + using (var sr = new StreamReader(context.Stream)) + { + unmarshalledObject.<#=eventPayloadMember.PropertyName#> = sr.ReadToEnd(); + } +<# + } +#> +<# + else + { +#> + unmarshalledObject.<#=eventPayloadMember.PropertyName#> = context.Stream as MemoryStream; +<# + } +#> +<# + } +#> +<# + if(this.Structure != null && (this.Structure.HasImplicitEventPayloadMembers() || !this.Structure.IsEvent)) + { +#> + context.Read(ref reader); + if (context.CurrentTokenType == JsonTokenType.Null) + return null; + + int targetDepth = context.CurrentDepth; + while (context.ReadAtDepth(targetDepth, ref reader)) + { +<# + } +#> +<# + if(this.Structure != null && (!this.Structure.IsEvent || this.Structure.HasImplicitEventPayloadMembers())) + { + foreach (var member in this.Structure.Members) + { +#> + if (context.TestExpression("<#=member.MarshallName#>", targetDepth)) + { + var unmarshaller = <#= member.DetermineTypeUnmarshallerInstantiate() #>; + unmarshalledObject.<#=member.PropertyName#> = unmarshaller.Unmarshall(context, ref reader); + continue; + } +<# + } + } +#> +<# + if(this.Structure != null && (!this.Structure.IsEvent || this.Structure.HasImplicitEventPayloadMembers())) + { +#> + } +<# + } +#> + return unmarshalledObject; + } + + +<# + this.AddStructureSingletonMethod(); +#> + } +} \ No newline at end of file diff --git a/generator/ServiceClientGeneratorLib/Generators/SourceFiles/EventStreamOutputGenerator.cs b/generator/ServiceClientGeneratorLib/Generators/SourceFiles/EventStreamOutputGenerator.cs index 33c89b81345f..0d38dbc15d72 100644 --- a/generator/ServiceClientGeneratorLib/Generators/SourceFiles/EventStreamOutputGenerator.cs +++ b/generator/ServiceClientGeneratorLib/Generators/SourceFiles/EventStreamOutputGenerator.cs @@ -18,7 +18,7 @@ namespace ServiceClientGenerator.Generators.SourceFiles /// Class to produce the template output /// - #line 1 "C:\codebase\v4\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\SourceFiles\EventStreamOutputGenerator.tt" + #line 1 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\SourceFiles\EventStreamOutputGenerator.tt" [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")] public partial class EventStreamOutputGenerator : StructureGenerator { @@ -29,7 +29,7 @@ public partial class EventStreamOutputGenerator : StructureGenerator public override string TransformText() { - #line 6 "C:\codebase\v4\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\SourceFiles\EventStreamOutputGenerator.tt" + #line 6 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\SourceFiles\EventStreamOutputGenerator.tt" bool isRequest = this.Operation.RequestStructure.Members.Any(x => x.ModelShape.MarshallName == this.Structure.Name); bool isResponse = this.Operation.ResponseStructure.Members.Any(x => x.ModelShape.MarshallName == this.Structure.Name); @@ -40,7 +40,7 @@ public override string TransformText() this.Write(" [System.Diagnostics.CodeAnalysis.SuppressMessage(\"Naming\", \"CA1710:Identifier" + "s should have correct suffix\", Justification = \""); - #line 10 "C:\codebase\v4\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\SourceFiles\EventStreamOutputGenerator.tt" + #line 10 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\SourceFiles\EventStreamOutputGenerator.tt" this.Write(this.ToStringHelper.ToStringWithCulture(this.Structure.Name)); #line default @@ -49,14 +49,14 @@ public override string TransformText() [System.Diagnostics.CodeAnalysis.SuppressMessage(""Microsoft.Design"", ""CA1063"", Justification = ""IDisposable is a transient interface from IEventOutputStream. Users need to be able to call Dispose."")] public sealed class "); - #line 12 "C:\codebase\v4\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\SourceFiles\EventStreamOutputGenerator.tt" + #line 12 "C:\repos\aws-sdk-net-v4\generator\ServiceClientGeneratorLib\Generators\SourceFiles\EventStreamOutputGenerator.tt" this.Write(this.ToStringHelper.ToStringWithCulture(this.Structure.Name)); #line default #line hidden this.Write(" : EnumerableEventOutputStream