From 8a87cafb9ecb225e4f9e2bf61b6cc06ac7f4849f Mon Sep 17 00:00:00 2001 From: Malhar Khimsaria <96malhar@gmail.com> Date: Mon, 29 Apr 2024 18:31:39 -0700 Subject: [PATCH 01/35] chore: Update release changelog --- RELEASE.CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/RELEASE.CHANGELOG.md b/RELEASE.CHANGELOG.md index bc96809b6..7743ebea5 100644 --- a/RELEASE.CHANGELOG.md +++ b/RELEASE.CHANGELOG.md @@ -1,3 +1,13 @@ +### Release 2024-04-25 +* **Amazon.Lambda.Annotations (1.3.1)** + * Update User-Agent string +* **Amazon.Lambda.TestTool (0.15.2)** + * Update User-Agent string +* **AWSLambdaPSCore PowerShell Module (4.0.1.0)** + * Update User-Agent string +* **Amazon.Lambda.Serialization.SystemTextJson (2.4.3)** + * Pull Request [#1736](https://github.com/aws/aws-lambda-dotnet/pull/1736) Update ByteArrayConverter to support base64 deserialization of byte[]. Thanks [brendonparker](https://github.com/brendonparker) + ### Release 2024-04-11 * **Amazon.Lambda.Templates (7.1.1)** * Update templates to use Amazon.Lambda.Annotations v1.3.0 From 9156ebd0f0e73dc81b4e94c11c611c438ddeafaa Mon Sep 17 00:00:00 2001 From: Phil Asmar Date: Fri, 26 Apr 2024 16:03:39 -0400 Subject: [PATCH 02/35] fix: Fixed failing unit test due to unsupported operation in latest .NET patches --- .../AspNetCoreAPIExample/LocalEntryPoint.cs | 35 ++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/Tools/LambdaTestTool/tests/LambdaFunctions/AspNetCoreAPIExample/LocalEntryPoint.cs b/Tools/LambdaTestTool/tests/LambdaFunctions/AspNetCoreAPIExample/LocalEntryPoint.cs index dd8c63772..6612690e0 100644 --- a/Tools/LambdaTestTool/tests/LambdaFunctions/AspNetCoreAPIExample/LocalEntryPoint.cs +++ b/Tools/LambdaTestTool/tests/LambdaFunctions/AspNetCoreAPIExample/LocalEntryPoint.cs @@ -3,6 +3,8 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; namespace AspNetCoreAPIExample @@ -14,14 +16,39 @@ public class LocalEntryPoint { public static void Main(string[] args) { - CreateHostBuilder(args).Build().Run(); + CreateHostBuilder(args).Run(); } - public static WebApplicationBuilder CreateHostBuilder(string[] args) + public static WebApplication CreateHostBuilder(string[] args) { var builder = WebApplication.CreateBuilder(args); - builder.WebHost.UseStartup(); - return builder; + + builder.Services.AddScoped(); + builder.Services.AddControllers(); + + var app = builder.Build(); + + if (app.Environment.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + + app.UseHttpsRedirection(); + + app.UseRouting(); + + app.UseAuthorization(); + + app.UseEndpoints(endpoints => + { + endpoints.MapControllers(); + endpoints.MapGet("/", async context => + { + await context.Response.WriteAsync("Welcome to running ASP.NET Core on AWS Lambda"); + }); + }); + + return app; } } } From 3b5a47c6d19f0f47670112c4cffcf5eb34d0f4ee Mon Sep 17 00:00:00 2001 From: Phil Asmar Date: Thu, 2 May 2024 12:30:29 -0400 Subject: [PATCH 03/35] feat: onboard the repo to the testing infra --- .github/workflows/aws-ci.yml | 47 ++++++++++++++++++++++++++++++++++++ buildtools/build.proj | 8 +++--- buildtools/ci.buildspec.yml | 16 ++++++++++++ 3 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/aws-ci.yml create mode 100644 buildtools/ci.buildspec.yml diff --git a/.github/workflows/aws-ci.yml b/.github/workflows/aws-ci.yml new file mode 100644 index 000000000..c3fad6dcf --- /dev/null +++ b/.github/workflows/aws-ci.yml @@ -0,0 +1,47 @@ + +name: AWS CI + +on: + workflow_dispatch: + pull_request: + branches: + - main + - dev + - 'feature/**' + +permissions: + id-token: write + +jobs: + run-ci: + runs-on: ubuntu-latest + steps: + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 #v4 + with: + role-to-assume: ${{ secrets.CI_MAIN_TESTING_ACCOUNT_ROLE_ARN }} + role-duration-seconds: 7200 + aws-region: us-west-2 + - name: Invoke Load Balancer Lambda + id: lambda + shell: pwsh + run: | + aws lambda invoke response.json --function-name "${{ secrets.CI_TESTING_LOAD_BALANCER_LAMBDA_NAME }}" --cli-binary-format raw-in-base64-out --payload '{"Roles": "${{ secrets.CI_TEST_RUNNER_ACCOUNT_ROLES }}", "ProjectName": "${{ secrets.CI_TESTING_CODE_BUILD_PROJECT_NAME }}", "Branch": "${{ github.sha }}"}' + $roleArn=$(cat ./response.json) + "roleArn=$($roleArn -replace '"', '')" >> $env:GITHUB_OUTPUT + - name: Configure Test Runner Credentials + uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 #v4 + with: + role-to-assume: ${{ steps.lambda.outputs.roleArn }} + role-duration-seconds: 7200 + aws-region: us-west-2 + - name: Run Tests on AWS + id: codebuild + uses: aws-actions/aws-codebuild-run-build@v1 + with: + project-name: ${{ secrets.CI_TESTING_CODE_BUILD_PROJECT_NAME }} + - name: CodeBuild Link + shell: pwsh + run: | + $buildId = "${{ steps.codebuild.outputs.aws-build-id }}" + echo $buildId diff --git a/buildtools/build.proj b/buildtools/build.proj index beb681a63..be0b331c8 100644 --- a/buildtools/build.proj +++ b/buildtools/build.proj @@ -38,9 +38,11 @@ - - - + + + + + diff --git a/buildtools/ci.buildspec.yml b/buildtools/ci.buildspec.yml new file mode 100644 index 000000000..9094387d9 --- /dev/null +++ b/buildtools/ci.buildspec.yml @@ -0,0 +1,16 @@ +version: 0.2 + +phases: + install: + runtime-versions: + dotnet: 8.x + commands: + # The tests need .NET 3.1, 6 and 8. .NET6 is installed by default. .NET8 is added in the runtime-versions. .NET 3.1 is installed manually. + - curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --channel 3.1 + # Mono is needed to run the unit tests on Linux + - curl https://download.mono-project.com/repo/centos8-stable.repo | tee /etc/yum.repos.d/mono-stable.repo + - dnf install -y mono-complete mono-devel + build: + commands: + - dotnet msbuild buildtools/build.proj /t:unit-tests /p:Cicd=true + - dotnet msbuild buildtools/build.proj /t:integ-tests /p:Cicd=true \ No newline at end of file From e86fa638e63913c757e607d38640c361e0111df3 Mon Sep 17 00:00:00 2001 From: Malhar Khimsaria <96malhar@gmail.com> Date: Fri, 10 May 2024 15:06:53 -0700 Subject: [PATCH 04/35] chore: Generate documentation comments for public memebers and add the '' hint --- .../Models/GeneratedMethodModelBuilder.cs | 14 +++- .../Models/ParameterModel.cs | 5 ++ .../Templates/ExecutableAssembly.cs | 72 +++++++++++-------- .../Templates/ExecutableAssembly.tt | 5 ++ .../Templates/FieldsAndConstructor.cs | 42 ++++++----- .../Templates/FieldsAndConstructor.tt | 5 ++ .../Templates/LambdaFunctionTemplate.cs | 62 +++++++++++----- .../Templates/LambdaFunctionTemplate.tt | 11 +++ .../Templates/LambdaFunctionTemplateCode.cs | 32 +++++++++ .../ComplexCalculator_Add_Generated.g.cs | 15 +++- .../ComplexCalculator_Subtract_Generated.g.cs | 15 +++- ...ndResponseWithHeaderV1Async_Generated.g.cs | 13 ++++ ...otFoundResponseWithHeaderV1_Generated.g.cs | 13 ++++ ...ndResponseWithHeaderV2Async_Generated.g.cs | 13 ++++ ...otFoundResponseWithHeaderV2_Generated.g.cs | 13 ++++ ...s_OkResponseWithHeaderAsync_Generated.g.cs | 13 ++++ ...amples_OkResponseWithHeader_Generated.g.cs | 13 ++++ ...DynamicExample_DynamicInput_Generated.g.cs | 13 ++++ ...ynamicExample_DynamicReturn_Generated.g.cs | 13 ++++ .../FunctionsZipOutput_ToLower_Generated.g.cs | 71 ++++++++++++++++++ ...nctions_AsyncStartupToLower_Generated.g.cs | 12 ++++ ...nctions_AsyncStartupToUpper_Generated.g.cs | 12 ++++ .../Functions_ToUpper_Generated.g.cs | 12 ++++ .../Functions_ToUpper_Generated_NET8.g.cs | 12 ++++ ...terExecutable_SayHelloAsync_Generated.g.cs | 15 +++- .../GreeterExecutable_SayHello_Generated.g.cs | 15 +++- .../Greeter_SayHelloAsync_Generated.g.cs | 15 +++- .../Snapshots/Greeter_SayHello_Generated.g.cs | 15 +++- ...trinsicExample_HasIntrinsic_Generated.g.cs | 15 +++- ...ample_NullableHeaderHttpApi_Generated.g.cs | 13 ++++ ...nse_NoParameterWithResponse_Generated.g.cs | 56 +++++++++++++++ ...sMethodWithResponse_ToUpper_Generated.g.cs | 11 +++ ...eterlessMethods_NoParameter_Generated.g.cs | 56 +++++++++++++++ ...arameterlessMethods_ToUpper_Generated.g.cs | 11 +++ .../Snapshots/Program.g.cs | 7 +- .../Snapshots/ProgramMultiHandler.g.cs | 7 +- .../Snapshots/ProgramParameterless.g.cs | 7 +- .../ProgramParameterlessWithResponse.g.cs | 7 +- ...amSourceGeneratorSerializationExample.g.cs | 7 +- .../Snapshots/ProgramZipOutput.g.cs | 7 +- .../SimpleCalculator_Add_Generated.g.cs | 15 +++- ...impleCalculator_DivideAsync_Generated.g.cs | 15 +++- .../SimpleCalculator_Multiply_Generated.g.cs | 15 +++- .../SimpleCalculator_Pi_Generated.g.cs | 13 +++- .../SimpleCalculator_Random_Generated.g.cs | 15 +++- .../SimpleCalculator_Randoms_Generated.g.cs | 15 +++- .../SimpleCalculator_Subtract_Generated.g.cs | 15 +++- ...ializationExample_GetPerson_Generated.g.cs | 13 ++++ .../TaskExample_TaskReturn_Generated.g.cs | 13 ++++ .../VoidExample_VoidReturn_Generated.g.cs | 13 ++++ .../SourceGeneratorTests.cs | 4 +- .../WriterTests/CloudFormationWriterTests.cs | 2 +- 52 files changed, 820 insertions(+), 93 deletions(-) create mode 100644 Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/FunctionsZipOutput_ToLower_Generated.g.cs create mode 100644 Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ParameterlessMethodWithResponse_NoParameterWithResponse_Generated.g.cs create mode 100644 Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ParameterlessMethods_NoParameter_Generated.g.cs diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/GeneratedMethodModelBuilder.cs b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/GeneratedMethodModelBuilder.cs index 5a0460beb..6150dda8d 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/GeneratedMethodModelBuilder.cs +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/GeneratedMethodModelBuilder.cs @@ -148,7 +148,8 @@ private static IList BuildParameters(IMethodSymbol lambdaMethodS Type = new TypeModel { FullName = TypeFullNames.ILambdaContext - } + }, + Documentation = "The ILambdaContext that provides methods for logging and describing the Lambda environment." }; if (lambdaMethodSymbol.HasAttribute(context, TypeFullNames.RestApiAttribute)) @@ -158,7 +159,8 @@ private static IList BuildParameters(IMethodSymbol lambdaMethodS var requestParameter = new ParameterModel { Name = "__request__", - Type = type + Type = type, + Documentation = "The API Gateway request object that will be processed by the Lambda function handler." }; parameters.Add(requestParameter); parameters.Add(contextParameter); @@ -188,7 +190,8 @@ private static IList BuildParameters(IMethodSymbol lambdaMethodS var requestParameter = new ParameterModel { Name = "__request__", - Type = type + Type = type, + Documentation = "The API Gateway request object that will be processed by the Lambda function handler." }; parameters.Add(requestParameter); parameters.Add(contextParameter); @@ -208,6 +211,11 @@ private static IList BuildParameters(IMethodSymbol lambdaMethodS else if(param.Type.FullName == TypeFullNames.ILambdaContext) { param.Name = "__context__"; + param.Documentation = "The ILambdaContext that provides methods for logging and describing the Lambda environment."; + } + else + { + param.Documentation = "The request object that will be processed by the Lambda function handler."; } parameters.Add(param); diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/ParameterModel.cs b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/ParameterModel.cs index ddcaa525b..26780f09b 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/ParameterModel.cs +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/ParameterModel.cs @@ -23,5 +23,10 @@ public class ParameterModel /// an empty list. /// public IList Attributes { get; set; } = new List(); + + /// + /// Gets or sets the documentation of parameter. + /// + public string Documentation { get; set; } } } \ No newline at end of file diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/ExecutableAssembly.cs b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/ExecutableAssembly.cs index 34a04334b..1ecd7c311 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/ExecutableAssembly.cs +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/ExecutableAssembly.cs @@ -23,7 +23,7 @@ namespace Amazon.Lambda.Annotations.SourceGenerator.Templates /// Class to produce the template output /// - #line 1 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" + #line 1 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")] public partial class ExecutableAssembly : ExecutableAssemblyBase { @@ -33,20 +33,30 @@ public partial class ExecutableAssembly : ExecutableAssemblyBase /// public virtual string TransformText() { - this.Write("using System;\r\nusing System.Linq;\r\nusing System.Collections.Generic;\r\nusing Syste" + - "m.Text;\r\nusing System.Threading.Tasks;\r\nusing System.IO;\r\nusing Amazon.Lambda.Co" + - "re;\r\n\r\nnamespace "); + this.Write("// \r\n\r\nusing System;\r\nusing System.Linq;\r\nusing System.Collectio" + + "ns.Generic;\r\nusing System.Text;\r\nusing System.Threading.Tasks;\r\nusing System.IO;" + + "\r\nusing Amazon.Lambda.Core;\r\n\r\nnamespace "); - #line 19 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" + #line 21 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" this.Write(this.ToStringHelper.ToStringWithCulture(this._containingNamespace)); #line default #line hidden - this.Write(";\r\n\r\npublic class GeneratedProgram\r\n{\r\n public static async Task Main(string[]" + - " args)\r\n {\r\n\r\n switch (Environment.GetEnvironmentVariable(\"ANNOTATIONS" + - "_HANDLER\"))\r\n {\r\n"); + this.Write(@"; + +public class GeneratedProgram +{ + /// + /// This is responsible for inspecting the 'ANNOTATIONS_HANDLER' environment variable and invoking the appropriate Lambda function handler. + /// + public static async Task Main(string[] args) + { + + switch (Environment.GetEnvironmentVariable(""ANNOTATIONS_HANDLER"")) + { +"); - #line 28 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" + #line 33 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" foreach (var model in this._lambdaFunctions) { @@ -56,14 +66,14 @@ public virtual string TransformText() #line hidden this.Write(" case \""); - #line 32 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" + #line 37 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" this.Write(this.ToStringHelper.ToStringWithCulture(model.LambdaMethod.Name)); #line default #line hidden this.Write("\":\r\n"); - #line 33 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" + #line 38 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" if (model.GeneratedMethod.ReturnType.FullName == "void") { @@ -73,42 +83,42 @@ public virtual string TransformText() #line hidden this.Write(" Action<"); - #line 37 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" + #line 42 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" this.Write(this.ToStringHelper.ToStringWithCulture(model.GeneratedMethod.Parameters.Any() ? string.Join(", ", model.GeneratedMethod.Parameters.Select(p => $"{p.Type.FullName}")) : "Stream")); #line default #line hidden this.Write("> "); - #line 37 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" + #line 42 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" this.Write(this.ToStringHelper.ToStringWithCulture(model.LambdaMethod.ExecutableAssemblyHandlerName)); #line default #line hidden this.Write(" = new "); - #line 37 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" + #line 42 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" this.Write(this.ToStringHelper.ToStringWithCulture(model.LambdaMethod.ContainingNamespace)); #line default #line hidden this.Write("."); - #line 37 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" + #line 42 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" this.Write(this.ToStringHelper.ToStringWithCulture(model.LambdaMethod.ContainingType.Name)); #line default #line hidden this.Write("_"); - #line 37 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" + #line 42 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" this.Write(this.ToStringHelper.ToStringWithCulture(model.LambdaMethod.Name)); #line default #line hidden this.Write("_Generated()."); - #line 37 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" + #line 42 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" this.Write(this.ToStringHelper.ToStringWithCulture(model.LambdaMethod.Name)); #line default @@ -116,21 +126,21 @@ public virtual string TransformText() this.Write(";\r\n await Amazon.Lambda.RuntimeSupport.LambdaBootstrapBuilder.Crea" + "te("); - #line 38 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" + #line 43 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" this.Write(this.ToStringHelper.ToStringWithCulture(model.LambdaMethod.ExecutableAssemblyHandlerName)); #line default #line hidden this.Write(", new "); - #line 38 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" + #line 43 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" this.Write(this.ToStringHelper.ToStringWithCulture(this._lambdaFunctions[0].SerializerInfo.SerializerName)); #line default #line hidden this.Write("()).Build().RunAsync();\r\n break;\r\n"); - #line 40 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" + #line 45 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" } else @@ -141,49 +151,49 @@ public virtual string TransformText() #line hidden this.Write(" Func<"); - #line 45 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" + #line 50 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" this.Write(this.ToStringHelper.ToStringWithCulture(model.GeneratedMethod.Parameters.Any() ? string.Join(", ", model.GeneratedMethod.Parameters.Select(p => $"{p.Type.FullName}")) : "Stream")); #line default #line hidden this.Write(", "); - #line 45 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" + #line 50 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" this.Write(this.ToStringHelper.ToStringWithCulture(model.GeneratedMethod.ReturnType.FullName)); #line default #line hidden this.Write("> "); - #line 45 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" + #line 50 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" this.Write(this.ToStringHelper.ToStringWithCulture(model.LambdaMethod.ExecutableAssemblyHandlerName)); #line default #line hidden this.Write(" = new "); - #line 45 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" + #line 50 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" this.Write(this.ToStringHelper.ToStringWithCulture(model.LambdaMethod.ContainingNamespace)); #line default #line hidden this.Write("."); - #line 45 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" + #line 50 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" this.Write(this.ToStringHelper.ToStringWithCulture(model.LambdaMethod.ContainingType.Name)); #line default #line hidden this.Write("_"); - #line 45 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" + #line 50 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" this.Write(this.ToStringHelper.ToStringWithCulture(model.LambdaMethod.Name)); #line default #line hidden this.Write("_Generated()."); - #line 45 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" + #line 50 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" this.Write(this.ToStringHelper.ToStringWithCulture(model.LambdaMethod.Name)); #line default @@ -191,21 +201,21 @@ public virtual string TransformText() this.Write(";\r\n await Amazon.Lambda.RuntimeSupport.LambdaBootstrapBuilder.Crea" + "te("); - #line 46 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" + #line 51 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" this.Write(this.ToStringHelper.ToStringWithCulture(model.LambdaMethod.ExecutableAssemblyHandlerName)); #line default #line hidden this.Write(", new "); - #line 46 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" + #line 51 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" this.Write(this.ToStringHelper.ToStringWithCulture(model.SerializerInfo.SerializerName)); #line default #line hidden this.Write("()).Build().RunAsync();\r\n break;\r\n"); - #line 48 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" + #line 53 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" } } @@ -215,7 +225,7 @@ public virtual string TransformText() #line hidden this.Write("\r\n }\r\n"); - #line 54 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" + #line 59 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt" diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/ExecutableAssembly.tt b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/ExecutableAssembly.tt index 526e9b65e..f387a999b 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/ExecutableAssembly.tt +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/ExecutableAssembly.tt @@ -8,6 +8,8 @@ <#@ import namespace="Amazon.Lambda.Annotations.SourceGenerator.Validation" #> <#@ import namespace="Amazon.Lambda.Annotations.SourceGenerator.Models" #> <#@ import namespace="Amazon.Lambda.Annotations.SourceGenerator.Models.Attributes" #> +// + using System; using System.Linq; using System.Collections.Generic; @@ -20,6 +22,9 @@ namespace <#= this._containingNamespace #>; public class GeneratedProgram { + /// + /// This is responsible for inspecting the 'ANNOTATIONS_HANDLER' environment variable and invoking the appropriate Lambda function handler. + /// public static async Task Main(string[] args) { diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/FieldsAndConstructor.cs b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/FieldsAndConstructor.cs index c606fb5d0..aa63be57b 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/FieldsAndConstructor.cs +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/FieldsAndConstructor.cs @@ -19,7 +19,7 @@ namespace Amazon.Lambda.Annotations.SourceGenerator.Templates /// Class to produce the template output /// - #line 1 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" + #line 1 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")] public partial class FieldsAndConstructor : FieldsAndConstructorBase { @@ -30,7 +30,7 @@ public partial class FieldsAndConstructor : FieldsAndConstructorBase public virtual string TransformText() { - #line 7 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" + #line 7 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" if (_model.LambdaMethod.UsingDependencyInjection) { @@ -40,7 +40,7 @@ public virtual string TransformText() #line hidden this.Write(" private readonly ServiceProvider serviceProvider;\r\n"); - #line 12 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" + #line 12 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" } else @@ -51,44 +51,50 @@ public virtual string TransformText() #line hidden this.Write(" private readonly "); - #line 17 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" + #line 17 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.LambdaMethod.ContainingType.Name)); #line default #line hidden this.Write(" "); - #line 17 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" + #line 17 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.LambdaMethod.ContainingType.Name.ToCamelCase())); #line default #line hidden this.Write(";\r\n private readonly "); - #line 18 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" + #line 18 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.SerializerInfo.SerializerName)); #line default #line hidden this.Write(" serializer;\r\n"); - #line 19 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" + #line 19 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" } #line default #line hidden - this.Write("\r\n public "); + this.Write(@" + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// + public "); - #line 23 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" + #line 28 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.GeneratedMethod.ContainingType.Name)); #line default #line hidden this.Write("()\r\n {\r\n SetExecutionEnvironment();\r\n"); - #line 26 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" + #line 31 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" if (_model.LambdaMethod.UsingDependencyInjection) { @@ -102,21 +108,21 @@ public virtual string TransformText() // To use a different lifetime, specify the lifetime in Startup.ConfigureServices(IServiceCollection) method. services.AddSingleton<"); - #line 34 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" + #line 39 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.LambdaMethod.ContainingType.Name)); #line default #line hidden this.Write(">();\r\n services.AddSingleton<"); - #line 35 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" + #line 40 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.SerializerInfo.SerializerName)); #line default #line hidden this.Write(">();\r\n\r\n var startup = new "); - #line 37 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" + #line 42 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.StartupType.FullName)); #line default @@ -124,7 +130,7 @@ public virtual string TransformText() this.Write("();\r\n startup.ConfigureServices(services);\r\n serviceProvide" + "r = services.BuildServiceProvider();\r\n"); - #line 40 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" + #line 45 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" } else @@ -135,28 +141,28 @@ public virtual string TransformText() #line hidden this.Write(" "); - #line 45 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" + #line 50 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.LambdaMethod.ContainingType.Name.ToCamelCase())); #line default #line hidden this.Write(" = new "); - #line 45 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" + #line 50 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.LambdaMethod.ContainingType.Name)); #line default #line hidden this.Write("();\r\n serializer = new "); - #line 46 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" + #line 51 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.SerializerInfo.SerializerName)); #line default #line hidden this.Write("();\r\n"); - #line 47 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" + #line 52 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\FieldsAndConstructor.tt" } diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/FieldsAndConstructor.tt b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/FieldsAndConstructor.tt index 8434ff348..6c4fd3d43 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/FieldsAndConstructor.tt +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/FieldsAndConstructor.tt @@ -20,6 +20,11 @@ } #> + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// public <#= _model.GeneratedMethod.ContainingType.Name #>() { SetExecutionEnvironment(); diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/LambdaFunctionTemplate.cs b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/LambdaFunctionTemplate.cs index 5352e3e34..0dfa338e2 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/LambdaFunctionTemplate.cs +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/LambdaFunctionTemplate.cs @@ -34,8 +34,9 @@ public partial class LambdaFunctionTemplate : LambdaFunctionTemplateBase /// public virtual string TransformText() { + this.Write("// \r\n\r\n"); - #line 12 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" + #line 14 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" foreach (var ns in _model.GeneratedMethod.Usings) { @@ -45,14 +46,14 @@ public virtual string TransformText() #line hidden this.Write("using "); - #line 16 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" + #line 18 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(ns)); #line default #line hidden this.Write(";\r\n"); - #line 17 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" + #line 19 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" } @@ -61,57 +62,84 @@ public virtual string TransformText() #line hidden this.Write("\r\nnamespace "); - #line 21 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" + #line 23 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.LambdaMethod.ContainingNamespace)); #line default #line hidden this.Write("\r\n{\r\n public class "); - #line 23 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" + #line 25 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.GeneratedMethod.ContainingType.Name)); #line default #line hidden this.Write("\r\n {\r\n"); - #line 25 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" + #line 27 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" this.Write(new FieldsAndConstructor(_model).TransformText()); #line default #line hidden - this.Write("\r\n\r\n public "); + this.Write("\r\n\r\n"); + + #line 32 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" + + var methodDocumentationLines = GetMethodDocumentation(); + foreach (var line in methodDocumentationLines) + { + + + #line default + #line hidden + this.Write(" "); + + #line 37 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(line)); + + #line default + #line hidden + this.Write("\r\n"); - #line 30 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" + #line 38 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" + + } + + + #line default + #line hidden + this.Write(" public "); + + #line 41 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.LambdaMethod.ReturnsVoidOrGenericTask ? "async " : "")); #line default #line hidden - #line 30 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" + #line 41 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.GeneratedMethod.ReturnType.FullName)); #line default #line hidden this.Write(" "); - #line 30 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" + #line 41 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.LambdaMethod.Name)); #line default #line hidden this.Write("("); - #line 30 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" + #line 41 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.GeneratedMethod.Parameters.Any() ? string.Join(", ", _model.GeneratedMethod.Parameters.Select(p => $"{p.Type.FullName} {p.Name}")) : "Stream stream")); #line default #line hidden this.Write(")\r\n {\r\n"); - #line 32 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" + #line 43 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" if (_model.LambdaMethod.UsingDependencyInjection) { @@ -123,28 +151,28 @@ public virtual string TransformText() "ting scoped dependencies without creating a scope manually.\r\n using v" + "ar scope = serviceProvider.CreateScope();\r\n var "); - #line 39 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" + #line 50 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.LambdaMethod.ContainingType.Name.ToCamelCase())); #line default #line hidden this.Write(" = scope.ServiceProvider.GetRequiredService<"); - #line 40 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" + #line 51 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.LambdaMethod.ContainingType.Name)); #line default #line hidden this.Write(">();\r\n var serializer = scope.ServiceProvider.GetRequiredService<"); - #line 41 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" + #line 52 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.SerializerInfo.SerializerName)); #line default #line hidden this.Write(">();\r\n\r\n"); - #line 43 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" + #line 54 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" } @@ -178,7 +206,7 @@ private static void SetExecutionEnvironment() envValue.Append(""lib/amazon-lambda-annotations#"); - #line 71 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" + #line 82 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.SourceGeneratorVersion)); #line default diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/LambdaFunctionTemplate.tt b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/LambdaFunctionTemplate.tt index c38e683d9..f1aa76cb0 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/LambdaFunctionTemplate.tt +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/LambdaFunctionTemplate.tt @@ -9,6 +9,8 @@ <#@ import namespace="Amazon.Lambda.Annotations.SourceGenerator.Models.Attributes" #> <#@ import namespace="Microsoft.CodeAnalysis" #> <#@ import namespace="Amazon.Lambda.Annotations.SourceGenerator.Validation" #> +// + <# foreach (var ns in _model.GeneratedMethod.Usings) { @@ -27,6 +29,15 @@ this.Write(new FieldsAndConstructor(_model).TransformText()); #> +<# + var methodDocumentationLines = GetMethodDocumentation(); + foreach (var line in methodDocumentationLines) + { +#> + <#= line #> +<# + } +#> public <#= _model.LambdaMethod.ReturnsVoidOrGenericTask ? "async " : "" #><#= _model.GeneratedMethod.ReturnType.FullName #> <#= _model.LambdaMethod.Name #>(<#= _model.GeneratedMethod.Parameters.Any() ? string.Join(", ", _model.GeneratedMethod.Parameters.Select(p => $"{p.Type.FullName} {p.Name}")) : "Stream stream" #>) { <# diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/LambdaFunctionTemplateCode.cs b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/LambdaFunctionTemplateCode.cs index 64120260f..311b253f0 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/LambdaFunctionTemplateCode.cs +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/LambdaFunctionTemplateCode.cs @@ -1,4 +1,8 @@ using Amazon.Lambda.Annotations.SourceGenerator.Models; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using YamlDotNet.Core.Tokens; namespace Amazon.Lambda.Annotations.SourceGenerator.Templates { @@ -10,5 +14,33 @@ public LambdaFunctionTemplate(LambdaFunctionModel model) { _model = model; } + + private List GetMethodDocumentation() + { + var lambdaMethod = _model.LambdaMethod; + var generatedMethod = _model.GeneratedMethod; + var docStringlines = new List + { + "/// " + }; + if (lambdaMethod.Parameters.Any()) + { + docStringlines.Add($"/// The generated Lambda function handler for p.Type.FullName))})\"/>"); + } + else + { + docStringlines.Add($"/// The generated Lambda function handler for "); + } + docStringlines.Add("/// "); + + foreach (var parameter in generatedMethod.Parameters) + { + docStringlines.Add($"/// {parameter.Documentation}"); + } + + docStringlines.Add("/// Result of the Lambda function execution"); + + return docStringlines; + } } } \ No newline at end of file diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ComplexCalculator_Add_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ComplexCalculator_Add_Generated.g.cs index 368ab6f97..7d24f327f 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ComplexCalculator_Add_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ComplexCalculator_Add_Generated.g.cs @@ -1,4 +1,6 @@ -using System; +// + +using System; using System.Linq; using System.Collections.Generic; using System.Text; @@ -13,6 +15,11 @@ public class ComplexCalculator_Add_Generated private readonly ComplexCalculator complexCalculator; private readonly Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer serializer; + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// public ComplexCalculator_Add_Generated() { SetExecutionEnvironment(); @@ -20,6 +27,12 @@ public ComplexCalculator_Add_Generated() serializer = new Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer(); } + /// + /// The generated Lambda function handler for + /// + /// The API Gateway request object that will be processed by the Lambda function handler. + /// The ILambdaContext that provides methods for logging and describing the Lambda environment. + /// Result of the Lambda function execution public Amazon.Lambda.APIGatewayEvents.APIGatewayHttpApiV2ProxyResponse Add(Amazon.Lambda.APIGatewayEvents.APIGatewayHttpApiV2ProxyRequest __request__, Amazon.Lambda.Core.ILambdaContext __context__) { var complexNumbers = __request__.Body; diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ComplexCalculator_Subtract_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ComplexCalculator_Subtract_Generated.g.cs index b1a77978d..5178eb44d 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ComplexCalculator_Subtract_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ComplexCalculator_Subtract_Generated.g.cs @@ -1,4 +1,6 @@ -using System; +// + +using System; using System.Linq; using System.Collections.Generic; using System.Text; @@ -13,6 +15,11 @@ public class ComplexCalculator_Subtract_Generated private readonly ComplexCalculator complexCalculator; private readonly Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer serializer; + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// public ComplexCalculator_Subtract_Generated() { SetExecutionEnvironment(); @@ -20,6 +27,12 @@ public ComplexCalculator_Subtract_Generated() serializer = new Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer(); } + /// + /// The generated Lambda function handler for + /// + /// The API Gateway request object that will be processed by the Lambda function handler. + /// The ILambdaContext that provides methods for logging and describing the Lambda environment. + /// Result of the Lambda function execution public Amazon.Lambda.APIGatewayEvents.APIGatewayHttpApiV2ProxyResponse Subtract(Amazon.Lambda.APIGatewayEvents.APIGatewayHttpApiV2ProxyRequest __request__, Amazon.Lambda.Core.ILambdaContext __context__) { var validationErrors = new List(); diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV1Async_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV1Async_Generated.g.cs index 66a9b2f4c..be43ef9aa 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV1Async_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV1Async_Generated.g.cs @@ -1,3 +1,5 @@ +// + using System; using System.Linq; using System.Collections.Generic; @@ -14,6 +16,11 @@ public class CustomizeResponseExamples_NotFoundResponseWithHeaderV1Async_Generat private readonly CustomizeResponseExamples customizeResponseExamples; private readonly Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer serializer; + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// public CustomizeResponseExamples_NotFoundResponseWithHeaderV1Async_Generated() { SetExecutionEnvironment(); @@ -21,6 +28,12 @@ public CustomizeResponseExamples_NotFoundResponseWithHeaderV1Async_Generated() serializer = new Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer(); } + /// + /// The generated Lambda function handler for + /// + /// The API Gateway request object that will be processed by the Lambda function handler. + /// The ILambdaContext that provides methods for logging and describing the Lambda environment. + /// Result of the Lambda function execution public async System.Threading.Tasks.Task NotFoundResponseWithHeaderV1Async(Amazon.Lambda.APIGatewayEvents.APIGatewayProxyRequest __request__, Amazon.Lambda.Core.ILambdaContext __context__) { var validationErrors = new List(); diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV1_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV1_Generated.g.cs index dc9f19a6c..be1ba0bf3 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV1_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV1_Generated.g.cs @@ -1,3 +1,5 @@ +// + using System; using System.Linq; using System.Collections.Generic; @@ -14,6 +16,11 @@ public class CustomizeResponseExamples_NotFoundResponseWithHeaderV1_Generated private readonly CustomizeResponseExamples customizeResponseExamples; private readonly Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer serializer; + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// public CustomizeResponseExamples_NotFoundResponseWithHeaderV1_Generated() { SetExecutionEnvironment(); @@ -21,6 +28,12 @@ public CustomizeResponseExamples_NotFoundResponseWithHeaderV1_Generated() serializer = new Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer(); } + /// + /// The generated Lambda function handler for + /// + /// The API Gateway request object that will be processed by the Lambda function handler. + /// The ILambdaContext that provides methods for logging and describing the Lambda environment. + /// Result of the Lambda function execution public System.IO.Stream NotFoundResponseWithHeaderV1(Amazon.Lambda.APIGatewayEvents.APIGatewayProxyRequest __request__, Amazon.Lambda.Core.ILambdaContext __context__) { var validationErrors = new List(); diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV2Async_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV2Async_Generated.g.cs index 50cb6c472..8ffaa989f 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV2Async_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV2Async_Generated.g.cs @@ -1,3 +1,5 @@ +// + using System; using System.Linq; using System.Collections.Generic; @@ -14,6 +16,11 @@ public class CustomizeResponseExamples_NotFoundResponseWithHeaderV2Async_Generat private readonly CustomizeResponseExamples customizeResponseExamples; private readonly Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer serializer; + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// public CustomizeResponseExamples_NotFoundResponseWithHeaderV2Async_Generated() { SetExecutionEnvironment(); @@ -21,6 +28,12 @@ public CustomizeResponseExamples_NotFoundResponseWithHeaderV2Async_Generated() serializer = new Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer(); } + /// + /// The generated Lambda function handler for + /// + /// The API Gateway request object that will be processed by the Lambda function handler. + /// The ILambdaContext that provides methods for logging and describing the Lambda environment. + /// Result of the Lambda function execution public async System.Threading.Tasks.Task NotFoundResponseWithHeaderV2Async(Amazon.Lambda.APIGatewayEvents.APIGatewayHttpApiV2ProxyRequest __request__, Amazon.Lambda.Core.ILambdaContext __context__) { var validationErrors = new List(); diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV2_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV2_Generated.g.cs index d809f6c9b..30b029167 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV2_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV2_Generated.g.cs @@ -1,3 +1,5 @@ +// + using System; using System.Linq; using System.Collections.Generic; @@ -14,6 +16,11 @@ public class CustomizeResponseExamples_NotFoundResponseWithHeaderV2_Generated private readonly CustomizeResponseExamples customizeResponseExamples; private readonly Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer serializer; + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// public CustomizeResponseExamples_NotFoundResponseWithHeaderV2_Generated() { SetExecutionEnvironment(); @@ -21,6 +28,12 @@ public CustomizeResponseExamples_NotFoundResponseWithHeaderV2_Generated() serializer = new Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer(); } + /// + /// The generated Lambda function handler for + /// + /// The API Gateway request object that will be processed by the Lambda function handler. + /// The ILambdaContext that provides methods for logging and describing the Lambda environment. + /// Result of the Lambda function execution public System.IO.Stream NotFoundResponseWithHeaderV2(Amazon.Lambda.APIGatewayEvents.APIGatewayHttpApiV2ProxyRequest __request__, Amazon.Lambda.Core.ILambdaContext __context__) { var validationErrors = new List(); diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_OkResponseWithHeaderAsync_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_OkResponseWithHeaderAsync_Generated.g.cs index 6f56db9fa..90ba6c73b 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_OkResponseWithHeaderAsync_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_OkResponseWithHeaderAsync_Generated.g.cs @@ -1,3 +1,5 @@ +// + using System; using System.Linq; using System.Collections.Generic; @@ -14,6 +16,11 @@ public class CustomizeResponseExamples_OkResponseWithHeaderAsync_Generated private readonly CustomizeResponseExamples customizeResponseExamples; private readonly Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer serializer; + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// public CustomizeResponseExamples_OkResponseWithHeaderAsync_Generated() { SetExecutionEnvironment(); @@ -21,6 +28,12 @@ public CustomizeResponseExamples_OkResponseWithHeaderAsync_Generated() serializer = new Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer(); } + /// + /// The generated Lambda function handler for + /// + /// The API Gateway request object that will be processed by the Lambda function handler. + /// The ILambdaContext that provides methods for logging and describing the Lambda environment. + /// Result of the Lambda function execution public async System.Threading.Tasks.Task OkResponseWithHeaderAsync(Amazon.Lambda.APIGatewayEvents.APIGatewayProxyRequest __request__, Amazon.Lambda.Core.ILambdaContext __context__) { var validationErrors = new List(); diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_OkResponseWithHeader_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_OkResponseWithHeader_Generated.g.cs index d56149923..eaa400ee1 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_OkResponseWithHeader_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_OkResponseWithHeader_Generated.g.cs @@ -1,3 +1,5 @@ +// + using System; using System.Linq; using System.Collections.Generic; @@ -14,6 +16,11 @@ public class CustomizeResponseExamples_OkResponseWithHeader_Generated private readonly CustomizeResponseExamples customizeResponseExamples; private readonly Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer serializer; + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// public CustomizeResponseExamples_OkResponseWithHeader_Generated() { SetExecutionEnvironment(); @@ -21,6 +28,12 @@ public CustomizeResponseExamples_OkResponseWithHeader_Generated() serializer = new Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer(); } + /// + /// The generated Lambda function handler for + /// + /// The API Gateway request object that will be processed by the Lambda function handler. + /// The ILambdaContext that provides methods for logging and describing the Lambda environment. + /// Result of the Lambda function execution public System.IO.Stream OkResponseWithHeader(Amazon.Lambda.APIGatewayEvents.APIGatewayProxyRequest __request__, Amazon.Lambda.Core.ILambdaContext __context__) { var validationErrors = new List(); diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/DynamicExample_DynamicInput_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/DynamicExample_DynamicInput_Generated.g.cs index dc55b2493..51c294ee7 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/DynamicExample_DynamicInput_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/DynamicExample_DynamicInput_Generated.g.cs @@ -1,3 +1,5 @@ +// + using System; using System.Linq; using System.Collections.Generic; @@ -13,6 +15,11 @@ public class DynamicExample_DynamicInput_Generated private readonly DynamicExample dynamicExample; private readonly Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer serializer; + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// public DynamicExample_DynamicInput_Generated() { SetExecutionEnvironment(); @@ -20,6 +27,12 @@ public DynamicExample_DynamicInput_Generated() serializer = new Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer(); } + /// + /// The generated Lambda function handler for + /// + /// The request object that will be processed by the Lambda function handler. + /// The ILambdaContext that provides methods for logging and describing the Lambda environment. + /// Result of the Lambda function execution public string DynamicInput(dynamic text, Amazon.Lambda.Core.ILambdaContext __context__) { return dynamicExample.DynamicInput(text, __context__); diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/DynamicExample_DynamicReturn_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/DynamicExample_DynamicReturn_Generated.g.cs index 22ac630dc..160864b99 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/DynamicExample_DynamicReturn_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/DynamicExample_DynamicReturn_Generated.g.cs @@ -1,3 +1,5 @@ +// + using System; using System.Linq; using System.Collections.Generic; @@ -13,6 +15,11 @@ public class DynamicExample_DynamicReturn_Generated private readonly DynamicExample dynamicExample; private readonly Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer serializer; + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// public DynamicExample_DynamicReturn_Generated() { SetExecutionEnvironment(); @@ -20,6 +27,12 @@ public DynamicExample_DynamicReturn_Generated() serializer = new Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer(); } + /// + /// The generated Lambda function handler for + /// + /// The request object that will be processed by the Lambda function handler. + /// The ILambdaContext that provides methods for logging and describing the Lambda environment. + /// Result of the Lambda function execution public dynamic DynamicReturn(string text, Amazon.Lambda.Core.ILambdaContext __context__) { return dynamicExample.DynamicReturn(text, __context__); diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/FunctionsZipOutput_ToLower_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/FunctionsZipOutput_ToLower_Generated.g.cs new file mode 100644 index 000000000..7bca2834e --- /dev/null +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/FunctionsZipOutput_ToLower_Generated.g.cs @@ -0,0 +1,71 @@ +// + +using System; +using System.Linq; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using System.IO; +using Microsoft.Extensions.DependencyInjection; +using Amazon.Lambda.Core; + +namespace TestServerlessApp.Sub1 +{ + public class FunctionsZipOutput_ToLower_Generated + { + private readonly ServiceProvider serviceProvider; + + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// + public FunctionsZipOutput_ToLower_Generated() + { + SetExecutionEnvironment(); + var services = new ServiceCollection(); + + // By default, Lambda function class is added to the service container using the singleton lifetime + // To use a different lifetime, specify the lifetime in Startup.ConfigureServices(IServiceCollection) method. + services.AddSingleton(); + services.AddSingleton(); + + var startup = new TestServerlessApp.Startup(); + startup.ConfigureServices(services); + serviceProvider = services.BuildServiceProvider(); + } + + /// + /// The generated Lambda function handler for + /// + /// The request object that will be processed by the Lambda function handler. + /// Result of the Lambda function execution + public string ToLower(string text) + { + // Create a scope for every request, + // this allows creating scoped dependencies without creating a scope manually. + using var scope = serviceProvider.CreateScope(); + var functionsZipOutput = scope.ServiceProvider.GetRequiredService(); + var serializer = scope.ServiceProvider.GetRequiredService(); + + return functionsZipOutput.ToLower(text); + } + + private static void SetExecutionEnvironment() + { + const string envName = "AWS_EXECUTION_ENV"; + + var envValue = new StringBuilder(); + + // If there is an existing execution environment variable add the annotations package as a suffix. + if(!string.IsNullOrEmpty(Environment.GetEnvironmentVariable(envName))) + { + envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); + } + + envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + + Environment.SetEnvironmentVariable(envName, envValue.ToString()); + } + } +} \ No newline at end of file diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Functions_AsyncStartupToLower_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Functions_AsyncStartupToLower_Generated.g.cs index a95cfeb01..7bca2834e 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Functions_AsyncStartupToLower_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Functions_AsyncStartupToLower_Generated.g.cs @@ -1,3 +1,5 @@ +// + using System; using System.Linq; using System.Collections.Generic; @@ -13,6 +15,11 @@ public class FunctionsZipOutput_ToLower_Generated { private readonly ServiceProvider serviceProvider; + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// public FunctionsZipOutput_ToLower_Generated() { SetExecutionEnvironment(); @@ -28,6 +35,11 @@ public FunctionsZipOutput_ToLower_Generated() serviceProvider = services.BuildServiceProvider(); } + /// + /// The generated Lambda function handler for + /// + /// The request object that will be processed by the Lambda function handler. + /// Result of the Lambda function execution public string ToLower(string text) { // Create a scope for every request, diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Functions_AsyncStartupToUpper_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Functions_AsyncStartupToUpper_Generated.g.cs index c2249cd46..854b69221 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Functions_AsyncStartupToUpper_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Functions_AsyncStartupToUpper_Generated.g.cs @@ -1,3 +1,5 @@ +// + using System; using System.Linq; using System.Collections.Generic; @@ -13,6 +15,11 @@ public class Functions_ToUpper_Generated { private readonly ServiceProvider serviceProvider; + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// public Functions_ToUpper_Generated() { SetExecutionEnvironment(); @@ -28,6 +35,11 @@ public Functions_ToUpper_Generated() serviceProvider = services.BuildServiceProvider(); } + /// + /// The generated Lambda function handler for + /// + /// The request object that will be processed by the Lambda function handler. + /// Result of the Lambda function execution public string ToUpper(string text) { // Create a scope for every request, diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Functions_ToUpper_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Functions_ToUpper_Generated.g.cs index 07ece12af..8e80d3711 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Functions_ToUpper_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Functions_ToUpper_Generated.g.cs @@ -1,3 +1,5 @@ +// + using System; using System.Linq; using System.Collections.Generic; @@ -13,6 +15,11 @@ public class Functions_ToUpper_Generated private readonly Functions functions; private readonly Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer serializer; + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// public Functions_ToUpper_Generated() { SetExecutionEnvironment(); @@ -20,6 +27,11 @@ public Functions_ToUpper_Generated() serializer = new Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer(); } + /// + /// The generated Lambda function handler for + /// + /// The request object that will be processed by the Lambda function handler. + /// Result of the Lambda function execution public string ToUpper(string text) { return functions.ToUpper(text); diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Functions_ToUpper_Generated_NET8.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Functions_ToUpper_Generated_NET8.g.cs index 9a2db7419..214a8df58 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Functions_ToUpper_Generated_NET8.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Functions_ToUpper_Generated_NET8.g.cs @@ -1,3 +1,5 @@ +// + using System; using System.Linq; using System.Collections.Generic; @@ -13,6 +15,11 @@ public class Functions_ToUpper_Generated private readonly Functions functions; private readonly Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer serializer; + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// public Functions_ToUpper_Generated() { SetExecutionEnvironment(); @@ -20,6 +27,11 @@ public Functions_ToUpper_Generated() serializer = new Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer(); } + /// + /// The generated Lambda function handler for + /// + /// The request object that will be processed by the Lambda function handler. + /// Result of the Lambda function execution public string ToUpper(string text) { return functions.ToUpper(text); diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/GreeterExecutable_SayHelloAsync_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/GreeterExecutable_SayHelloAsync_Generated.g.cs index 29f4c59cf..5e0d66ee3 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/GreeterExecutable_SayHelloAsync_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/GreeterExecutable_SayHelloAsync_Generated.g.cs @@ -1,4 +1,6 @@ -using System; +// + +using System; using System.Linq; using System.Collections.Generic; using System.Text; @@ -13,6 +15,11 @@ public class Greeter_SayHelloAsync_Generated { private readonly ServiceProvider serviceProvider; + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// public Greeter_SayHelloAsync_Generated() { SetExecutionEnvironment(); @@ -28,6 +35,12 @@ public Greeter_SayHelloAsync_Generated() serviceProvider = services.BuildServiceProvider(); } + /// + /// The generated Lambda function handler for + /// + /// The API Gateway request object that will be processed by the Lambda function handler. + /// The ILambdaContext that provides methods for logging and describing the Lambda environment. + /// Result of the Lambda function execution public async System.Threading.Tasks.Task SayHelloAsync(Amazon.Lambda.APIGatewayEvents.APIGatewayProxyRequest __request__, Amazon.Lambda.Core.ILambdaContext __context__) { // Create a scope for every request, diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/GreeterExecutable_SayHello_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/GreeterExecutable_SayHello_Generated.g.cs index 6583888c0..b9034fa37 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/GreeterExecutable_SayHello_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/GreeterExecutable_SayHello_Generated.g.cs @@ -1,4 +1,6 @@ -using System; +// + +using System; using System.Linq; using System.Collections.Generic; using System.Text; @@ -13,6 +15,11 @@ public class Greeter_SayHello_Generated { private readonly ServiceProvider serviceProvider; + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// public Greeter_SayHello_Generated() { SetExecutionEnvironment(); @@ -28,6 +35,12 @@ public Greeter_SayHello_Generated() serviceProvider = services.BuildServiceProvider(); } + /// + /// The generated Lambda function handler for + /// + /// The API Gateway request object that will be processed by the Lambda function handler. + /// The ILambdaContext that provides methods for logging and describing the Lambda environment. + /// Result of the Lambda function execution public Amazon.Lambda.APIGatewayEvents.APIGatewayProxyResponse SayHello(Amazon.Lambda.APIGatewayEvents.APIGatewayProxyRequest __request__, Amazon.Lambda.Core.ILambdaContext __context__) { // Create a scope for every request, diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Greeter_SayHelloAsync_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Greeter_SayHelloAsync_Generated.g.cs index bf255b7df..2b3da55eb 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Greeter_SayHelloAsync_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Greeter_SayHelloAsync_Generated.g.cs @@ -1,4 +1,6 @@ -using System; +// + +using System; using System.Linq; using System.Collections.Generic; using System.Text; @@ -13,6 +15,11 @@ public class Greeter_SayHelloAsync_Generated private readonly Greeter greeter; private readonly Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer serializer; + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// public Greeter_SayHelloAsync_Generated() { SetExecutionEnvironment(); @@ -20,6 +27,12 @@ public Greeter_SayHelloAsync_Generated() serializer = new Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer(); } + /// + /// The generated Lambda function handler for + /// + /// The API Gateway request object that will be processed by the Lambda function handler. + /// The ILambdaContext that provides methods for logging and describing the Lambda environment. + /// Result of the Lambda function execution public async System.Threading.Tasks.Task SayHelloAsync(Amazon.Lambda.APIGatewayEvents.APIGatewayProxyRequest __request__, Amazon.Lambda.Core.ILambdaContext __context__) { var validationErrors = new List(); diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Greeter_SayHello_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Greeter_SayHello_Generated.g.cs index 186f814f9..6120f86ce 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Greeter_SayHello_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Greeter_SayHello_Generated.g.cs @@ -1,4 +1,6 @@ -using System; +// + +using System; using System.Linq; using System.Collections.Generic; using System.Text; @@ -13,6 +15,11 @@ public class Greeter_SayHello_Generated private readonly Greeter greeter; private readonly Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer serializer; + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// public Greeter_SayHello_Generated() { SetExecutionEnvironment(); @@ -20,6 +27,12 @@ public Greeter_SayHello_Generated() serializer = new Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer(); } + /// + /// The generated Lambda function handler for + /// + /// The API Gateway request object that will be processed by the Lambda function handler. + /// The ILambdaContext that provides methods for logging and describing the Lambda environment. + /// Result of the Lambda function execution public Amazon.Lambda.APIGatewayEvents.APIGatewayProxyResponse SayHello(Amazon.Lambda.APIGatewayEvents.APIGatewayProxyRequest __request__, Amazon.Lambda.Core.ILambdaContext __context__) { var validationErrors = new List(); diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/IntrinsicExample_HasIntrinsic_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/IntrinsicExample_HasIntrinsic_Generated.g.cs index a1c627ca1..f45bdedb9 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/IntrinsicExample_HasIntrinsic_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/IntrinsicExample_HasIntrinsic_Generated.g.cs @@ -1,4 +1,6 @@ -using System; +// + +using System; using System.Linq; using System.Collections.Generic; using System.Text; @@ -13,6 +15,11 @@ public class IntrinsicExample_HasIntrinsic_Generated private readonly IntrinsicExample intrinsicExample; private readonly Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer serializer; + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// public IntrinsicExample_HasIntrinsic_Generated() { SetExecutionEnvironment(); @@ -20,6 +27,12 @@ public IntrinsicExample_HasIntrinsic_Generated() serializer = new Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer(); } + /// + /// The generated Lambda function handler for + /// + /// The request object that will be processed by the Lambda function handler. + /// The ILambdaContext that provides methods for logging and describing the Lambda environment. + /// Result of the Lambda function execution public void HasIntrinsic(string text, Amazon.Lambda.Core.ILambdaContext __context__) { intrinsicExample.HasIntrinsic(text, __context__); diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/NullableReferenceTypeExample_NullableHeaderHttpApi_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/NullableReferenceTypeExample_NullableHeaderHttpApi_Generated.g.cs index 60da26f9d..53987cc9a 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/NullableReferenceTypeExample_NullableHeaderHttpApi_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/NullableReferenceTypeExample_NullableHeaderHttpApi_Generated.g.cs @@ -1,3 +1,5 @@ +// + using System; using System.Linq; using System.Collections.Generic; @@ -13,6 +15,11 @@ public class NullableReferenceTypeExample_NullableHeaderHttpApi_Generated private readonly NullableReferenceTypeExample nullableReferenceTypeExample; private readonly Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer serializer; + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// public NullableReferenceTypeExample_NullableHeaderHttpApi_Generated() { SetExecutionEnvironment(); @@ -20,6 +27,12 @@ public NullableReferenceTypeExample_NullableHeaderHttpApi_Generated() serializer = new Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer(); } + /// + /// The generated Lambda function handler for + /// + /// The API Gateway request object that will be processed by the Lambda function handler. + /// The ILambdaContext that provides methods for logging and describing the Lambda environment. + /// Result of the Lambda function execution public Amazon.Lambda.APIGatewayEvents.APIGatewayHttpApiV2ProxyResponse NullableHeaderHttpApi(Amazon.Lambda.APIGatewayEvents.APIGatewayHttpApiV2ProxyRequest __request__, Amazon.Lambda.Core.ILambdaContext __context__) { var validationErrors = new List(); diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ParameterlessMethodWithResponse_NoParameterWithResponse_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ParameterlessMethodWithResponse_NoParameterWithResponse_Generated.g.cs new file mode 100644 index 000000000..e96636875 --- /dev/null +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ParameterlessMethodWithResponse_NoParameterWithResponse_Generated.g.cs @@ -0,0 +1,56 @@ +// + +using System; +using System.Linq; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using System.IO; +using Amazon.Lambda.Core; + +namespace TestServerlessApp +{ + public class ParameterlessMethodWithResponse_NoParameterWithResponse_Generated + { + private readonly ParameterlessMethodWithResponse parameterlessMethodWithResponse; + private readonly Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer serializer; + + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// + public ParameterlessMethodWithResponse_NoParameterWithResponse_Generated() + { + SetExecutionEnvironment(); + parameterlessMethodWithResponse = new ParameterlessMethodWithResponse(); + serializer = new Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer(); + } + + /// + /// The generated Lambda function handler for + /// + /// Result of the Lambda function execution + public string NoParameterWithResponse(Stream stream) + { + return parameterlessMethodWithResponse.NoParameterWithResponse(); + } + + private static void SetExecutionEnvironment() + { + const string envName = "AWS_EXECUTION_ENV"; + + var envValue = new StringBuilder(); + + // If there is an existing execution environment variable add the annotations package as a suffix. + if(!string.IsNullOrEmpty(Environment.GetEnvironmentVariable(envName))) + { + envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); + } + + envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + + Environment.SetEnvironmentVariable(envName, envValue.ToString()); + } + } +} \ No newline at end of file diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ParameterlessMethodWithResponse_ToUpper_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ParameterlessMethodWithResponse_ToUpper_Generated.g.cs index bc295995c..e96636875 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ParameterlessMethodWithResponse_ToUpper_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ParameterlessMethodWithResponse_ToUpper_Generated.g.cs @@ -1,3 +1,5 @@ +// + using System; using System.Linq; using System.Collections.Generic; @@ -13,6 +15,11 @@ public class ParameterlessMethodWithResponse_NoParameterWithResponse_Generated private readonly ParameterlessMethodWithResponse parameterlessMethodWithResponse; private readonly Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer serializer; + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// public ParameterlessMethodWithResponse_NoParameterWithResponse_Generated() { SetExecutionEnvironment(); @@ -20,6 +27,10 @@ public ParameterlessMethodWithResponse_NoParameterWithResponse_Generated() serializer = new Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer(); } + /// + /// The generated Lambda function handler for + /// + /// Result of the Lambda function execution public string NoParameterWithResponse(Stream stream) { return parameterlessMethodWithResponse.NoParameterWithResponse(); diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ParameterlessMethods_NoParameter_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ParameterlessMethods_NoParameter_Generated.g.cs new file mode 100644 index 000000000..d2e8e4c7b --- /dev/null +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ParameterlessMethods_NoParameter_Generated.g.cs @@ -0,0 +1,56 @@ +// + +using System; +using System.Linq; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using System.IO; +using Amazon.Lambda.Core; + +namespace TestServerlessApp +{ + public class ParameterlessMethods_NoParameter_Generated + { + private readonly ParameterlessMethods parameterlessMethods; + private readonly Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer serializer; + + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// + public ParameterlessMethods_NoParameter_Generated() + { + SetExecutionEnvironment(); + parameterlessMethods = new ParameterlessMethods(); + serializer = new Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer(); + } + + /// + /// The generated Lambda function handler for + /// + /// Result of the Lambda function execution + public void NoParameter(Stream stream) + { + parameterlessMethods.NoParameter(); + } + + private static void SetExecutionEnvironment() + { + const string envName = "AWS_EXECUTION_ENV"; + + var envValue = new StringBuilder(); + + // If there is an existing execution environment variable add the annotations package as a suffix. + if(!string.IsNullOrEmpty(Environment.GetEnvironmentVariable(envName))) + { + envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); + } + + envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + + Environment.SetEnvironmentVariable(envName, envValue.ToString()); + } + } +} \ No newline at end of file diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ParameterlessMethods_ToUpper_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ParameterlessMethods_ToUpper_Generated.g.cs index a20de4643..d2e8e4c7b 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ParameterlessMethods_ToUpper_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ParameterlessMethods_ToUpper_Generated.g.cs @@ -1,3 +1,5 @@ +// + using System; using System.Linq; using System.Collections.Generic; @@ -13,6 +15,11 @@ public class ParameterlessMethods_NoParameter_Generated private readonly ParameterlessMethods parameterlessMethods; private readonly Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer serializer; + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// public ParameterlessMethods_NoParameter_Generated() { SetExecutionEnvironment(); @@ -20,6 +27,10 @@ public ParameterlessMethods_NoParameter_Generated() serializer = new Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer(); } + /// + /// The generated Lambda function handler for + /// + /// Result of the Lambda function execution public void NoParameter(Stream stream) { parameterlessMethods.NoParameter(); diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Program.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Program.g.cs index 594bd7af9..58299b050 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Program.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Program.g.cs @@ -1,4 +1,6 @@ -using System; +// + +using System; using System.Linq; using System.Collections.Generic; using System.Text; @@ -10,6 +12,9 @@ namespace TestServerlessApp.Sub1; public class GeneratedProgram { + /// + /// This is responsible for inspecting the 'ANNOTATIONS_HANDLER' environment variable and invoking the appropriate Lambda function handler. + /// public static async Task Main(string[] args) { diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ProgramMultiHandler.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ProgramMultiHandler.g.cs index d3b7728d5..909f9c604 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ProgramMultiHandler.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ProgramMultiHandler.g.cs @@ -1,4 +1,6 @@ -using System; +// + +using System; using System.Linq; using System.Collections.Generic; using System.Text; @@ -10,6 +12,9 @@ namespace TestServerlessApp; public class GeneratedProgram { + /// + /// This is responsible for inspecting the 'ANNOTATIONS_HANDLER' environment variable and invoking the appropriate Lambda function handler. + /// public static async Task Main(string[] args) { diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ProgramParameterless.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ProgramParameterless.g.cs index dcf6c591a..39d79eca7 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ProgramParameterless.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ProgramParameterless.g.cs @@ -1,4 +1,6 @@ -using System; +// + +using System; using System.Linq; using System.Collections.Generic; using System.Text; @@ -10,6 +12,9 @@ namespace TestServerlessApp; public class GeneratedProgram { + /// + /// This is responsible for inspecting the 'ANNOTATIONS_HANDLER' environment variable and invoking the appropriate Lambda function handler. + /// public static async Task Main(string[] args) { diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ProgramParameterlessWithResponse.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ProgramParameterlessWithResponse.g.cs index b60ed0e85..f9077a6d9 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ProgramParameterlessWithResponse.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ProgramParameterlessWithResponse.g.cs @@ -1,4 +1,6 @@ -using System; +// + +using System; using System.Linq; using System.Collections.Generic; using System.Text; @@ -10,6 +12,9 @@ namespace TestServerlessApp; public class GeneratedProgram { + /// + /// This is responsible for inspecting the 'ANNOTATIONS_HANDLER' environment variable and invoking the appropriate Lambda function handler. + /// public static async Task Main(string[] args) { diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ProgramSourceGeneratorSerializationExample.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ProgramSourceGeneratorSerializationExample.g.cs index 850761100..3bb638a28 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ProgramSourceGeneratorSerializationExample.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ProgramSourceGeneratorSerializationExample.g.cs @@ -1,4 +1,6 @@ -using System; +// + +using System; using System.Linq; using System.Collections.Generic; using System.Text; @@ -10,6 +12,9 @@ namespace TestExecutableServerlessApp; public class GeneratedProgram { + /// + /// This is responsible for inspecting the 'ANNOTATIONS_HANDLER' environment variable and invoking the appropriate Lambda function handler. + /// public static async Task Main(string[] args) { diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ProgramZipOutput.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ProgramZipOutput.g.cs index 337fc01f7..2518a7ce8 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ProgramZipOutput.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ProgramZipOutput.g.cs @@ -1,4 +1,6 @@ -using System; +// + +using System; using System.Linq; using System.Collections.Generic; using System.Text; @@ -10,6 +12,9 @@ namespace TestServerlessApp.Sub1; public class GeneratedProgram { + /// + /// This is responsible for inspecting the 'ANNOTATIONS_HANDLER' environment variable and invoking the appropriate Lambda function handler. + /// public static async Task Main(string[] args) { diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Add_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Add_Generated.g.cs index 4429228c8..c5935847c 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Add_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Add_Generated.g.cs @@ -1,4 +1,6 @@ -using System; +// + +using System; using System.Linq; using System.Collections.Generic; using System.Text; @@ -13,6 +15,11 @@ public class SimpleCalculator_Add_Generated { private readonly ServiceProvider serviceProvider; + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// public SimpleCalculator_Add_Generated() { SetExecutionEnvironment(); @@ -28,6 +35,12 @@ public SimpleCalculator_Add_Generated() serviceProvider = services.BuildServiceProvider(); } + /// + /// The generated Lambda function handler for + /// + /// The API Gateway request object that will be processed by the Lambda function handler. + /// The ILambdaContext that provides methods for logging and describing the Lambda environment. + /// Result of the Lambda function execution public Amazon.Lambda.APIGatewayEvents.APIGatewayProxyResponse Add(Amazon.Lambda.APIGatewayEvents.APIGatewayProxyRequest __request__, Amazon.Lambda.Core.ILambdaContext __context__) { // Create a scope for every request, diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_DivideAsync_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_DivideAsync_Generated.g.cs index c89c25ba1..59cf33f3b 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_DivideAsync_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_DivideAsync_Generated.g.cs @@ -1,4 +1,6 @@ -using System; +// + +using System; using System.Linq; using System.Collections.Generic; using System.Text; @@ -13,6 +15,11 @@ public class SimpleCalculator_DivideAsync_Generated { private readonly ServiceProvider serviceProvider; + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// public SimpleCalculator_DivideAsync_Generated() { SetExecutionEnvironment(); @@ -28,6 +35,12 @@ public SimpleCalculator_DivideAsync_Generated() serviceProvider = services.BuildServiceProvider(); } + /// + /// The generated Lambda function handler for + /// + /// The API Gateway request object that will be processed by the Lambda function handler. + /// The ILambdaContext that provides methods for logging and describing the Lambda environment. + /// Result of the Lambda function execution public async System.Threading.Tasks.Task DivideAsync(Amazon.Lambda.APIGatewayEvents.APIGatewayProxyRequest __request__, Amazon.Lambda.Core.ILambdaContext __context__) { // Create a scope for every request, diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Multiply_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Multiply_Generated.g.cs index ba715c9e9..77dde822a 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Multiply_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Multiply_Generated.g.cs @@ -1,4 +1,6 @@ -using System; +// + +using System; using System.Linq; using System.Collections.Generic; using System.Text; @@ -13,6 +15,11 @@ public class SimpleCalculator_Multiply_Generated { private readonly ServiceProvider serviceProvider; + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// public SimpleCalculator_Multiply_Generated() { SetExecutionEnvironment(); @@ -28,6 +35,12 @@ public SimpleCalculator_Multiply_Generated() serviceProvider = services.BuildServiceProvider(); } + /// + /// The generated Lambda function handler for + /// + /// The API Gateway request object that will be processed by the Lambda function handler. + /// The ILambdaContext that provides methods for logging and describing the Lambda environment. + /// Result of the Lambda function execution public Amazon.Lambda.APIGatewayEvents.APIGatewayProxyResponse Multiply(Amazon.Lambda.APIGatewayEvents.APIGatewayProxyRequest __request__, Amazon.Lambda.Core.ILambdaContext __context__) { // Create a scope for every request, diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Pi_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Pi_Generated.g.cs index 3439eab52..c1df83995 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Pi_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Pi_Generated.g.cs @@ -1,4 +1,6 @@ -using System; +// + +using System; using System.Linq; using System.Collections.Generic; using System.Text; @@ -13,6 +15,11 @@ public class SimpleCalculator_Pi_Generated { private readonly ServiceProvider serviceProvider; + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// public SimpleCalculator_Pi_Generated() { SetExecutionEnvironment(); @@ -28,6 +35,10 @@ public SimpleCalculator_Pi_Generated() serviceProvider = services.BuildServiceProvider(); } + /// + /// The generated Lambda function handler for + /// + /// Result of the Lambda function execution public double Pi(Stream stream) { // Create a scope for every request, diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Random_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Random_Generated.g.cs index f6a99480b..2f837b721 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Random_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Random_Generated.g.cs @@ -1,4 +1,6 @@ -using System; +// + +using System; using System.Linq; using System.Collections.Generic; using System.Text; @@ -13,6 +15,11 @@ public class SimpleCalculator_Random_Generated { private readonly ServiceProvider serviceProvider; + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// public SimpleCalculator_Random_Generated() { SetExecutionEnvironment(); @@ -28,6 +35,12 @@ public SimpleCalculator_Random_Generated() serviceProvider = services.BuildServiceProvider(); } + /// + /// The generated Lambda function handler for + /// + /// The request object that will be processed by the Lambda function handler. + /// The ILambdaContext that provides methods for logging and describing the Lambda environment. + /// Result of the Lambda function execution public async System.Threading.Tasks.Task Random(int maxValue, Amazon.Lambda.Core.ILambdaContext __context__) { // Create a scope for every request, diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Randoms_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Randoms_Generated.g.cs index 6af86d1be..31885ce85 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Randoms_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Randoms_Generated.g.cs @@ -1,4 +1,6 @@ -using System; +// + +using System; using System.Linq; using System.Collections.Generic; using System.Text; @@ -13,6 +15,11 @@ public class SimpleCalculator_Randoms_Generated { private readonly ServiceProvider serviceProvider; + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// public SimpleCalculator_Randoms_Generated() { SetExecutionEnvironment(); @@ -28,6 +35,12 @@ public SimpleCalculator_Randoms_Generated() serviceProvider = services.BuildServiceProvider(); } + /// + /// The generated Lambda function handler for + /// + /// The request object that will be processed by the Lambda function handler. + /// The ILambdaContext that provides methods for logging and describing the Lambda environment. + /// Result of the Lambda function execution public System.Collections.Generic.IList Randoms(TestServerlessApp.SimpleCalculator.RandomsInput input, Amazon.Lambda.Core.ILambdaContext __context__) { // Create a scope for every request, diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Subtract_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Subtract_Generated.g.cs index 8edda1d35..db0d3a798 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Subtract_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Subtract_Generated.g.cs @@ -1,4 +1,6 @@ -using System; +// + +using System; using System.Linq; using System.Collections.Generic; using System.Text; @@ -13,6 +15,11 @@ public class SimpleCalculator_Subtract_Generated { private readonly ServiceProvider serviceProvider; + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// public SimpleCalculator_Subtract_Generated() { SetExecutionEnvironment(); @@ -28,6 +35,12 @@ public SimpleCalculator_Subtract_Generated() serviceProvider = services.BuildServiceProvider(); } + /// + /// The generated Lambda function handler for + /// + /// The API Gateway request object that will be processed by the Lambda function handler. + /// The ILambdaContext that provides methods for logging and describing the Lambda environment. + /// Result of the Lambda function execution public Amazon.Lambda.APIGatewayEvents.APIGatewayProxyResponse Subtract(Amazon.Lambda.APIGatewayEvents.APIGatewayProxyRequest __request__, Amazon.Lambda.Core.ILambdaContext __context__) { // Create a scope for every request, diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SourceGenerationSerializationExample_GetPerson_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SourceGenerationSerializationExample_GetPerson_Generated.g.cs index f23c50208..b06ab5801 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SourceGenerationSerializationExample_GetPerson_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SourceGenerationSerializationExample_GetPerson_Generated.g.cs @@ -1,3 +1,5 @@ +// + using System; using System.Linq; using System.Collections.Generic; @@ -14,6 +16,11 @@ public class SourceGenerationSerializationExample_GetPerson_Generated private readonly SourceGenerationSerializationExample sourceGenerationSerializationExample; private readonly Amazon.Lambda.Serialization.SystemTextJson.SourceGeneratorLambdaJsonSerializer serializer; + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// public SourceGenerationSerializationExample_GetPerson_Generated() { SetExecutionEnvironment(); @@ -21,6 +28,12 @@ public SourceGenerationSerializationExample_GetPerson_Generated() serializer = new Amazon.Lambda.Serialization.SystemTextJson.SourceGeneratorLambdaJsonSerializer(); } + /// + /// The generated Lambda function handler for + /// + /// The API Gateway request object that will be processed by the Lambda function handler. + /// The ILambdaContext that provides methods for logging and describing the Lambda environment. + /// Result of the Lambda function execution public System.IO.Stream GetPerson(Amazon.Lambda.APIGatewayEvents.APIGatewayProxyRequest __request__, Amazon.Lambda.Core.ILambdaContext __context__) { var httpResults = sourceGenerationSerializationExample.GetPerson(__context__); diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/TaskExample_TaskReturn_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/TaskExample_TaskReturn_Generated.g.cs index 1bc6301ec..3b2ba2198 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/TaskExample_TaskReturn_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/TaskExample_TaskReturn_Generated.g.cs @@ -1,3 +1,5 @@ +// + using System; using System.Linq; using System.Collections.Generic; @@ -13,6 +15,11 @@ public class TaskExample_TaskReturn_Generated private readonly TaskExample taskExample; private readonly Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer serializer; + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// public TaskExample_TaskReturn_Generated() { SetExecutionEnvironment(); @@ -20,6 +27,12 @@ public TaskExample_TaskReturn_Generated() serializer = new Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer(); } + /// + /// The generated Lambda function handler for + /// + /// The request object that will be processed by the Lambda function handler. + /// The ILambdaContext that provides methods for logging and describing the Lambda environment. + /// Result of the Lambda function execution public async System.Threading.Tasks.Task TaskReturn(string text, Amazon.Lambda.Core.ILambdaContext __context__) { await taskExample.TaskReturn(text, __context__); diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/VoidExample_VoidReturn_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/VoidExample_VoidReturn_Generated.g.cs index addc8db10..ec097ee71 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/VoidExample_VoidReturn_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/VoidExample_VoidReturn_Generated.g.cs @@ -1,3 +1,5 @@ +// + using System; using System.Linq; using System.Collections.Generic; @@ -13,6 +15,11 @@ public class VoidExample_VoidReturn_Generated private readonly VoidExample voidExample; private readonly Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer serializer; + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// public VoidExample_VoidReturn_Generated() { SetExecutionEnvironment(); @@ -20,6 +27,12 @@ public VoidExample_VoidReturn_Generated() serializer = new Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer(); } + /// + /// The generated Lambda function handler for + /// + /// The request object that will be processed by the Lambda function handler. + /// The ILambdaContext that provides methods for logging and describing the Lambda environment. + /// Result of the Lambda function execution public void VoidReturn(string text, Amazon.Lambda.Core.ILambdaContext __context__) { voidExample.VoidReturn(text, __context__); diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/SourceGeneratorTests.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/SourceGeneratorTests.cs index a8c04be0d..1aae03b1a 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/SourceGeneratorTests.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/SourceGeneratorTests.cs @@ -284,7 +284,6 @@ public async Task VerifyFunctionInSubNamespace() { var expectedTemplateContent = (await File.ReadAllTextAsync(Path.Combine("Snapshots", "ServerlessTemplates", "subnamespace.template"))).ToEnvironmentLineEndings(); var expectedSubNamespaceGenerated = (await File.ReadAllTextAsync(Path.Combine("Snapshots", "Functions_ToUpper_Generated.g.cs"))).ToEnvironmentLineEndings(); - var expectedProgramGenerated = (await File.ReadAllTextAsync(Path.Combine("Snapshots", "Program.g.cs"))).ToEnvironmentLineEndings(); await new VerifyCS.Test { @@ -552,7 +551,6 @@ public async Task VerifyExecutableAssembly_WithNullAttributeValues_ShouldComplet { var expectedTemplateContent = (await File.ReadAllTextAsync(Path.Combine("Snapshots", "ServerlessTemplates", "subnamespace.template"))).ToEnvironmentLineEndings(); var expectedSubNamespaceGenerated = (await File.ReadAllTextAsync(Path.Combine("Snapshots", "Functions_ToUpper_Generated.g.cs"))).ToEnvironmentLineEndings(); - var expectedProgramGenerated = (await File.ReadAllTextAsync(Path.Combine("Snapshots", "Program.g.cs"))).ToEnvironmentLineEndings(); await new VerifyCS.Test { @@ -691,7 +689,7 @@ public async Task VerifySourceGeneratorSerializerWithHttpResultsBody() // The test framework doesn't appear to also execute the System.Text.Json source generator so Annotations generated code relying on the generated System.Text.Json code does not exist // so we get compile errors. In an real world scenario they are both run and the applicaton compiles correctly. - DiagnosticResult.CompilerError("CS0117").WithSpan($"Amazon.Lambda.Annotations.SourceGenerator{Path.DirectorySeparatorChar}Amazon.Lambda.Annotations.SourceGenerator.Generator{Path.DirectorySeparatorChar}SourceGenerationSerializationExample_GetPerson_Generated.g.cs", 29, 137, 29, 144).WithArguments("TestExecutableServerlessApp.HttpApiJsonSerializerContext", "Default"), + DiagnosticResult.CompilerError("CS0117").WithSpan($"Amazon.Lambda.Annotations.SourceGenerator{Path.DirectorySeparatorChar}Amazon.Lambda.Annotations.SourceGenerator.Generator{Path.DirectorySeparatorChar}SourceGenerationSerializationExample_GetPerson_Generated.g.cs", 42, 137, 42, 144).WithArguments("TestExecutableServerlessApp.HttpApiJsonSerializerContext", "Default"), DiagnosticResult.CompilerError("CS0534").WithSpan($"TestExecutableServerlessApp{Path.DirectorySeparatorChar}SourceGenerationSerializationExample.cs", 28, 26, 28, 54).WithArguments("TestExecutableServerlessApp.HttpApiJsonSerializerContext", "System.Text.Json.Serialization.JsonSerializerContext.GeneratedSerializerOptions.get"), DiagnosticResult.CompilerError("CS0534").WithSpan($"TestExecutableServerlessApp{Path.DirectorySeparatorChar}SourceGenerationSerializationExample.cs", 28, 26, 28, 54).WithArguments("TestExecutableServerlessApp.HttpApiJsonSerializerContext", "System.Text.Json.Serialization.JsonSerializerContext.GetTypeInfo(System.Type)"), DiagnosticResult.CompilerError("CS7036").WithSpan($"TestExecutableServerlessApp{Path.DirectorySeparatorChar}SourceGenerationSerializationExample.cs", 28, 26, 28, 54).WithArguments("options", "System.Text.Json.Serialization.JsonSerializerContext.JsonSerializerContext(System.Text.Json.JsonSerializerOptions?)"), diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/WriterTests/CloudFormationWriterTests.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/WriterTests/CloudFormationWriterTests.cs index d10267a52..4495a572d 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/WriterTests/CloudFormationWriterTests.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/WriterTests/CloudFormationWriterTests.cs @@ -56,7 +56,7 @@ public void ApplyLambdaFunctionDefaultProperties(CloudFormationTemplateFormat te Assert.False(templateWriter.Exists("ImageConfig")); } - [Theory] + [Theory] [InlineData(CloudFormationTemplateFormat.Json)] [InlineData(CloudFormationTemplateFormat.Yaml)] public void AddSingletonFunctionToEmptyTemplate(CloudFormationTemplateFormat templateFormat) From f246c92813435d0cb125a11628c203482037b476 Mon Sep 17 00:00:00 2001 From: Malhar Khimsaria <96malhar@gmail.com> Date: Sun, 12 May 2024 18:10:05 -0700 Subject: [PATCH 05/35] fix: Use the ILambdaSerializer to serialize the response body when returning an IHttpResult BREAKING CHANGE: Removed the JsonContext property in the HttpResultSerializationOptions class and replaced it with an ILambdaSerializer --- .../Generator.cs | 10 +- .../Models/LambdaFunctionModel.cs | 2 +- .../Models/LambdaSerializerInfo.cs | 8 +- .../Templates/APIGatewayInvoke.cs | 76 ++++++------ .../Templates/APIGatewayInvoke.tt | 3 +- .../APIGateway/HttpResults.cs | 39 ++---- ....Annotations.SourceGenerators.Tests.csproj | 1 + ...Usage.cs => HttpResultsStatusCodeUsage.cs} | 2 +- .../HttpResultsTest.cs | 57 ++++++++- ...ndResponseWithHeaderV1Async_Generated.g.cs | 3 +- ...otFoundResponseWithHeaderV1_Generated.g.cs | 3 +- ...ndResponseWithHeaderV2Async_Generated.g.cs | 3 +- ...otFoundResponseWithHeaderV2_Generated.g.cs | 3 +- ...esponseWithCustomSerializer_Generated.g.cs | 111 ++++++++++++++++++ ...s_OkResponseWithHeaderAsync_Generated.g.cs | 3 +- ...amples_OkResponseWithHeader_Generated.g.cs | 3 +- .../FunctionsZipOutput_ToLower_Generated.g.cs | 71 ----------- ...nse_NoParameterWithResponse_Generated.g.cs | 56 --------- ...eterlessMethods_NoParameter_Generated.g.cs | 56 --------- .../customizeResponse.template | 33 ++++++ ...ializationExample_GetPerson_Generated.g.cs | 3 +- .../SourceGeneratorTests.cs | 20 +++- .../SourceGenerationSerializationExample.cs | 2 - .../CustomResponse.cs | 12 ++ .../IntegrationTestContextFixture.cs | 2 +- .../CustomizeResponseExamples.cs | 33 ++++++ .../TestServerlessApp.csproj | 1 + .../TestServerlessApp/serverless.template | 33 ++++++ 28 files changed, 349 insertions(+), 300 deletions(-) rename Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/{HtttpResultsStatusCodeUsage.cs => HttpResultsStatusCodeUsage.cs} (95%) create mode 100644 Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_OkResponseWithCustomSerializer_Generated.g.cs delete mode 100644 Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/FunctionsZipOutput_ToLower_Generated.g.cs delete mode 100644 Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ParameterlessMethodWithResponse_NoParameterWithResponse_Generated.g.cs delete mode 100644 Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ParameterlessMethods_NoParameter_Generated.g.cs diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Generator.cs b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Generator.cs index 4ff503042..01413fb16 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Generator.cs +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Generator.cs @@ -356,7 +356,6 @@ private bool HasSerializerAttribute(GeneratorExecutionContext context, IMethodSy private LambdaSerializerInfo GetSerializerInfoAttribute(GeneratorExecutionContext context, IMethodSymbol methodModel) { var serializerString = DEFAULT_LAMBDA_SERIALIZER; - string serializerJsonContext = null; ISymbol symbol = null; @@ -377,24 +376,19 @@ private LambdaSerializerInfo GetSerializerInfoAttribute(GeneratorExecutionContex // Else return the default serializer. else { - return new LambdaSerializerInfo(serializerString, serializerJsonContext); + return new LambdaSerializerInfo(serializerString); } var attribute = symbol.GetAttributes().FirstOrDefault(attr => attr.AttributeClass.Name == TypeFullNames.LambdaSerializerAttributeWithoutNamespace); var serializerValue = attribute.ConstructorArguments.FirstOrDefault(kvp => kvp.Type.Name == nameof(Type)).Value; - if(serializerValue is INamedTypeSymbol typeSymbol && typeSymbol.Name.Contains("SourceGeneratorLambdaJsonSerializer") && typeSymbol.TypeArguments.Length == 1) - { - serializerJsonContext = typeSymbol.TypeArguments[0].ToString(); - } - if (serializerValue != null) { serializerString = serializerValue.ToString(); } - return new LambdaSerializerInfo(serializerString, serializerJsonContext); + return new LambdaSerializerInfo(serializerString); } public void Initialize(GeneratorInitializationContext context) diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/LambdaFunctionModel.cs b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/LambdaFunctionModel.cs index cba07d22a..8ef99542c 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/LambdaFunctionModel.cs +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/LambdaFunctionModel.cs @@ -35,7 +35,7 @@ public class LambdaFunctionModel : ILambdaFunctionSerializable /// Gets or sets fully qualified name of the serializer used for serialization or deserialization. /// public LambdaSerializerInfo SerializerInfo { get; set; } = - new LambdaSerializerInfo("Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer", null); + new LambdaSerializerInfo("Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer"); /// /// Gets or sets if the output is an executable. diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/LambdaSerializerInfo.cs b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/LambdaSerializerInfo.cs index 195818065..b73ce84af 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/LambdaSerializerInfo.cs +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/LambdaSerializerInfo.cs @@ -14,20 +14,14 @@ public class LambdaSerializerInfo /// /// /// - public LambdaSerializerInfo(string serializerName, string serializerJsonContextName) + public LambdaSerializerInfo(string serializerName) { SerializerName = serializerName; - SerializerJsonContextName = serializerJsonContextName; } /// /// The full name of the type registered as the ILambdaSerializer. /// public string SerializerName { get; } - - /// - /// The full name of the type used as the generic parameter of the SourceGeneratorLambdaJsonSerializer. - /// - public string SerializerJsonContextName { get; } } } diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/APIGatewayInvoke.cs b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/APIGatewayInvoke.cs index 36dff2f66..2e7b0ef9e 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/APIGatewayInvoke.cs +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/APIGatewayInvoke.cs @@ -22,7 +22,7 @@ namespace Amazon.Lambda.Annotations.SourceGenerator.Templates /// Class to produce the template output /// - #line 1 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" + #line 1 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")] public partial class APIGatewayInvoke : APIGatewayInvokeBase { @@ -33,7 +33,7 @@ public partial class APIGatewayInvoke : APIGatewayInvokeBase public virtual string TransformText() { - #line 10 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" + #line 10 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" var restApiAttribute = _model.LambdaMethod.Attributes.FirstOrDefault(att => att.Type.FullName == TypeFullNames.RestApiAttribute) as AttributeModel; var httpApiAttribute = _model.LambdaMethod.Attributes.FirstOrDefault(att => att.Type.FullName == TypeFullNames.HttpApiAttribute) as AttributeModel; @@ -46,27 +46,27 @@ public virtual string TransformText() #line hidden this.Write(" var httpResults = "); - #line 17 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" + #line 17 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.LambdaMethod.ReturnsGenericTask ? "await " : "")); #line default #line hidden - #line 17 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" + #line 17 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.LambdaMethod.ContainingType.Name.ToCamelCase())); #line default #line hidden this.Write("."); - #line 17 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" + #line 17 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.LambdaMethod.Name)); #line default #line hidden this.Write("("); - #line 17 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" + #line 17 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_parameterSignature)); #line default @@ -74,7 +74,7 @@ public virtual string TransformText() this.Write(");\r\n HttpResultSerializationOptions.ProtocolFormat serializationFormat" + " = "); - #line 18 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" + #line 18 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" this.Write(this.ToStringHelper.ToStringWithCulture(restApiAttribute != null ? "HttpResultSerializationOptions.ProtocolFormat.RestApi" : "HttpResultSerializationOptions.ProtocolFormat.HttpApi")); #line default @@ -82,25 +82,17 @@ public virtual string TransformText() this.Write(";\r\n HttpResultSerializationOptions.ProtocolVersion serializationVersio" + "n = "); - #line 19 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" + #line 19 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" this.Write(this.ToStringHelper.ToStringWithCulture(restApiAttribute != null || httpApiAttribute?.Data.Version == Amazon.Lambda.Annotations.APIGateway.HttpApiVersion.V1 ? "HttpResultSerializationOptions.ProtocolVersion.V1" : "HttpResultSerializationOptions.ProtocolVersion.V2")); - #line default - #line hidden - this.Write(";\r\n System.Text.Json.Serialization.JsonSerializerContext jsonContext =" + - " "); - - #line 20 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(_model.SerializerInfo.SerializerJsonContextName != null ? _model.SerializerInfo.SerializerJsonContextName + ".Default" : "null")); - #line default #line hidden this.Write(";\r\n var serializationOptions = new HttpResultSerializationOptions { Fo" + - "rmat = serializationFormat, Version = serializationVersion, JsonContext = jsonCo" + - "ntext };\r\n var response = httpResults.Serialize(serializationOptions)" + - ";\r\n"); + "rmat = serializationFormat, Version = serializationVersion, Serializer = seriali" + + "zer };\r\n var response = httpResults.Serialize(serializationOptions);\r" + + "\n"); - #line 23 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" + #line 22 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" } else if (_model.LambdaMethod.ReturnsVoid) @@ -111,28 +103,28 @@ public virtual string TransformText() #line hidden this.Write(" "); - #line 28 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" + #line 27 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.LambdaMethod.ContainingType.Name.ToCamelCase())); #line default #line hidden this.Write("."); - #line 28 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" + #line 27 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.LambdaMethod.Name)); #line default #line hidden this.Write("("); - #line 28 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" + #line 27 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_parameterSignature)); #line default #line hidden this.Write(");\r\n"); - #line 29 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" + #line 28 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" } else if (_model.LambdaMethod.ReturnsVoidTask) @@ -143,28 +135,28 @@ public virtual string TransformText() #line hidden this.Write(" await "); - #line 34 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" + #line 33 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.LambdaMethod.ContainingType.Name.ToCamelCase())); #line default #line hidden this.Write("."); - #line 34 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" + #line 33 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.LambdaMethod.Name)); #line default #line hidden this.Write("("); - #line 34 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" + #line 33 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_parameterSignature)); #line default #line hidden this.Write(");\r\n"); - #line 35 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" + #line 34 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" } else @@ -175,34 +167,34 @@ public virtual string TransformText() #line hidden this.Write(" var response = "); - #line 40 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" + #line 39 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.LambdaMethod.ReturnsGenericTask ? "await " : "")); #line default #line hidden - #line 40 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" + #line 39 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.LambdaMethod.ContainingType.Name.ToCamelCase())); #line default #line hidden this.Write("."); - #line 40 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" + #line 39 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.LambdaMethod.Name)); #line default #line hidden this.Write("("); - #line 40 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" + #line 39 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_parameterSignature)); #line default #line hidden this.Write(");\r\n"); - #line 41 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" + #line 40 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" } @@ -214,7 +206,7 @@ public virtual string TransformText() #line hidden this.Write(" return response;\r\n"); - #line 48 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" + #line 47 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" } else @@ -229,7 +221,7 @@ public virtual string TransformText() #line hidden this.Write("\r\n var body = response.ToString();\r\n"); - #line 59 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" + #line 58 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" } else if (_model.LambdaMethod.ReturnType.IsString()) @@ -251,7 +243,7 @@ public virtual string TransformText() var body = reader.ReadToEnd(); "); - #line 75 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" + #line 74 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" } } @@ -261,14 +253,14 @@ public virtual string TransformText() #line hidden this.Write("\r\n return new "); - #line 80 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" + #line 79 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.LambdaMethod.ReturnsVoidOrGenericTask ? _model.GeneratedMethod.ReturnType.TaskTypeArgument : _model.GeneratedMethod.ReturnType.FullName)); #line default #line hidden this.Write("\r\n {\r\n"); - #line 82 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" + #line 81 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" if (!_model.LambdaMethod.ReturnsVoid && !_model.LambdaMethod.ReturnsVoidTask) { @@ -278,7 +270,7 @@ public virtual string TransformText() #line hidden this.Write(" Body = "); - #line 86 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" + #line 85 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.LambdaMethod.ReturnType.IsString() ? "response" : "body")); #line default @@ -286,14 +278,14 @@ public virtual string TransformText() this.Write(",\r\n Headers = new Dictionary\r\n {\r\n " + " {\"Content-Type\", "); - #line 89 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" + #line 88 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.LambdaMethod.ReturnType.IsString() ? "\"text/plain\"" : "\"application/json\"")); #line default #line hidden this.Write("}\r\n },\r\n"); - #line 91 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" + #line 90 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" } @@ -302,7 +294,7 @@ public virtual string TransformText() #line hidden this.Write(" StatusCode = 200\r\n };\r\n"); - #line 96 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" + #line 95 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewayInvoke.tt" } diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/APIGatewayInvoke.tt b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/APIGatewayInvoke.tt index c7cc555a2..890a72972 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/APIGatewayInvoke.tt +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/APIGatewayInvoke.tt @@ -17,8 +17,7 @@ var httpResults = <#= _model.LambdaMethod.ReturnsGenericTask ? "await " : "" #><#= _model.LambdaMethod.ContainingType.Name.ToCamelCase() #>.<#= _model.LambdaMethod.Name #>(<#= _parameterSignature #>); HttpResultSerializationOptions.ProtocolFormat serializationFormat = <#= restApiAttribute != null ? "HttpResultSerializationOptions.ProtocolFormat.RestApi" : "HttpResultSerializationOptions.ProtocolFormat.HttpApi"#>; HttpResultSerializationOptions.ProtocolVersion serializationVersion = <#= restApiAttribute != null || httpApiAttribute?.Data.Version == Amazon.Lambda.Annotations.APIGateway.HttpApiVersion.V1 ? "HttpResultSerializationOptions.ProtocolVersion.V1" : "HttpResultSerializationOptions.ProtocolVersion.V2"#>; - System.Text.Json.Serialization.JsonSerializerContext jsonContext = <#= _model.SerializerInfo.SerializerJsonContextName != null ? _model.SerializerInfo.SerializerJsonContextName + ".Default" : "null"#>; - var serializationOptions = new HttpResultSerializationOptions { Format = serializationFormat, Version = serializationVersion, JsonContext = jsonContext }; + var serializationOptions = new HttpResultSerializationOptions { Format = serializationFormat, Version = serializationVersion, Serializer = serializer }; var response = httpResults.Serialize(serializationOptions); <# } diff --git a/Libraries/src/Amazon.Lambda.Annotations/APIGateway/HttpResults.cs b/Libraries/src/Amazon.Lambda.Annotations/APIGateway/HttpResults.cs index a8224a32c..539da4546 100644 --- a/Libraries/src/Amazon.Lambda.Annotations/APIGateway/HttpResults.cs +++ b/Libraries/src/Amazon.Lambda.Annotations/APIGateway/HttpResults.cs @@ -3,6 +3,8 @@ using System.IO; using System.Linq; using System.Net; +using Amazon.Lambda.Core; + #if NET6_0_OR_GREATER using System.Buffers; using System.Text.Json; @@ -66,16 +68,11 @@ public enum ProtocolVersion { /// public ProtocolVersion Version { get; set; } -#if !NETSTANDARD2_0 /// - /// The JsonSerializerContext used for serializing response body using .NET's source generator serializer. - /// This is set when the SourceGeneratorLambdaJsonSerializer serializer is registered taking the JsonSerializerContext - /// assigned with it. If SourceGeneratorLambdaJsonSerializer is not used then the reflection based - /// JsonSerializer.Serialize method is used. + /// The JSON serializer used for serializing the response body. /// - public JsonSerializerContext JsonContext { get; set; } -#endif + public ILambdaSerializer Serializer { get; set; } } /// @@ -350,13 +347,7 @@ public static IHttpResult NewResult(HttpStatusCode statusCode, object body = nul #if !NETSTANDARD2_0 - // See comment in class documentation on the rules for serializing. If any changes are made in this method be sure to update - // the comment above. - [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026", - Justification = "When using this library with the Native AOT the SourceGeneratorLambdaJsonSerializer has to be registered which will provide the information needed for JsonSerializerContext and avoid the reflection based JsonSerializer.Serialize call")] - [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("ReflectionAnalysis", "IL3050", - Justification = "When using this library with the Native AOT the SourceGeneratorLambdaJsonSerializer has to be registered which will provide the information needed for JsonSerializerContext and avoid the reflection based JsonSerializer.Serialize call")] - private static (string body, string contentType, bool base64Encoded) FormatBody(object body, JsonSerializerContext context) + private static (string body, string contentType, bool base64Encoded) FormatBody(object body, ILambdaSerializer serializer) { if (body == null) return new (null, null, false); @@ -392,16 +383,10 @@ private static (string body, string contentType, bool base64Encoded) FormatBody( } else { - string serializedBody; - if (context != null) - { - serializedBody = JsonSerializer.Serialize(body, body.GetType(), context); - } - else - { - serializedBody = JsonSerializer.Serialize(body); - } - + var bodyStream = new MemoryStream(); + serializer.Serialize(body, bodyStream); + bodyStream.Position = 0; + var serializedBody = new StreamReader(bodyStream).ReadToEnd(); return new(serializedBody, CONTENT_TYPE_APPLICATION_JSON, false); } } @@ -421,7 +406,7 @@ public Stream Serialize(HttpResultSerializationOptions options) throw new NotImplementedException(); #else - var (serializedBody, defaultContentType, isBase64Encoded) = FormatBody(_rawBody, options.JsonContext); + var (serializedBody, defaultContentType, isBase64Encoded) = FormatBody(_rawBody, options.Serializer); // If the user didn't explicit set the content type then default to application/json if (!string.IsNullOrEmpty(serializedBody) && (_headers == null || !_headers.ContainsKey(HEADER_NAME_CONTENT_TYPE))) @@ -429,7 +414,6 @@ public Stream Serialize(HttpResultSerializationOptions options) AddHeader(HEADER_NAME_CONTENT_TYPE, defaultContentType); } - var stream = new MemoryStream(); object response; Type responseType; if (options.Format == HttpResultSerializationOptions.ProtocolFormat.RestApi || @@ -457,9 +441,8 @@ public Stream Serialize(HttpResultSerializationOptions options) responseType = typeof(APIGatewayV2Response); } - + var stream = new MemoryStream(); JsonSerializer.Serialize(stream, response, responseType, AnnotationsResponseJsonSerializerContext.Default); - stream.Position = 0; return stream; #endif diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Amazon.Lambda.Annotations.SourceGenerators.Tests.csproj b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Amazon.Lambda.Annotations.SourceGenerators.Tests.csproj index b57a3f00c..1d89cbeb6 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Amazon.Lambda.Annotations.SourceGenerators.Tests.csproj +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Amazon.Lambda.Annotations.SourceGenerators.Tests.csproj @@ -11,6 +11,7 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/HtttpResultsStatusCodeUsage.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/HttpResultsStatusCodeUsage.cs similarity index 95% rename from Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/HtttpResultsStatusCodeUsage.cs rename to Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/HttpResultsStatusCodeUsage.cs index e9dc6acb3..0d99b0a7e 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/HtttpResultsStatusCodeUsage.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/HttpResultsStatusCodeUsage.cs @@ -5,7 +5,7 @@ namespace Amazon.Lambda.Annotations.SourceGenerators.Tests { - public class HtttpResultsStatusCodeUsage + public class HttpResultsStatusCodeUsage { [Fact] public void UsageOfIHttpResultStatusCode() diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/HttpResultsTest.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/HttpResultsTest.cs index 04e72cdd7..df4b8a73f 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/HttpResultsTest.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/HttpResultsTest.cs @@ -6,6 +6,9 @@ using Xunit; using System.IO; using System.Linq; +using Amazon.Lambda.Serialization.SystemTextJson; +using Amazon.Lambda.Core; +using Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Interfaces; namespace Amazon.Lambda.Annotations.SourceGenerators.Tests { @@ -357,21 +360,42 @@ public void ServiceUnavailable_WithRetryAfter() }); } + [Fact] + public void HttpResult_WithCustomSerializer() + { + var result = HttpResults.Ok(new Person { FirstName = "John", LastName = "Doe" }); + var response = result.Serialize(new HttpResultSerializationOptions + { + Format = HttpResultSerializationOptions.ProtocolFormat.HttpApi, + Version = HttpResultSerializationOptions.ProtocolVersion.V2, + Serializer = new CustomLambdaSerializer() + }); + + var jsonDoc = JsonDocument.Parse(response); + Assert.Equal(200, jsonDoc.RootElement.GetProperty("statusCode").GetInt32()); + + var body = jsonDoc.RootElement.GetProperty("body").GetString(); + var person = JsonSerializer.Deserialize>(body); + Assert.Equal("John", person["FIRST_NAME"]); + Assert.Equal("Doe", person["LAST_NAME"]); + } + private void ValidateResult(Func resultCreator, HttpStatusCode statusCode, string body = null, bool isBase64Encoded = false, IDictionary> headers = null) { - var testScenarios = new List> + var lambdaSerializer = new DefaultLambdaJsonSerializer(); + var testScenarios = new List> { - new (HttpResultSerializationOptions.ProtocolFormat.RestApi, HttpResultSerializationOptions.ProtocolVersion.V1), - new (HttpResultSerializationOptions.ProtocolFormat.HttpApi, HttpResultSerializationOptions.ProtocolVersion.V1), - new (HttpResultSerializationOptions.ProtocolFormat.HttpApi, HttpResultSerializationOptions.ProtocolVersion.V2) + new (HttpResultSerializationOptions.ProtocolFormat.RestApi, HttpResultSerializationOptions.ProtocolVersion.V1, lambdaSerializer), + new (HttpResultSerializationOptions.ProtocolFormat.HttpApi, HttpResultSerializationOptions.ProtocolVersion.V1, lambdaSerializer), + new (HttpResultSerializationOptions.ProtocolFormat.HttpApi, HttpResultSerializationOptions.ProtocolVersion.V2, lambdaSerializer) }; - foreach(var (format, version) in testScenarios) + foreach(var (format, version, serializer) in testScenarios) { IHttpResult result = resultCreator(); - var stream = result.Serialize(new HttpResultSerializationOptions { Format = format, Version = version }); + var stream = result.Serialize(new HttpResultSerializationOptions { Format = format, Version = version, Serializer = serializer }); var jsonDoc = JsonDocument.Parse(stream); if (format == HttpResultSerializationOptions.ProtocolFormat.RestApi || (format == HttpResultSerializationOptions.ProtocolFormat.HttpApi && version == HttpResultSerializationOptions.ProtocolVersion.V1)) { @@ -456,5 +480,26 @@ public class FakeBody { public int Id { get; set; } = 1; } + + public class Person + { + public string FirstName { get; set; } + public string LastName { get; set; } + } + + public class CustomLambdaSerializer : DefaultLambdaJsonSerializer + { + public CustomLambdaSerializer() + : base(CreateCustomizer()) + { } + + private static Action CreateCustomizer() + { + return (JsonSerializerOptions options) => + { + options.PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseUpper; + }; + } + } } } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV1Async_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV1Async_Generated.g.cs index be43ef9aa..8f4ca49ab 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV1Async_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV1Async_Generated.g.cs @@ -73,8 +73,7 @@ public CustomizeResponseExamples_NotFoundResponseWithHeaderV1Async_Generated() var httpResults = await customizeResponseExamples.NotFoundResponseWithHeaderV1Async(x, __context__); HttpResultSerializationOptions.ProtocolFormat serializationFormat = HttpResultSerializationOptions.ProtocolFormat.HttpApi; HttpResultSerializationOptions.ProtocolVersion serializationVersion = HttpResultSerializationOptions.ProtocolVersion.V1; - System.Text.Json.Serialization.JsonSerializerContext jsonContext = null; - var serializationOptions = new HttpResultSerializationOptions { Format = serializationFormat, Version = serializationVersion, JsonContext = jsonContext }; + var serializationOptions = new HttpResultSerializationOptions { Format = serializationFormat, Version = serializationVersion, Serializer = serializer }; var response = httpResults.Serialize(serializationOptions); return response; } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV1_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV1_Generated.g.cs index be1ba0bf3..0d2ceb3ec 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV1_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV1_Generated.g.cs @@ -73,8 +73,7 @@ public System.IO.Stream NotFoundResponseWithHeaderV1(Amazon.Lambda.APIGatewayEve var httpResults = customizeResponseExamples.NotFoundResponseWithHeaderV1(x, __context__); HttpResultSerializationOptions.ProtocolFormat serializationFormat = HttpResultSerializationOptions.ProtocolFormat.HttpApi; HttpResultSerializationOptions.ProtocolVersion serializationVersion = HttpResultSerializationOptions.ProtocolVersion.V1; - System.Text.Json.Serialization.JsonSerializerContext jsonContext = null; - var serializationOptions = new HttpResultSerializationOptions { Format = serializationFormat, Version = serializationVersion, JsonContext = jsonContext }; + var serializationOptions = new HttpResultSerializationOptions { Format = serializationFormat, Version = serializationVersion, Serializer = serializer }; var response = httpResults.Serialize(serializationOptions); return response; } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV2Async_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV2Async_Generated.g.cs index 8ffaa989f..efc53ac27 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV2Async_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV2Async_Generated.g.cs @@ -73,8 +73,7 @@ public CustomizeResponseExamples_NotFoundResponseWithHeaderV2Async_Generated() var httpResults = await customizeResponseExamples.NotFoundResponseWithHeaderV2Async(x, __context__); HttpResultSerializationOptions.ProtocolFormat serializationFormat = HttpResultSerializationOptions.ProtocolFormat.HttpApi; HttpResultSerializationOptions.ProtocolVersion serializationVersion = HttpResultSerializationOptions.ProtocolVersion.V2; - System.Text.Json.Serialization.JsonSerializerContext jsonContext = null; - var serializationOptions = new HttpResultSerializationOptions { Format = serializationFormat, Version = serializationVersion, JsonContext = jsonContext }; + var serializationOptions = new HttpResultSerializationOptions { Format = serializationFormat, Version = serializationVersion, Serializer = serializer }; var response = httpResults.Serialize(serializationOptions); return response; } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV2_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV2_Generated.g.cs index 30b029167..7aab90492 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV2_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV2_Generated.g.cs @@ -73,8 +73,7 @@ public System.IO.Stream NotFoundResponseWithHeaderV2(Amazon.Lambda.APIGatewayEve var httpResults = customizeResponseExamples.NotFoundResponseWithHeaderV2(x, __context__); HttpResultSerializationOptions.ProtocolFormat serializationFormat = HttpResultSerializationOptions.ProtocolFormat.HttpApi; HttpResultSerializationOptions.ProtocolVersion serializationVersion = HttpResultSerializationOptions.ProtocolVersion.V2; - System.Text.Json.Serialization.JsonSerializerContext jsonContext = null; - var serializationOptions = new HttpResultSerializationOptions { Format = serializationFormat, Version = serializationVersion, JsonContext = jsonContext }; + var serializationOptions = new HttpResultSerializationOptions { Format = serializationFormat, Version = serializationVersion, Serializer = serializer }; var response = httpResults.Serialize(serializationOptions); return response; } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_OkResponseWithCustomSerializer_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_OkResponseWithCustomSerializer_Generated.g.cs new file mode 100644 index 000000000..b4674fa21 --- /dev/null +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_OkResponseWithCustomSerializer_Generated.g.cs @@ -0,0 +1,111 @@ +// + +using System; +using System.Linq; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using System.IO; +using Amazon.Lambda.Core; +using Amazon.Lambda.Annotations.APIGateway; + +namespace TestServerlessApp +{ + public class CustomizeResponseExamples_OkResponseWithCustomSerializer_Generated + { + private readonly CustomizeResponseExamples customizeResponseExamples; + private readonly TestServerlessApp.PersonSerializer serializer; + + /// + /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment + /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the + /// region the Lambda function is executed in. + /// + public CustomizeResponseExamples_OkResponseWithCustomSerializer_Generated() + { + SetExecutionEnvironment(); + customizeResponseExamples = new CustomizeResponseExamples(); + serializer = new TestServerlessApp.PersonSerializer(); + } + + /// + /// The generated Lambda function handler for + /// + /// The API Gateway request object that will be processed by the Lambda function handler. + /// The ILambdaContext that provides methods for logging and describing the Lambda environment. + /// Result of the Lambda function execution + public async System.Threading.Tasks.Task OkResponseWithCustomSerializer(Amazon.Lambda.APIGatewayEvents.APIGatewayProxyRequest __request__, Amazon.Lambda.Core.ILambdaContext __context__) + { + var validationErrors = new List(); + + var firstName = default(string); + if (__request__.PathParameters?.ContainsKey("firstName") == true) + { + try + { + firstName = (string)Convert.ChangeType(__request__.PathParameters["firstName"], typeof(string)); + } + catch (Exception e) when (e is InvalidCastException || e is FormatException || e is OverflowException || e is ArgumentException) + { + validationErrors.Add($"Value {__request__.PathParameters["firstName"]} at 'firstName' failed to satisfy constraint: {e.Message}"); + } + } + + var lastName = default(string); + if (__request__.PathParameters?.ContainsKey("lastName") == true) + { + try + { + lastName = (string)Convert.ChangeType(__request__.PathParameters["lastName"], typeof(string)); + } + catch (Exception e) when (e is InvalidCastException || e is FormatException || e is OverflowException || e is ArgumentException) + { + validationErrors.Add($"Value {__request__.PathParameters["lastName"]} at 'lastName' failed to satisfy constraint: {e.Message}"); + } + } + + // return 400 Bad Request if there exists a validation error + if (validationErrors.Any()) + { + var errorResult = new Amazon.Lambda.APIGatewayEvents.APIGatewayProxyResponse + { + Body = @$"{{""message"": ""{validationErrors.Count} validation error(s) detected: {string.Join(",", validationErrors)}""}}", + Headers = new Dictionary + { + {"Content-Type", "application/json"}, + {"x-amzn-ErrorType", "ValidationException"} + }, + StatusCode = 400 + }; + var errorStream = new System.IO.MemoryStream(); + serializer.Serialize(errorResult, errorStream); + errorStream.Position = 0; + return errorStream; + } + + var httpResults = await customizeResponseExamples.OkResponseWithCustomSerializer(firstName, lastName, __context__); + HttpResultSerializationOptions.ProtocolFormat serializationFormat = HttpResultSerializationOptions.ProtocolFormat.HttpApi; + HttpResultSerializationOptions.ProtocolVersion serializationVersion = HttpResultSerializationOptions.ProtocolVersion.V1; + var serializationOptions = new HttpResultSerializationOptions { Format = serializationFormat, Version = serializationVersion, Serializer = serializer }; + var response = httpResults.Serialize(serializationOptions); + return response; + } + + private static void SetExecutionEnvironment() + { + const string envName = "AWS_EXECUTION_ENV"; + + var envValue = new StringBuilder(); + + // If there is an existing execution environment variable add the annotations package as a suffix. + if(!string.IsNullOrEmpty(Environment.GetEnvironmentVariable(envName))) + { + envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); + } + + envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + + Environment.SetEnvironmentVariable(envName, envValue.ToString()); + } + } +} \ No newline at end of file diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_OkResponseWithHeaderAsync_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_OkResponseWithHeaderAsync_Generated.g.cs index 90ba6c73b..366cc83e7 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_OkResponseWithHeaderAsync_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_OkResponseWithHeaderAsync_Generated.g.cs @@ -73,8 +73,7 @@ public CustomizeResponseExamples_OkResponseWithHeaderAsync_Generated() var httpResults = await customizeResponseExamples.OkResponseWithHeaderAsync(x, __context__); HttpResultSerializationOptions.ProtocolFormat serializationFormat = HttpResultSerializationOptions.ProtocolFormat.RestApi; HttpResultSerializationOptions.ProtocolVersion serializationVersion = HttpResultSerializationOptions.ProtocolVersion.V1; - System.Text.Json.Serialization.JsonSerializerContext jsonContext = null; - var serializationOptions = new HttpResultSerializationOptions { Format = serializationFormat, Version = serializationVersion, JsonContext = jsonContext }; + var serializationOptions = new HttpResultSerializationOptions { Format = serializationFormat, Version = serializationVersion, Serializer = serializer }; var response = httpResults.Serialize(serializationOptions); return response; } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_OkResponseWithHeader_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_OkResponseWithHeader_Generated.g.cs index eaa400ee1..c99f4c2b3 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_OkResponseWithHeader_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_OkResponseWithHeader_Generated.g.cs @@ -73,8 +73,7 @@ public System.IO.Stream OkResponseWithHeader(Amazon.Lambda.APIGatewayEvents.APIG var httpResults = customizeResponseExamples.OkResponseWithHeader(x, __context__); HttpResultSerializationOptions.ProtocolFormat serializationFormat = HttpResultSerializationOptions.ProtocolFormat.RestApi; HttpResultSerializationOptions.ProtocolVersion serializationVersion = HttpResultSerializationOptions.ProtocolVersion.V1; - System.Text.Json.Serialization.JsonSerializerContext jsonContext = null; - var serializationOptions = new HttpResultSerializationOptions { Format = serializationFormat, Version = serializationVersion, JsonContext = jsonContext }; + var serializationOptions = new HttpResultSerializationOptions { Format = serializationFormat, Version = serializationVersion, Serializer = serializer }; var response = httpResults.Serialize(serializationOptions); return response; } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/FunctionsZipOutput_ToLower_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/FunctionsZipOutput_ToLower_Generated.g.cs deleted file mode 100644 index 7bca2834e..000000000 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/FunctionsZipOutput_ToLower_Generated.g.cs +++ /dev/null @@ -1,71 +0,0 @@ -// - -using System; -using System.Linq; -using System.Collections.Generic; -using System.Text; -using System.Threading.Tasks; -using System.IO; -using Microsoft.Extensions.DependencyInjection; -using Amazon.Lambda.Core; - -namespace TestServerlessApp.Sub1 -{ - public class FunctionsZipOutput_ToLower_Generated - { - private readonly ServiceProvider serviceProvider; - - /// - /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment - /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the - /// region the Lambda function is executed in. - /// - public FunctionsZipOutput_ToLower_Generated() - { - SetExecutionEnvironment(); - var services = new ServiceCollection(); - - // By default, Lambda function class is added to the service container using the singleton lifetime - // To use a different lifetime, specify the lifetime in Startup.ConfigureServices(IServiceCollection) method. - services.AddSingleton(); - services.AddSingleton(); - - var startup = new TestServerlessApp.Startup(); - startup.ConfigureServices(services); - serviceProvider = services.BuildServiceProvider(); - } - - /// - /// The generated Lambda function handler for - /// - /// The request object that will be processed by the Lambda function handler. - /// Result of the Lambda function execution - public string ToLower(string text) - { - // Create a scope for every request, - // this allows creating scoped dependencies without creating a scope manually. - using var scope = serviceProvider.CreateScope(); - var functionsZipOutput = scope.ServiceProvider.GetRequiredService(); - var serializer = scope.ServiceProvider.GetRequiredService(); - - return functionsZipOutput.ToLower(text); - } - - private static void SetExecutionEnvironment() - { - const string envName = "AWS_EXECUTION_ENV"; - - var envValue = new StringBuilder(); - - // If there is an existing execution environment variable add the annotations package as a suffix. - if(!string.IsNullOrEmpty(Environment.GetEnvironmentVariable(envName))) - { - envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); - } - - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); - - Environment.SetEnvironmentVariable(envName, envValue.ToString()); - } - } -} \ No newline at end of file diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ParameterlessMethodWithResponse_NoParameterWithResponse_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ParameterlessMethodWithResponse_NoParameterWithResponse_Generated.g.cs deleted file mode 100644 index e96636875..000000000 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ParameterlessMethodWithResponse_NoParameterWithResponse_Generated.g.cs +++ /dev/null @@ -1,56 +0,0 @@ -// - -using System; -using System.Linq; -using System.Collections.Generic; -using System.Text; -using System.Threading.Tasks; -using System.IO; -using Amazon.Lambda.Core; - -namespace TestServerlessApp -{ - public class ParameterlessMethodWithResponse_NoParameterWithResponse_Generated - { - private readonly ParameterlessMethodWithResponse parameterlessMethodWithResponse; - private readonly Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer serializer; - - /// - /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment - /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the - /// region the Lambda function is executed in. - /// - public ParameterlessMethodWithResponse_NoParameterWithResponse_Generated() - { - SetExecutionEnvironment(); - parameterlessMethodWithResponse = new ParameterlessMethodWithResponse(); - serializer = new Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer(); - } - - /// - /// The generated Lambda function handler for - /// - /// Result of the Lambda function execution - public string NoParameterWithResponse(Stream stream) - { - return parameterlessMethodWithResponse.NoParameterWithResponse(); - } - - private static void SetExecutionEnvironment() - { - const string envName = "AWS_EXECUTION_ENV"; - - var envValue = new StringBuilder(); - - // If there is an existing execution environment variable add the annotations package as a suffix. - if(!string.IsNullOrEmpty(Environment.GetEnvironmentVariable(envName))) - { - envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); - } - - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); - - Environment.SetEnvironmentVariable(envName, envValue.ToString()); - } - } -} \ No newline at end of file diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ParameterlessMethods_NoParameter_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ParameterlessMethods_NoParameter_Generated.g.cs deleted file mode 100644 index d2e8e4c7b..000000000 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ParameterlessMethods_NoParameter_Generated.g.cs +++ /dev/null @@ -1,56 +0,0 @@ -// - -using System; -using System.Linq; -using System.Collections.Generic; -using System.Text; -using System.Threading.Tasks; -using System.IO; -using Amazon.Lambda.Core; - -namespace TestServerlessApp -{ - public class ParameterlessMethods_NoParameter_Generated - { - private readonly ParameterlessMethods parameterlessMethods; - private readonly Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer serializer; - - /// - /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment - /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the - /// region the Lambda function is executed in. - /// - public ParameterlessMethods_NoParameter_Generated() - { - SetExecutionEnvironment(); - parameterlessMethods = new ParameterlessMethods(); - serializer = new Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer(); - } - - /// - /// The generated Lambda function handler for - /// - /// Result of the Lambda function execution - public void NoParameter(Stream stream) - { - parameterlessMethods.NoParameter(); - } - - private static void SetExecutionEnvironment() - { - const string envName = "AWS_EXECUTION_ENV"; - - var envValue = new StringBuilder(); - - // If there is an existing execution environment variable add the annotations package as a suffix. - if(!string.IsNullOrEmpty(Environment.GetEnvironmentVariable(envName))) - { - envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); - } - - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); - - Environment.SetEnvironmentVariable(envName, envValue.ToString()); - } - } -} \ No newline at end of file diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/customizeResponse.template b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/customizeResponse.template index 2ccc7b4ca..d0c7c6879 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/customizeResponse.template +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/customizeResponse.template @@ -196,6 +196,39 @@ } } } + }, + "TestServerlessAppCustomizeResponseExamplesOkResponseWithCustomSerializerGenerated": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations", + "SyncedEvents": [ + "RootGet" + ] + }, + "Properties": { + "MemorySize": 512, + "Timeout": 30, + "Policies": [ + "AWSLambdaBasicExecutionRole" + ], + "PackageType": "Image", + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestProject::TestServerlessApp.CustomizeResponseExamples_OkResponseWithCustomSerializer_Generated::OkResponseWithCustomSerializer" + ] + }, + "Events": { + "RootGet": { + "Type": "HttpApi", + "Properties": { + "Path": "/okresponsewithcustomserializerasync/{firstName}/{lastName}", + "Method": "GET", + "PayloadFormatVersion": "1.0" + } + } + } + } } } } \ No newline at end of file diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SourceGenerationSerializationExample_GetPerson_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SourceGenerationSerializationExample_GetPerson_Generated.g.cs index b06ab5801..930690a11 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SourceGenerationSerializationExample_GetPerson_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SourceGenerationSerializationExample_GetPerson_Generated.g.cs @@ -39,8 +39,7 @@ public System.IO.Stream GetPerson(Amazon.Lambda.APIGatewayEvents.APIGatewayProxy var httpResults = sourceGenerationSerializationExample.GetPerson(__context__); HttpResultSerializationOptions.ProtocolFormat serializationFormat = HttpResultSerializationOptions.ProtocolFormat.RestApi; HttpResultSerializationOptions.ProtocolVersion serializationVersion = HttpResultSerializationOptions.ProtocolVersion.V1; - System.Text.Json.Serialization.JsonSerializerContext jsonContext = TestExecutableServerlessApp.HttpApiJsonSerializerContext.Default; - var serializationOptions = new HttpResultSerializationOptions { Format = serializationFormat, Version = serializationVersion, JsonContext = jsonContext }; + var serializationOptions = new HttpResultSerializationOptions { Format = serializationFormat, Version = serializationVersion, Serializer = serializer }; var response = httpResults.Serialize(serializationOptions); return response; } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/SourceGeneratorTests.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/SourceGeneratorTests.cs index 1aae03b1a..6b02c6015 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/SourceGeneratorTests.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/SourceGeneratorTests.cs @@ -689,10 +689,9 @@ public async Task VerifySourceGeneratorSerializerWithHttpResultsBody() // The test framework doesn't appear to also execute the System.Text.Json source generator so Annotations generated code relying on the generated System.Text.Json code does not exist // so we get compile errors. In an real world scenario they are both run and the applicaton compiles correctly. - DiagnosticResult.CompilerError("CS0117").WithSpan($"Amazon.Lambda.Annotations.SourceGenerator{Path.DirectorySeparatorChar}Amazon.Lambda.Annotations.SourceGenerator.Generator{Path.DirectorySeparatorChar}SourceGenerationSerializationExample_GetPerson_Generated.g.cs", 42, 137, 42, 144).WithArguments("TestExecutableServerlessApp.HttpApiJsonSerializerContext", "Default"), - DiagnosticResult.CompilerError("CS0534").WithSpan($"TestExecutableServerlessApp{Path.DirectorySeparatorChar}SourceGenerationSerializationExample.cs", 28, 26, 28, 54).WithArguments("TestExecutableServerlessApp.HttpApiJsonSerializerContext", "System.Text.Json.Serialization.JsonSerializerContext.GeneratedSerializerOptions.get"), - DiagnosticResult.CompilerError("CS0534").WithSpan($"TestExecutableServerlessApp{Path.DirectorySeparatorChar}SourceGenerationSerializationExample.cs", 28, 26, 28, 54).WithArguments("TestExecutableServerlessApp.HttpApiJsonSerializerContext", "System.Text.Json.Serialization.JsonSerializerContext.GetTypeInfo(System.Type)"), - DiagnosticResult.CompilerError("CS7036").WithSpan($"TestExecutableServerlessApp{Path.DirectorySeparatorChar}SourceGenerationSerializationExample.cs", 28, 26, 28, 54).WithArguments("options", "System.Text.Json.Serialization.JsonSerializerContext.JsonSerializerContext(System.Text.Json.JsonSerializerOptions?)"), + DiagnosticResult.CompilerError("CS0534").WithSpan($"TestExecutableServerlessApp{Path.DirectorySeparatorChar}SourceGenerationSerializationExample.cs", 26, 26, 26, 54).WithArguments("TestExecutableServerlessApp.HttpApiJsonSerializerContext", "System.Text.Json.Serialization.JsonSerializerContext.GeneratedSerializerOptions.get"), + DiagnosticResult.CompilerError("CS0534").WithSpan($"TestExecutableServerlessApp{Path.DirectorySeparatorChar}SourceGenerationSerializationExample.cs", 26, 26, 26, 54).WithArguments("TestExecutableServerlessApp.HttpApiJsonSerializerContext", "System.Text.Json.Serialization.JsonSerializerContext.GetTypeInfo(System.Type)"), + DiagnosticResult.CompilerError("CS7036").WithSpan($"TestExecutableServerlessApp{Path.DirectorySeparatorChar}SourceGenerationSerializationExample.cs", 26, 26, 26, 54).WithArguments("options", "System.Text.Json.Serialization.JsonSerializerContext.JsonSerializerContext(System.Text.Json.JsonSerializerOptions?)"), } } }; @@ -880,6 +879,7 @@ public async Task CustomizeResponses() var expectedOkResponseWithHeaderAsyncGenerated = (await File.ReadAllTextAsync(Path.Combine("Snapshots", "CustomizeResponseExamples_OkResponseWithHeaderAsync_Generated.g.cs"))).ToEnvironmentLineEndings(); var expectedNotFoundResponseWithHeaderV2AsyncGenerated = (await File.ReadAllTextAsync(Path.Combine("Snapshots", "CustomizeResponseExamples_NotFoundResponseWithHeaderV2Async_Generated.g.cs"))).ToEnvironmentLineEndings(); var expectedNotFoundResponseWithHeaderV1AsyncGenerated = (await File.ReadAllTextAsync(Path.Combine("Snapshots", "CustomizeResponseExamples_NotFoundResponseWithHeaderV1Async_Generated.g.cs"))).ToEnvironmentLineEndings(); + var expectedOkResponseWithCustomSerializerGenerated = (await File.ReadAllTextAsync(Path.Combine("Snapshots", "CustomizeResponseExamples_OkResponseWithCustomSerializer_Generated.g.cs"))).ToEnvironmentLineEndings(); await new VerifyCS.Test { @@ -925,6 +925,11 @@ public async Task CustomizeResponses() typeof(SourceGenerator.Generator), "CustomizeResponseExamples_NotFoundResponseWithHeaderV1Async_Generated.g.cs", SourceText.From(expectedNotFoundResponseWithHeaderV1AsyncGenerated, Encoding.UTF8, SourceHashAlgorithm.Sha256) + ), + ( + typeof(SourceGenerator.Generator), + "CustomizeResponseExamples_OkResponseWithCustomSerializer_Generated.g.cs", + SourceText.From(expectedOkResponseWithCustomSerializerGenerated, Encoding.UTF8, SourceHashAlgorithm.Sha256) ) }, ExpectedDiagnostics = @@ -934,10 +939,15 @@ public async Task CustomizeResponses() new DiagnosticResult("AWSLambda0103", DiagnosticSeverity.Info).WithArguments("CustomizeResponseExamples_NotFoundResponseWithHeaderV2_Generated.g.cs", expectedNotFoundResponseWithHeaderV2Generated), new DiagnosticResult("AWSLambda0103", DiagnosticSeverity.Info).WithArguments("CustomizeResponseExamples_NotFoundResponseWithHeaderV2Async_Generated.g.cs", expectedNotFoundResponseWithHeaderV2AsyncGenerated), - + new DiagnosticResult("AWSLambda0103", DiagnosticSeverity.Info).WithArguments("CustomizeResponseExamples_NotFoundResponseWithHeaderV1_Generated.g.cs", expectedNotFoundResponseWithHeaderV1Generated), new DiagnosticResult("AWSLambda0103", DiagnosticSeverity.Info).WithArguments("CustomizeResponseExamples_NotFoundResponseWithHeaderV1Async_Generated.g.cs", expectedNotFoundResponseWithHeaderV1AsyncGenerated), + new DiagnosticResult("AWSLambda0103", DiagnosticSeverity.Info).WithArguments("CustomizeResponseExamples_OkResponseWithCustomSerializer_Generated.g.cs", expectedOkResponseWithCustomSerializerGenerated), + // The test framework doesn't appear to also execute the System.Text.Json source generator so Annotations generated code relying on the generated System.Text.Json code does not exist + // so we get compile errors. In an real world scenario they are both run and the applicaton compiles correctly. + DiagnosticResult.CompilerError("CS0117").WithSpan($"TestServerlessApp{Path.DirectorySeparatorChar}CustomizeResponseExamples.cs", 99, 65, 99, 79).WithArguments("System.Text.Json.JsonNamingPolicy", "SnakeCaseUpper"), + new DiagnosticResult("AWSLambda0103", DiagnosticSeverity.Info).WithArguments($"TestServerlessApp{Path.DirectorySeparatorChar}serverless.template", expectedTemplateContent) } } diff --git a/Libraries/test/TestExecutableServerlessApp/SourceGenerationSerializationExample.cs b/Libraries/test/TestExecutableServerlessApp/SourceGenerationSerializationExample.cs index 32362c0b8..80fda943f 100644 --- a/Libraries/test/TestExecutableServerlessApp/SourceGenerationSerializationExample.cs +++ b/Libraries/test/TestExecutableServerlessApp/SourceGenerationSerializationExample.cs @@ -22,8 +22,6 @@ public IHttpResult GetPerson(ILambdaContext context) } } - [JsonSerializable(typeof(APIGatewayHttpApiV2ProxyRequest))] - [JsonSerializable(typeof(APIGatewayHttpApiV2ProxyResponse))] [JsonSerializable(typeof(Person))] public partial class HttpApiJsonSerializerContext : JsonSerializerContext { diff --git a/Libraries/test/TestServerlessApp.IntegrationTests/CustomResponse.cs b/Libraries/test/TestServerlessApp.IntegrationTests/CustomResponse.cs index 07735277a..3d987c391 100644 --- a/Libraries/test/TestServerlessApp.IntegrationTests/CustomResponse.cs +++ b/Libraries/test/TestServerlessApp.IntegrationTests/CustomResponse.cs @@ -37,5 +37,17 @@ public async Task OkResponseWithHeader_ReturnsValidationErrors() var expectedErrorMessage = "1 validation error(s) detected: Value hello at 'x' failed to satisfy constraint: Input string was not in a correct format."; Assert.Equal(expectedErrorMessage, errorJson["message"]); } + + [Fact] + public async Task OkResponseWithCustomSerializer_Returns200Status() + { + var response = await _fixture.HttpClient.GetAsync($"{_fixture.HttpApiUrlPrefix}/okresponsewithcustomserializerasync/John/Doe"); + response.EnsureSuccessStatusCode(); + + var content = await response.Content.ReadAsStringAsync(); + var person = JObject.Parse(content); + Assert.Equal("John", person["FIRST_NAME"]); + Assert.Equal("Doe", person["LAST_NAME"]); + } } } diff --git a/Libraries/test/TestServerlessApp.IntegrationTests/IntegrationTestContextFixture.cs b/Libraries/test/TestServerlessApp.IntegrationTests/IntegrationTestContextFixture.cs index 211abab5b..8e2d0fafd 100644 --- a/Libraries/test/TestServerlessApp.IntegrationTests/IntegrationTestContextFixture.cs +++ b/Libraries/test/TestServerlessApp.IntegrationTests/IntegrationTestContextFixture.cs @@ -55,7 +55,7 @@ public async Task InitializeAsync() Assert.Equal(StackStatus.CREATE_COMPLETE, await _cloudFormationHelper.GetStackStatusAsync(_stackName)); Assert.True(await _s3Helper.BucketExistsAsync(_bucketName)); - Assert.Equal(26, LambdaFunctions.Count); + Assert.Equal(27, LambdaFunctions.Count); Assert.False(string.IsNullOrEmpty(RestApiUrlPrefix)); Assert.False(string.IsNullOrEmpty(RestApiUrlPrefix)); diff --git a/Libraries/test/TestServerlessApp/CustomizeResponseExamples.cs b/Libraries/test/TestServerlessApp/CustomizeResponseExamples.cs index 708921d45..12d0dc702 100644 --- a/Libraries/test/TestServerlessApp/CustomizeResponseExamples.cs +++ b/Libraries/test/TestServerlessApp/CustomizeResponseExamples.cs @@ -1,6 +1,10 @@ using Amazon.Lambda.Annotations; using Amazon.Lambda.Annotations.APIGateway; using Amazon.Lambda.Core; +using Amazon.Lambda.Serialization.SystemTextJson; +using System; +using System.Text.Json; +using System.Text.Json.Serialization; using System.Threading.Tasks; namespace TestServerlessApp @@ -66,5 +70,34 @@ public Task NotFoundResponseWithHeaderV1Async(int x, ILambdaContext .AddHeader("Multi-Header", "Foo") .AddHeader("Multi-Header", "Bar")); } + + [LambdaFunction(PackageType = LambdaPackageType.Image)] + [HttpApi(LambdaHttpMethod.Get, "/okresponsewithcustomserializerasync/{firstName}/{lastName}", Version = HttpApiVersion.V1)] + [LambdaSerializer(typeof(PersonSerializer))] + public Task OkResponseWithCustomSerializer(string firstName, string lastName, ILambdaContext context) + { + return Task.FromResult(HttpResults.Ok(new Person { FirstName = firstName, LastName = lastName })); + } + } + + public class Person + { + public string FirstName { get; set; } + public string LastName { get; set; } + } + + public class PersonSerializer : DefaultLambdaJsonSerializer + { + public PersonSerializer() + : base(CreateCustomizer()) + { } + + private static Action CreateCustomizer() + { + return (JsonSerializerOptions options) => + { + options.PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseUpper; + }; + } } } diff --git a/Libraries/test/TestServerlessApp/TestServerlessApp.csproj b/Libraries/test/TestServerlessApp/TestServerlessApp.csproj index 043085adc..37fbb5832 100644 --- a/Libraries/test/TestServerlessApp/TestServerlessApp.csproj +++ b/Libraries/test/TestServerlessApp/TestServerlessApp.csproj @@ -19,6 +19,7 @@ + diff --git a/Libraries/test/TestServerlessApp/serverless.template b/Libraries/test/TestServerlessApp/serverless.template index cd81651fe..fbad7233d 100644 --- a/Libraries/test/TestServerlessApp/serverless.template +++ b/Libraries/test/TestServerlessApp/serverless.template @@ -737,6 +737,39 @@ ] } } + }, + "TestServerlessAppCustomizeResponseExamplesOkResponseWithCustomSerializerGenerated": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations", + "SyncedEvents": [ + "RootGet" + ] + }, + "Properties": { + "MemorySize": 512, + "Timeout": 30, + "Policies": [ + "AWSLambdaBasicExecutionRole" + ], + "PackageType": "Image", + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestServerlessApp::TestServerlessApp.CustomizeResponseExamples_OkResponseWithCustomSerializer_Generated::OkResponseWithCustomSerializer" + ] + }, + "Events": { + "RootGet": { + "Type": "HttpApi", + "Properties": { + "Path": "/okresponsewithcustomserializerasync/{firstName}/{lastName}", + "Method": "GET", + "PayloadFormatVersion": "1.0" + } + } + } + } } }, "Outputs": { From c5e50d77b08974aec654971a7cd6cd7cb6de6248 Mon Sep 17 00:00:00 2001 From: Malhar Khimsaria <96malhar@gmail.com> Date: Wed, 15 May 2024 11:06:33 -0700 Subject: [PATCH 06/35] chore: Version bump Amazon.Lambda.Annotations to 1.4.0.0 --- .../Amazon.Lambda.Annotations.SourceGenerator.csproj | 2 +- Libraries/src/Amazon.Lambda.Annotations.nuspec | 2 +- .../Amazon.Lambda.Annotations/Amazon.Lambda.Annotations.csproj | 2 +- .../Snapshots/ComplexCalculator_Add_Generated.g.cs | 2 +- .../Snapshots/ComplexCalculator_Subtract_Generated.g.cs | 2 +- ...nseExamples_NotFoundResponseWithHeaderV1Async_Generated.g.cs | 2 +- ...ResponseExamples_NotFoundResponseWithHeaderV1_Generated.g.cs | 2 +- ...nseExamples_NotFoundResponseWithHeaderV2Async_Generated.g.cs | 2 +- ...ResponseExamples_NotFoundResponseWithHeaderV2_Generated.g.cs | 2 +- ...sponseExamples_OkResponseWithCustomSerializer_Generated.g.cs | 2 +- ...izeResponseExamples_OkResponseWithHeaderAsync_Generated.g.cs | 2 +- ...ustomizeResponseExamples_OkResponseWithHeader_Generated.g.cs | 2 +- .../Snapshots/DynamicExample_DynamicInput_Generated.g.cs | 2 +- .../Snapshots/DynamicExample_DynamicReturn_Generated.g.cs | 2 +- .../Snapshots/Functions_AsyncStartupToLower_Generated.g.cs | 2 +- .../Snapshots/Functions_AsyncStartupToUpper_Generated.g.cs | 2 +- .../Snapshots/Functions_ToUpper_Generated.g.cs | 2 +- .../Snapshots/Functions_ToUpper_Generated_NET8.g.cs | 2 +- .../Snapshots/GreeterExecutable_SayHelloAsync_Generated.g.cs | 2 +- .../Snapshots/GreeterExecutable_SayHello_Generated.g.cs | 2 +- .../Snapshots/Greeter_SayHelloAsync_Generated.g.cs | 2 +- .../Snapshots/Greeter_SayHello_Generated.g.cs | 2 +- .../Snapshots/IntrinsicExample_HasIntrinsic_Generated.g.cs | 2 +- ...bleReferenceTypeExample_NullableHeaderHttpApi_Generated.g.cs | 2 +- .../ParameterlessMethodWithResponse_ToUpper_Generated.g.cs | 2 +- .../Snapshots/ParameterlessMethods_ToUpper_Generated.g.cs | 2 +- .../Snapshots/ServerlessTemplates/complexCalculator.template | 2 +- .../Snapshots/ServerlessTemplates/customizeResponse.template | 2 +- .../Snapshots/ServerlessTemplates/dynamicexample.template | 2 +- .../Snapshots/ServerlessTemplates/greeter.template | 2 +- .../Snapshots/ServerlessTemplates/greeter_executable.template | 2 +- .../Snapshots/ServerlessTemplates/intrinsicexample.template | 2 +- .../Snapshots/ServerlessTemplates/net8.template | 2 +- .../Snapshots/ServerlessTemplates/nullreferenceexample.template | 2 +- .../Snapshots/ServerlessTemplates/parameterless.template | 2 +- .../ServerlessTemplates/parameterlesswithresponse.template | 2 +- .../Snapshots/ServerlessTemplates/simpleCalculator.template | 2 +- .../sourcegeneratorserializationexample.template | 2 +- .../Snapshots/ServerlessTemplates/subnamespace.template | 2 +- .../ServerlessTemplates/subnamespace_executable.template | 2 +- .../ServerlessTemplates/subnamespace_executableimage.template | 2 +- .../Snapshots/ServerlessTemplates/taskexample.template | 2 +- .../Snapshots/ServerlessTemplates/voidexample - Copy.template | 2 +- .../Snapshots/ServerlessTemplates/voidexample.template | 2 +- .../Snapshots/SimpleCalculator_Add_Generated.g.cs | 2 +- .../Snapshots/SimpleCalculator_DivideAsync_Generated.g.cs | 2 +- .../Snapshots/SimpleCalculator_Multiply_Generated.g.cs | 2 +- .../Snapshots/SimpleCalculator_Pi_Generated.g.cs | 2 +- .../Snapshots/SimpleCalculator_Random_Generated.g.cs | 2 +- .../Snapshots/SimpleCalculator_Randoms_Generated.g.cs | 2 +- .../Snapshots/SimpleCalculator_Subtract_Generated.g.cs | 2 +- ...ourceGenerationSerializationExample_GetPerson_Generated.g.cs | 2 +- .../Snapshots/TaskExample_TaskReturn_Generated.g.cs | 2 +- .../Snapshots/VoidExample_VoidReturn_Generated.g.cs | 2 +- Libraries/test/TestExecutableServerlessApp/serverless.template | 2 +- Libraries/test/TestServerlessApp.NET8/serverless.template | 2 +- Libraries/test/TestServerlessApp/serverless.template | 2 +- 57 files changed, 57 insertions(+), 57 deletions(-) diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Amazon.Lambda.Annotations.SourceGenerator.csproj b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Amazon.Lambda.Annotations.SourceGenerator.csproj index 842688f81..622e6a0df 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Amazon.Lambda.Annotations.SourceGenerator.csproj +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Amazon.Lambda.Annotations.SourceGenerator.csproj @@ -1,7 +1,7 @@  - 1.3.1 + 1.4.0 netstandard2.0 diff --git a/Libraries/src/Amazon.Lambda.Annotations.nuspec b/Libraries/src/Amazon.Lambda.Annotations.nuspec index 466b9c6d1..4cf118f6b 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.nuspec +++ b/Libraries/src/Amazon.Lambda.Annotations.nuspec @@ -1,7 +1,7 @@ Amazon.Lambda.Annotations - 1.3.1 + 1.4.0 Amazon Web Services AWS Amazon Lambda Annotations that can be added to Lambda projects to generate C# code and CloudFormation templates. This library is currently in dev preview. diff --git a/Libraries/src/Amazon.Lambda.Annotations/Amazon.Lambda.Annotations.csproj b/Libraries/src/Amazon.Lambda.Annotations/Amazon.Lambda.Annotations.csproj index 64e62e6b2..dfa34f2c0 100644 --- a/Libraries/src/Amazon.Lambda.Annotations/Amazon.Lambda.Annotations.csproj +++ b/Libraries/src/Amazon.Lambda.Annotations/Amazon.Lambda.Annotations.csproj @@ -1,7 +1,7 @@  - 1.3.1 + 1.4.0 netstandard2.0;net6.0;net8.0 true diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ComplexCalculator_Add_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ComplexCalculator_Add_Generated.g.cs index 7d24f327f..4cb9bcf27 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ComplexCalculator_Add_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ComplexCalculator_Add_Generated.g.cs @@ -69,7 +69,7 @@ private static void SetExecutionEnvironment() envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); } - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + envValue.Append("lib/amazon-lambda-annotations#1.4.0.0"); Environment.SetEnvironmentVariable(envName, envValue.ToString()); } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ComplexCalculator_Subtract_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ComplexCalculator_Subtract_Generated.g.cs index 5178eb44d..c53c020e7 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ComplexCalculator_Subtract_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ComplexCalculator_Subtract_Generated.g.cs @@ -98,7 +98,7 @@ private static void SetExecutionEnvironment() envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); } - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + envValue.Append("lib/amazon-lambda-annotations#1.4.0.0"); Environment.SetEnvironmentVariable(envName, envValue.ToString()); } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV1Async_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV1Async_Generated.g.cs index 8f4ca49ab..673542de8 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV1Async_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV1Async_Generated.g.cs @@ -90,7 +90,7 @@ private static void SetExecutionEnvironment() envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); } - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + envValue.Append("lib/amazon-lambda-annotations#1.4.0.0"); Environment.SetEnvironmentVariable(envName, envValue.ToString()); } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV1_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV1_Generated.g.cs index 0d2ceb3ec..ad2b00d10 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV1_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV1_Generated.g.cs @@ -90,7 +90,7 @@ private static void SetExecutionEnvironment() envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); } - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + envValue.Append("lib/amazon-lambda-annotations#1.4.0.0"); Environment.SetEnvironmentVariable(envName, envValue.ToString()); } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV2Async_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV2Async_Generated.g.cs index efc53ac27..bd8c1938c 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV2Async_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV2Async_Generated.g.cs @@ -90,7 +90,7 @@ private static void SetExecutionEnvironment() envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); } - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + envValue.Append("lib/amazon-lambda-annotations#1.4.0.0"); Environment.SetEnvironmentVariable(envName, envValue.ToString()); } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV2_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV2_Generated.g.cs index 7aab90492..ba1a128fe 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV2_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_NotFoundResponseWithHeaderV2_Generated.g.cs @@ -90,7 +90,7 @@ private static void SetExecutionEnvironment() envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); } - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + envValue.Append("lib/amazon-lambda-annotations#1.4.0.0"); Environment.SetEnvironmentVariable(envName, envValue.ToString()); } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_OkResponseWithCustomSerializer_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_OkResponseWithCustomSerializer_Generated.g.cs index b4674fa21..9bc638cbb 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_OkResponseWithCustomSerializer_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_OkResponseWithCustomSerializer_Generated.g.cs @@ -103,7 +103,7 @@ private static void SetExecutionEnvironment() envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); } - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + envValue.Append("lib/amazon-lambda-annotations#1.4.0.0"); Environment.SetEnvironmentVariable(envName, envValue.ToString()); } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_OkResponseWithHeaderAsync_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_OkResponseWithHeaderAsync_Generated.g.cs index 366cc83e7..9e2accbe5 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_OkResponseWithHeaderAsync_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_OkResponseWithHeaderAsync_Generated.g.cs @@ -90,7 +90,7 @@ private static void SetExecutionEnvironment() envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); } - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + envValue.Append("lib/amazon-lambda-annotations#1.4.0.0"); Environment.SetEnvironmentVariable(envName, envValue.ToString()); } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_OkResponseWithHeader_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_OkResponseWithHeader_Generated.g.cs index c99f4c2b3..6b123e91d 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_OkResponseWithHeader_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomizeResponseExamples_OkResponseWithHeader_Generated.g.cs @@ -90,7 +90,7 @@ private static void SetExecutionEnvironment() envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); } - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + envValue.Append("lib/amazon-lambda-annotations#1.4.0.0"); Environment.SetEnvironmentVariable(envName, envValue.ToString()); } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/DynamicExample_DynamicInput_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/DynamicExample_DynamicInput_Generated.g.cs index 51c294ee7..db6ebdf74 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/DynamicExample_DynamicInput_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/DynamicExample_DynamicInput_Generated.g.cs @@ -50,7 +50,7 @@ private static void SetExecutionEnvironment() envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); } - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + envValue.Append("lib/amazon-lambda-annotations#1.4.0.0"); Environment.SetEnvironmentVariable(envName, envValue.ToString()); } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/DynamicExample_DynamicReturn_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/DynamicExample_DynamicReturn_Generated.g.cs index 160864b99..151a1aab5 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/DynamicExample_DynamicReturn_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/DynamicExample_DynamicReturn_Generated.g.cs @@ -50,7 +50,7 @@ private static void SetExecutionEnvironment() envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); } - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + envValue.Append("lib/amazon-lambda-annotations#1.4.0.0"); Environment.SetEnvironmentVariable(envName, envValue.ToString()); } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Functions_AsyncStartupToLower_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Functions_AsyncStartupToLower_Generated.g.cs index 7bca2834e..5020e704d 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Functions_AsyncStartupToLower_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Functions_AsyncStartupToLower_Generated.g.cs @@ -63,7 +63,7 @@ private static void SetExecutionEnvironment() envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); } - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + envValue.Append("lib/amazon-lambda-annotations#1.4.0.0"); Environment.SetEnvironmentVariable(envName, envValue.ToString()); } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Functions_AsyncStartupToUpper_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Functions_AsyncStartupToUpper_Generated.g.cs index 854b69221..7b1c46f7c 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Functions_AsyncStartupToUpper_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Functions_AsyncStartupToUpper_Generated.g.cs @@ -63,7 +63,7 @@ private static void SetExecutionEnvironment() envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); } - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + envValue.Append("lib/amazon-lambda-annotations#1.4.0.0"); Environment.SetEnvironmentVariable(envName, envValue.ToString()); } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Functions_ToUpper_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Functions_ToUpper_Generated.g.cs index 8e80d3711..853521a55 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Functions_ToUpper_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Functions_ToUpper_Generated.g.cs @@ -49,7 +49,7 @@ private static void SetExecutionEnvironment() envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); } - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + envValue.Append("lib/amazon-lambda-annotations#1.4.0.0"); Environment.SetEnvironmentVariable(envName, envValue.ToString()); } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Functions_ToUpper_Generated_NET8.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Functions_ToUpper_Generated_NET8.g.cs index 214a8df58..c823578e9 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Functions_ToUpper_Generated_NET8.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Functions_ToUpper_Generated_NET8.g.cs @@ -49,7 +49,7 @@ private static void SetExecutionEnvironment() envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); } - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + envValue.Append("lib/amazon-lambda-annotations#1.4.0.0"); Environment.SetEnvironmentVariable(envName, envValue.ToString()); } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/GreeterExecutable_SayHelloAsync_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/GreeterExecutable_SayHelloAsync_Generated.g.cs index 5e0d66ee3..6efed43d6 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/GreeterExecutable_SayHelloAsync_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/GreeterExecutable_SayHelloAsync_Generated.g.cs @@ -106,7 +106,7 @@ private static void SetExecutionEnvironment() envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); } - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + envValue.Append("lib/amazon-lambda-annotations#1.4.0.0"); Environment.SetEnvironmentVariable(envName, envValue.ToString()); } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/GreeterExecutable_SayHello_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/GreeterExecutable_SayHello_Generated.g.cs index b9034fa37..cc4ad0cfc 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/GreeterExecutable_SayHello_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/GreeterExecutable_SayHello_Generated.g.cs @@ -106,7 +106,7 @@ private static void SetExecutionEnvironment() envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); } - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + envValue.Append("lib/amazon-lambda-annotations#1.4.0.0"); Environment.SetEnvironmentVariable(envName, envValue.ToString()); } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Greeter_SayHelloAsync_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Greeter_SayHelloAsync_Generated.g.cs index 2b3da55eb..c360755bd 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Greeter_SayHelloAsync_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Greeter_SayHelloAsync_Generated.g.cs @@ -92,7 +92,7 @@ private static void SetExecutionEnvironment() envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); } - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + envValue.Append("lib/amazon-lambda-annotations#1.4.0.0"); Environment.SetEnvironmentVariable(envName, envValue.ToString()); } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Greeter_SayHello_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Greeter_SayHello_Generated.g.cs index 6120f86ce..088716c1e 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Greeter_SayHello_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/Greeter_SayHello_Generated.g.cs @@ -92,7 +92,7 @@ private static void SetExecutionEnvironment() envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); } - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + envValue.Append("lib/amazon-lambda-annotations#1.4.0.0"); Environment.SetEnvironmentVariable(envName, envValue.ToString()); } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/IntrinsicExample_HasIntrinsic_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/IntrinsicExample_HasIntrinsic_Generated.g.cs index f45bdedb9..cb47e11ad 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/IntrinsicExample_HasIntrinsic_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/IntrinsicExample_HasIntrinsic_Generated.g.cs @@ -50,7 +50,7 @@ private static void SetExecutionEnvironment() envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); } - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + envValue.Append("lib/amazon-lambda-annotations#1.4.0.0"); Environment.SetEnvironmentVariable(envName, envValue.ToString()); } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/NullableReferenceTypeExample_NullableHeaderHttpApi_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/NullableReferenceTypeExample_NullableHeaderHttpApi_Generated.g.cs index 53987cc9a..5147382c8 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/NullableReferenceTypeExample_NullableHeaderHttpApi_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/NullableReferenceTypeExample_NullableHeaderHttpApi_Generated.g.cs @@ -86,7 +86,7 @@ private static void SetExecutionEnvironment() envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); } - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + envValue.Append("lib/amazon-lambda-annotations#1.4.0.0"); Environment.SetEnvironmentVariable(envName, envValue.ToString()); } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ParameterlessMethodWithResponse_ToUpper_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ParameterlessMethodWithResponse_ToUpper_Generated.g.cs index e96636875..07be9c5ac 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ParameterlessMethodWithResponse_ToUpper_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ParameterlessMethodWithResponse_ToUpper_Generated.g.cs @@ -48,7 +48,7 @@ private static void SetExecutionEnvironment() envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); } - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + envValue.Append("lib/amazon-lambda-annotations#1.4.0.0"); Environment.SetEnvironmentVariable(envName, envValue.ToString()); } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ParameterlessMethods_ToUpper_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ParameterlessMethods_ToUpper_Generated.g.cs index d2e8e4c7b..b84d77b29 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ParameterlessMethods_ToUpper_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ParameterlessMethods_ToUpper_Generated.g.cs @@ -48,7 +48,7 @@ private static void SetExecutionEnvironment() envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); } - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + envValue.Append("lib/amazon-lambda-annotations#1.4.0.0"); Environment.SetEnvironmentVariable(envName, envValue.ToString()); } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/complexCalculator.template b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/complexCalculator.template index 6c6158b34..e60b2008b 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/complexCalculator.template +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/complexCalculator.template @@ -1,7 +1,7 @@ { "AWSTemplateFormatVersion": "2010-09-09", "Transform": "AWS::Serverless-2016-10-31", - "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.3.1.0).", + "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.4.0.0).", "Resources": { "TestServerlessAppComplexCalculatorAddGenerated": { "Type": "AWS::Serverless::Function", diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/customizeResponse.template b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/customizeResponse.template index d0c7c6879..c8afbb2f7 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/customizeResponse.template +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/customizeResponse.template @@ -1,7 +1,7 @@ { "AWSTemplateFormatVersion": "2010-09-09", "Transform": "AWS::Serverless-2016-10-31", - "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.3.1.0).", + "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.4.0.0).", "Resources": { "TestServerlessAppCustomizeResponseExamplesOkResponseWithHeaderGenerated": { "Type": "AWS::Serverless::Function", diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/dynamicexample.template b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/dynamicexample.template index 1386b159d..17e3b7be9 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/dynamicexample.template +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/dynamicexample.template @@ -1,7 +1,7 @@ { "AWSTemplateFormatVersion": "2010-09-09", "Transform": "AWS::Serverless-2016-10-31", - "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.3.1.0).", + "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.4.0.0).", "Resources": { "TestServerlessAppDynamicExampleDynamicReturnGenerated": { "Type": "AWS::Serverless::Function", diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/greeter.template b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/greeter.template index 97bb5f113..dac59ba30 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/greeter.template +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/greeter.template @@ -1,7 +1,7 @@ { "AWSTemplateFormatVersion": "2010-09-09", "Transform": "AWS::Serverless-2016-10-31", - "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.3.1.0).", + "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.4.0.0).", "Resources": { "GreeterSayHello": { "Type": "AWS::Serverless::Function", diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/greeter_executable.template b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/greeter_executable.template index ff401bd72..801538290 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/greeter_executable.template +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/greeter_executable.template @@ -1,7 +1,7 @@ { "AWSTemplateFormatVersion": "2010-09-09", "Transform": "AWS::Serverless-2016-10-31", - "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.3.1.0).", + "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.4.0.0).", "Resources": { "GreeterSayHello": { "Type": "AWS::Serverless::Function", diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/intrinsicexample.template b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/intrinsicexample.template index 5195625b4..a104ea0e0 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/intrinsicexample.template +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/intrinsicexample.template @@ -1,6 +1,6 @@ AWSTemplateFormatVersion: '2010-09-09' Transform: 'AWS::Serverless-2016-10-31' -Description: This template is partially managed by Amazon.Lambda.Annotations (v1.3.1.0). +Description: This template is partially managed by Amazon.Lambda.Annotations (v1.4.0.0). Resources: TestServerlessAppIntrinsicExampleHasIntrinsicGenerated: Type: AWS::Serverless::Function diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/net8.template b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/net8.template index 3df6e882e..0e541f1bb 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/net8.template +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/net8.template @@ -1,7 +1,7 @@ { "AWSTemplateFormatVersion": "2010-09-09", "Transform": "AWS::Serverless-2016-10-31", - "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.3.1.0).", + "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.4.0.0).", "Resources": { "TestServerlessAppNET8FunctionsToUpperGenerated": { "Type": "AWS::Serverless::Function", diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/nullreferenceexample.template b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/nullreferenceexample.template index 2a5751e0b..1f93c1ab4 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/nullreferenceexample.template +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/nullreferenceexample.template @@ -1,7 +1,7 @@ { "AWSTemplateFormatVersion": "2010-09-09", "Transform": "AWS::Serverless-2016-10-31", - "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.3.1.0).", + "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.4.0.0).", "Resources": { "TestServerlessAppNullableReferenceTypeExampleNullableHeaderHttpApiGenerated": { "Type": "AWS::Serverless::Function", diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/parameterless.template b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/parameterless.template index de964ea27..ee7241168 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/parameterless.template +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/parameterless.template @@ -1,7 +1,7 @@ { "AWSTemplateFormatVersion": "2010-09-09", "Transform": "AWS::Serverless-2016-10-31", - "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.3.1.0).", + "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.4.0.0).", "Resources": { "TestServerlessAppParameterlessMethodsNoParameterGenerated": { "Type": "AWS::Serverless::Function", diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/parameterlesswithresponse.template b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/parameterlesswithresponse.template index 8045c911e..23dec2814 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/parameterlesswithresponse.template +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/parameterlesswithresponse.template @@ -1,7 +1,7 @@ { "AWSTemplateFormatVersion": "2010-09-09", "Transform": "AWS::Serverless-2016-10-31", - "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.3.1.0).", + "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.4.0.0).", "Resources": { "TestServerlessAppParameterlessMethodWithResponseNoParameterWithResponseGenerated": { "Type": "AWS::Serverless::Function", diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/simpleCalculator.template b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/simpleCalculator.template index dc992ef91..f10527aa4 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/simpleCalculator.template +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/simpleCalculator.template @@ -1,7 +1,7 @@ { "AWSTemplateFormatVersion": "2010-09-09", "Transform": "AWS::Serverless-2016-10-31", - "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.3.1.0).", + "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.4.0.0).", "Resources": { "SimpleCalculatorAdd": { "Type": "AWS::Serverless::Function", diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/sourcegeneratorserializationexample.template b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/sourcegeneratorserializationexample.template index 1e673920d..15d441474 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/sourcegeneratorserializationexample.template +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/sourcegeneratorserializationexample.template @@ -1,7 +1,7 @@ { "AWSTemplateFormatVersion": "2010-09-09", "Transform": "AWS::Serverless-2016-10-31", - "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.3.1.0).", + "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.4.0.0).", "Resources": { "TestExecutableServerlessAppSourceGenerationSerializationExampleGetPersonGenerated": { "Type": "AWS::Serverless::Function", diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/subnamespace.template b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/subnamespace.template index 927d86c6a..92f782843 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/subnamespace.template +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/subnamespace.template @@ -1,7 +1,7 @@ { "AWSTemplateFormatVersion": "2010-09-09", "Transform": "AWS::Serverless-2016-10-31", - "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.3.1.0).", + "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.4.0.0).", "Resources": { "ToUpper": { "Type": "AWS::Serverless::Function", diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/subnamespace_executable.template b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/subnamespace_executable.template index 8b04a8604..54678f9fd 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/subnamespace_executable.template +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/subnamespace_executable.template @@ -1,7 +1,7 @@ { "AWSTemplateFormatVersion": "2010-09-09", "Transform": "AWS::Serverless-2016-10-31", - "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.3.1.0).", + "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.4.0.0).", "Resources": { "ToLower": { "Type": "AWS::Serverless::Function", diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/subnamespace_executableimage.template b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/subnamespace_executableimage.template index 1560909c5..7dd0bebef 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/subnamespace_executableimage.template +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/subnamespace_executableimage.template @@ -1,7 +1,7 @@ { "AWSTemplateFormatVersion": "2010-09-09", "Transform": "AWS::Serverless-2016-10-31", - "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.3.1.0).", + "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.4.0.0).", "Resources": { "ToUpper": { "Type": "AWS::Serverless::Function", diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/taskexample.template b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/taskexample.template index 37e768a63..a85d7e4a8 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/taskexample.template +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/taskexample.template @@ -1,7 +1,7 @@ { "AWSTemplateFormatVersion": "2010-09-09", "Transform": "AWS::Serverless-2016-10-31", - "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.3.1.0).", + "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.4.0.0).", "Resources": { "TestServerlessAppTaskExampleTaskReturnGenerated": { "Type": "AWS::Serverless::Function", diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/voidexample - Copy.template b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/voidexample - Copy.template index 427e5ea0a..099054185 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/voidexample - Copy.template +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/voidexample - Copy.template @@ -1,7 +1,7 @@ { "AWSTemplateFormatVersion": "2010-09-09", "Transform": "AWS::Serverless-2016-10-31", - "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.3.1.0).", + "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.4.0.0).", "Resources": { "TestServerlessAppVoidExampleVoidReturnGenerated": { "Type": "AWS::Serverless::Function", diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/voidexample.template b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/voidexample.template index acc35a1df..5e475f113 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/voidexample.template +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/voidexample.template @@ -1,7 +1,7 @@ { "AWSTemplateFormatVersion": "2010-09-09", "Transform": "AWS::Serverless-2016-10-31", - "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.3.1.0).", + "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.4.0.0).", "Resources": { "TestServerlessAppVoidExampleVoidReturnGenerated": { "Type": "AWS::Serverless::Function", diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Add_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Add_Generated.g.cs index c5935847c..a5333c1b7 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Add_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Add_Generated.g.cs @@ -120,7 +120,7 @@ private static void SetExecutionEnvironment() envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); } - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + envValue.Append("lib/amazon-lambda-annotations#1.4.0.0"); Environment.SetEnvironmentVariable(envName, envValue.ToString()); } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_DivideAsync_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_DivideAsync_Generated.g.cs index 59cf33f3b..8dedf200b 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_DivideAsync_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_DivideAsync_Generated.g.cs @@ -125,7 +125,7 @@ private static void SetExecutionEnvironment() envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); } - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + envValue.Append("lib/amazon-lambda-annotations#1.4.0.0"); Environment.SetEnvironmentVariable(envName, envValue.ToString()); } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Multiply_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Multiply_Generated.g.cs index 77dde822a..37927b93a 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Multiply_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Multiply_Generated.g.cs @@ -118,7 +118,7 @@ private static void SetExecutionEnvironment() envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); } - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + envValue.Append("lib/amazon-lambda-annotations#1.4.0.0"); Environment.SetEnvironmentVariable(envName, envValue.ToString()); } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Pi_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Pi_Generated.g.cs index c1df83995..6347a0a84 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Pi_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Pi_Generated.g.cs @@ -63,7 +63,7 @@ private static void SetExecutionEnvironment() envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); } - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + envValue.Append("lib/amazon-lambda-annotations#1.4.0.0"); Environment.SetEnvironmentVariable(envName, envValue.ToString()); } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Random_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Random_Generated.g.cs index 2f837b721..73e43ddd4 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Random_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Random_Generated.g.cs @@ -64,7 +64,7 @@ private static void SetExecutionEnvironment() envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); } - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + envValue.Append("lib/amazon-lambda-annotations#1.4.0.0"); Environment.SetEnvironmentVariable(envName, envValue.ToString()); } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Randoms_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Randoms_Generated.g.cs index 31885ce85..6a9cc6ac5 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Randoms_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Randoms_Generated.g.cs @@ -64,7 +64,7 @@ private static void SetExecutionEnvironment() envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); } - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + envValue.Append("lib/amazon-lambda-annotations#1.4.0.0"); Environment.SetEnvironmentVariable(envName, envValue.ToString()); } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Subtract_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Subtract_Generated.g.cs index db0d3a798..a736b0e52 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Subtract_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SimpleCalculator_Subtract_Generated.g.cs @@ -110,7 +110,7 @@ private static void SetExecutionEnvironment() envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); } - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + envValue.Append("lib/amazon-lambda-annotations#1.4.0.0"); Environment.SetEnvironmentVariable(envName, envValue.ToString()); } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SourceGenerationSerializationExample_GetPerson_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SourceGenerationSerializationExample_GetPerson_Generated.g.cs index 930690a11..6aaf55220 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SourceGenerationSerializationExample_GetPerson_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SourceGenerationSerializationExample_GetPerson_Generated.g.cs @@ -56,7 +56,7 @@ private static void SetExecutionEnvironment() envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); } - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + envValue.Append("lib/amazon-lambda-annotations#1.4.0.0"); Environment.SetEnvironmentVariable(envName, envValue.ToString()); } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/TaskExample_TaskReturn_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/TaskExample_TaskReturn_Generated.g.cs index 3b2ba2198..80f52fa52 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/TaskExample_TaskReturn_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/TaskExample_TaskReturn_Generated.g.cs @@ -50,7 +50,7 @@ private static void SetExecutionEnvironment() envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); } - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + envValue.Append("lib/amazon-lambda-annotations#1.4.0.0"); Environment.SetEnvironmentVariable(envName, envValue.ToString()); } diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/VoidExample_VoidReturn_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/VoidExample_VoidReturn_Generated.g.cs index ec097ee71..39ba962d7 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/VoidExample_VoidReturn_Generated.g.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/VoidExample_VoidReturn_Generated.g.cs @@ -50,7 +50,7 @@ private static void SetExecutionEnvironment() envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); } - envValue.Append("lib/amazon-lambda-annotations#1.3.1.0"); + envValue.Append("lib/amazon-lambda-annotations#1.4.0.0"); Environment.SetEnvironmentVariable(envName, envValue.ToString()); } diff --git a/Libraries/test/TestExecutableServerlessApp/serverless.template b/Libraries/test/TestExecutableServerlessApp/serverless.template index 5a710323e..0af6e8fe5 100644 --- a/Libraries/test/TestExecutableServerlessApp/serverless.template +++ b/Libraries/test/TestExecutableServerlessApp/serverless.template @@ -1,7 +1,7 @@ { "AWSTemplateFormatVersion": "2010-09-09", "Transform": "AWS::Serverless-2016-10-31", - "Description": "An AWS Serverless Application. This template is partially managed by Amazon.Lambda.Annotations (v1.3.1.0).", + "Description": "An AWS Serverless Application. This template is partially managed by Amazon.Lambda.Annotations (v1.4.0.0).", "Parameters": { "ArchitectureTypeParameter": { "Type": "String", diff --git a/Libraries/test/TestServerlessApp.NET8/serverless.template b/Libraries/test/TestServerlessApp.NET8/serverless.template index 183efc3f7..5a5c010ca 100644 --- a/Libraries/test/TestServerlessApp.NET8/serverless.template +++ b/Libraries/test/TestServerlessApp.NET8/serverless.template @@ -1,7 +1,7 @@ { "AWSTemplateFormatVersion": "2010-09-09", "Transform": "AWS::Serverless-2016-10-31", - "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.3.1.0).", + "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.4.0.0).", "Resources": { "TestServerlessAppNET8FunctionsToUpperGenerated": { "Type": "AWS::Serverless::Function", diff --git a/Libraries/test/TestServerlessApp/serverless.template b/Libraries/test/TestServerlessApp/serverless.template index fbad7233d..6f9725c31 100644 --- a/Libraries/test/TestServerlessApp/serverless.template +++ b/Libraries/test/TestServerlessApp/serverless.template @@ -1,7 +1,7 @@ { "AWSTemplateFormatVersion": "2010-09-09", "Transform": "AWS::Serverless-2016-10-31", - "Description": "An AWS Serverless Application. This template is partially managed by Amazon.Lambda.Annotations (v1.3.1.0).", + "Description": "An AWS Serverless Application. This template is partially managed by Amazon.Lambda.Annotations (v1.4.0.0).", "Parameters": { "ArchitectureTypeParameter": { "Type": "String", From e56be54051d067cf1ee6eb4e692eecea74e37cde Mon Sep 17 00:00:00 2001 From: Malhar Khimsaria <96malhar@gmail.com> Date: Fri, 17 May 2024 10:25:58 -0700 Subject: [PATCH 07/35] chore: Update release changelog --- RELEASE.CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/RELEASE.CHANGELOG.md b/RELEASE.CHANGELOG.md index 7743ebea5..d69f5d767 100644 --- a/RELEASE.CHANGELOG.md +++ b/RELEASE.CHANGELOG.md @@ -1,3 +1,10 @@ +### Release 2024-05-16 +* **Amazon.Lambda.Annotations (1.4.0)** + * Updated the source generator to add documentation on public members in the generated files. + * Added the "\" top-level comment on the generated files to skip them from being processed by analyzers. + * Use the `ILambdaSerializer` to serialize the response body when returning an `IHttpResult`. + * BREAKING CHANGE: Removed the `JsonContext` property in the `HttpResultSerializationOptions` class and replaced it with an `ILambdaSerializer` + ### Release 2024-04-25 * **Amazon.Lambda.Annotations (1.3.1)** * Update User-Agent string From 0558191fdff4235b5dbd2b2ba80633edd94c10ab Mon Sep 17 00:00:00 2001 From: aws-sdk-dotnet-automation Date: Mon, 20 May 2024 13:18:11 +0000 Subject: [PATCH 08/35] chore: ASP.NET Core version update in Dockerfiles --- LambdaRuntimeDockerfiles/Images/net6/amd64/Dockerfile | 4 ++-- LambdaRuntimeDockerfiles/Images/net6/arm64/Dockerfile | 4 ++-- LambdaRuntimeDockerfiles/Images/net7/amd64/Dockerfile | 4 ++-- LambdaRuntimeDockerfiles/Images/net7/arm64/Dockerfile | 4 ++-- LambdaRuntimeDockerfiles/Images/net8/amd64/Dockerfile | 4 ++-- LambdaRuntimeDockerfiles/Images/net8/arm64/Dockerfile | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/LambdaRuntimeDockerfiles/Images/net6/amd64/Dockerfile b/LambdaRuntimeDockerfiles/Images/net6/amd64/Dockerfile index e1c4d9f6d..0452a6465 100644 --- a/LambdaRuntimeDockerfiles/Images/net6/amd64/Dockerfile +++ b/LambdaRuntimeDockerfiles/Images/net6/amd64/Dockerfile @@ -1,7 +1,7 @@ # Based on Docker image from: https://github.com/dotnet/dotnet-docker/ -ARG ASPNET_VERSION=6.0.29 -ARG ASPNET_SHA512=6dc21e1a8dd597df9c1135065f7350bbde9cc040c3079ec7850b0e5f254051b883c6c6e0056682d2963ec74dadff8eb32d82c13b35c9088f3d7c055d3d3f0863 +ARG ASPNET_VERSION=6.0.30 +ARG ASPNET_SHA512=757d017db28b8e34c4b242c082aa51eb85bce8fca16af37a0beabedb271c9bd13e1631868faa131745d7784db48974567f82275da09041ba434dcb7abe821a2d ARG LAMBDA_RUNTIME_NAME=dotnet6 ARG AMAZON_LINUX=public.ecr.aws/lambda/provided:al2 diff --git a/LambdaRuntimeDockerfiles/Images/net6/arm64/Dockerfile b/LambdaRuntimeDockerfiles/Images/net6/arm64/Dockerfile index 5af5640c7..dc507203f 100644 --- a/LambdaRuntimeDockerfiles/Images/net6/arm64/Dockerfile +++ b/LambdaRuntimeDockerfiles/Images/net6/arm64/Dockerfile @@ -1,7 +1,7 @@ # Based on Docker image from: https://github.com/dotnet/dotnet-docker/ -ARG ASPNET_VERSION=6.0.29 -ARG ASPNET_SHA512=6e4a504f37ba4bf7d0316d2a3077c5088962c8b8445b659fa05844697bd11427afabacb6fee34094aa4313dd6dca70c862c1c68b30731b12b4451bd59067bc8f +ARG ASPNET_VERSION=6.0.30 +ARG ASPNET_SHA512=de0921903ba55e21195107b126e271457550543fd6a9698ab3c2b1e2b95f7fe2d6fb2f067e08ed10c9e56940c247733dd9a2f9775e7993e033a945899461e130 ARG ICU_VERSION=68.1 ARG ICU_MD5=6a99b541ea01f271257b121a4433c7c0 diff --git a/LambdaRuntimeDockerfiles/Images/net7/amd64/Dockerfile b/LambdaRuntimeDockerfiles/Images/net7/amd64/Dockerfile index c3d0acf55..3158c7b5f 100644 --- a/LambdaRuntimeDockerfiles/Images/net7/amd64/Dockerfile +++ b/LambdaRuntimeDockerfiles/Images/net7/amd64/Dockerfile @@ -1,7 +1,7 @@ # Based on Docker image from: https://github.com/dotnet/dotnet-docker/ -ARG ASPNET_VERSION=7.0.18 -ARG ASPNET_SHA512=d2c3af93b9b8280c4e519f052f443e0504ccf7a04b3eef60500b2e3a8874a60a3a545ca936f8433887bfa6388106c19283c5a6a2c78ffdc19889bde3edbefbda +ARG ASPNET_VERSION=7.0.19 +ARG ASPNET_SHA512=569fcc25f0c32df3b28c4569bbeabb6c20afc8865088f14a405d3847bbfd159cf291d2dc4810140b8f436f06c95ebb09214ac837b5ade6bd8121e9c0204eb217 ARG LAMBDA_RUNTIME_NAME=dotnet7 ARG AMAZON_LINUX=public.ecr.aws/lambda/provided:al2 diff --git a/LambdaRuntimeDockerfiles/Images/net7/arm64/Dockerfile b/LambdaRuntimeDockerfiles/Images/net7/arm64/Dockerfile index 27ebbb685..caa33e0e4 100644 --- a/LambdaRuntimeDockerfiles/Images/net7/arm64/Dockerfile +++ b/LambdaRuntimeDockerfiles/Images/net7/arm64/Dockerfile @@ -1,7 +1,7 @@ # Based on Docker image from: https://github.com/dotnet/dotnet-docker/ -ARG ASPNET_VERSION=7.0.18 -ARG ASPNET_SHA512=62bc42a8d094be8253be90acba02253c27afb1eb6b06976c3adea74f967f522bf7938eaed25c824d6e36a9fb71f7248ba315cc67577a3c7fb73b0d3d7a41ecac +ARG ASPNET_VERSION=7.0.19 +ARG ASPNET_SHA512=c71e6a756bdac7f68289fb6c67fcb8c347586e421cbf4345fb510686ff5948e25898759dc7ab30904ac07a7d595508e59d66b5b6dc88d30b54c141c82bd590cf ARG ICU_VERSION=68.1 ARG ICU_MD5=6a99b541ea01f271257b121a4433c7c0 diff --git a/LambdaRuntimeDockerfiles/Images/net8/amd64/Dockerfile b/LambdaRuntimeDockerfiles/Images/net8/amd64/Dockerfile index dcb42a44d..05ab32369 100644 --- a/LambdaRuntimeDockerfiles/Images/net8/amd64/Dockerfile +++ b/LambdaRuntimeDockerfiles/Images/net8/amd64/Dockerfile @@ -1,7 +1,7 @@ # Based on Docker image from: https://github.com/dotnet/dotnet-docker/ -ARG ASPNET_VERSION=8.0.4 -ARG ASPNET_SHA512=8ab281977116bf59a672afe5463bce4433378cc8a67d332c564a012939b7dbdd8756df82a115a5ab93f8186c22700a6dc0272b99a0f484db837da96820c78e79 +ARG ASPNET_VERSION=8.0.5 +ARG ASPNET_SHA512=ffe6a534ed7dffe031e7d687b153f09a743792fad6ddcdf70fcbdbe4564462d5db71a8c9eb52036b817192386ef6a8fc574d995e0cdf572226302e797a6581c4 ARG LAMBDA_RUNTIME_NAME=dotnet8 ARG AMAZON_LINUX=public.ecr.aws/lambda/provided:al2023 diff --git a/LambdaRuntimeDockerfiles/Images/net8/arm64/Dockerfile b/LambdaRuntimeDockerfiles/Images/net8/arm64/Dockerfile index 9464729c4..4a24c5c8d 100644 --- a/LambdaRuntimeDockerfiles/Images/net8/arm64/Dockerfile +++ b/LambdaRuntimeDockerfiles/Images/net8/arm64/Dockerfile @@ -1,7 +1,7 @@ # Based on Docker image from: https://github.com/dotnet/dotnet-docker/ -ARG ASPNET_VERSION=8.0.4 -ARG ASPNET_SHA512=0b0b3dffe678211afcaeca5d7e381f2218f156421c79dd06e083b1abd92ceb2b5c04c8a159b7d67b866393b8169de826ede70240226e0164451b329b7d46b570 +ARG ASPNET_VERSION=8.0.5 +ARG ASPNET_SHA512=54ad859a3307a4ccce6aa794df20dab3fc38cb4a8fc9f1c2cb41636d6d19fed1e82f88a0099bdc9f30e08c919ae5653da828ae54b0299291dafcc755575f02db ARG LAMBDA_RUNTIME_NAME=dotnet8 ARG AMAZON_LINUX=public.ecr.aws/lambda/provided:al2023 From 3ef0bc9f27c979db185f2a4154edb58cd4a8cad0 Mon Sep 17 00:00:00 2001 From: aws-sdk-dotnet-automation Date: Fri, 7 Jun 2024 13:50:09 +0000 Subject: [PATCH 09/35] chore: ASP.NET Core version update in Dockerfiles --- LambdaRuntimeDockerfiles/Images/net6/amd64/Dockerfile | 4 ++-- LambdaRuntimeDockerfiles/Images/net6/arm64/Dockerfile | 4 ++-- LambdaRuntimeDockerfiles/Images/net7/amd64/Dockerfile | 4 ++-- LambdaRuntimeDockerfiles/Images/net7/arm64/Dockerfile | 4 ++-- LambdaRuntimeDockerfiles/Images/net8/amd64/Dockerfile | 4 ++-- LambdaRuntimeDockerfiles/Images/net8/arm64/Dockerfile | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/LambdaRuntimeDockerfiles/Images/net6/amd64/Dockerfile b/LambdaRuntimeDockerfiles/Images/net6/amd64/Dockerfile index 0452a6465..3e36dd74f 100644 --- a/LambdaRuntimeDockerfiles/Images/net6/amd64/Dockerfile +++ b/LambdaRuntimeDockerfiles/Images/net6/amd64/Dockerfile @@ -1,7 +1,7 @@ # Based on Docker image from: https://github.com/dotnet/dotnet-docker/ -ARG ASPNET_VERSION=6.0.30 -ARG ASPNET_SHA512=757d017db28b8e34c4b242c082aa51eb85bce8fca16af37a0beabedb271c9bd13e1631868faa131745d7784db48974567f82275da09041ba434dcb7abe821a2d +ARG ASPNET_VERSION=6.0.31 +ARG ASPNET_SHA512=ebb20a3461bf9d1e3a5c91761452f5ef2e60873826ad3158493768a18d207319bccc40d6c1a64fd61dd8c22bad51c26689394b0e6a40c4bfe4cca00ce4c00db1 ARG LAMBDA_RUNTIME_NAME=dotnet6 ARG AMAZON_LINUX=public.ecr.aws/lambda/provided:al2 diff --git a/LambdaRuntimeDockerfiles/Images/net6/arm64/Dockerfile b/LambdaRuntimeDockerfiles/Images/net6/arm64/Dockerfile index dc507203f..3e86e29e3 100644 --- a/LambdaRuntimeDockerfiles/Images/net6/arm64/Dockerfile +++ b/LambdaRuntimeDockerfiles/Images/net6/arm64/Dockerfile @@ -1,7 +1,7 @@ # Based on Docker image from: https://github.com/dotnet/dotnet-docker/ -ARG ASPNET_VERSION=6.0.30 -ARG ASPNET_SHA512=de0921903ba55e21195107b126e271457550543fd6a9698ab3c2b1e2b95f7fe2d6fb2f067e08ed10c9e56940c247733dd9a2f9775e7993e033a945899461e130 +ARG ASPNET_VERSION=6.0.31 +ARG ASPNET_SHA512=5d395554520a62c81e01f045245749d771d728a353631879462ac499e78658377e475bca756668eeafdd65ac55ad55f244f778809c127a553c5c330b76ef9dd8 ARG ICU_VERSION=68.1 ARG ICU_MD5=6a99b541ea01f271257b121a4433c7c0 diff --git a/LambdaRuntimeDockerfiles/Images/net7/amd64/Dockerfile b/LambdaRuntimeDockerfiles/Images/net7/amd64/Dockerfile index 3158c7b5f..e62003224 100644 --- a/LambdaRuntimeDockerfiles/Images/net7/amd64/Dockerfile +++ b/LambdaRuntimeDockerfiles/Images/net7/amd64/Dockerfile @@ -1,7 +1,7 @@ # Based on Docker image from: https://github.com/dotnet/dotnet-docker/ -ARG ASPNET_VERSION=7.0.19 -ARG ASPNET_SHA512=569fcc25f0c32df3b28c4569bbeabb6c20afc8865088f14a405d3847bbfd159cf291d2dc4810140b8f436f06c95ebb09214ac837b5ade6bd8121e9c0204eb217 +ARG ASPNET_VERSION=7.0.20 +ARG ASPNET_SHA512=62ed9743972043a72e48d5aa2f7fdf3483cf684a32b051315004d1c778e9712bf66e5e7a97a5a53993fa8e92daf5bacaf2cdb3eae44bb9a9e25532b9a80f4f70 ARG LAMBDA_RUNTIME_NAME=dotnet7 ARG AMAZON_LINUX=public.ecr.aws/lambda/provided:al2 diff --git a/LambdaRuntimeDockerfiles/Images/net7/arm64/Dockerfile b/LambdaRuntimeDockerfiles/Images/net7/arm64/Dockerfile index caa33e0e4..83ddd8431 100644 --- a/LambdaRuntimeDockerfiles/Images/net7/arm64/Dockerfile +++ b/LambdaRuntimeDockerfiles/Images/net7/arm64/Dockerfile @@ -1,7 +1,7 @@ # Based on Docker image from: https://github.com/dotnet/dotnet-docker/ -ARG ASPNET_VERSION=7.0.19 -ARG ASPNET_SHA512=c71e6a756bdac7f68289fb6c67fcb8c347586e421cbf4345fb510686ff5948e25898759dc7ab30904ac07a7d595508e59d66b5b6dc88d30b54c141c82bd590cf +ARG ASPNET_VERSION=7.0.20 +ARG ASPNET_SHA512=dfb1c1bef4d826defd3d995599a5c03e1bf1a64c65d98b675d6c05dbb7380d98233953e68d53fc5ebec60ad4ef75417073fb1fb3256a0176bb964f0e01161f6c ARG ICU_VERSION=68.1 ARG ICU_MD5=6a99b541ea01f271257b121a4433c7c0 diff --git a/LambdaRuntimeDockerfiles/Images/net8/amd64/Dockerfile b/LambdaRuntimeDockerfiles/Images/net8/amd64/Dockerfile index 05ab32369..237b7e76d 100644 --- a/LambdaRuntimeDockerfiles/Images/net8/amd64/Dockerfile +++ b/LambdaRuntimeDockerfiles/Images/net8/amd64/Dockerfile @@ -1,7 +1,7 @@ # Based on Docker image from: https://github.com/dotnet/dotnet-docker/ -ARG ASPNET_VERSION=8.0.5 -ARG ASPNET_SHA512=ffe6a534ed7dffe031e7d687b153f09a743792fad6ddcdf70fcbdbe4564462d5db71a8c9eb52036b817192386ef6a8fc574d995e0cdf572226302e797a6581c4 +ARG ASPNET_VERSION=8.0.6 +ARG ASPNET_SHA512=16cd54c431d80710a06037f8ea593e04764a80cbaad75e1db4225fbe3e7fce4c4d279f40757b9811e1c092436d2a1ca3be64c74cb190ebf78418a9865992ad12 ARG LAMBDA_RUNTIME_NAME=dotnet8 ARG AMAZON_LINUX=public.ecr.aws/lambda/provided:al2023 diff --git a/LambdaRuntimeDockerfiles/Images/net8/arm64/Dockerfile b/LambdaRuntimeDockerfiles/Images/net8/arm64/Dockerfile index 4a24c5c8d..4c53f031e 100644 --- a/LambdaRuntimeDockerfiles/Images/net8/arm64/Dockerfile +++ b/LambdaRuntimeDockerfiles/Images/net8/arm64/Dockerfile @@ -1,7 +1,7 @@ # Based on Docker image from: https://github.com/dotnet/dotnet-docker/ -ARG ASPNET_VERSION=8.0.5 -ARG ASPNET_SHA512=54ad859a3307a4ccce6aa794df20dab3fc38cb4a8fc9f1c2cb41636d6d19fed1e82f88a0099bdc9f30e08c919ae5653da828ae54b0299291dafcc755575f02db +ARG ASPNET_VERSION=8.0.6 +ARG ASPNET_SHA512=9ed12847e404a0a4fdd8fca33a9a787c5ac2e6745d23821c7890f731f2f8f5682e7f9166b2764b13b612b08e091c71e13359b68acc11bcf990afdef1d42f6473 ARG LAMBDA_RUNTIME_NAME=dotnet8 ARG AMAZON_LINUX=public.ecr.aws/lambda/provided:al2023 From f2c3c07bb4cfa9e90934ce03a99dc214279d79d2 Mon Sep 17 00:00:00 2001 From: Malhar Khimsaria <96malhar@gmail.com> Date: Mon, 17 Jun 2024 09:20:36 -0700 Subject: [PATCH 10/35] feat: Add support for SQS events in Amazon.Lambda.Annotations (#1758) --- Libraries/Amazon.Lambda.Annotations.slnf | 1 + ....Lambda.Annotations.SourceGenerator.csproj | 5 + .../Diagnostics/AnalyzerReleases.Shipped.md | 9 + .../Diagnostics/DiagnosticDescriptors.cs | 23 +- .../Generator.cs | 196 +-------- .../Attributes/AttributeModelBuilder.cs | 10 + .../Attributes/SQSEventAttributeBuilder.cs | 52 +++ .../Models/EventTypeBuilder.cs | 8 +- .../Models/ILambdaFunctionSerializable.cs | 8 +- .../Models/LambdaFunctionModel.cs | 9 +- .../Models/LambdaFunctionModelBuilder.cs | 62 ++- .../Models/LambdaMethodModel.cs | 17 +- .../Templates/LambdaFunctionTemplate.cs | 6 +- .../Templates/LambdaFunctionTemplate.tt | 4 +- .../TypeFullNames.cs | 10 +- .../Validation/LambdaFunctionValidator.cs | 208 +++++++++ .../Writers/CloudFormationWriter.cs | 222 ++++++++-- .../Writers/ITemplateWriter.cs | 7 + .../Writers/JsonWriter.cs | 30 +- .../Writers/YamlWriter.cs | 26 +- .../Amazon.Lambda.Annotations.csproj | 21 +- .../src/Amazon.Lambda.Annotations/README.md | 123 +++++- .../SQS/SQSEventAttribute.cs | 175 ++++++++ ....Annotations.SourceGenerators.Tests.csproj | 9 +- .../CSharpSourceGeneratorVerifier.cs | 2 + ...esWithBatchFailureReporting_Generated.g.cs | 57 +++ ...idSQSEvents_ProcessMessages_Generated.g.cs | 57 +++ .../complexCalculator.template | 16 +- .../customizeResponse.template | 59 ++- .../ServerlessTemplates/greeter.template | 18 +- .../greeter_executable.template | 18 +- .../nullreferenceexample.template | 8 +- .../simpleCalculator.template | 32 +- ...urcegeneratorserializationexample.template | 8 +- .../ServerlessTemplates/sqsEvents.template | 135 ++++++ .../SourceGeneratorTests.cs | 131 +++++- .../WriterTests/CloudFormationWriterTests.cs | 16 +- .../WriterTests/JsonWriterTests.cs | 39 ++ .../WriterTests/SQSEventsTests.cs | 399 ++++++++++++++++++ .../WriterTests/YamlWriterTests.cs | 40 ++ .../WriterTests/snapshot.json | 10 +- .../WriterTests/snapshot.yaml | 5 +- .../serverless.template | 84 +++- .../Helpers/LambdaHelper.cs | 9 + .../IntegrationTestContextFixture.cs | 4 +- .../SQSEventSourceMapping.cs | 43 ++ .../TestServerlessApp.IntegrationTests.csproj | 2 +- .../InvalidSQSEvents.cs.error | 87 ++++ .../SQSEventExamples/ValidSQSEvents.cs.txt | 33 ++ .../TestServerlessApp/SqsMessageProcessing.cs | 18 + .../TestServerlessApp.csproj | 1 + .../TestServerlessApp/serverless.template | 214 +++++++++- 52 files changed, 2480 insertions(+), 306 deletions(-) create mode 100644 Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/Attributes/SQSEventAttributeBuilder.cs create mode 100644 Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Validation/LambdaFunctionValidator.cs create mode 100644 Libraries/src/Amazon.Lambda.Annotations/SQS/SQSEventAttribute.cs create mode 100644 Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SQS/ValidSQSEvents_ProcessMessagesWithBatchFailureReporting_Generated.g.cs create mode 100644 Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/SQS/ValidSQSEvents_ProcessMessages_Generated.g.cs create mode 100644 Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/sqsEvents.template create mode 100644 Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/WriterTests/SQSEventsTests.cs create mode 100644 Libraries/test/TestServerlessApp.IntegrationTests/SQSEventSourceMapping.cs create mode 100644 Libraries/test/TestServerlessApp/SQSEventExamples/InvalidSQSEvents.cs.error create mode 100644 Libraries/test/TestServerlessApp/SQSEventExamples/ValidSQSEvents.cs.txt create mode 100644 Libraries/test/TestServerlessApp/SqsMessageProcessing.cs diff --git a/Libraries/Amazon.Lambda.Annotations.slnf b/Libraries/Amazon.Lambda.Annotations.slnf index 1b89a7014..377a01b7e 100644 --- a/Libraries/Amazon.Lambda.Annotations.slnf +++ b/Libraries/Amazon.Lambda.Annotations.slnf @@ -7,6 +7,7 @@ "src\\Amazon.Lambda.Annotations\\Amazon.Lambda.Annotations.csproj", "src\\Amazon.Lambda.Core\\Amazon.Lambda.Core.csproj", "src\\Amazon.Lambda.RuntimeSupport\\Amazon.Lambda.RuntimeSupport.csproj", + "src\\Amazon.Lambda.SQSEvents\\Amazon.Lambda.SQSEvents.csproj", "src\\Amazon.Lambda.Serialization.SystemTextJson\\Amazon.Lambda.Serialization.SystemTextJson.csproj", "test\\Amazon.Lambda.Annotations.SourceGenerators.Tests\\Amazon.Lambda.Annotations.SourceGenerators.Tests.csproj", "test\\TestExecutableServerlessApp\\TestExecutableServerlessApp.csproj", diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Amazon.Lambda.Annotations.SourceGenerator.csproj b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Amazon.Lambda.Annotations.SourceGenerator.csproj index 622e6a0df..114feb426 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Amazon.Lambda.Annotations.SourceGenerator.csproj +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Amazon.Lambda.Annotations.SourceGenerator.csproj @@ -4,6 +4,11 @@ 1.4.0 netstandard2.0 + + ..\..\..\buildtools\public.snk + true + true diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Diagnostics/AnalyzerReleases.Shipped.md b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Diagnostics/AnalyzerReleases.Shipped.md index e59823e20..f664c3c35 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Diagnostics/AnalyzerReleases.Shipped.md +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Diagnostics/AnalyzerReleases.Shipped.md @@ -1,6 +1,15 @@ ; Shipped analyzer releases ; https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md +## Release 1.5.0 +### New Rules + +Rule ID | Category | Severity | Notes +--------|----------|----------|------- +AWSLambda0115 | AWSLambdaCSharpGenerator | Error | Invalid Usage of API Parameters +AWSLambda0116 | AWSLambdaCSharpGenerator | Error | Invalid SQSEventAttribute encountered +AWSLambda0117 | AWSLambdaCSharpGenerator | Error | Invalid Lambda Method Signature + ## Release 1.1.0 ### New Rules diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Diagnostics/DiagnosticDescriptors.cs b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Diagnostics/DiagnosticDescriptors.cs index a511b4b60..fdf0813ec 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Diagnostics/DiagnosticDescriptors.cs +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Diagnostics/DiagnosticDescriptors.cs @@ -103,7 +103,7 @@ public static class DiagnosticDescriptors category: "AWSLambdaCSharpGenerator", DiagnosticSeverity.Error, isEnabledByDefault: true); - + public static readonly DiagnosticDescriptor ExecutableWithNoFunctions = new DiagnosticDescriptor(id: "AWSLambda0113", title: "Executable output with no LambdaFunction annotations", messageFormat: "Your project is configured to output an executable and generate a static Main method, but you have not configured any methods with the 'LambdaFunction' attribute", @@ -117,5 +117,26 @@ public static class DiagnosticDescriptors category: "AWSLambdaCSharpGenerator", DiagnosticSeverity.Error, isEnabledByDefault: true); + + public static readonly DiagnosticDescriptor ApiParametersOnNonApiFunction = new DiagnosticDescriptor(id: "AWSLambda0115", + title: "Invalid Usage of API Parameters", + messageFormat: "The Lambda function parameters are annotated with HTTP API attributes but the Lambda function itself is not annotated with an HTTP API attribute", + category: "AWSLambdaCSharpGenerator", + DiagnosticSeverity.Error, + isEnabledByDefault: true); + + public static readonly DiagnosticDescriptor InvalidSqsEventAttribute = new DiagnosticDescriptor(id: "AWSLambda0116", + title: "Invalid SQSEventAttribute", + messageFormat: "Invalid SQSEventAttribute encountered: {0}", + category: "AWSLambdaCSharpGenerator", + DiagnosticSeverity.Error, + isEnabledByDefault: true); + + public static readonly DiagnosticDescriptor InvalidLambdaMethodSignature = new DiagnosticDescriptor(id: "AWSLambda0117", + title: "Invalid Lambda Method Signature", + messageFormat: "Invalid Lambda method signature encountered: {0}", + category: "AWSLambdaCSharpGenerator", + DiagnosticSeverity.Error, + isEnabledByDefault: true); } } \ No newline at end of file diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Generator.cs b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Generator.cs index 01413fb16..ee14afd19 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Generator.cs +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Generator.cs @@ -2,18 +2,14 @@ using Amazon.Lambda.Annotations.SourceGenerator.Extensions; using Amazon.Lambda.Annotations.SourceGenerator.FileIO; using Amazon.Lambda.Annotations.SourceGenerator.Models; -using Amazon.Lambda.Annotations.SourceGenerator.Models.Attributes; using Amazon.Lambda.Annotations.SourceGenerator.Templates; using Amazon.Lambda.Annotations.SourceGenerator.Writers; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using System.Text; -using System.Text.RegularExpressions; namespace Amazon.Lambda.Annotations.SourceGenerator { @@ -41,12 +37,6 @@ public class Generator : ISourceGenerator "dotnet8" }; - // Only allow alphanumeric characters - private readonly Regex _resourceNameRegex = new Regex("^[a-zA-Z0-9]+$"); - - // Regex for the 'Name' property for API Gateway attributes - https://docs.aws.amazon.com/apigateway/latest/developerguide/request-response-data-mappings.html - private readonly Regex _parameterAttributeNameRegex = new Regex("^[a-zA-Z0-9._$-]+$"); - public Generator() { #if DEBUG @@ -144,7 +134,7 @@ public void Execute(GeneratorExecutionContext context) } } - var configureMethodModel = semanticModelProvider.GetConfigureMethodModel(receiver.StartupClasses.FirstOrDefault()); + var configureMethodSymbol = semanticModelProvider.GetConfigureMethodModel(receiver.StartupClasses.FirstOrDefault()); var annotationReport = new AnnotationReport(); @@ -152,98 +142,38 @@ public void Execute(GeneratorExecutionContext context) var lambdaModels = new List(); - foreach (var lambdaMethod in receiver.LambdaMethods) + foreach (var lambdaMethodDeclarationSyntax in receiver.LambdaMethods) { - var lambdaMethodModel = semanticModelProvider.GetMethodSemanticModel(lambdaMethod); + var lambdaMethodSymbol = semanticModelProvider.GetMethodSemanticModel(lambdaMethodDeclarationSyntax); + var lambdaMethodLocation = lambdaMethodDeclarationSyntax.GetLocation(); - if (!HasSerializerAttribute(context, lambdaMethodModel)) + var lambdaFunctionModel = LambdaFunctionModelBuilder.BuildAndValidate(lambdaMethodSymbol, lambdaMethodLocation, configureMethodSymbol, context, isExecutable, defaultRuntime, diagnosticReporter); + if (!lambdaFunctionModel.IsValid) { - diagnosticReporter.Report(Diagnostic.Create(DiagnosticDescriptors.MissingLambdaSerializer, - lambdaMethod.GetLocation())); - + // If the model is not valid then skip it from further processing foundFatalError = true; continue; } - // Check for necessary references - if (lambdaMethodModel.HasAttribute(context, TypeFullNames.RestApiAttribute) - || lambdaMethodModel.HasAttribute(context, TypeFullNames.HttpApiAttribute)) - { - // Check for arbitrary type from "Amazon.Lambda.APIGatewayEvents" - if (context.Compilation.ReferencedAssemblyNames.FirstOrDefault(x => x.Name == "Amazon.Lambda.APIGatewayEvents") == null) - { - diagnosticReporter.Report(Diagnostic.Create(DiagnosticDescriptors.MissingDependencies, - lambdaMethod.GetLocation(), - "Amazon.Lambda.APIGatewayEvents")); - - foundFatalError = true; - continue; - } - } - - var serializerInfo = GetSerializerInfoAttribute(context, lambdaMethodModel); - - var model = LambdaFunctionModelBuilder.Build(lambdaMethodModel, configureMethodModel, context, isExecutable, serializerInfo, defaultRuntime); - - // If there are more than one event, report them as errors - if (model.LambdaMethod.Events.Count > 1) - { - foreach (var attribute in lambdaMethodModel.GetAttributes().Where(attribute => TypeFullNames.Events.Contains(attribute.AttributeClass.ToDisplayString()))) - { - diagnosticReporter.Report(Diagnostic.Create(DiagnosticDescriptors.MultipleEventsNotSupported, - Location.Create(attribute.ApplicationSyntaxReference.SyntaxTree, attribute.ApplicationSyntaxReference.Span), - DiagnosticSeverity.Error)); - } - - foundFatalError = true; - // Skip multi-event lambda method from processing and check remaining lambda methods for diagnostics - continue; - } - if(model.LambdaMethod.ReturnsIHttpResults && !model.LambdaMethod.Events.Contains(EventType.API)) - { - diagnosticReporter.Report(Diagnostic.Create(DiagnosticDescriptors.HttpResultsOnNonApiFunction, - Location.Create(lambdaMethod.SyntaxTree, lambdaMethod.Span), - DiagnosticSeverity.Error)); - - foundFatalError = true; - continue; - } - - if (!_resourceNameRegex.IsMatch(model.ResourceName)) - { - diagnosticReporter.Report(Diagnostic.Create(DiagnosticDescriptors.InvalidResourceName, - Location.Create(lambdaMethod.SyntaxTree, lambdaMethod.Span), - DiagnosticSeverity.Error)); - - foundFatalError = true; - continue; - } - - if (!AreLambdaMethodParametersValid(lambdaMethod, model, diagnosticReporter)) - { - foundFatalError = true; - continue; - } - - var template = new LambdaFunctionTemplate(model); + var template = new LambdaFunctionTemplate(lambdaFunctionModel); string sourceText; try { sourceText = template.TransformText().ToEnvironmentLineEndings(); - context.AddSource($"{model.GeneratedMethod.ContainingType.Name}.g.cs", SourceText.From(sourceText, Encoding.UTF8, SourceHashAlgorithm.Sha256)); + context.AddSource($"{lambdaFunctionModel.GeneratedMethod.ContainingType.Name}.g.cs", SourceText.From(sourceText, Encoding.UTF8, SourceHashAlgorithm.Sha256)); } catch (Exception e) when (e is NotSupportedException || e is InvalidOperationException) { - diagnosticReporter.Report(Diagnostic.Create(DiagnosticDescriptors.CodeGenerationFailed, Location.Create(lambdaMethod.SyntaxTree, lambdaMethod.Span), e.Message)); + diagnosticReporter.Report(Diagnostic.Create(DiagnosticDescriptors.CodeGenerationFailed, Location.Create(lambdaMethodDeclarationSyntax.SyntaxTree, lambdaMethodDeclarationSyntax.Span), e.Message)); return; } // report every generated file to build output - diagnosticReporter.Report(Diagnostic.Create(DiagnosticDescriptors.CodeGeneration, Location.None, $"{model.GeneratedMethod.ContainingType.Name}.g.cs", sourceText)); + diagnosticReporter.Report(Diagnostic.Create(DiagnosticDescriptors.CodeGeneration, Location.None, $"{lambdaFunctionModel.GeneratedMethod.ContainingType.Name}.g.cs", sourceText)); - lambdaModels.Add(model); - annotationReport.LambdaFunctions.Add(model); + lambdaModels.Add(lambdaFunctionModel); + annotationReport.LambdaFunctions.Add(lambdaFunctionModel); } if (isExecutable) @@ -348,110 +278,10 @@ private static ExecutableAssembly GenerateExecutableAssemblySource( lambdaModels[0].LambdaMethod.ContainingNamespace); } - private bool HasSerializerAttribute(GeneratorExecutionContext context, IMethodSymbol methodModel) - { - return methodModel.ContainingAssembly.HasAttribute(context, TypeFullNames.LambdaSerializerAttribute); - } - - private LambdaSerializerInfo GetSerializerInfoAttribute(GeneratorExecutionContext context, IMethodSymbol methodModel) - { - var serializerString = DEFAULT_LAMBDA_SERIALIZER; - - ISymbol symbol = null; - - // First check if method has the Lambda Serializer. - if (methodModel.HasAttribute( - context, - TypeFullNames.LambdaSerializerAttribute)) - { - symbol = methodModel; - } - // Then check assembly - else if (methodModel.ContainingAssembly.HasAttribute( - context, - TypeFullNames.LambdaSerializerAttribute)) - { - symbol = methodModel.ContainingAssembly; - } - // Else return the default serializer. - else - { - return new LambdaSerializerInfo(serializerString); - } - - var attribute = symbol.GetAttributes().FirstOrDefault(attr => attr.AttributeClass.Name == TypeFullNames.LambdaSerializerAttributeWithoutNamespace); - - var serializerValue = attribute.ConstructorArguments.FirstOrDefault(kvp => kvp.Type.Name == nameof(Type)).Value; - - if (serializerValue != null) - { - serializerString = serializerValue.ToString(); - } - - return new LambdaSerializerInfo(serializerString); - } - public void Initialize(GeneratorInitializationContext context) { // Register a syntax receiver that will be created for each generation pass context.RegisterForSyntaxNotifications(() => new SyntaxReceiver(_fileManager, _directoryManager)); } - - private bool AreLambdaMethodParametersValid(MethodDeclarationSyntax declarationSyntax, LambdaFunctionModel model, DiagnosticReporter diagnosticReporter) - { - var isValid = true; - foreach (var parameter in model.LambdaMethod.Parameters) - { - if (parameter.Attributes.Any(att => att.Type.FullName == TypeFullNames.FromQueryAttribute)) - { - var fromQueryAttribute = parameter.Attributes.First(att => att.Type.FullName == TypeFullNames.FromQueryAttribute) as AttributeModel; - // Use parameter name as key, if Name has not specified explicitly in the attribute definition. - var parameterKey = fromQueryAttribute?.Data?.Name ?? parameter.Name; - - if (!parameter.Type.IsPrimitiveType() && !parameter.Type.IsPrimitiveEnumerableType()) - { - isValid = false; - diagnosticReporter.Report(Diagnostic.Create(DiagnosticDescriptors.UnsupportedMethodParameterType, - Location.Create(declarationSyntax.SyntaxTree, declarationSyntax.Span), - parameterKey, parameter.Type.FullName)); - } - } - - foreach (var att in parameter.Attributes) - { - var parameterAttributeName = string.Empty; - switch (att.Type.FullName) - { - case TypeFullNames.FromQueryAttribute: - var fromQueryAttribute = (AttributeModel)att; - parameterAttributeName = fromQueryAttribute.Data.Name; - break; - - case TypeFullNames.FromRouteAttribute: - var fromRouteAttribute = (AttributeModel)att; - parameterAttributeName = fromRouteAttribute.Data.Name; - break; - - case TypeFullNames.FromHeaderAttribute: - var fromHeaderAttribute = (AttributeModel)att; - parameterAttributeName = fromHeaderAttribute.Data.Name; - break; - - default: - break; - } - - if (!string.IsNullOrEmpty(parameterAttributeName) && !_parameterAttributeNameRegex.IsMatch(parameterAttributeName)) - { - isValid = false; - diagnosticReporter.Report(Diagnostic.Create(DiagnosticDescriptors.InvalidParameterAttributeName, - Location.Create(declarationSyntax.SyntaxTree, declarationSyntax.Span), - parameterAttributeName, parameter.Name)); - } - } - } - - return isValid; - } } } \ No newline at end of file diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/Attributes/AttributeModelBuilder.cs b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/Attributes/AttributeModelBuilder.cs index 21419dcb8..fe18ca208 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/Attributes/AttributeModelBuilder.cs +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/Attributes/AttributeModelBuilder.cs @@ -1,5 +1,6 @@ using System; using Amazon.Lambda.Annotations.APIGateway; +using Amazon.Lambda.Annotations.SQS; using Microsoft.CodeAnalysis; namespace Amazon.Lambda.Annotations.SourceGenerator.Models.Attributes @@ -71,6 +72,15 @@ public static AttributeModel Build(AttributeData att, GeneratorExecutionContext Type = TypeModelBuilder.Build(att.AttributeClass, context) }; } + else if (att.AttributeClass.Equals(context.Compilation.GetTypeByMetadataName(TypeFullNames.SQSEventAttribute), SymbolEqualityComparer.Default)) + { + var data = SQSEventAttributeBuilder.Build(att); + model = new AttributeModel + { + Data = data, + Type = TypeModelBuilder.Build(att.AttributeClass, context) + }; + } else { model = new AttributeModel diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/Attributes/SQSEventAttributeBuilder.cs b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/Attributes/SQSEventAttributeBuilder.cs new file mode 100644 index 000000000..c58063c48 --- /dev/null +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/Attributes/SQSEventAttributeBuilder.cs @@ -0,0 +1,52 @@ +using Amazon.Lambda.Annotations.SQS; +using Microsoft.CodeAnalysis; +using System; + +namespace Amazon.Lambda.Annotations.SourceGenerator.Models.Attributes +{ + /// + /// Builder for . + /// + public class SQSEventAttributeBuilder + { + public static SQSEventAttribute Build(AttributeData att) + { + if (att.ConstructorArguments.Length != 1) + { + throw new NotSupportedException($"{TypeFullNames.SQSEventAttribute} must have constructor with 1 argument."); + } + var queue = att.ConstructorArguments[0].Value as string; + var data = new SQSEventAttribute(queue); + + foreach (var pair in att.NamedArguments) + { + if (pair.Key == nameof(data.ResourceName) && pair.Value.Value is string resourceName) + { + data.ResourceName = resourceName; + } + if (pair.Key == nameof(data.BatchSize) && pair.Value.Value is uint batchSize) + { + data.BatchSize = batchSize; + } + else if (pair.Key == nameof(data.Enabled) && pair.Value.Value is bool enabled) + { + data.Enabled = enabled; + } + else if (pair.Key == nameof(data.MaximumBatchingWindowInSeconds) && pair.Value.Value is uint maximumBatchingWindowInSeconds) + { + data.MaximumBatchingWindowInSeconds = maximumBatchingWindowInSeconds; + } + else if (pair.Key == nameof(data.Filters) && pair.Value.Value is string filters) + { + data.Filters = filters; + } + else if (pair.Key == nameof(data.MaximumConcurrency) && pair.Value.Value is uint maximumConcurrency) + { + data.MaximumConcurrency = maximumConcurrency; + } + } + + return data; + } + } +} diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/EventTypeBuilder.cs b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/EventTypeBuilder.cs index 246504491..f70260803 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/EventTypeBuilder.cs +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/EventTypeBuilder.cs @@ -11,10 +11,10 @@ namespace Amazon.Lambda.Annotations.SourceGenerator.Models /// public class EventTypeBuilder { - public static List Build(IMethodSymbol lambdaMethodSymbol, + public static HashSet Build(IMethodSymbol lambdaMethodSymbol, GeneratorExecutionContext context) { - var events = new List(); + var events = new HashSet(); foreach (var attribute in lambdaMethodSymbol.GetAttributes()) { if (attribute.AttributeClass.ToDisplayString() == TypeFullNames.RestApiAttribute @@ -22,6 +22,10 @@ public static List Build(IMethodSymbol lambdaMethodSymbol, { events.Add(EventType.API); } + else if (attribute.AttributeClass.ToDisplayString() == TypeFullNames.SQSEventAttribute) + { + events.Add(EventType.SQS); + } } return events; diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/ILambdaFunctionSerializable.cs b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/ILambdaFunctionSerializable.cs index 9ed23c88f..6cb6161fa 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/ILambdaFunctionSerializable.cs +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/ILambdaFunctionSerializable.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using Amazon.Lambda.Annotations.SourceGenerator.Models.Attributes; namespace Amazon.Lambda.Annotations.SourceGenerator.Models @@ -69,6 +68,11 @@ public interface ILambdaFunctionSerializable /// IList Attributes { get; } + /// + /// The fully qualified name of the return type of the Lambda method written by the user. + /// + string ReturnTypeFullName { get; } + /// /// The assembly version of the Amazon.Lambda.Annotations.SourceGenerator package. /// diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/LambdaFunctionModel.cs b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/LambdaFunctionModel.cs index 8ef99542c..fad1f5f53 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/LambdaFunctionModel.cs +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/LambdaFunctionModel.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Linq; using Amazon.Lambda.Annotations.SourceGenerator.Models.Attributes; @@ -73,7 +72,15 @@ public class LambdaFunctionModel : ILambdaFunctionSerializable /// public IList Attributes => LambdaMethod.Attributes ?? new List(); + /// + public string ReturnTypeFullName => LambdaMethod.ReturnType.FullName; + /// public string SourceGeneratorVersion { get; set; } + + /// + /// Indicates if the model is valid. + /// + public bool IsValid { get; set; } } } \ No newline at end of file diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/LambdaFunctionModelBuilder.cs b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/LambdaFunctionModelBuilder.cs index 545a5e8fa..f347789a7 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/LambdaFunctionModelBuilder.cs +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/LambdaFunctionModelBuilder.cs @@ -1,5 +1,8 @@ +using System; using System.Linq; -using System.Reflection; +using Amazon.Lambda.Annotations.SourceGenerator.Diagnostics; +using Amazon.Lambda.Annotations.SourceGenerator.Extensions; +using Amazon.Lambda.Annotations.SourceGenerator.Validation; using Microsoft.CodeAnalysis; namespace Amazon.Lambda.Annotations.SourceGenerator.Models @@ -9,7 +12,20 @@ namespace Amazon.Lambda.Annotations.SourceGenerator.Models /// public static class LambdaFunctionModelBuilder { - public static LambdaFunctionModel Build(IMethodSymbol lambdaMethodSymbol, IMethodSymbol configureMethodSymbol, GeneratorExecutionContext context, bool isExecutable, LambdaSerializerInfo serializerInfo, string runtime) + public static LambdaFunctionModel BuildAndValidate(IMethodSymbol lambdaMethodSymbol, Location LambdamethodLocation, IMethodSymbol configureMethodSymbol, GeneratorExecutionContext context, bool isExecutable, string runtime, DiagnosticReporter diagnosticReporter) + { + // We need to check for the necessary dependencies before attempting to build the LambdaFunctionModel otherwise the generator blows up with unknown exceptions. + if (!LambdaFunctionValidator.ValidateDependencies(context, lambdaMethodSymbol, LambdamethodLocation, diagnosticReporter)) + { + return new LambdaFunctionModel() { IsValid = false }; + } + + var lambdaFunctionModel = Build(lambdaMethodSymbol, configureMethodSymbol, context, isExecutable, runtime); + lambdaFunctionModel.IsValid = LambdaFunctionValidator.ValidateFunction(context, lambdaMethodSymbol, LambdamethodLocation, lambdaFunctionModel, diagnosticReporter); + return lambdaFunctionModel; + } + + private static LambdaFunctionModel Build(IMethodSymbol lambdaMethodSymbol, IMethodSymbol configureMethodSymbol, GeneratorExecutionContext context, bool isExecutable, string runtime) { var lambdaMethod = LambdaMethodModelBuilder.Build(lambdaMethodSymbol, configureMethodSymbol, context); var generatedMethod = GeneratedMethodModelBuilder.Build(lambdaMethodSymbol, configureMethodSymbol, lambdaMethod, context); @@ -17,16 +33,54 @@ public static LambdaFunctionModel Build(IMethodSymbol lambdaMethodSymbol, IMetho { GeneratedMethod = generatedMethod, LambdaMethod = lambdaMethod, - SerializerInfo = serializerInfo, + SerializerInfo = GetSerializerInfoAttribute(context, lambdaMethodSymbol), StartupType = configureMethodSymbol != null ? TypeModelBuilder.Build(configureMethodSymbol.ContainingType, context) : null, SourceGeneratorVersion = context.Compilation .ReferencedAssemblyNames.FirstOrDefault(x => string.Equals(x.Name, "Amazon.Lambda.Annotations")) ?.Version.ToString(), IsExecutable = isExecutable, - Runtime = runtime + Runtime = runtime, }; return model; } + + private static LambdaSerializerInfo GetSerializerInfoAttribute(GeneratorExecutionContext context, IMethodSymbol methodModel) + { + var serializerString = TypeFullNames.DefaultLambdaSerializer; + + ISymbol symbol = null; + + // First check if method has the Lambda Serializer. + if (methodModel.HasAttribute( + context, + TypeFullNames.LambdaSerializerAttribute)) + { + symbol = methodModel; + } + // Then check assembly + else if (methodModel.ContainingAssembly.HasAttribute( + context, + TypeFullNames.LambdaSerializerAttribute)) + { + symbol = methodModel.ContainingAssembly; + } + // Else return the default serializer. + else + { + return new LambdaSerializerInfo(serializerString); + } + + var attribute = symbol.GetAttributes().FirstOrDefault(attr => attr.AttributeClass.Name == TypeFullNames.LambdaSerializerAttributeWithoutNamespace); + + var serializerValue = attribute.ConstructorArguments.FirstOrDefault(kvp => kvp.Type.Name == nameof(Type)).Value; + + if (serializerValue != null) + { + serializerString = serializerValue.ToString(); + } + + return new LambdaSerializerInfo(serializerString); + } } } \ No newline at end of file diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/LambdaMethodModel.cs b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/LambdaMethodModel.cs index 9a81ee95c..24caa34c1 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/LambdaMethodModel.cs +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/LambdaMethodModel.cs @@ -64,6 +64,21 @@ public bool ReturnsIHttpResults } } + /// + /// Returns true if the Lambda function returns either void, Task, SQSBatchResponse or Task + /// + public bool ReturnsVoidTaskOrSqsBatchResponse + { + get + { + if (ReturnsVoid || ReturnsVoidTask || ReturnType.FullName == TypeFullNames.SQSBatchResponse) + { + return true; + } + return ReturnsGenericTask && ReturnType.TypeArguments.Count == 1 && ReturnType.TypeArguments[0].FullName == TypeFullNames.SQSBatchResponse; + } + } + /// /// Gets or sets the parameters of original method. If this method has no parameters, returns /// an empty list. @@ -99,7 +114,7 @@ public bool ReturnsIHttpResults /// /// Gets or sets type of Lambda event /// - public List Events { get; set; } + public HashSet Events { get; set; } /// /// Gets or sets the for the containing type. Returns null if the diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/LambdaFunctionTemplate.cs b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/LambdaFunctionTemplate.cs index 0dfa338e2..ced24e1d1 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/LambdaFunctionTemplate.cs +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/LambdaFunctionTemplate.cs @@ -182,7 +182,9 @@ public virtual string TransformText() this.Write(apiParameters.TransformText()); this.Write(new APIGatewayInvoke(_model, apiParameters.ParameterSignature).TransformText()); } - else if (_model.LambdaMethod.Events.Count == 0) + // Currently we only support 2 event types - APIGatewayEvents and SQSEvents. + // Since SQSEvents does not require any special code generation, the generated method body will be same as when the Lambda method contains no events. + else { this.Write(new NoEventMethodBody(_model).TransformText()); } @@ -206,7 +208,7 @@ private static void SetExecutionEnvironment() envValue.Append(""lib/amazon-lambda-annotations#"); - #line 82 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" + #line 84 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\LambdaFunctionTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(_model.SourceGeneratorVersion)); #line default diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/LambdaFunctionTemplate.tt b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/LambdaFunctionTemplate.tt index f1aa76cb0..e32430f70 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/LambdaFunctionTemplate.tt +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/LambdaFunctionTemplate.tt @@ -60,7 +60,9 @@ this.Write(new FieldsAndConstructor(_model).TransformText()); this.Write(apiParameters.TransformText()); this.Write(new APIGatewayInvoke(_model, apiParameters.ParameterSignature).TransformText()); } - else if (_model.LambdaMethod.Events.Count == 0) + // Currently we only support 2 event types - APIGatewayEvents and SQSEvents. + // Since SQSEvents does not require any special code generation, the generated method body will be same as when the Lambda method contains no events. + else { this.Write(new NoEventMethodBody(_model).TransformText()); } diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/TypeFullNames.cs b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/TypeFullNames.cs index 6450a31b9..53a0cc610 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/TypeFullNames.cs +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/TypeFullNames.cs @@ -32,8 +32,13 @@ public static class TypeFullNames public const string FromBodyAttribute = "Amazon.Lambda.Annotations.APIGateway.FromBodyAttribute"; public const string FromRouteAttribute = "Amazon.Lambda.Annotations.APIGateway.FromRouteAttribute"; + public const string SQSEvent = "Amazon.Lambda.SQSEvents.SQSEvent"; + public const string SQSBatchResponse = "Amazon.Lambda.SQSEvents.SQSBatchResponse"; + public const string SQSEventAttribute = "Amazon.Lambda.Annotations.SQS.SQSEventAttribute"; + public const string LambdaSerializerAttribute = "Amazon.Lambda.Core.LambdaSerializerAttribute"; - + public const string DefaultLambdaSerializer = "Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer"; + public const string LambdaSerializerAttributeWithoutNamespace = "LambdaSerializerAttribute"; public static HashSet Requests = new HashSet @@ -45,7 +50,8 @@ public static class TypeFullNames public static HashSet Events = new HashSet { RestApiAttribute, - HttpApiAttribute + HttpApiAttribute, + SQSEventAttribute }; } } \ No newline at end of file diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Validation/LambdaFunctionValidator.cs b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Validation/LambdaFunctionValidator.cs new file mode 100644 index 000000000..f8e31c0b0 --- /dev/null +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Validation/LambdaFunctionValidator.cs @@ -0,0 +1,208 @@ +using Amazon.Lambda.Annotations.SourceGenerator.Diagnostics; +using Amazon.Lambda.Annotations.SourceGenerator.Extensions; +using Amazon.Lambda.Annotations.SourceGenerator.Models; +using Amazon.Lambda.Annotations.SourceGenerator.Models.Attributes; +using Amazon.Lambda.Annotations.SQS; +using Microsoft.CodeAnalysis; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; + +namespace Amazon.Lambda.Annotations.SourceGenerator.Validation +{ + internal static class LambdaFunctionValidator + { + // Only allow alphanumeric characters + private static readonly Regex _resourceNameRegex = new Regex("^[a-zA-Z0-9]+$"); + + // Regex for the 'Name' property for API Gateway attributes - https://docs.aws.amazon.com/apigateway/latest/developerguide/request-response-data-mappings.html + private static readonly Regex _parameterAttributeNameRegex = new Regex("^[a-zA-Z0-9._$-]+$"); + + internal static bool ValidateFunction(GeneratorExecutionContext context, IMethodSymbol lambdaMethodSymbol, Location methodLocation, LambdaFunctionModel lambdaFunctionModel, DiagnosticReporter diagnosticReporter) + { + var diagnostics = new List(); + + // Validate the resource name + if (!_resourceNameRegex.IsMatch(lambdaFunctionModel.ResourceName)) + { + diagnostics.Add(Diagnostic.Create(DiagnosticDescriptors.InvalidResourceName, methodLocation)); + } + + // Check for Serializer attribute + if (!lambdaMethodSymbol.ContainingAssembly.HasAttribute(context, TypeFullNames.LambdaSerializerAttribute)) + { + if (!lambdaMethodSymbol.HasAttribute(context, TypeFullNames.LambdaSerializerAttribute)) + { + diagnostics.Add(Diagnostic.Create(DiagnosticDescriptors.MissingLambdaSerializer, methodLocation)); + } + } + + // Check for multiple event types + if (lambdaFunctionModel.LambdaMethod.Events.Count > 1) + { + diagnostics.Add(Diagnostic.Create(DiagnosticDescriptors.MultipleEventsNotSupported, methodLocation)); + + // If multiple event types are encountered then return early without validating each individual event + // since at this point we do not know which event type does the user want to preserve + return ReportDiagnostics(diagnosticReporter, diagnostics); + } + + // Validate Events + ValidateApiGatewayEvents(lambdaFunctionModel, methodLocation, diagnostics); + ValidateSqsEvents(lambdaFunctionModel, methodLocation, diagnostics); + + return ReportDiagnostics(diagnosticReporter, diagnostics); + } + + internal static bool ValidateDependencies(GeneratorExecutionContext context, IMethodSymbol lambdaMethodSymbol, Location methodLocation, DiagnosticReporter diagnosticReporter) + { + // Check for references to "Amazon.Lambda.APIGatewayEvents" if the Lambda method is annotated with RestApi or HttpApi attributes. + if (lambdaMethodSymbol.HasAttribute(context, TypeFullNames.RestApiAttribute) || lambdaMethodSymbol.HasAttribute(context, TypeFullNames.HttpApiAttribute)) + { + if (context.Compilation.ReferencedAssemblyNames.FirstOrDefault(x => x.Name == "Amazon.Lambda.APIGatewayEvents") == null) + { + diagnosticReporter.Report(Diagnostic.Create(DiagnosticDescriptors.MissingDependencies, methodLocation, "Amazon.Lambda.APIGatewayEvents")); + return false; + } + } + + // Check for references to "Amazon.Lambda.SQSEvents" if the Lambda method is annotated with SQSEvent attribute. + if (lambdaMethodSymbol.HasAttribute(context, TypeFullNames.SQSEventAttribute)) + { + if (context.Compilation.ReferencedAssemblyNames.FirstOrDefault(x => x.Name == "Amazon.Lambda.SQSEvents") == null) + { + diagnosticReporter.Report(Diagnostic.Create(DiagnosticDescriptors.MissingDependencies, methodLocation, "Amazon.Lambda.SQSEvents")); + return false; + } + } + + return true; + } + + private static void ValidateApiGatewayEvents(LambdaFunctionModel lambdaFunctionModel, Location methodLocation, List diagnostics) + { + // If the method does not contain any APIGatewayEvents, then it cannot return IHttpResults and can also not have parameters that are annotated with HTTP API attributes + if (!lambdaFunctionModel.LambdaMethod.Events.Contains(EventType.API)) + { + if (lambdaFunctionModel.LambdaMethod.ReturnsIHttpResults) + { + diagnostics.Add(Diagnostic.Create(DiagnosticDescriptors.HttpResultsOnNonApiFunction, methodLocation)); + } + + foreach (var parameter in lambdaFunctionModel.LambdaMethod.Parameters) + { + if (parameter.Attributes.Any(att => + att.Type.FullName == TypeFullNames.FromBodyAttribute || + att.Type.FullName == TypeFullNames.FromHeaderAttribute || + att.Type.FullName == TypeFullNames.FromRouteAttribute || + att.Type.FullName == TypeFullNames.FromQueryAttribute)) + { + diagnostics.Add(Diagnostic.Create(DiagnosticDescriptors.ApiParametersOnNonApiFunction, methodLocation)); + } + } + + return; + } + + // Validate FromRoute, FromQuery and FromHeader parameters + foreach (var parameter in lambdaFunctionModel.LambdaMethod.Parameters) + { + if (parameter.Attributes.Any(att => att.Type.FullName == TypeFullNames.FromQueryAttribute)) + { + var fromQueryAttribute = parameter.Attributes.First(att => att.Type.FullName == TypeFullNames.FromQueryAttribute) as AttributeModel; + // Use parameter name as key, if Name has not specified explicitly in the attribute definition. + var parameterKey = fromQueryAttribute?.Data?.Name ?? parameter.Name; + + if (!parameter.Type.IsPrimitiveType() && !parameter.Type.IsPrimitiveEnumerableType()) + { + diagnostics.Add(Diagnostic.Create(DiagnosticDescriptors.UnsupportedMethodParameterType, methodLocation, parameter.Name, parameter.Type.FullName)); + } + } + + foreach (var att in parameter.Attributes) + { + var parameterAttributeName = string.Empty; + switch (att.Type.FullName) + { + case TypeFullNames.FromQueryAttribute: + var fromQueryAttribute = (AttributeModel)att; + parameterAttributeName = fromQueryAttribute.Data.Name; + break; + + case TypeFullNames.FromRouteAttribute: + var fromRouteAttribute = (AttributeModel)att; + parameterAttributeName = fromRouteAttribute.Data.Name; + break; + + case TypeFullNames.FromHeaderAttribute: + var fromHeaderAttribute = (AttributeModel)att; + parameterAttributeName = fromHeaderAttribute.Data.Name; + break; + + default: + break; + } + + if (!string.IsNullOrEmpty(parameterAttributeName) && !_parameterAttributeNameRegex.IsMatch(parameterAttributeName)) + { + diagnostics.Add(Diagnostic.Create(DiagnosticDescriptors.InvalidParameterAttributeName, methodLocation, parameterAttributeName, parameter.Name)); + } + } + } + } + + private static void ValidateSqsEvents(LambdaFunctionModel lambdaFunctionModel, Location methodLocation, List diagnostics) + { + // If the method does not contain any SQS events, then simply return early + if (!lambdaFunctionModel.LambdaMethod.Events.Contains(EventType.SQS)) + { + return; + } + + // Validate SQSEventAttributes + foreach (var att in lambdaFunctionModel.Attributes) + { + if (att.Type.FullName != TypeFullNames.SQSEventAttribute) + continue; + + var sqsEventAttribute = ((AttributeModel)att).Data; + var validationErrors = sqsEventAttribute.Validate(); + validationErrors.ForEach(errorMessage => diagnostics.Add(Diagnostic.Create(DiagnosticDescriptors.InvalidSqsEventAttribute, methodLocation, errorMessage))); + } + + // Validate method parameters - When using SQSEventAttribute, the method signature must be (SQSEvent sqsEvent) or (SQSEvent sqsEvent, ILambdaContext context) + var parameters = lambdaFunctionModel.LambdaMethod.Parameters; + if (parameters.Count == 0 || + parameters.Count > 2 || + (parameters.Count == 1 && parameters[0].Type.FullName != TypeFullNames.SQSEvent) || + (parameters.Count == 2 && (parameters[0].Type.FullName != TypeFullNames.SQSEvent || parameters[1].Type.FullName != TypeFullNames.ILambdaContext))) + { + var errorMessage = $"When using the {nameof(SQSEventAttribute)}, the Lambda method can accept at most 2 parameters. " + + $"The first parameter is required and must be of type {TypeFullNames.SQSEvent}. " + + $"The second parameter is optional and must be of type {TypeFullNames.ILambdaContext}."; + diagnostics.Add(Diagnostic.Create(DiagnosticDescriptors.InvalidLambdaMethodSignature, methodLocation, errorMessage)); + } + + // Validate method return type - When using SQSEventAttribute, the return type must be either void, Task, SQSBatchResponse or Task + if (!lambdaFunctionModel.LambdaMethod.ReturnsVoidTaskOrSqsBatchResponse) + { + var errorMessage = $"When using the {nameof(SQSEventAttribute)}, the Lambda method can return either void, {TypeFullNames.Task}, {TypeFullNames.SQSBatchResponse} or Task<{TypeFullNames.SQSBatchResponse}>"; + diagnostics.Add(Diagnostic.Create(DiagnosticDescriptors.InvalidLambdaMethodSignature, methodLocation, errorMessage)); + } + } + + private static bool ReportDiagnostics(DiagnosticReporter diagnosticReporter, List diagnostics) + { + var isValid = true; + foreach (var diagnostic in diagnostics) + { + diagnosticReporter.Report(diagnostic); + if (diagnostic.Severity == DiagnosticSeverity.Error) + { + isValid = false; + } + } + return isValid; + } + } +} diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Writers/CloudFormationWriter.cs b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Writers/CloudFormationWriter.cs index 3f0cd08c7..993a312ed 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Writers/CloudFormationWriter.cs +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Writers/CloudFormationWriter.cs @@ -3,11 +3,11 @@ using Amazon.Lambda.Annotations.SourceGenerator.FileIO; using Amazon.Lambda.Annotations.SourceGenerator.Models; using Amazon.Lambda.Annotations.SourceGenerator.Models.Attributes; +using Amazon.Lambda.Annotations.SQS; using Microsoft.CodeAnalysis; using System; using System.Collections.Generic; using System.ComponentModel; -using System.IO; using System.Linq; using System.Reflection; @@ -183,6 +183,7 @@ private void ProcessPackageTypeProperty(ILambdaFunctionSerializable lambdaFuncti private void ProcessLambdaFunctionEventAttributes(ILambdaFunctionSerializable lambdaFunction) { var currentSyncedEvents = new List(); + var currentSyncedEventProperties = new Dictionary>(); foreach (var attributeModel in lambdaFunction.Attributes) { @@ -190,70 +191,137 @@ private void ProcessLambdaFunctionEventAttributes(ILambdaFunctionSerializable la switch (attributeModel) { case AttributeModel httpApiAttributeModel: - eventName = ProcessHttpApiAttribute(lambdaFunction, httpApiAttributeModel.Data); + eventName = ProcessHttpApiAttribute(lambdaFunction, httpApiAttributeModel.Data, currentSyncedEventProperties); currentSyncedEvents.Add(eventName); break; case AttributeModel restApiAttributeModel: - eventName = ProcessRestApiAttribute(lambdaFunction, restApiAttributeModel.Data); + eventName = ProcessRestApiAttribute(lambdaFunction, restApiAttributeModel.Data, currentSyncedEventProperties); + currentSyncedEvents.Add(eventName); + break; + case AttributeModel sqsAttributeModel: + eventName = ProcessSqsAttribute(lambdaFunction, sqsAttributeModel.Data, currentSyncedEventProperties); currentSyncedEvents.Add(eventName); break; } } - var eventsPath = $"Resources.{lambdaFunction.ResourceName}.Properties.Events"; - var syncedEventsMetadataPath = $"Resources.{lambdaFunction.ResourceName}.Metadata.SyncedEvents"; - var previousSyncedEvents = _templateWriter.GetToken>(syncedEventsMetadataPath, new List()); - - // Remove all events that exist in the serverless template but were not encountered during the current source generation pass. - foreach (var previousEventName in previousSyncedEvents) - { - if (!currentSyncedEvents.Contains(previousEventName)) - _templateWriter.RemoveToken($"{eventsPath}.{previousEventName}"); - } - - if (currentSyncedEvents.Any()) - _templateWriter.SetToken(syncedEventsMetadataPath, currentSyncedEvents, TokenType.List); - else - _templateWriter.RemoveToken(syncedEventsMetadataPath); + SynchronizeEventsAndProperties(currentSyncedEvents, currentSyncedEventProperties, lambdaFunction); } /// /// Writes all properties associated with to the serverless template. /// - private string ProcessRestApiAttribute(ILambdaFunctionSerializable lambdaFunction, RestApiAttribute restApiAttribute) + private string ProcessRestApiAttribute(ILambdaFunctionSerializable lambdaFunction, RestApiAttribute restApiAttribute, Dictionary> syncedEventProperties) { - var eventPath = $"Resources.{lambdaFunction.ResourceName}.Properties.Events"; - var methodName = restApiAttribute.Method.ToString(); - var methodPath = $"{eventPath}.Root{methodName}"; + var eventName = $"Root{restApiAttribute.Method}"; + var eventPath = $"Resources.{lambdaFunction.ResourceName}.Properties.Events.{eventName}"; - _templateWriter.SetToken($"{methodPath}.Type", "Api"); - _templateWriter.SetToken($"{methodPath}.Properties.Path", restApiAttribute.Template); - _templateWriter.SetToken($"{methodPath}.Properties.Method", methodName.ToUpper()); + _templateWriter.SetToken($"{eventPath}.Type", "Api"); + SetEventProperty(syncedEventProperties, lambdaFunction.ResourceName, eventName, "Path", restApiAttribute.Template); + SetEventProperty(syncedEventProperties, lambdaFunction.ResourceName, eventName, "Method", restApiAttribute.Method.ToString().ToUpper()); - return $"Root{methodName}"; + return eventName; } /// /// Writes all properties associated with to the serverless template. /// - private string ProcessHttpApiAttribute(ILambdaFunctionSerializable lambdaFunction, HttpApiAttribute httpApiAttribute) + private string ProcessHttpApiAttribute(ILambdaFunctionSerializable lambdaFunction, HttpApiAttribute httpApiAttribute, Dictionary> syncedEventProperties) { - var eventPath = $"Resources.{lambdaFunction.ResourceName}.Properties.Events"; - var methodName = httpApiAttribute.Method.ToString(); - var methodPath = $"{eventPath}.Root{methodName}"; + var eventName = $"Root{httpApiAttribute.Method}"; + var eventPath = $"Resources.{lambdaFunction.ResourceName}.Properties.Events.{eventName}"; - _templateWriter.SetToken($"{methodPath}.Type", "HttpApi"); - _templateWriter.SetToken($"{methodPath}.Properties.Path", httpApiAttribute.Template); - _templateWriter.SetToken($"{methodPath}.Properties.Method", methodName.ToUpper()); + _templateWriter.SetToken($"{eventPath}.Type", "HttpApi"); + SetEventProperty(syncedEventProperties, lambdaFunction.ResourceName, eventName, "Path", httpApiAttribute.Template); + SetEventProperty(syncedEventProperties, lambdaFunction.ResourceName, eventName, "Method", httpApiAttribute.Method.ToString().ToUpper()); // Only set the PayloadFormatVersion for 1.0. // If no PayloadFormatVersion is specified then by default 2.0 is used. if (httpApiAttribute.Version == HttpApiVersion.V1) - _templateWriter.SetToken($"{methodPath}.Properties.PayloadFormatVersion", "1.0"); + SetEventProperty(syncedEventProperties, lambdaFunction.ResourceName, eventName, "PayloadFormatVersion", "1.0"); - return $"Root{methodName}"; + return eventName; } + /// + /// Writes all properties associated with to the serverless template. + /// + private string ProcessSqsAttribute(ILambdaFunctionSerializable lambdaFunction, SQSEventAttribute att, Dictionary> syncedEventProperties) + { + var eventName = att.ResourceName; + var eventPath = $"Resources.{lambdaFunction.ResourceName}.Properties.Events.{eventName}"; + + // Set event type - https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-function-eventsource.html#sam-function-eventsource-type + _templateWriter.SetToken($"{eventPath}.Type", "SQS"); + + // Set SQS properties - https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-function-sqs.html + + // Queue + // Remove Queue if set previously + _templateWriter.RemoveToken($"{eventPath}.Properties.Queue"); + if (!att.Queue.StartsWith("@")) + { + SetEventProperty(syncedEventProperties, lambdaFunction.ResourceName, eventName, "Queue", att.Queue); + } + else + { + var queue = att.Queue.Substring(1); + if (_templateWriter.Exists($"{PARAMETERS}.{queue}")) + SetEventProperty(syncedEventProperties, lambdaFunction.ResourceName, eventName, $"Queue.{REF}", queue); + else + SetEventProperty(syncedEventProperties, lambdaFunction.ResourceName, eventName, $"Queue.{GET_ATTRIBUTE}", new List { queue, "Arn" }, TokenType.List); + } + + // BatchSize + if (att.IsBatchSizeSet) + { + SetEventProperty(syncedEventProperties, lambdaFunction.ResourceName, eventName, "BatchSize", att.BatchSize); + } + + // Enabled + if (att.IsEnabledSet) + { + SetEventProperty(syncedEventProperties, lambdaFunction.ResourceName, eventName, "Enabled", att.Enabled); + } + + // FilterCriteria + if (att.IsFiltersSet) + { + const char SEPERATOR = ';'; + var filters = att.Filters.Split(SEPERATOR).Select(x => x.Trim()).ToList(); + var filterList = new List>(); + foreach (var filter in filters) + { + filterList.Add(new Dictionary { { "Pattern", filter } }); + } + SetEventProperty(syncedEventProperties, lambdaFunction.ResourceName, eventName, "FilterCriteria.Filters", filterList, TokenType.List); + } + + // FunctionResponseTypes + if (lambdaFunction.ReturnTypeFullName.Contains(TypeFullNames.SQSBatchResponse)) + { + SetEventProperty(syncedEventProperties, lambdaFunction.ResourceName, eventName, "FunctionResponseTypes", new List { "ReportBatchItemFailures" }, TokenType.List); + } + + // MaximumBatchingWindowInSeconds + if (att.IsMaximumBatchingWindowInSecondsSet) + { + SetEventProperty(syncedEventProperties, lambdaFunction.ResourceName, eventName, "MaximumBatchingWindowInSeconds", att.MaximumBatchingWindowInSeconds); + } + + // ScalingConfig + if (att.IsMaximumConcurrencySet) + { + SetEventProperty(syncedEventProperties, lambdaFunction.ResourceName, eventName, "ScalingConfig.MaximumConcurrency", att.MaximumConcurrency); + } + + return att.ResourceName; + } + + /// + /// Writes all properties associated with to the serverless template. + /// + /// /// Writes the default values for the Lambda function's metadata and properties. /// @@ -462,5 +530,89 @@ private string ExtractCurrentDescriptionSuffix(string templateDescription) return string.Empty; } + + /// + /// This sets the event property for a given event and property path. + /// It also keeps track of which properties have been set for each event so that we can remove any orphaned properties later. + /// + private void SetEventProperty(Dictionary> syncedEventProperties, string lambdaResourceName, string eventResourceName, string propertyPath, object value, TokenType tokenType = TokenType.Other) + { + _templateWriter.SetToken($"Resources.{lambdaResourceName}.Properties.Events.{eventResourceName}.Properties.{propertyPath}", value, tokenType); + if (!syncedEventProperties.ContainsKey(eventResourceName)) + { + syncedEventProperties[eventResourceName] = new List(); + } + syncedEventProperties[eventResourceName].Add(propertyPath); + } + + /// + /// Synchronizes events and their properties for a given lambda function in its CloudFormation metadata. + /// + /// List of events to synchronize. + /// Dictionary containing event properties to synchronize. + /// The lambda function for which to synchronize events and properties. + private void SynchronizeEventsAndProperties(List syncedEvents, Dictionary> syncedEventProperties, ILambdaFunctionSerializable lambdaFunction) + { + // Construct paths for synced events in the resource template. + var eventsPath = $"Resources.{lambdaFunction.ResourceName}.Properties.Events"; + var syncedEventsPath = $"Resources.{lambdaFunction.ResourceName}.Metadata.SyncedEvents"; + + // Get previously synced events. + var previousSyncedEvents = _templateWriter.GetToken>(syncedEventsPath, new List()); + + // Remove orphaned events. + var orphanedEvents = previousSyncedEvents.Except(syncedEvents).ToList(); + orphanedEvents.ForEach(eventName => _templateWriter.RemoveToken($"{eventsPath}.{eventName}")); + + // Update synced events in the template. + _templateWriter.RemoveToken(syncedEventsPath); + if (syncedEvents.Any()) + _templateWriter.SetToken(syncedEventsPath, syncedEvents, TokenType.List); + + // Construct path for synced event properties in the resource template. + var syncedEventPropertiesPath = $"Resources.{lambdaFunction.ResourceName}.Metadata.SyncedEventProperties"; + + // Get previously synced event properties. + var previousSyncedEventProperties = _templateWriter.GetToken>>(syncedEventPropertiesPath, new Dictionary>()); + + // Remove orphaned event properties. + foreach (var eventName in previousSyncedEventProperties.Keys.Intersect(syncedEventProperties.Keys)) + { + var orphanedEventProperties = previousSyncedEventProperties[eventName].Except(syncedEventProperties[eventName]).ToList(); + orphanedEventProperties.ForEach(propertyPath => + { + // If previously a property existed as a terminal property but now exists as complex property then do not delete it. + // This can happen when a property was previously added as an ARN by is now being added as a Ref. + if (syncedEventProperties[eventName].Any(p => p.StartsWith(propertyPath))) + { + return; + } + + _templateWriter.RemoveToken($"{eventsPath}.{eventName}.Properties.{propertyPath}"); + + // Remove the terminal property and parent properties if they're now empty. + // Consider the following example: + // { + // "A": { + // "B": { + // "C": "D" + // } + // } + // } + // If A.B.C is removed, then A.B and A must also be removed since they're now empty because of the cascading effects. + var propertyPathList = propertyPath.Split('.').ToList(); + while (propertyPathList.Any()) + { + _templateWriter.RemoveTokenIfNullOrEmpty($"{eventsPath}.{eventName}.Properties.{string.Join(".", propertyPathList)}"); + propertyPathList.RemoveAt(propertyPathList.Count - 1); + } + }); + } + + // Update synced event properties in the template. + _templateWriter.RemoveToken(syncedEventPropertiesPath); + if (syncedEventProperties.Any()) + _templateWriter.SetToken(syncedEventPropertiesPath, syncedEventProperties, TokenType.KeyVal); + } } } \ No newline at end of file diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Writers/ITemplateWriter.cs b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Writers/ITemplateWriter.cs index 3712bccbd..209d6c315 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Writers/ITemplateWriter.cs +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Writers/ITemplateWriter.cs @@ -43,6 +43,13 @@ public interface ITemplateWriter /// dot(.) seperated path. Example "Person.Name.FirstName" void RemoveToken(string path); + /// + /// Deletes the token found at the dot(.) separated path if it points to a null value or empty object. + /// It does not do anything if the jsonPath does not exist. + /// + /// dot(.) seperated path. Example "Person.Name.FirstName" + void RemoveTokenIfNullOrEmpty(string path); + /// /// Returns the template as a string /// diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Writers/JsonWriter.cs b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Writers/JsonWriter.cs index 1290b91eb..9bacea74b 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Writers/JsonWriter.cs +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Writers/JsonWriter.cs @@ -39,7 +39,15 @@ public bool Exists(string jsonPath) { return false; } - currentNode = currentNode[property]; + try + { + currentNode = currentNode[property]; + } + // If the currentNode is already a leaf value then we will encounter an InvalidOperationException + catch (InvalidOperationException) + { + return false; + } } return currentNode != null; @@ -174,6 +182,26 @@ public void RemoveToken(string jsonPath) currentNode.Remove(lastProperty); } + /// + public void RemoveTokenIfNullOrEmpty(string jsonPath) + { + if (!Exists(jsonPath)) + { + return; + } + + JToken currentNode = _rootNode; + foreach (var property in jsonPath.Split('.')) + { + currentNode = currentNode[property]; + } + + if (currentNode.Type == JTokenType.Null || (currentNode.Type == JTokenType.Object && !currentNode.HasValues)) + { + RemoveToken(jsonPath); + } + } + /// /// Returns the template as a string /// diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Writers/YamlWriter.cs b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Writers/YamlWriter.cs index 9b89e717d..78db53886 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Writers/YamlWriter.cs +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Writers/YamlWriter.cs @@ -38,7 +38,7 @@ public bool Exists(string yamlPath) YamlNode currentNode = _rootNode; foreach (var property in yamlPath.Split('.')) { - if (currentNode == null) + if (currentNode == null || currentNode.NodeType != YamlNodeType.Mapping) { return false; } @@ -213,6 +213,30 @@ public void RemoveToken(string yamlPath) terminalNode.Children.Remove(lastProperty); } + /// + public void RemoveTokenIfNullOrEmpty(string yamlPath) + { + if (!Exists(yamlPath)) + { + return; + } + + YamlNode currentNode = _rootNode; + foreach (var property in yamlPath.Split('.')) + { + currentNode = currentNode[property]; + } + + if (currentNode is YamlScalarNode scalarNode && (scalarNode.Value == "null" || scalarNode.Value == string.Empty)) + { + RemoveToken(yamlPath); + } + else if (currentNode is YamlMappingNode mappingNode && mappingNode.Children.Count == 0) + { + RemoveToken(yamlPath); + } + } + /// /// Parses the YAML string as a /// diff --git a/Libraries/src/Amazon.Lambda.Annotations/Amazon.Lambda.Annotations.csproj b/Libraries/src/Amazon.Lambda.Annotations/Amazon.Lambda.Annotations.csproj index dfa34f2c0..c90d519af 100644 --- a/Libraries/src/Amazon.Lambda.Annotations/Amazon.Lambda.Annotations.csproj +++ b/Libraries/src/Amazon.Lambda.Annotations/Amazon.Lambda.Annotations.csproj @@ -4,8 +4,13 @@ 1.4.0 netstandard2.0;net6.0;net8.0 true - - + + + ..\..\..\buildtools\public.snk + true + + IL2026,IL2067,IL2075,IL3050 true @@ -14,5 +19,15 @@ - + + + + + <_Parameter1>Amazon.Lambda.Annotations.SourceGenerator, PublicKey="0024000004800000940000000602000000240000525341310004000001000100db5f59f098d27276c7833875a6263a3cc74ab17ba9a9df0b52aedbe7252745db7274d5271fd79c1f08f668ecfa8eaab5626fa76adc811d3c8fc55859b0d09d3bc0a84eecd0ba891f2b8a2fc55141cdcc37c2053d53491e650a479967c3622762977900eddbf1252ed08a2413f00a28f3a0752a81203f03ccb7f684db373518b4" + + + <_Parameter1>Amazon.Lambda.Annotations.SourceGenerators.Tests, PublicKey="0024000004800000940000000602000000240000525341310004000001000100db5f59f098d27276c7833875a6263a3cc74ab17ba9a9df0b52aedbe7252745db7274d5271fd79c1f08f668ecfa8eaab5626fa76adc811d3c8fc55859b0d09d3bc0a84eecd0ba891f2b8a2fc55141cdcc37c2053d53491e650a479967c3622762977900eddbf1252ed08a2413f00a28f3a0752a81203f03ccb7f684db373518b4" + + + \ No newline at end of file diff --git a/Libraries/src/Amazon.Lambda.Annotations/README.md b/Libraries/src/Amazon.Lambda.Annotations/README.md index 31dc65772..3de36aa1b 100644 --- a/Libraries/src/Amazon.Lambda.Annotations/README.md +++ b/Libraries/src/Amazon.Lambda.Annotations/README.md @@ -5,14 +5,27 @@ idiomatic .NET coding patterns. [C# Source Generators](https://docs.microsoft.co gap between the Lambda programming model to the Lambda Annotations programming model without adding any performance penalty. Topics: -* [Getting Started](#getting-started) -* [How does Lambda Annotations work?](#how-does-lambda-annotations-work) -* [Dependency Injection integration](#dependency-injection-integration) -* [Synchronizing CloudFormation template](#synchronizing-cloudFormation-template) -* [Getting build information](#getting-build-information) -* [Amazon API Gateway example](#amazon-api-gateway-example) -* [Amazon S3 example](#amazon-s3-example) -* [Lambda .NET Attributes Reference](#lambda-net-attributes-reference) +- [Amazon.Lambda.Annotations](#amazonlambdaannotations) + - [How does Lambda Annotations work?](#how-does-lambda-annotations-work) + - [Getting started](#getting-started) + - [Visual Studio 2022](#visual-studio-2022) + - [.NET CLI](#net-cli) + - [The sample project](#the-sample-project) + - [Deployment](#deployment) + - [Adding Lambda Annotations to an existing project](#adding-lambda-annotations-to-an-existing-project) + - [Dependency Injection integration](#dependency-injection-integration) + - [Synchronizing CloudFormation template](#synchronizing-cloudformation-template) + - [Lambda Global Properties](#lambda-global-properties) + - [Amazon API Gateway example](#amazon-api-gateway-example) + - [Amazon S3 example](#amazon-s3-example) + - [SQS Event Example](#sqs-event-example) + - [Getting build information](#getting-build-information) + - [Lambda .NET Attributes Reference](#lambda-net-attributes-reference) + - [Event Attributes](#event-attributes) + - [Parameter Attributes](#parameter-attributes) + - [Customizing responses for API Gateway Lambda functions](#customizing-responses-for-api-gateway-lambda-functions) + - [Content-Type](#content-type) + - [Project References](#project-references) ## How does Lambda Annotations work? @@ -709,6 +722,98 @@ public class Functions_Resize_Generated } ``` +## SQS Event Example +This example shows how users can use the `SQSEvent` attribute to set up event source mapping between their SQS queues and Lambda function. + +The `SQSEvent` attribute contains the following properties: +* **Queue** (Required) - The SQS queue that will act as the event trigger for the Lambda function. This can either be the queue ARN or reference to the SQS queue resource that is already defined in the serverless template. To reference a SQS queue resource in the serverless template, prefix the resource name with "@" symbol. +* **ResourceName** (Optional) - The CloudFormation resource name for the SQS event source mapping. By default this is set to the SQS queue name if `Queue` is set to an SQS queue ARN. If `Queue` is set to an existing CloudFormation resource, than that is used as the default value without the "@" prefix. +* **Enabled** (Optional) - If set to false, the event source mapping will be disabled and message polling will be paused. Default value is true. +* **BatchSize** (Optional) - The maximum number of messages that will be sent for processing in a single batch. This value must be between 1 to 10000. For FIFO queues the maximum allowed value is 10. Default value is 10. +* **MaximumBatchingWindowInSeconds** (Optional) - The maximum amount of time, in seconds, to gather records before invoking the function. This value must be between 0 to 300. Default value is 0. When BatchSize is set to a value greater than 10 MaximumBatchingWindowInSeconds must be set to at least 1. This property must not be set if the event source mapping is being created for a FIFO queue. +* **Filters** (Optional) - A collection of semicolon (;) separated strings where each string denotes a pattern. Only those SQS messages that conform to at least 1 pattern will be forwarded to the Lambda function for processing. +* **MaximumConcurrency** (Optional) - The maximum number of concurrent Lambda invocations that the SQS queue can trigger. This value must be between 2 to 1000. The default value is 1000. + +The `SQSEvent` attribute must be applied to Lambda method along with the `LambdaFunction` attribute. + +The Lambda method must conform to the following rules when it is tagged with the `SQSEvent` attribute: + + 1. It must have at least 1 argument and can have at most 2 arguments. + - The first argument is required and must be of type `SQSEvent` defined in the [Amazon.Lambda.SQSEvents](https://github.com/aws/aws-lambda-dotnet/blob/master/Libraries/src/Amazon.Lambda.SQSEvents/SQSEvent.cs) package. + - The second argument is optional and must be of type `ILambdaContext` defined in the [Amazon.Lambda.Core](https://github.com/aws/aws-lambda-dotnet/blob/master/Libraries/src/Amazon.Lambda.Core/ILambdaContext.cs) package. + 2. The method return type must be one of `void`, `Task`, `SQSBatchResponse` or `Task`. The `SQSBatchResponse` type is defined in the [Amazon.Lambda.SQSEvents](https://github.com/aws/aws-lambda-dotnet/blob/master/Libraries/src/Amazon.Lambda.SQSEvents/SQSBatchResponse.cs) package. If the return type is `SQSBatchResponse` or `Task`, then the [FunctionResponseTypes](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-function-sqs.html#sam-function-sqs-functionresponsetypes) in the event source mapping is set to report `ReportBatchItemFailures` + +```csharp + +[LambdaFunction(ResourceName = "SQSMessageHandler", Policies = "AWSLambdaSQSQueueExecutionRole", PackageType = LambdaPackageType.Image)] +[SQSEvent("@TestQueue", ResourceName = "TestQueueEvent", BatchSize = 50, MaximumConcurrency = 5, MaximumBatchingWindowInSeconds = 5, Filters = "{ \"body\" : { \"RequestCode\" : [ \"BBBB\" ] } }")] +public SQSBatchResponse HandleMessage(SQSEvent evnt, ILambdaContext lambdaContext) +{ + lambdaContext.Logger.Log($"Received {evnt.Records.Count} messages"); + return new SQSBatchResponse(); +} +``` +In the above example `TestQueue` refers to an existing SQS queue resource in the CloudFormation template. + +The following SQS event source mapping will be generated for the `SQSMessageHandler` Lambda function + +```json + "SQSMessageHandler": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations", + "SyncedEvents": [ + "TestQueueEvent" + ] + }, + "Properties": { + "MemorySize": 512, + "Timeout": 30, + "Policies": [ + "AWSLambdaSQSQueueExecutionRole" + ], + "PackageType": "Image", + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestServerlessApp::TestServerlessApp.SqsMessageProcessing_HandleMessage_Generated::HandleMessage" + ] + }, + "Events": { + "TestQueueEvent": { + "Type": "SQS", + "Properties": { + "Queue": { + "Fn::GetAtt": [ + "TestQueue", + "Arn" + ] + }, + "BatchSize": 50, + "FilterCriteria": { + "Filters": [ + { + "Pattern": "{ \"body\" : { \"RequestCode\" : [ \"BBBB\" ] } }" + } + ] + }, + "FunctionResponseTypes": [ + "ReportBatchItemFailures" + ], + "MaximumBatchingWindowInSeconds": 5, + "ScalingConfig": { + "MaximumConcurrency": 5 + } + } + } + } + } + }, + "TestQueue": { + "Type": "AWS::SQS::Queue" + } +``` + ## Getting build information The source generator integrates with MSBuild's compiler error and warning reporting when there are problems generating the boiler plate code. @@ -741,6 +846,8 @@ parameter to the `LambdaFunction` must be the event object and the event source * Configures the Lambda function to be called from an API Gateway REST API. The HTTP method and resource path are required to be set on the attribute. * HttpApi * Configures the Lambda function to be called from an API Gateway HTTP API. The HTTP method, HTTP API payload version and resource path are required to be set on the attribute. +* SQSEvent + * Sets up event source mapping between the Lambda function and SQS queues. The SQS queue ARN is required to be set on the attribute. If users want to pass a reference to an existing SQS queue resource defined in their CloudFormation template, they can pass the SQS queue resource name prefixed with the '@' symbol. ### Parameter Attributes diff --git a/Libraries/src/Amazon.Lambda.Annotations/SQS/SQSEventAttribute.cs b/Libraries/src/Amazon.Lambda.Annotations/SQS/SQSEventAttribute.cs new file mode 100644 index 000000000..3358eee36 --- /dev/null +++ b/Libraries/src/Amazon.Lambda.Annotations/SQS/SQSEventAttribute.cs @@ -0,0 +1,175 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; + +namespace Amazon.Lambda.Annotations.SQS +{ + /// + /// This attribute defines the SQS event source configuration for a Lambda function. + /// + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + public class SQSEventAttribute : Attribute + { + // Except for Queue all other properties are optional. + // .NET attributes cannot be nullable. To work around this, we have added nullable backing fields to all optional properties and added an internal IsSet method to identify which properties were explicitly set the customer. + // These internal methods are used by the CloudFormationWriter while deciding which properties to write in the CF template. + + // Only allow alphanumeric characters + private static readonly Regex _resourceNameRegex = new Regex("^[a-zA-Z0-9]+$"); + + /// + /// The SQS queue that will act as the event trigger for the Lambda function. + /// This can either be the queue ARN or reference to the SQS queue resource that is already defined in the serverless template. + /// To reference a SQS queue resource in the serverless template, prefix the resource name with "@" symbol. + /// + public string Queue { get; set; } + + /// + /// The CloudFormation resource name for the SQS event source mapping. By default this is set to the SQS queue name if the is set to an SQS queue ARN. + /// If is set to an existing CloudFormation resource, than that is used as the default value without the "@" prefix. + /// + public string ResourceName + { + get + { + if (IsResourceNameSet) + { + return resourceName; + } + if (Queue.StartsWith("@")) + { + return Queue.Substring(1); + } + + var arnTokens = Queue.Split(new char[] { ':' }, 6); + var queueName = arnTokens[5]; + var sanitizedQueueName = string.Join(string.Empty, queueName.Where(char.IsLetterOrDigit)); + return sanitizedQueueName; + } + set => resourceName = value; + } + + private string resourceName { get; set; } = null; + internal bool IsResourceNameSet => resourceName != null; + + + /// + /// If set to false, the event source mapping will be disabled and message polling will be paused. + /// Default value is true. + /// + public bool Enabled + { + get => enabled.GetValueOrDefault(); + set => enabled = value; + } + private bool? enabled { get; set; } + internal bool IsEnabledSet => enabled.HasValue; + + /// + /// The maximum number of messages that will be sent for processing in a single batch. + /// This value must be between 1 to 10000. For FIFO queues the maximum allowed value is 10. Default value is 10. + /// + public uint BatchSize + { + get => batchSize.GetValueOrDefault(); + set => batchSize = value; + } + private uint? batchSize { get; set; } + internal bool IsBatchSizeSet => batchSize.HasValue; + + /// + /// The maximum amount of time, in seconds, to gather records before invoking the function. + /// This value must be between 0 to 300. Default value is 0. + /// When is set to a value greater than 10 must be set to at least 1. + /// This property must not be set if the event source mapping is being created for a FIFO queue. + /// + public uint MaximumBatchingWindowInSeconds + { + get => maximumBatchingWindowInSeconds.GetValueOrDefault(); + set => maximumBatchingWindowInSeconds = value; + } + private uint? maximumBatchingWindowInSeconds { get; set; } + internal bool IsMaximumBatchingWindowInSecondsSet => maximumBatchingWindowInSeconds.HasValue; + + /// + /// A collection of semicolon (;) separated strings where each string denotes a pattern. + /// Only those SQS messages that conform to at least 1 pattern will be forwarded to the Lambda function for processing. + /// + public string Filters { get; set; } = null; + internal bool IsFiltersSet => Filters != null; + + /// + /// The maximum number of concurrent Lambda invocations that the SQS queue can trigger. + /// This value must be between 2 to 1000. The default value is 1000. + /// + public uint MaximumConcurrency + { + get => maximumConcurrency.GetValueOrDefault(); + set => maximumConcurrency = value; + } + private uint? maximumConcurrency { get; set; } + internal bool IsMaximumConcurrencySet => maximumConcurrency.HasValue; + + /// + /// Creates an instance of the class. + /// + /// property"/> + public SQSEventAttribute(string queue) + { + Queue = queue; + } + + internal List Validate() + { + var validationErrors = new List(); + + if (IsBatchSizeSet && (BatchSize < 1 || BatchSize > 10000)) + { + validationErrors.Add($"{nameof(SQSEventAttribute.BatchSize)} = {BatchSize}. It must be between 1 and 10000"); + } + if (IsMaximumConcurrencySet && (MaximumConcurrency < 2 || MaximumConcurrency > 1000)) + { + validationErrors.Add($"{nameof(SQSEventAttribute.MaximumConcurrency)} = {MaximumConcurrency}. It must be between 2 and 1000"); + } + if (IsMaximumBatchingWindowInSecondsSet && (MaximumBatchingWindowInSeconds < 0 || MaximumBatchingWindowInSeconds > 300)) + { + validationErrors.Add($"{nameof(SQSEventAttribute.MaximumBatchingWindowInSeconds)} = {MaximumBatchingWindowInSeconds}. It must be between 0 and 300"); + } + if (IsBatchSizeSet && BatchSize > 10 && (!IsMaximumBatchingWindowInSecondsSet || MaximumBatchingWindowInSeconds < 1)) + { + validationErrors.Add($"{nameof(SQSEventAttribute.MaximumBatchingWindowInSeconds)} is not set or set to a value less than 1. " + + $"It must be set to at least 1 when {nameof(SQSEventAttribute.BatchSize)} is greater than 10"); + } + + // The queue is FIFO if the queue ARN ends in ".fifo" + var isFifo = !Queue.StartsWith("@") && Queue.EndsWith(".fifo"); + if (isFifo) + { + if (IsMaximumBatchingWindowInSecondsSet) + { + validationErrors.Add($"{nameof(SQSEventAttribute.MaximumBatchingWindowInSeconds)} must not be set when the event source mapping is for a FIFO queue"); + } + if (IsBatchSizeSet && BatchSize > 10) + { + validationErrors.Add($"{nameof(SQSEventAttribute.BatchSize)} = {BatchSize}. It must be less than or equal to 10 when the event source mapping is for a FIFO queue"); + } + } + + if (!Queue.StartsWith("@")) + { + var arnTokens = Queue.Split(new char[] { ':' }, 6); + if (arnTokens.Length != 6) + { + validationErrors.Add($"{nameof(SQSEventAttribute.Queue)} = {Queue}. The SQS queue ARN is invalid. The ARN format is 'arn::sqs:::'"); + } + } + if (IsResourceNameSet && !_resourceNameRegex.IsMatch(ResourceName)) + { + validationErrors.Add($"{nameof(SQSEventAttribute.ResourceName)} = {ResourceName}. It must only contain alphanumeric characters and must not be an empty string"); + } + + return validationErrors; + } + } +} diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Amazon.Lambda.Annotations.SourceGenerators.Tests.csproj b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Amazon.Lambda.Annotations.SourceGenerators.Tests.csproj index 1d89cbeb6..525f4b668 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Amazon.Lambda.Annotations.SourceGenerators.Tests.csproj +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Amazon.Lambda.Annotations.SourceGenerators.Tests.csproj @@ -4,7 +4,12 @@ net6.0 true latest - + + + ..\..\..\buildtools\public.snk + true + @@ -150,6 +155,7 @@ + @@ -171,6 +177,7 @@ + diff --git a/Libraries/test/TestServerlessApp/SQSEventExamples/InvalidSQSEvents.cs.error b/Libraries/test/TestServerlessApp/SQSEventExamples/InvalidSQSEvents.cs.error new file mode 100644 index 000000000..0b90371a7 --- /dev/null +++ b/Libraries/test/TestServerlessApp/SQSEventExamples/InvalidSQSEvents.cs.error @@ -0,0 +1,87 @@ +using Amazon.Lambda.Annotations; +using Amazon.Lambda.Annotations.APIGateway; +using Amazon.Lambda.Annotations.SQS; +using Amazon.Lambda.SQSEvents; +using System; + +namespace TestServerlessApp.SQSEventExamples +{ + // This file represents invalid usage of the SQSEventAttribute. + // This file is sent as input to the source generator unit tests and we assert that compilation errors are thrown with the appropriate diagnostic message. + // Refer to the VerifyInvalidSQSEvents_ThrowsCompilationErrors unit test. + + public class InvalidSQSEvents + { + [LambdaFunction] + [SQSEvent("@testQueue", BatchSize = 0, MaximumBatchingWindowInSeconds = 302, MaximumConcurrency = 1)] + public void ProcessMessageWithInvalidSQSEventAttributes(SQSEvent evnt) + { + Console.WriteLine($"Event processed: {evnt}"); + } + + [LambdaFunction] + [SQSEvent("@testQueue")] + public void ProcessMessageWithInvalidParameters(SQSEvent evnt, bool invalidParameter1, int invalidParameter2) + { + Console.WriteLine($"Event processed: {evnt}"); + } + + [LambdaFunction] + [SQSEvent("@testQueue")] + public bool ProcessMessageWithInvalidReturnType(SQSEvent evnt) + { + Console.WriteLine($"Event processed: {evnt}"); + return true; + } + + [LambdaFunction] + [RestApi(LambdaHttpMethod.Get, "/")] + [SQSEvent("@testQueue")] + public void ProcessMessageWithMultipleEventTypes(SQSEvent evnt) + { + Console.WriteLine($"Event processed: {evnt}"); + } + + [LambdaFunction] + [SQSEvent("test-queue")] + public void ProcessMessageWithInvalidQueueArn(SQSEvent evnt) + { + Console.WriteLine($"Event processed: {evnt}"); + } + + [LambdaFunction] + [SQSEvent("@testQueue", ResourceName = "sqs-event-source")] + public void ProcessMessageWithInvalidResourceName(SQSEvent evnt) + { + Console.WriteLine($"Event processed: {evnt}"); + } + + [LambdaFunction] + [SQSEvent("@testQueue", ResourceName = "")] + public void ProcessMessageWithEmptyResourceName(SQSEvent evnt) + { + Console.WriteLine($"Event processed: {evnt}"); + } + + [LambdaFunction] + [SQSEvent("@testQueue", BatchSize = 100)] + public void ProcessMessageWithMaximumBatchingWindowInSecondsNotSpecified(SQSEvent evnt) + { + Console.WriteLine($"Event processed: {evnt}"); + } + + [LambdaFunction] + [SQSEvent("@testQueue", BatchSize = 100, MaximumBatchingWindowInSeconds = 0)] + public void ProcessMessageWithMaximumBatchingWindowInSecondsLessThanOne(SQSEvent evnt) + { + Console.WriteLine($"Event processed: {evnt}"); + } + + [LambdaFunction] + [SQSEvent("arn:aws:sqs:us-east-2:444455556666:test-queue.fifo", BatchSize = 100, MaximumBatchingWindowInSeconds = 5)] + public void ProcessMessageWithFifoQueue(SQSEvent evnt) + { + Console.WriteLine($"Event processed: {evnt}"); + } + } +} diff --git a/Libraries/test/TestServerlessApp/SQSEventExamples/ValidSQSEvents.cs.txt b/Libraries/test/TestServerlessApp/SQSEventExamples/ValidSQSEvents.cs.txt new file mode 100644 index 000000000..28327c33f --- /dev/null +++ b/Libraries/test/TestServerlessApp/SQSEventExamples/ValidSQSEvents.cs.txt @@ -0,0 +1,33 @@ +using Amazon.Lambda.Annotations; +using Amazon.Lambda.Annotations.SQS; +using Amazon.Lambda.SQSEvents; +using System; +using System.Threading.Tasks; + +namespace TestServerlessApp.SQSEventExamples +{ + // This file represents valid usage of the SQSEventAttribute. This is added as .txt file since we do not want to deploy these functions during our integration tests. + // This file is only sent as input to the source generator unit tests. + // Refer to VerifyValidSQSEvents unit test. + + public class ValidSQSEvents + { + [LambdaFunction] + [SQSEvent("arn:aws:sqs:us-east-2:444455556666:queue1", BatchSize = 50, MaximumBatchingWindowInSeconds = 2, MaximumConcurrency = 30, Filters = "My-Filter-1; My-Filter-2")] + [SQSEvent("arn:aws:sqs:us-east-2:444455556666:queue2", MaximumBatchingWindowInSeconds = 5, Enabled = false)] + [SQSEvent("arn:aws:sqs:us-east-2:444455556666:my-queue")] + [SQSEvent("@testQueue", ResourceName = "testQueueEvent")] + public void ProcessMessages(SQSEvent evnt) + { + Console.WriteLine($"Event processed: {evnt}"); + } + + [LambdaFunction] + [SQSEvent("arn:aws:sqs:us-east-2:444455556666:queue3")] + public async Task ProcessMessagesWithBatchFailureReporting(SQSEvent evnt) + { + await Console.Out.WriteLineAsync($"Event processed: {evnt}"); + return new SQSBatchResponse(); + } + } +} diff --git a/Libraries/test/TestServerlessApp/SqsMessageProcessing.cs b/Libraries/test/TestServerlessApp/SqsMessageProcessing.cs new file mode 100644 index 000000000..7562be678 --- /dev/null +++ b/Libraries/test/TestServerlessApp/SqsMessageProcessing.cs @@ -0,0 +1,18 @@ +using Amazon.Lambda.Annotations; +using Amazon.Lambda.Annotations.SQS; +using Amazon.Lambda.Core; +using Amazon.Lambda.SQSEvents; + +namespace TestServerlessApp +{ + public class SqsMessageProcessing + { + [LambdaFunction(ResourceName = "SQSMessageHandler", Policies = "AWSLambdaSQSQueueExecutionRole", PackageType = LambdaPackageType.Image)] + [SQSEvent("@TestQueue", ResourceName = "TestQueueEvent", BatchSize = 50, MaximumConcurrency = 5, MaximumBatchingWindowInSeconds = 5, Filters = "{ \"body\" : { \"RequestCode\" : [ \"BBBB\" ] } }")] + public SQSBatchResponse HandleMessage(SQSEvent evnt, ILambdaContext lambdaContext) + { + lambdaContext.Logger.Log($"Received {evnt.Records.Count} messages"); + return new SQSBatchResponse(); + } + } +} diff --git a/Libraries/test/TestServerlessApp/TestServerlessApp.csproj b/Libraries/test/TestServerlessApp/TestServerlessApp.csproj index 37fbb5832..512ac2170 100644 --- a/Libraries/test/TestServerlessApp/TestServerlessApp.csproj +++ b/Libraries/test/TestServerlessApp/TestServerlessApp.csproj @@ -25,6 +25,7 @@ + diff --git a/Libraries/test/TestServerlessApp/serverless.template b/Libraries/test/TestServerlessApp/serverless.template index 6f9725c31..34078ba43 100644 --- a/Libraries/test/TestServerlessApp/serverless.template +++ b/Libraries/test/TestServerlessApp/serverless.template @@ -108,7 +108,13 @@ "Tool": "Amazon.Lambda.Annotations", "SyncedEvents": [ "RootGet" - ] + ], + "SyncedEventProperties": { + "RootGet": [ + "Path", + "Method" + ] + } }, "Properties": { "MemorySize": 512, @@ -140,7 +146,13 @@ "Tool": "Amazon.Lambda.Annotations", "SyncedEvents": [ "RootGet" - ] + ], + "SyncedEventProperties": { + "RootGet": [ + "Path", + "Method" + ] + } }, "Properties": { "MemorySize": 512, @@ -172,7 +184,13 @@ "Tool": "Amazon.Lambda.Annotations", "SyncedEvents": [ "RootGet" - ] + ], + "SyncedEventProperties": { + "RootGet": [ + "Path", + "Method" + ] + } }, "Properties": { "MemorySize": 512, @@ -204,7 +222,13 @@ "Tool": "Amazon.Lambda.Annotations", "SyncedEvents": [ "RootGet" - ] + ], + "SyncedEventProperties": { + "RootGet": [ + "Path", + "Method" + ] + } }, "Properties": { "MemorySize": 512, @@ -236,7 +260,14 @@ "Tool": "Amazon.Lambda.Annotations", "SyncedEvents": [ "RootGet" - ] + ], + "SyncedEventProperties": { + "RootGet": [ + "Path", + "Method", + "PayloadFormatVersion" + ] + } }, "Properties": { "MemorySize": 512, @@ -269,7 +300,14 @@ "Tool": "Amazon.Lambda.Annotations", "SyncedEvents": [ "RootGet" - ] + ], + "SyncedEventProperties": { + "RootGet": [ + "Path", + "Method", + "PayloadFormatVersion" + ] + } }, "Properties": { "MemorySize": 512, @@ -322,7 +360,14 @@ "Tool": "Amazon.Lambda.Annotations", "SyncedEvents": [ "RootGet" - ] + ], + "SyncedEventProperties": { + "RootGet": [ + "Path", + "Method", + "PayloadFormatVersion" + ] + } }, "Properties": { "MemorySize": 1024, @@ -355,7 +400,14 @@ "Tool": "Amazon.Lambda.Annotations", "SyncedEvents": [ "RootGet" - ] + ], + "SyncedEventProperties": { + "RootGet": [ + "Path", + "Method", + "PayloadFormatVersion" + ] + } }, "Properties": { "MemorySize": 512, @@ -388,7 +440,13 @@ "Tool": "Amazon.Lambda.Annotations", "SyncedEvents": [ "RootPost" - ] + ], + "SyncedEventProperties": { + "RootPost": [ + "Path", + "Method" + ] + } }, "Properties": { "MemorySize": 512, @@ -420,7 +478,13 @@ "Tool": "Amazon.Lambda.Annotations", "SyncedEvents": [ "RootPost" - ] + ], + "SyncedEventProperties": { + "RootPost": [ + "Path", + "Method" + ] + } }, "Properties": { "MemorySize": 512, @@ -452,7 +516,13 @@ "Tool": "Amazon.Lambda.Annotations", "SyncedEvents": [ "RootGet" - ] + ], + "SyncedEventProperties": { + "RootGet": [ + "Path", + "Method" + ] + } }, "Properties": { "MemorySize": 512, @@ -484,7 +554,13 @@ "Tool": "Amazon.Lambda.Annotations", "SyncedEvents": [ "RootGet" - ] + ], + "SyncedEventProperties": { + "RootGet": [ + "Path", + "Method" + ] + } }, "Properties": { "MemorySize": 512, @@ -516,7 +592,13 @@ "Tool": "Amazon.Lambda.Annotations", "SyncedEvents": [ "RootGet" - ] + ], + "SyncedEventProperties": { + "RootGet": [ + "Path", + "Method" + ] + } }, "Properties": { "MemorySize": 512, @@ -548,7 +630,13 @@ "Tool": "Amazon.Lambda.Annotations", "SyncedEvents": [ "RootGet" - ] + ], + "SyncedEventProperties": { + "RootGet": [ + "Path", + "Method" + ] + } }, "Properties": { "MemorySize": 512, @@ -580,7 +668,13 @@ "Tool": "Amazon.Lambda.Annotations", "SyncedEvents": [ "RootGet" - ] + ], + "SyncedEventProperties": { + "RootGet": [ + "Path", + "Method" + ] + } }, "Properties": { "MemorySize": 512, @@ -692,7 +786,13 @@ "Tool": "Amazon.Lambda.Annotations", "SyncedEvents": [ "RootGet" - ] + ], + "SyncedEventProperties": { + "RootGet": [ + "Path", + "Method" + ] + } }, "Properties": { "MemorySize": 512, @@ -744,7 +844,14 @@ "Tool": "Amazon.Lambda.Annotations", "SyncedEvents": [ "RootGet" - ] + ], + "SyncedEventProperties": { + "RootGet": [ + "Path", + "Method", + "PayloadFormatVersion" + ] + } }, "Properties": { "MemorySize": 512, @@ -770,6 +877,70 @@ } } } + }, + "SQSMessageHandler": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations", + "SyncedEvents": [ + "TestQueueEvent" + ], + "SyncedEventProperties": { + "TestQueueEvent": [ + "Queue.Fn::GetAtt", + "BatchSize", + "FilterCriteria.Filters", + "FunctionResponseTypes", + "MaximumBatchingWindowInSeconds", + "ScalingConfig.MaximumConcurrency" + ] + } + }, + "Properties": { + "MemorySize": 512, + "Timeout": 30, + "Policies": [ + "AWSLambdaSQSQueueExecutionRole" + ], + "PackageType": "Image", + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestServerlessApp::TestServerlessApp.SqsMessageProcessing_HandleMessage_Generated::HandleMessage" + ] + }, + "Events": { + "TestQueueEvent": { + "Type": "SQS", + "Properties": { + "Queue": { + "Fn::GetAtt": [ + "TestQueue", + "Arn" + ] + }, + "BatchSize": 50, + "FilterCriteria": { + "Filters": [ + { + "Pattern": "{ \"body\" : { \"RequestCode\" : [ \"BBBB\" ] } }" + } + ] + }, + "FunctionResponseTypes": [ + "ReportBatchItemFailures" + ], + "MaximumBatchingWindowInSeconds": 5, + "ScalingConfig": { + "MaximumConcurrency": 5 + } + } + } + } + } + }, + "TestQueue": { + "Type": "AWS::SQS::Queue" } }, "Outputs": { @@ -784,6 +955,15 @@ "Value": { "Fn::Sub": "https://${ServerlessHttpApi}.execute-api.${AWS::Region}.amazonaws.com" } + }, + "TestQueueARN": { + "Description": "ARN of the TestQueue resource", + "Value": { + "Fn::GetAtt": [ + "TestQueue", + "Arn" + ] + } } } } \ No newline at end of file From b0954e626a3e0a903a584d73f0ac5d4d721e21f5 Mon Sep 17 00:00:00 2001 From: Malhar Khimsaria <96malhar@gmail.com> Date: Mon, 17 Jun 2024 09:37:55 -0700 Subject: [PATCH 11/35] chore: Version bump Amazon.Lambda.Annotations to 1.5.0.0 --- .../Amazon.Lambda.Annotations.SourceGenerator.csproj | 2 +- Libraries/src/Amazon.Lambda.Annotations.nuspec | 2 +- .../Amazon.Lambda.Annotations/Amazon.Lambda.Annotations.csproj | 2 +- .../Snapshots/ComplexCalculator_Add_Generated.g.cs | 2 +- .../Snapshots/ComplexCalculator_Subtract_Generated.g.cs | 2 +- ...nseExamples_NotFoundResponseWithHeaderV1Async_Generated.g.cs | 2 +- ...ResponseExamples_NotFoundResponseWithHeaderV1_Generated.g.cs | 2 +- ...nseExamples_NotFoundResponseWithHeaderV2Async_Generated.g.cs | 2 +- ...ResponseExamples_NotFoundResponseWithHeaderV2_Generated.g.cs | 2 +- ...sponseExamples_OkResponseWithCustomSerializer_Generated.g.cs | 2 +- ...izeResponseExamples_OkResponseWithHeaderAsync_Generated.g.cs | 2 +- ...ustomizeResponseExamples_OkResponseWithHeader_Generated.g.cs | 2 +- .../Snapshots/DynamicExample_DynamicInput_Generated.g.cs | 2 +- .../Snapshots/DynamicExample_DynamicReturn_Generated.g.cs | 2 +- .../Snapshots/Functions_AsyncStartupToLower_Generated.g.cs | 2 +- .../Snapshots/Functions_AsyncStartupToUpper_Generated.g.cs | 2 +- .../Snapshots/Functions_ToUpper_Generated.g.cs | 2 +- .../Snapshots/Functions_ToUpper_Generated_NET8.g.cs | 2 +- .../Snapshots/GreeterExecutable_SayHelloAsync_Generated.g.cs | 2 +- .../Snapshots/GreeterExecutable_SayHello_Generated.g.cs | 2 +- .../Snapshots/Greeter_SayHelloAsync_Generated.g.cs | 2 +- .../Snapshots/Greeter_SayHello_Generated.g.cs | 2 +- .../Snapshots/IntrinsicExample_HasIntrinsic_Generated.g.cs | 2 +- ...bleReferenceTypeExample_NullableHeaderHttpApi_Generated.g.cs | 2 +- .../ParameterlessMethodWithResponse_ToUpper_Generated.g.cs | 2 +- .../Snapshots/ParameterlessMethods_ToUpper_Generated.g.cs | 2 +- ...ents_ProcessMessagesWithBatchFailureReporting_Generated.g.cs | 2 +- .../Snapshots/SQS/ValidSQSEvents_ProcessMessages_Generated.g.cs | 2 +- .../Snapshots/ServerlessTemplates/complexCalculator.template | 2 +- .../Snapshots/ServerlessTemplates/customizeResponse.template | 2 +- .../Snapshots/ServerlessTemplates/dynamicexample.template | 2 +- .../Snapshots/ServerlessTemplates/greeter.template | 2 +- .../Snapshots/ServerlessTemplates/greeter_executable.template | 2 +- .../Snapshots/ServerlessTemplates/intrinsicexample.template | 2 +- .../Snapshots/ServerlessTemplates/net8.template | 2 +- .../Snapshots/ServerlessTemplates/nullreferenceexample.template | 2 +- .../Snapshots/ServerlessTemplates/parameterless.template | 2 +- .../ServerlessTemplates/parameterlesswithresponse.template | 2 +- .../Snapshots/ServerlessTemplates/simpleCalculator.template | 2 +- .../sourcegeneratorserializationexample.template | 2 +- .../Snapshots/ServerlessTemplates/sqsEvents.template | 2 +- .../Snapshots/ServerlessTemplates/subnamespace.template | 2 +- .../ServerlessTemplates/subnamespace_executable.template | 2 +- .../ServerlessTemplates/subnamespace_executableimage.template | 2 +- .../Snapshots/ServerlessTemplates/taskexample.template | 2 +- .../Snapshots/ServerlessTemplates/voidexample - Copy.template | 2 +- .../Snapshots/ServerlessTemplates/voidexample.template | 2 +- .../Snapshots/SimpleCalculator_Add_Generated.g.cs | 2 +- .../Snapshots/SimpleCalculator_DivideAsync_Generated.g.cs | 2 +- .../Snapshots/SimpleCalculator_Multiply_Generated.g.cs | 2 +- .../Snapshots/SimpleCalculator_Pi_Generated.g.cs | 2 +- .../Snapshots/SimpleCalculator_Random_Generated.g.cs | 2 +- .../Snapshots/SimpleCalculator_Randoms_Generated.g.cs | 2 +- .../Snapshots/SimpleCalculator_Subtract_Generated.g.cs | 2 +- ...ourceGenerationSerializationExample_GetPerson_Generated.g.cs | 2 +- .../Snapshots/TaskExample_TaskReturn_Generated.g.cs | 2 +- .../Snapshots/VoidExample_VoidReturn_Generated.g.cs | 2 +- Libraries/test/TestExecutableServerlessApp/serverless.template | 2 +- Libraries/test/TestServerlessApp.NET8/serverless.template | 2 +- Libraries/test/TestServerlessApp/serverless.template | 2 +- 60 files changed, 60 insertions(+), 60 deletions(-) diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Amazon.Lambda.Annotations.SourceGenerator.csproj b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Amazon.Lambda.Annotations.SourceGenerator.csproj index 114feb426..93afcf880 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Amazon.Lambda.Annotations.SourceGenerator.csproj +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Amazon.Lambda.Annotations.SourceGenerator.csproj @@ -1,7 +1,7 @@  - 1.4.0 + 1.5.0 netstandard2.0