diff --git a/.autover/changes/1916e292-d131-4c9a-8036-0d7b68f0ce7a.json b/.autover/changes/1916e292-d131-4c9a-8036-0d7b68f0ce7a.json
deleted file mode 100644
index 5cd1858c2..000000000
--- a/.autover/changes/1916e292-d131-4c9a-8036-0d7b68f0ce7a.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "Projects": [
- {
- "Name": "Amazon.Lambda.CognitoEvents",
- "Type": "Patch",
- "ChangelogMessages": [
- "[Breaking Change] Fix issue around not handling null value during deserialization for `ForceAliasCreation` by making it nullable."
- ]
- }
- ]
-}
\ No newline at end of file
diff --git a/.autover/changes/b0df0353-6e47-4548-94a7-45b42f67b910.json b/.autover/changes/b0df0353-6e47-4548-94a7-45b42f67b910.json
deleted file mode 100644
index 147f21333..000000000
--- a/.autover/changes/b0df0353-6e47-4548-94a7-45b42f67b910.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "Projects": [
- {
- "Name": "Amazon.Lambda.APIGatewayEvents",
- "Type": "Patch",
- "ChangelogMessages": [
- "Added NotResource field to APIGatewayCustomAuthorizerPolicy.IAMPolicyStatement"
- ]
- }
- ]
-}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3bd65db42..503f3cb49 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,24 @@
+## Release 2025-11-21
+
+### Amazon.Lambda.DynamoDBEvents.SDK.Convertor (2.0.1)
+* Fix Empty Strings converted to null issue.
+
+## Release 2025-11-19
+
+### Amazon.Lambda.RuntimeSupport (1.14.1)
+* Fixed issue with output stream being reused when using multi concurrency mode
+
+## Release 2025-11-06
+
+### Amazon.Lambda.CognitoEvents (4.0.1)
+* [Breaking Change] Fix issue around not handling null value during deserialization for `ForceAliasCreation` by making it nullable.
+### Amazon.Lambda.Core (2.8.0)
+* Add LambdaTraceProvider to make the current trace id globally accessible
+### Amazon.Lambda.RuntimeSupport (1.14.0)
+* Add support for Lambda multi concurrency mode
+### Amazon.Lambda.APIGatewayEvents (2.7.2)
+* Added NotResource field to APIGatewayCustomAuthorizerPolicy.IAMPolicyStatement
+
## Release 2025-09-17
### Amazon.Lambda.RuntimeSupport (1.13.4)
diff --git a/LambdaRuntimeDockerfiles/Images/net10/amd64/Dockerfile b/LambdaRuntimeDockerfiles/Images/net10/amd64/Dockerfile
index 04cdc074e..0771fc1c6 100644
--- a/LambdaRuntimeDockerfiles/Images/net10/amd64/Dockerfile
+++ b/LambdaRuntimeDockerfiles/Images/net10/amd64/Dockerfile
@@ -1,7 +1,7 @@
# Based on Docker image from: https://github.com/dotnet/dotnet-docker/
-ARG ASPNET_VERSION=10.0.0-rc.1.25451.107
-ARG ASPNET_SHA512=d2219850cab73cebe3625a3e5321c67e2921d3bfefb6c238044a21d8a95ca07ca731507ba7c027a8b03fe8eeba7f23d8d884d34f02437d6a5830423484053d70
+ARG ASPNET_VERSION=10.0.0
+ARG ASPNET_SHA512=73314cf4815f551ee6f980273836568c66020fde7e87b7fe27f8224bb6ece5e767bf2a80e42bc5aad383dcb38c823f4b2b25d0fffcbb0fbd73fa82f20e66e8cf
ARG LAMBDA_RUNTIME_NAME=dotnet10
ARG AMAZON_LINUX=public.ecr.aws/lambda/provided:al2023
diff --git a/LambdaRuntimeDockerfiles/Images/net10/arm64/Dockerfile b/LambdaRuntimeDockerfiles/Images/net10/arm64/Dockerfile
index c0c066c50..74467cb61 100644
--- a/LambdaRuntimeDockerfiles/Images/net10/arm64/Dockerfile
+++ b/LambdaRuntimeDockerfiles/Images/net10/arm64/Dockerfile
@@ -1,7 +1,7 @@
# Based on Docker image from: https://github.com/dotnet/dotnet-docker/
-ARG ASPNET_VERSION=10.0.0-rc.1.25451.107
-ARG ASPNET_SHA512=bd86bac48405084fecb610260e60a1f645de455dfaf208caec9771af160fd1d7bdc99a4a1f88169c1cef7595536d55dc571472ca7a15928271d40ae45fdedefa
+ARG ASPNET_VERSION=10.0.0
+ARG ASPNET_SHA512=0ed022f7a7a2bf0660b2d4cdcb94a5444b9b9ece87f22a60a2029137630fd91385c61a19b1301e81bef363b5b890924d53a7c824e58bd4edd327723aa72c6fb5
ARG LAMBDA_RUNTIME_NAME=dotnet10
ARG AMAZON_LINUX=public.ecr.aws/lambda/provided:al2023
diff --git a/LambdaRuntimeDockerfiles/Images/net8/amd64/Dockerfile b/LambdaRuntimeDockerfiles/Images/net8/amd64/Dockerfile
index d1bd8d3e0..aab88f675 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.20
-ARG ASPNET_SHA512=228713f3c3600c49e7924e26dc86115c9674b5308b44514a53f670fa785038aa885ead8cd2c1c1850d1565b689a95a92e97f472d86429930dbfb114aa6020eb7
+ARG ASPNET_VERSION=8.0.22
+ARG ASPNET_SHA512=842fb896e6d496875cd6bb6943779ca8a7a9684170d7200b7ab2b53433aa151a9a1800998f9da5582237a690996d8168822e50b8d4be8cf9a512cbe7a2240e88
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 122fe3fba..4ae7448f3 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.20
-ARG ASPNET_SHA512=17b01d6309899eea40200fc449cb606df5541c5802b973c21e71d7f5539b72cb35e2daf38bd9e17ec6dccfb23c3c17afdb1e7f05fb13f10701561d2e00b19645
+ARG ASPNET_VERSION=8.0.22
+ARG ASPNET_SHA512=538eb7ce62c77f383606906f38f9aa9911339c2ad4ee849c5fb552491c1bc812492395f2975510eb808410263baf06f0771c7caf0b46695251e6c9273111288f
ARG LAMBDA_RUNTIME_NAME=dotnet8
ARG AMAZON_LINUX=public.ecr.aws/lambda/provided:al2023
diff --git a/LambdaRuntimeDockerfiles/Images/net9/amd64/Dockerfile b/LambdaRuntimeDockerfiles/Images/net9/amd64/Dockerfile
index 909d72a95..ec4eb7c15 100644
--- a/LambdaRuntimeDockerfiles/Images/net9/amd64/Dockerfile
+++ b/LambdaRuntimeDockerfiles/Images/net9/amd64/Dockerfile
@@ -1,7 +1,7 @@
# Based on Docker image from: https://github.com/dotnet/dotnet-docker/
-ARG ASPNET_VERSION=9.0.9
-ARG ASPNET_SHA512=7ff1b517c45b2c7720fc1be808842c5b7f644ff9138f221862620e23660db528b5961f791434aa75885c808ecb3bf9d213a33e8ff3eaa477df7d6256d215a6c4
+ARG ASPNET_VERSION=9.0.11
+ARG ASPNET_SHA512=0a3c6a20dd2b00928cd22aca0c99d1ddd36ba93e9909a15097b952b54097e0b817454db7beae482a895d1877c281218fffee0f3f07f6a0cbe521e4c39cda5d4a
ARG LAMBDA_RUNTIME_NAME=dotnet9
ARG AMAZON_LINUX=public.ecr.aws/lambda/provided:al2023
diff --git a/LambdaRuntimeDockerfiles/Images/net9/arm64/Dockerfile b/LambdaRuntimeDockerfiles/Images/net9/arm64/Dockerfile
index 29a8ffcaa..b8d63cf44 100644
--- a/LambdaRuntimeDockerfiles/Images/net9/arm64/Dockerfile
+++ b/LambdaRuntimeDockerfiles/Images/net9/arm64/Dockerfile
@@ -1,7 +1,7 @@
# Based on Docker image from: https://github.com/dotnet/dotnet-docker/
-ARG ASPNET_VERSION=9.0.9
-ARG ASPNET_SHA512=cd2d24e16edfdbd34287a4ae25e0a517aaf1bbfa0ffd4d3bc7eac63d85dd544d43b12d081aa2419af13ac27fdb524f918ecf2fdfa916039aed66d502318a72ee
+ARG ASPNET_VERSION=9.0.11
+ARG ASPNET_SHA512=bcf66a56f780b720f663e4f276ebbffeb1f8117523d19fe12c545c53f929ce1036710ba078f3019767ccd19e915dc457d60dad426f926b0be46cef74c01143e8
ARG LAMBDA_RUNTIME_NAME=dotnet9
ARG AMAZON_LINUX=public.ecr.aws/lambda/provided:al2023
diff --git a/LambdaRuntimeDockerfiles/Infrastructure/Infrastructure.sln b/LambdaRuntimeDockerfiles/Infrastructure/Infrastructure.sln
deleted file mode 100644
index 020a42e1d..000000000
--- a/LambdaRuntimeDockerfiles/Infrastructure/Infrastructure.sln
+++ /dev/null
@@ -1,37 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.30711.63
-MinimumVisualStudioVersion = 15.0.26124.0
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{85BC34C2-2C30-40EB-9AA2-2B42988B40C8}"
- ProjectSection(SolutionItems) = preProject
- cdk.json = cdk.json
- README.md = README.md
- bootstrap.ps1 = bootstrap.ps1
- EndProjectSection
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{DFAD9A3B-0EB2-46E0-8BF6-85850DA60AA8}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Infrastructure", "src\Infrastructure\Infrastructure.csproj", "{B9A511E5-C78B-4476-A50D-BEF6C3FE97DD}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {B9A511E5-C78B-4476-A50D-BEF6C3FE97DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {B9A511E5-C78B-4476-A50D-BEF6C3FE97DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {B9A511E5-C78B-4476-A50D-BEF6C3FE97DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {B9A511E5-C78B-4476-A50D-BEF6C3FE97DD}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(NestedProjects) = preSolution
- {B9A511E5-C78B-4476-A50D-BEF6C3FE97DD} = {DFAD9A3B-0EB2-46E0-8BF6-85850DA60AA8}
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {EB7F9BE1-0375-4D29-A169-6C0354675255}
- EndGlobalSection
-EndGlobal
diff --git a/LambdaRuntimeDockerfiles/Infrastructure/README.md b/LambdaRuntimeDockerfiles/Infrastructure/README.md
deleted file mode 100644
index 533b3e873..000000000
--- a/LambdaRuntimeDockerfiles/Infrastructure/README.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# Infrastructure for .NET Lambda Runtime Dockerfiles
-
-Infrastructure project allows to create pipeline to build and push .NET Lambda Runtime Dockerfiles using CDK framework.
-
-## Getting started
-### Prerequisites
-1. [AWS CLI](https://aws.amazon.com/cli/)
-2. [AWS Account and User](https://portal.aws.amazon.com/billing/signup)
-3. [Node.js](https://nodejs.org/)
-4. [AWS CDK Toolkit](https://www.npmjs.com/package/aws-cdk)
-5. [.NET 8 SDK or above](https://dotnet.microsoft.com/download)
-
-### Bootstrap
-
-`bootstrap.ps1` provisions resources the AWS CDK needs to perform the deployment and deploys generated CloudFormation template.
-
-```powershell
-.\bootstrap.ps1 `
--PipelineAccountId "AccountId" `
--Region "AwsRegion" `
--GitHubTokenSecretName "SecretName" `
--GitHubTokenSecretKey "Key" `
--GitHubRepoOwner "GitHubOwner" `
--GitHubRepoName "GitHubRepo" `
--GitHubRepoBranch "GitHubBranch" `
--StageEcr "AccountId.dkr.ecr.us-west-2.amazonaws.com" `
--BetaEcrs "AccountId.dkr.ecr.us-west-2.amazonaws.com;AccountId.dkr.ecr.us-west-2.amazonaws.com" `
--ProdEcrs "AccountId.dkr.ecr.us-west-2.amazonaws.com;AccountId.dkr.ecr.us-west-2.amazonaws.com"
-```
-
-#### Notes
- - AWS Profiles used to execute `bootstrap.ps1` must have administrator access.
- - All resources used to bootstrap the pipeline must already exist.
- - `AccountId` is AWS AccountId used for deploying CDK App.
-
-## Useful commands
-* `npx cdk bootstrap --cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess` bootstrap this app
-* `dotnet build` compile this app
-* `cdk deploy` deploy this stack to your default AWS account/region
-* `cdk diff` compare deployed stack with current state
-* `cdk synth` emits the synthesized CloudFormation template
diff --git a/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/Common/manifest_push.psm1 b/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/Common/manifest_push.psm1
deleted file mode 100644
index 2ebef1d75..000000000
--- a/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/Common/manifest_push.psm1
+++ /dev/null
@@ -1,31 +0,0 @@
-function Push-MultiArchImageManifest($ManifestList, $Amd64Manifest, $Arm64Manifest)
-{
- if ($Arm64Manifest)
- {
- docker manifest create $ManifestList $Amd64Manifest $Arm64Manifest --amend
- if (!$?)
- {
- throw "Failed to create $ManifestList manifestlist with $Amd64Manifest $Arm64Manifest manifests"
- }
- }
- else
- {
- docker manifest create $ManifestList $Amd64Manifest --amend
- if (!$?)
- {
- throw "Failed to create $ManifestList manifestlist with $Amd64Manifest manifest"
- }
- }
-
- docker manifest push $ManifestList
- if (!$?)
- {
- throw "Failed to push $ManifestList manifestlist"
- }
-
- docker manifest inspect $ManifestList
- if (!$?)
- {
- throw "Failed to inspect $ManifestList manifestlist"
- }
-}
diff --git a/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/Configuration.cs b/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/Configuration.cs
deleted file mode 100644
index 4b38578e7..000000000
--- a/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/Configuration.cs
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-using System;
-using System.Collections.Generic;
-
-namespace Infrastructure;
-
-internal class Configuration
-{
- public string AccountId { get; } = Environment.GetEnvironmentVariable("AWS_LAMBDA_PIPELINE_ACCOUNT_ID");
- public string Region { get; } = Environment.GetEnvironmentVariable("AWS_LAMBDA_PIPELINE_REGION");
-
- public string GitHubTokenSecretName { get; } = Environment.GetEnvironmentVariable("AWS_LAMBDA_GITHUB_TOKEN_SECRET_NAME");
-
- public string GitHubTokenSecretKey { get; } = Environment.GetEnvironmentVariable("AWS_LAMBDA_GITHUB_TOKEN_SECRET_KEY");
- public string GitHubOwner { get; } = Environment.GetEnvironmentVariable("AWS_LAMBDA_GITHUB_REPO_OWNER");
- public string GitHubRepository { get; } = Environment.GetEnvironmentVariable("AWS_LAMBDA_GITHUB_REPO_NAME");
- public string GitHubBranch { get; } = Environment.GetEnvironmentVariable("AWS_LAMBDA_GITHUB_REPO_BRANCH");
-
- public string GitHubOwnerStaging { get; } = Environment.GetEnvironmentVariable("AWS_LAMBDA_GITHUB_REPO_OWNER_STAGING");
- public string GitHubRepositoryStaging { get; } = Environment.GetEnvironmentVariable("AWS_LAMBDA_GITHUB_REPO_NAME_STAGING");
- public string GitHubBranchStaging { get; } = Environment.GetEnvironmentVariable("AWS_LAMBDA_GITHUB_REPO_BRANCH_STAGING");
-
- public Ecrs Ecrs { get; } = new Ecrs();
- public const string ProjectRoot = "LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure";
- public string ProjectName { get; } = "aws-lambda-container-images";
-
- public readonly FrameworkConfiguration[] Frameworks = new[]
- {
- new FrameworkConfiguration
- {
- Framework = "net8",
- Channel = "8.0",
- EcrRepositoryName = "awslambda/dotnet8-runtime",
- DockerBuildImage = "8.0-bookworm-slim",
- BaseImageAmd64Tag = "contributed-base-image-x86_64",
- BaseImageArm64Tag = "contributed-base-image-arm64",
- HasArm64Image = true
- },
- new FrameworkConfiguration
- {
- Framework = "net9",
- Channel = "9.0",
- EcrRepositoryName = "awslambda/dotnet9-runtime",
- DockerBuildImage = "9.0-bookworm-slim",
- BaseImageAmd64Tag = "contributed-base-image-x86_64",
- BaseImageArm64Tag = "contributed-base-image-arm64",
- HasArm64Image = true
- },
- new FrameworkConfiguration
- {
- Framework = "net10",
- Channel = "10.0",
- EcrRepositoryName = "awslambda/dotnet10-runtime",
- DockerBuildImage = "10.0-preview-trixie-slim",
- BaseImageAmd64Tag = "contributed-base-image-x86_64",
- BaseImageArm64Tag = "contributed-base-image-arm64",
- HasArm64Image = true
- }
- };
-}
-
-internal class Ecrs
-{
- public string Stage { get; } = Environment.GetEnvironmentVariable("AWS_LAMBDA_STAGE_ECR");
- public string Beta { get; } = Environment.GetEnvironmentVariable("AWS_LAMBDA_BETA_ECRS");
- public string Prod { get; } = Environment.GetEnvironmentVariable("AWS_LAMBDA_PROD_ECRS");
-}
-
-internal class FrameworkConfiguration
-{
- public string Framework { get; set; }
-
- public string Channel { get; set; }
-
- public string EcrRepositoryName { get; set; }
-
- public string DockerBuildImage { get; set; }
-
- public string BaseImageAmd64Tag { get; set; }
-
- public string BaseImageArm64Tag { get; set; }
-
- public bool HasArm64Image { get; set; }
-
- // DotnetSdkVersions is used to specify a specific version of the .NET SDK to be installed on the CodeBuild image
- // The default behavior is to specify a channel and that installs the latest version in that channel
- // By specifying a specific .NET SDK version, you override the default channel behavior
- public string SpecificSdkVersion { get; set; } = string.Empty;
-}
diff --git a/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/DockerBuild/build.ps1 b/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/DockerBuild/build.ps1
deleted file mode 100644
index 104a6b378..000000000
--- a/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/DockerBuild/build.ps1
+++ /dev/null
@@ -1,73 +0,0 @@
-param (
- [Parameter(HelpMessage = "ECR to push built image.")]
- [string] $StageEcr,
-
- [Parameter(HelpMessage = "ECR repository name to push final image.")]
- [string] $EcrRepositoryName,
-
- [Parameter(HelpMessage = "Final image tag to push.")]
- [string] $ImageTag,
-
- [Parameter(HelpMessage = "Image architecture")]
- [string] $Architecture,
-
- [Parameter(HelpMessage = ".NET version")]
- [string] $Framework
-)
-
-# Change the ErrorActionPreference to 'Stop' to allow aborting script on error
-$ErrorActionPreference = 'Stop'
-
-# Login in the stage ECR
-$StageRegion = $StageEcr.Split(".")[3]
-aws ecr get-login-password --region $StageRegion | docker login --username AWS --password-stdin $StageEcr
-if (!$?)
-{
- throw "Failed to login in ${StageEcr}"
-}
-
-$SourceNameTagPair = "aws-lambda-${Framework}:latest"
-
-# Check if the repository exists
-aws ecr describe-repositories --repository-names $EcrRepositoryName --region $StageRegion
-if (!$?) {
- Write-Output "Repository '$EcrRepositoryName' does not exist. Creating it..."
- aws ecr create-repository --repository-name $EcrRepositoryName --region $StageRegion
-}
-else {
- Write-Output "Repository '$EcrRepositoryName' exists."
-}
-
-# Build runtime docker image
-try
-{
- # runtime docker image need to be built from the root of the reposiotory
- # so it can include the Amazon.Lambda.RuntimeSupport project in its Docker Build Context
- Push-Location $PSScriptRoot\..\..\..\..\..
- docker build -f (Join-Path $PWD '.\LambdaRuntimeDockerfiles\Images' $Framework $Architecture 'Dockerfile') -t $SourceNameTagPair .
-}
-finally
-{
- Pop-Location
-}
-
-# Push built image
-$DestinationUris = @(
- "$StageEcr/${EcrRepositoryName}:latest",
- "$StageEcr/${EcrRepositoryName}:${ImageTag}"
-)
-
-foreach ($DestinationUri in $DestinationUris)
-{
- docker tag $SourceNameTagPair $DestinationUri
- if (!$?)
- {
- throw "Failed to tag. SourceTag: ${SourceNameTagPair}, TargetTag: ${DestinationUri}"
- }
-
- docker push $DestinationUri
- if (!$?)
- {
- throw "Failed to push at ${DestinationUri}"
- }
-}
\ No newline at end of file
diff --git a/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/DockerBuild/buildspec.yml b/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/DockerBuild/buildspec.yml
deleted file mode 100644
index cb734f7bb..000000000
--- a/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/DockerBuild/buildspec.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-version: 0.2
-phases:
- pre_build:
- commands:
- # Find and delete the global.json files that were added by CodeBuild. This causes issues when multiple SDKs are installed.
- - find / -type f -name 'global.json' -delete
- - |
- if [ "$AWS_LAMBDA_DOTNET_SDK_VERSION" = "" ]; then
- curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --channel $AWS_LAMBDA_DOTNET_FRAMEWORK_CHANNEL
- else
- curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --version $AWS_LAMBDA_DOTNET_SDK_VERSION
- fi
- - export PATH="$PATH:$HOME/.dotnet"
- - export DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
- - rm -rf /usr/bin/pwsh
- - dotnet tool install --global PowerShell --version $AWS_LAMBDA_POWERSHELL_VERSION
- build:
- commands:
- - pwsh LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/DockerBuild/build.ps1
- -StageEcr $AWS_LAMBDA_STAGE_ECR
- -EcrRepositoryName $AWS_LAMBDA_ECR_REPOSITORY_NAME
- -ImageTag $AWS_LAMBDA_IMAGE_TAG
- -Architecture $AWS_LAMBDA_ARCHITECTURE
- -Framework $AWS_LAMBDA_DOTNET_FRAMEWORK_VERSION
diff --git a/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/DockerImageManifest/build.ps1 b/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/DockerImageManifest/build.ps1
deleted file mode 100644
index 63cc71be6..000000000
--- a/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/DockerImageManifest/build.ps1
+++ /dev/null
@@ -1,45 +0,0 @@
-param (
- [Parameter(HelpMessage = "ECR to push built image.")]
- [string] $StageEcr,
-
- [Parameter(HelpMessage = "ECR repository name to push final image.")]
- [string] $EcrRepositoryName,
-
- [Parameter(HelpMessage = "Final image tag to push.")]
- [string] $MultiArchImageTag,
-
- [Parameter(HelpMessage = "Image architectures")]
- [string] $Arm64ImageTag,
-
- [Parameter(HelpMessage = "Image architectures")]
- [string] $Amd64ImageTag,
-
- [Parameter(HelpMessage = "Indicates whether to include an Arm64 image in the manifest")]
- [string] $IncludeArm64
-)
-
-Import-Module $PSScriptRoot/../Common/manifest_push.psm1
-
-# Change the ErrorActionPreference to 'Stop' to allow aborting script on error
-$ErrorActionPreference = 'Stop'
-
-# Login in the source ECR
-$StageRegion = $StageEcr.Split(".")[3]
-aws ecr get-login-password --region $StageRegion | docker login --username AWS --password-stdin $StageEcr
-if (!$?)
-{
- throw "Failed to login in ${StageEcr}"
-}
-
-# Push multi arch to stage ECR
-$ManifestList = "${StageEcr}/${EcrRepositoryName}:${MultiArchImageTag}"
-$Amd64Uri = "${StageEcr}/${EcrRepositoryName}:${Amd64ImageTag}"
-$Arm64Uri = "${StageEcr}/${EcrRepositoryName}:${Arm64ImageTag}"
-if ($IncludeArm64 -eq "True")
-{
- Push-MultiArchImageManifest -ManifestList $ManifestList -Amd64Manifest $Amd64Uri -Arm64Manifest $Arm64Uri
-}
-else
-{
- Push-MultiArchImageManifest -ManifestList $ManifestList -Amd64Manifest $Amd64Uri
-}
\ No newline at end of file
diff --git a/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/DockerImageManifest/buildspec.yml b/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/DockerImageManifest/buildspec.yml
deleted file mode 100644
index c1b3fc5f7..000000000
--- a/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/DockerImageManifest/buildspec.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-version: 0.2
-# Based on the Docker documentation, must include the DOCKER_CLI_EXPERIMENTAL environment variable
-# https://docs.docker.com/engine/reference/commandline/manifest/
-
-phases:
- build:
- commands:
- - export DOCKER_CLI_EXPERIMENTAL=enabled
- - pwsh LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/DockerImageManifest/build.ps1
- -StageEcr $AWS_LAMBDA_STAGE_ECR
- -EcrRepositoryName $AWS_LAMBDA_ECR_REPOSITORY_NAME
- -MultiArchImageTag $AWS_LAMBDA_MULTI_ARCH_IMAGE_TAG
- -Arm64ImageTag $AWS_LAMBDA_ARM64_IMAGE_TAG
- -Amd64ImageTag $AWS_LAMBDA_AMD64_IMAGE_TAG
- -IncludeArm64 $AWS_LAMBDA_INCLUDE_ARM64
diff --git a/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/DockerPush/build.ps1 b/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/DockerPush/build.ps1
deleted file mode 100644
index 46c8aeb9c..000000000
--- a/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/DockerPush/build.ps1
+++ /dev/null
@@ -1,99 +0,0 @@
-param (
- [Parameter(HelpMessage = "Source ECR containing source docker image.")]
- [string] $SourceEcr,
-
- [Parameter(HelpMessage = "Tag of the source image.")]
- [string] $Amd64ImageTag,
-
- [Parameter(HelpMessage = "Tag of the source image.")]
- [string] $Arm64ImageTag,
-
- [Parameter(HelpMessage = "Semicolon separated list of destincation ECR to push source image.")]
- [string] $DestinationEcrs,
-
- [Parameter(HelpMessage = "Tag of the destination image.")]
- [string] $MultiArchImageTag,
-
- [Parameter(HelpMessage = "ECR repository name for both source and destination ECRs.")]
- [string] $EcrRepositoryName,
-
- [Parameter(HelpMessage = "Indicates whether to include an Arm64 image in the manifest")]
- [string] $IncludeArm64
-)
-
-Import-Module $PSScriptRoot/../Common/manifest_push.psm1
-
-# Change the ErrorActionPreference to 'Stop' to allow aborting script on error
-$ErrorActionPreference = 'Stop'
-
-# Login in the source ECR
-$SourceRegion = $SourceEcr.Split(".")[3]
-aws ecr get-login-password --region $SourceRegion | docker login --username AWS --password-stdin $SourceEcr
-if (!$?)
-{
- throw "Failed to login in ${SourceEcr}"
-}
-
-# Pull image from source ECR
-$SourceAmd64Uri = "${SourceEcr}/${EcrRepositoryName}:${Amd64ImageTag}"
-docker pull $SourceAmd64Uri
-
-if ($IncludeArm64 -eq "True")
-{
- $SourceArm64Uri = "${SourceEcr}/${EcrRepositoryName}:${Arm64ImageTag}"
- docker pull $SourceArm64Uri
-}
-
-# Push pulled image to desination ECRs
-foreach ($DestinationEcr in $DestinationEcrs.Split(";"))
-{
- # Login in the source ECR
- $DestinationRegion = $DestinationEcr.Split(".")[3]
- aws ecr get-login-password --region $DestinationRegion | docker login --username AWS --password-stdin $DestinationEcr
- if (!$?)
- {
- throw "Failed to login in ${DestinationEcr}"
- }
-
- # Tag and push Amd64 image to destination ECR
- $Amd64Uri = "${DestinationEcr}/${EcrRepositoryName}:${Amd64ImageTag}"
- docker tag $SourceAmd64Uri $Amd64Uri
- if (!$?)
- {
- throw "Failed to tag. SourceTag: ${SourceAmd64Uri}, TargetTag: ${Amd64Uri}"
- }
-
- docker push $Amd64Uri
- if (!$?)
- {
- throw "Failed to push at ${Amd64Uri}"
- }
-
- if ($IncludeArm64 -eq "True")
- {
- # Tag and push Arm64 image to destination ECR
- $Arm64Uri = "${DestinationEcr}/${EcrRepositoryName}:${Arm64ImageTag}"
- docker tag $SourceArm64Uri $Arm64Uri
- if (!$?)
- {
- throw "Failed to tag. SourceTag: ${SourceArm64Uri}, TargetTag: ${Arm64Uri}"
- }
-
- docker push $Arm64Uri
- if (!$?)
- {
- throw "Failed to push at ${Arm64Uri}"
- }
- }
-
- # Push multi arch to destination ECR
- $ManifestList = "${DestinationEcr}/${EcrRepositoryName}:${MultiArchImageTag}"
- if ($IncludeArm64 -eq "True")
- {
- Push-MultiArchImageManifest -ManifestList $ManifestList -Amd64Manifest $Amd64Uri -Arm64Manifest $Arm64Uri
- }
- else
- {
- Push-MultiArchImageManifest -ManifestList $ManifestList -Amd64Manifest $Amd64Uri
- }
-}
\ No newline at end of file
diff --git a/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/DockerPush/buildspec.yml b/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/DockerPush/buildspec.yml
deleted file mode 100644
index 62232c224..000000000
--- a/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/DockerPush/buildspec.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-version: 0.2
-# Based on the Docker documentation, must include the DOCKER_CLI_EXPERIMENTAL environment variable
-# https://docs.docker.com/engine/reference/commandline/manifest/
-
-phases:
- build:
- commands:
- - export DOCKER_CLI_EXPERIMENTAL=enabled
- - pwsh LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/DockerPush/build.ps1
- -SourceEcr $AWS_LAMBDA_SOURCE_ECR
- -EcrRepositoryName $AWS_LAMBDA_ECR_REPOSITORY_NAME
- -Amd64ImageTag $AWS_LAMBDA_AMD64_IMAGE_TAG
- -Arm64ImageTag $AWS_LAMBDA_ARM64_IMAGE_TAG
- -MultiArchImageTag $AWS_LAMBDA_MULTI_ARCH_IMAGE_TAG
- -DestinationEcrs $AWS_LAMBDA_DESTINATION_ECRS
- -IncludeArm64 $AWS_LAMBDA_INCLUDE_ARM64
diff --git a/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/GlobalSuppressions.cs b/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/GlobalSuppressions.cs
deleted file mode 100644
index dfa1fce7f..000000000
--- a/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/GlobalSuppressions.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Potential Code Quality Issues", "RECS0026:Possible unassigned object created by 'new'", Justification = "Constructs add themselves to the scope in which they are created")]
diff --git a/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/Infrastructure.csproj b/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/Infrastructure.csproj
deleted file mode 100644
index 3a5ab3166..000000000
--- a/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/Infrastructure.csproj
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
- Exe
- net8
-
- Major
-
-
-
-
-
-
-
-
-
-
diff --git a/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/PipelineStack.cs b/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/PipelineStack.cs
deleted file mode 100644
index 101c0f113..000000000
--- a/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/PipelineStack.cs
+++ /dev/null
@@ -1,506 +0,0 @@
-/*
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-using System;
-using System.Collections.Generic;
-using Amazon.CDK;
-using Amazon.CDK.AWS.CodeBuild;
-using Amazon.CDK.AWS.CodePipeline;
-using Amazon.CDK.AWS.CodePipeline.Actions;
-using Amazon.CDK.AWS.IAM;
-using Constructs;
-
-namespace Infrastructure;
-
-public class PipelineStack : Stack
-{
- private const string PowershellVersion = "7.4.5";
- private const string BaseImageMultiArch = "contributed-base-image-multi-arch";
-
- internal PipelineStack(
- Construct scope,
- string id,
- Configuration configuration,
- FrameworkConfiguration frameworkConfiguration,
- string gitHubOwner,
- string gitHubRepository,
- string gitHubBranch,
- string pipelineName,
- IStackProps props = null) : base(scope, id, props)
- {
- var sourceArtifact = new Artifact_();
-
- var ecrPolicy = new PolicyStatement(new PolicyStatementProps
- {
- Effect = Effect.ALLOW,
- Actions = new[] { "ecr:*" },
- Resources = new[] { "*" }
- });
-
- var sourceAction = new GitHubSourceAction(new GitHubSourceActionProps
- {
- ActionName = gitHubRepository,
- Output = sourceArtifact,
- Owner = gitHubOwner,
- Repo = gitHubRepository,
- Branch = gitHubBranch,
- Trigger = GitHubTrigger.WEBHOOK,
- OauthToken = SecretValue.SecretsManager(configuration.GitHubTokenSecretName, new SecretsManagerSecretOptions
- {
- JsonField = configuration.GitHubTokenSecretKey
- })
- });
-
- var pipeline = new Pipeline(this, "CodePipeline", new PipelineProps
- {
- PipelineType = PipelineType.V2,
- PipelineName = pipelineName,
- RestartExecutionOnUpdate = true,
- Stages =
- [
- new StageOptions
- {
- StageName = "Source",
- Actions = [sourceAction]
- }
- ]
- });
-
- var stageEcr = GetStageEcr(this, frameworkConfiguration.EcrRepositoryName, configuration);
-
- var dockerBuildActions = new List();
-
- // Stage
- // Build AMD64 image
- var dockerBuildAmd64 = new Project(this, "DockerBuild-amd64", new ProjectProps
- {
- BuildSpec = BuildSpec.FromSourceFilename($"{Configuration.ProjectRoot}/DockerBuild/buildspec.yml"),
- Description = $"Builds and pushes image to {stageEcr}",
- Environment = new BuildEnvironment
- {
- BuildImage = LinuxBuildImage.AMAZON_LINUX_2_5,
- Privileged = true
- },
- Source = Source.GitHub(new GitHubSourceProps
- {
- Owner = gitHubOwner,
- Repo = gitHubRepository,
- BranchOrRef = gitHubBranch
- }),
- EnvironmentVariables = new Dictionary
- {
- {"AWS_LAMBDA_STAGE_ECR", new BuildEnvironmentVariable {Value = stageEcr}},
- {"AWS_LAMBDA_ECR_REPOSITORY_NAME", new BuildEnvironmentVariable {Value = frameworkConfiguration.EcrRepositoryName}},
- {"AWS_LAMBDA_ARCHITECTURE", new BuildEnvironmentVariable {Value = "amd64"}},
- {"AWS_LAMBDA_POWERSHELL_VERSION", new BuildEnvironmentVariable {Value = PowershellVersion}},
- {"AWS_LAMBDA_IMAGE_TAG", new BuildEnvironmentVariable {Value = frameworkConfiguration.BaseImageAmd64Tag}},
- {"AWS_LAMBDA_DOTNET_FRAMEWORK_VERSION", new BuildEnvironmentVariable {Value = frameworkConfiguration.Framework}},
- {"AWS_LAMBDA_DOTNET_FRAMEWORK_CHANNEL", new BuildEnvironmentVariable {Value = frameworkConfiguration.Channel}},
- {"AWS_LAMBDA_DOTNET_SDK_VERSION", new BuildEnvironmentVariable {Value = frameworkConfiguration.SpecificSdkVersion }}
- }
- });
-
- dockerBuildAmd64.AddToRolePolicy(ecrPolicy);
- dockerBuildActions.Add(new CodeBuildAction(new CodeBuildActionProps
- {
- Input = sourceArtifact,
- Project = dockerBuildAmd64,
- ActionName = "amd64"
- }));
-
- if (frameworkConfiguration.HasArm64Image)
- {
- // Build ARM64 image
- var dockerBuildArm64 = new Project(this, "DockerBuild-arm64", new ProjectProps
- {
- BuildSpec = BuildSpec.FromSourceFilename($"{Configuration.ProjectRoot}/DockerBuild/buildspec.yml"),
- Description = $"Builds and pushes image to {stageEcr}",
- Environment = new BuildEnvironment
- {
- BuildImage = LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_3_0,
- Privileged = true
- },
- Source = Source.GitHub(new GitHubSourceProps
- {
- Owner = gitHubOwner,
- Repo = gitHubRepository,
- BranchOrRef = gitHubBranch
- }),
- EnvironmentVariables = new Dictionary
- {
- {"AWS_LAMBDA_STAGE_ECR", new BuildEnvironmentVariable {Value = stageEcr}},
- {"AWS_LAMBDA_ECR_REPOSITORY_NAME", new BuildEnvironmentVariable {Value = frameworkConfiguration.EcrRepositoryName}},
- {"AWS_LAMBDA_ARCHITECTURE", new BuildEnvironmentVariable {Value = "arm64"}},
- {"AWS_LAMBDA_POWERSHELL_VERSION", new BuildEnvironmentVariable {Value = PowershellVersion}},
- {"AWS_LAMBDA_IMAGE_TAG", new BuildEnvironmentVariable {Value = frameworkConfiguration.BaseImageArm64Tag}},
- {"AWS_LAMBDA_DOTNET_FRAMEWORK_VERSION", new BuildEnvironmentVariable {Value = frameworkConfiguration.Framework}},
- {"AWS_LAMBDA_DOTNET_FRAMEWORK_CHANNEL", new BuildEnvironmentVariable {Value = frameworkConfiguration.Channel}},
- {"AWS_LAMBDA_DOTNET_SDK_VERSION", new BuildEnvironmentVariable {Value = frameworkConfiguration.SpecificSdkVersion }}
- }
- });
-
- dockerBuildArm64.AddToRolePolicy(ecrPolicy);
- dockerBuildActions.Add(new CodeBuildAction(new CodeBuildActionProps
- {
- Input = sourceArtifact,
- Project = dockerBuildArm64,
- ActionName = "arm64"
- }));
- }
-
- pipeline.AddStage(new StageOptions
- {
- StageName = "DockerBuild",
- Actions = dockerBuildActions.ToArray()
- });
-
- // Create multi arch image manifest
- var dockerImageManifest = new Project(this, "DockerImageManifest", new ProjectProps
- {
- BuildSpec = BuildSpec.FromSourceFilename($"{Configuration.ProjectRoot}/DockerImageManifest/buildspec.yml"),
- Description = $"Creates image manifest and pushes to {stageEcr}",
- Environment = new BuildEnvironment
- {
- BuildImage = LinuxBuildImage.AMAZON_LINUX_2_5,
- Privileged = true
- },
- Source = Source.GitHub(new GitHubSourceProps
- {
- Owner = gitHubOwner,
- Repo = gitHubRepository,
- BranchOrRef = gitHubBranch
- }),
- EnvironmentVariables = new Dictionary
- {
- {"AWS_LAMBDA_STAGE_ECR", new BuildEnvironmentVariable {Value = stageEcr}},
- {"AWS_LAMBDA_ECR_REPOSITORY_NAME", new BuildEnvironmentVariable {Value = frameworkConfiguration.EcrRepositoryName}},
- {"AWS_LAMBDA_MULTI_ARCH_IMAGE_TAG", new BuildEnvironmentVariable {Value = BaseImageMultiArch}},
- {"AWS_LAMBDA_AMD64_IMAGE_TAG", new BuildEnvironmentVariable {Value = frameworkConfiguration.BaseImageAmd64Tag}},
- {"AWS_LAMBDA_ARM64_IMAGE_TAG", new BuildEnvironmentVariable {Value = frameworkConfiguration.BaseImageArm64Tag}},
- {"AWS_LAMBDA_INCLUDE_ARM64", new BuildEnvironmentVariable {Value = frameworkConfiguration.HasArm64Image.ToString()}},
- }
- });
-
- dockerImageManifest.AddToRolePolicy(ecrPolicy);
-
- pipeline.AddStage(new StageOptions
- {
- StageName = "DockerImageManifest",
- Actions =
- [
- new CodeBuildAction(new CodeBuildActionProps
- {
- Input = sourceArtifact,
- Project = dockerImageManifest,
- ActionName = "DockerImageManifest"
- })
- ]
- });
-
- var smokeTestsLambdaFunctionRole = new Role(this, "SmokeTestsLambdaFunctionRole", new RoleProps
- {
- RoleName = $"image-function-tests-{Guid.NewGuid()}",
- ManagedPolicies = [ManagedPolicy.FromAwsManagedPolicyName("service-role/AWSLambdaBasicExecutionRole")],
- AssumedBy = new ServicePrincipal("lambda.amazonaws.com")
- });
-
- // Smoke test AMD64 image
- var amd64SmokeTests = new Project(this, "SmokeTests-amd64", new ProjectProps
- {
- BuildSpec = BuildSpec.FromSourceFilename($"{Configuration.ProjectRoot}/SmokeTests/buildspec.yml"),
- Description = "Runs smoke tests on the built image.",
- Environment = new BuildEnvironment
- {
- BuildImage = LinuxBuildImage.AMAZON_LINUX_2_5,
- Privileged = true
- },
- Source = Source.GitHub(new GitHubSourceProps
- {
- Owner = gitHubOwner,
- Repo = gitHubRepository,
- BranchOrRef = gitHubBranch
- }),
- EnvironmentVariables = new Dictionary
- {
- {"AWS_LAMBDA_SOURCE_ECR", new BuildEnvironmentVariable {Value = stageEcr}},
- {"AWS_LAMBDA_ECR_REPOSITORY_NAME", new BuildEnvironmentVariable {Value = frameworkConfiguration.EcrRepositoryName}},
- {"AWS_LAMBDA_SOURCE_IMAGE_TAG", new BuildEnvironmentVariable {Value = BaseImageMultiArch}},
- {"AWS_LAMBDA_POWERSHELL_VERSION", new BuildEnvironmentVariable {Value = PowershellVersion}},
- {"AWS_LAMBDA_DOTNET_FRAMEWORK_VERSION", new BuildEnvironmentVariable {Value = frameworkConfiguration.Framework}},
- {"AWS_LAMBDA_DOTNET_FRAMEWORK_CHANNEL", new BuildEnvironmentVariable {Value = frameworkConfiguration.Channel}},
- {"AWS_LAMBDA_DOTNET_BUILD_IMAGE", new BuildEnvironmentVariable {Value = frameworkConfiguration.DockerBuildImage}},
- {"AWS_LAMBDA_DOTNET_SDK_VERSION", new BuildEnvironmentVariable {Value = frameworkConfiguration.SpecificSdkVersion }},
- {"AWS_LAMBDA_SMOKETESTS_LAMBDA_ROLE", new BuildEnvironmentVariable {Value = smokeTestsLambdaFunctionRole.RoleArn}}
- },
- });
-
- var smokeTestsPolicies = new List();
-
- // ECR Policies
- smokeTestsPolicies.Add(new PolicyStatement(new PolicyStatementProps
- {
- Effect = Effect.ALLOW,
- Actions =
- [
- "ecr:BatchCheckLayerAvailability",
- "ecr:BatchDeleteImage",
- "ecr:BatchGetImage",
- "ecr:CompleteLayerUpload",
- "ecr:CreateRepository",
- "ecr:DescribeRepositories",
- "ecr:GetAuthorizationToken",
- "ecr:GetDownloadUrlForLayer",
- "ecr:InitiateLayerUpload",
- "ecr:PutImage",
- "ecr:UploadLayerPart"
- ],
- Resources =
- [
- $"arn:aws:ecr:{configuration.Region}:{configuration.AccountId}:repository/image-function-tests",
- $"arn:aws:ecr:{configuration.Region}:{configuration.AccountId}:repository/{frameworkConfiguration.EcrRepositoryName}"
- ]
- }));
-
- // The following ECR policy needs to specify * as the resource since that is what is explicitly stated by the following error:
- // An error occurred (AccessDeniedException) when calling the GetAuthorizationToken operation:
- // User: *** is not authorized to perform: ecr:GetAuthorizationToken on resource: * because no identity-based policy
- // allows the ecr:GetAuthorizationToken action
- smokeTestsPolicies.Add(new PolicyStatement(new PolicyStatementProps
- {
- Effect = Effect.ALLOW,
- Actions =
- [
- "ecr:GetAuthorizationToken"
- ],
- Resources = ["*"]
- }));
-
- // IAM Policies
- smokeTestsPolicies.Add(new PolicyStatement(new PolicyStatementProps
- {
- Effect = Effect.ALLOW,
- Actions =
- [
- "iam:PassRole"
- ],
- Resources = [smokeTestsLambdaFunctionRole.RoleArn]
- }));
-
- // Lambda Policies
- smokeTestsPolicies.Add(new PolicyStatement(new PolicyStatementProps
- {
- Effect = Effect.ALLOW,
- Actions =
- [
- "lambda:CreateFunction",
- "lambda:DeleteFunction",
- "lambda:GetFunction",
- "lambda:GetFunctionConfiguration",
- "lambda:InvokeFunction",
- "lambda:UpdateFunctionConfiguration"
- ],
- Resources =
- [
- $"arn:aws:lambda:{configuration.Region}:{configuration.AccountId}:function:image-function-tests-*"
- ]
- }));
-
- foreach (var policy in smokeTestsPolicies)
- amd64SmokeTests.AddToRolePolicy(policy);
-
- var smokeTestsActions = new List();
- smokeTestsActions.Add(new CodeBuildAction(new CodeBuildActionProps
- {
- Input = sourceArtifact,
- Project = amd64SmokeTests,
- ActionName = "amd64"
- }));
-
- if (frameworkConfiguration.HasArm64Image)
- {
- // Smoke test ARM64 image
- var arm64SmokeTests = new Project(this, "SmokeTests-arm64", new ProjectProps
- {
- BuildSpec = BuildSpec.FromSourceFilename($"{Configuration.ProjectRoot}/SmokeTests/buildspec.yml"),
- Description = "Runs smoke tests on the built image.",
- Environment = new BuildEnvironment
- {
- BuildImage = LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_3_0,
- Privileged = true
- },
- Source = Source.GitHub(new GitHubSourceProps
- {
- Owner = gitHubOwner,
- Repo = gitHubRepository,
- BranchOrRef = gitHubBranch
- }),
- EnvironmentVariables = new Dictionary
- {
- {"AWS_LAMBDA_SOURCE_ECR", new BuildEnvironmentVariable {Value = stageEcr}},
- {"AWS_LAMBDA_ECR_REPOSITORY_NAME", new BuildEnvironmentVariable {Value = frameworkConfiguration.EcrRepositoryName}},
- {"AWS_LAMBDA_SOURCE_IMAGE_TAG", new BuildEnvironmentVariable {Value = BaseImageMultiArch}},
- {"AWS_LAMBDA_POWERSHELL_VERSION", new BuildEnvironmentVariable {Value = PowershellVersion}},
- {"AWS_LAMBDA_DOTNET_FRAMEWORK_VERSION", new BuildEnvironmentVariable {Value = frameworkConfiguration.Framework}},
- {"AWS_LAMBDA_DOTNET_FRAMEWORK_CHANNEL", new BuildEnvironmentVariable {Value = frameworkConfiguration.Channel}},
- {"AWS_LAMBDA_DOTNET_BUILD_IMAGE", new BuildEnvironmentVariable {Value = frameworkConfiguration.DockerBuildImage}},
- {"AWS_LAMBDA_DOTNET_SDK_VERSION", new BuildEnvironmentVariable {Value = frameworkConfiguration.SpecificSdkVersion }},
- {"AWS_LAMBDA_SMOKETESTS_LAMBDA_ROLE", new BuildEnvironmentVariable {Value = smokeTestsLambdaFunctionRole.RoleArn}}
- }
- });
-
- foreach (var policy in smokeTestsPolicies)
- arm64SmokeTests.AddToRolePolicy(policy);
-
- smokeTestsActions.Add(new CodeBuildAction(new CodeBuildActionProps
- {
- Input = sourceArtifact,
- Project = arm64SmokeTests,
- ActionName = "arm64"
- }));
- }
-
- pipeline.AddStage(new StageOptions
- {
- StageName = "SmokeTests",
- Actions = smokeTestsActions.ToArray()
- });
-
- // Beta
- if (!string.IsNullOrWhiteSpace(configuration.Ecrs.Beta))
- {
- var betaDockerPush = new Project(this, "Beta-DockerPush", new ProjectProps
- {
- BuildSpec = BuildSpec.FromSourceFilename($"{Configuration.ProjectRoot}/DockerPush/buildspec.yml"),
- Description = $"Pushes staged image to {configuration.Ecrs.Beta}",
- Environment = new BuildEnvironment
- {
- BuildImage = LinuxBuildImage.AMAZON_LINUX_2_5,
- Privileged = true
- },
- Source = Source.GitHub(new GitHubSourceProps
- {
- Owner = gitHubOwner,
- Repo = gitHubRepository,
- BranchOrRef = gitHubBranch
- }),
- EnvironmentVariables = new Dictionary
- {
- {"AWS_LAMBDA_SOURCE_ECR", new BuildEnvironmentVariable {Value = stageEcr}},
- {"AWS_LAMBDA_ECR_REPOSITORY_NAME", new BuildEnvironmentVariable {Value = frameworkConfiguration.EcrRepositoryName}},
- {"AWS_LAMBDA_DESTINATION_ECRS", new BuildEnvironmentVariable {Value = configuration.Ecrs.Beta}},
- {"AWS_LAMBDA_MULTI_ARCH_IMAGE_TAG", new BuildEnvironmentVariable {Value = BaseImageMultiArch}},
- {"AWS_LAMBDA_AMD64_IMAGE_TAG", new BuildEnvironmentVariable {Value = frameworkConfiguration.BaseImageAmd64Tag}},
- {"AWS_LAMBDA_ARM64_IMAGE_TAG", new BuildEnvironmentVariable {Value = frameworkConfiguration.BaseImageArm64Tag}},
- {"AWS_LAMBDA_INCLUDE_ARM64", new BuildEnvironmentVariable {Value = frameworkConfiguration.HasArm64Image.ToString()}},
- }
- });
-
- betaDockerPush.AddToRolePolicy(ecrPolicy);
-
- pipeline.AddStage(new StageOptions
- {
- StageName = "Beta-DockerPush",
- Actions =
- [
- new CodeBuildAction(new CodeBuildActionProps
- {
- Input = sourceArtifact,
- Project = betaDockerPush,
- ActionName = "DockerPush"
- })
- ]
- });
- }
-
- // Prod
- if (!string.IsNullOrWhiteSpace(configuration.Ecrs.Prod))
- {
- // Manual Approval
- pipeline.AddStage(new StageOptions
- {
- StageName = "Prod-ManualApproval",
- Actions =
- [
- new ManualApprovalAction(new ManualApprovalActionProps
- {
- ActionName = "ManualApproval"
- })
- ]
- });
-
- var prodDockerPush = new Project(this, "Prod-DockerPush", new ProjectProps
- {
- BuildSpec = BuildSpec.FromSourceFilename($"{Configuration.ProjectRoot}/DockerPush/buildspec.yml"),
- Description = $"Pushes staged image to {configuration.Ecrs.Prod}",
- Environment = new BuildEnvironment
- {
- BuildImage = LinuxBuildImage.AMAZON_LINUX_2_5,
- Privileged = true
- },
- Source = Source.GitHub(new GitHubSourceProps
- {
- Owner = gitHubOwner,
- Repo = gitHubRepository,
- BranchOrRef = gitHubBranch
- }),
- EnvironmentVariables = new Dictionary
- {
- {"AWS_LAMBDA_SOURCE_ECR", new BuildEnvironmentVariable {Value = stageEcr}},
- {"AWS_LAMBDA_ECR_REPOSITORY_NAME", new BuildEnvironmentVariable {Value = frameworkConfiguration.EcrRepositoryName}},
- {"AWS_LAMBDA_DESTINATION_ECRS", new BuildEnvironmentVariable {Value = configuration.Ecrs.Prod}},
- {"AWS_LAMBDA_MULTI_ARCH_IMAGE_TAG", new BuildEnvironmentVariable {Value = BaseImageMultiArch}},
- {"AWS_LAMBDA_AMD64_IMAGE_TAG", new BuildEnvironmentVariable {Value = frameworkConfiguration.BaseImageAmd64Tag}},
- {"AWS_LAMBDA_ARM64_IMAGE_TAG", new BuildEnvironmentVariable {Value = frameworkConfiguration.BaseImageArm64Tag}},
- {"AWS_LAMBDA_INCLUDE_ARM64", new BuildEnvironmentVariable {Value = frameworkConfiguration.HasArm64Image.ToString()}},
- }
- });
-
- prodDockerPush.AddToRolePolicy(ecrPolicy);
-
- pipeline.AddStage(new StageOptions
- {
- StageName = "Prod-DockerPush",
- Actions =
- [
- new CodeBuildAction(new CodeBuildActionProps
- {
- Input = sourceArtifact,
- Project = prodDockerPush,
- ActionName = "DockerPush"
- })
- ]
- });
- }
- }
-
- private string GetStageEcr(Construct scope, string ecrRepositoryName, Configuration configuration)
- {
- if (string.IsNullOrWhiteSpace(configuration.Ecrs.Stage))
- {
- var repository = new Amazon.CDK.AWS.ECR.Repository(scope, "StageEcr", new Amazon.CDK.AWS.ECR.RepositoryProps
- {
- RepositoryName = ecrRepositoryName
- });
- return GetEcr(repository.RepositoryUri);
- }
-
- return configuration.Ecrs.Stage;
- }
-
- private static string GetEcr(string ecrRepositoryUri)
- {
- return ecrRepositoryUri.Split('/')[0];
- }
-}
diff --git a/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/PipelinesStage.cs b/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/PipelinesStage.cs
deleted file mode 100644
index 49a65b068..000000000
--- a/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/PipelinesStage.cs
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
-// SPDX-License-Identifier: Apache-2.0
-
-using Amazon.CDK;
-using Constructs;
-
-namespace Infrastructure;
-
-internal class PipelinesStage : Stage
-{
- public PipelinesStage(
- Construct scope,
- string id,
- Configuration configuration,
- IStageProps props = null) : base(scope, id, props)
- {
- // Create pipelines for main repository
- CreatePipelinesForRepository(configuration,
- configuration.ProjectName,
- configuration.GitHubOwner,
- configuration.GitHubRepository,
- configuration.GitHubBranch);
-
- // Create pipelines for staging repository
- CreatePipelinesForRepository(configuration,
- $"{configuration.ProjectName}-staging",
- configuration.GitHubOwnerStaging,
- configuration.GitHubRepositoryStaging,
- configuration.GitHubBranchStaging);
- }
-
- private void CreatePipelinesForRepository(
- Configuration configuration,
- string pipelinePrefix,
- string gitHubOwner,
- string gitHubRepository,
- string gitHubBranch)
- {
- for (var i = 0; i < configuration.Frameworks.Length; i++)
- {
-
- var pipelineName = $"{pipelinePrefix}-{configuration.Frameworks[i].Framework}";
-
- new PipelineStack(this,
- $"{pipelinePrefix}-{configuration.Frameworks[i].Framework}",
- configuration,
- configuration.Frameworks[i],
- gitHubOwner,
- gitHubRepository,
- gitHubBranch,
- pipelineName,
- new StackProps
- {
- TerminationProtection = true,
- Env = new Amazon.CDK.Environment
- {
- Account = configuration.AccountId,
- Region = configuration.Region
- }
- }
- );
- }
- }
-}
diff --git a/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/Program.cs b/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/Program.cs
deleted file mode 100644
index 75fe97257..000000000
--- a/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/Program.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-using Amazon.CDK;
-
-namespace Infrastructure;
-
-sealed class Program
-{
- public static void Main(string[] args)
- {
- var configuration = new Configuration();
- var app = new App();
-
- new SelfMutatingPipelineStack(
- app,
- configuration.ProjectName,
- configuration,
- new StackProps
- {
- TerminationProtection = true,
- Env = new Amazon.CDK.Environment
- {
- Account = configuration.AccountId,
- Region = configuration.Region
- }
- }
- );
-
- app.Synth();
- }
-}
diff --git a/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/SelfMutatingPipelineStack.cs b/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/SelfMutatingPipelineStack.cs
deleted file mode 100644
index e3140244a..000000000
--- a/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/SelfMutatingPipelineStack.cs
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
-// SPDX-License-Identifier: Apache-2.0
-
-using System.Collections.Generic;
-using Amazon.CDK;
-using Amazon.CDK.AWS.CodeBuild;
-using Amazon.CDK.AWS.CodePipeline;
-using Amazon.CDK.Pipelines;
-using Constructs;
-
-namespace Infrastructure;
-
-public class SelfMutatingPipelineStack : Stack
-{
- private const string CDK_CLI_VERSION = "2.1018.0";
-
- internal SelfMutatingPipelineStack(
- Construct scope,
- string id,
- Configuration configuration,
- IStackProps props = null) : base(scope, id, props)
- {
- var environmentVariables =
- new Dictionary
- {
- { "AWS_LAMBDA_PIPELINE_ACCOUNT_ID",
- new BuildEnvironmentVariable { Type = BuildEnvironmentVariableType.PLAINTEXT, Value =
- System.Environment.GetEnvironmentVariable("AWS_LAMBDA_PIPELINE_ACCOUNT_ID") ?? string.Empty } },
- { "AWS_LAMBDA_PIPELINE_NAME_SUFFIX",
- new BuildEnvironmentVariable { Type = BuildEnvironmentVariableType.PLAINTEXT, Value =
- System.Environment.GetEnvironmentVariable("AWS_LAMBDA_PIPELINE_NAME_SUFFIX") ?? string.Empty } },
- { "AWS_LAMBDA_PIPELINE_REGION",
- new BuildEnvironmentVariable { Type = BuildEnvironmentVariableType.PLAINTEXT, Value =
- System.Environment.GetEnvironmentVariable("AWS_LAMBDA_PIPELINE_REGION") ?? string.Empty } },
- { "AWS_LAMBDA_GITHUB_TOKEN_SECRET_NAME",
- new BuildEnvironmentVariable { Type = BuildEnvironmentVariableType.PLAINTEXT, Value =
- System.Environment.GetEnvironmentVariable("AWS_LAMBDA_GITHUB_TOKEN_SECRET_NAME") ?? string.Empty } },
- { "AWS_LAMBDA_GITHUB_TOKEN_SECRET_KEY",
- new BuildEnvironmentVariable { Type = BuildEnvironmentVariableType.PLAINTEXT, Value =
- System.Environment.GetEnvironmentVariable("AWS_LAMBDA_GITHUB_TOKEN_SECRET_KEY") ?? string.Empty } },
- { "AWS_LAMBDA_GITHUB_REPO_OWNER",
- new BuildEnvironmentVariable { Type = BuildEnvironmentVariableType.PLAINTEXT, Value =
- System.Environment.GetEnvironmentVariable("AWS_LAMBDA_GITHUB_REPO_OWNER") ?? string.Empty } },
- { "AWS_LAMBDA_GITHUB_REPO_NAME",
- new BuildEnvironmentVariable { Type = BuildEnvironmentVariableType.PLAINTEXT, Value =
- System.Environment.GetEnvironmentVariable("AWS_LAMBDA_GITHUB_REPO_NAME") ?? string.Empty } },
- { "AWS_LAMBDA_GITHUB_REPO_BRANCH",
- new BuildEnvironmentVariable { Type = BuildEnvironmentVariableType.PLAINTEXT, Value =
- System.Environment.GetEnvironmentVariable("AWS_LAMBDA_GITHUB_REPO_BRANCH") ?? string.Empty } },
- { "AWS_LAMBDA_STAGE_ECR",
- new BuildEnvironmentVariable { Type = BuildEnvironmentVariableType.PLAINTEXT, Value =
- System.Environment.GetEnvironmentVariable("AWS_LAMBDA_STAGE_ECR") ?? string.Empty } },
- { "AWS_LAMBDA_BETA_ECRS",
- new BuildEnvironmentVariable { Type = BuildEnvironmentVariableType.PLAINTEXT, Value =
- System.Environment.GetEnvironmentVariable("AWS_LAMBDA_BETA_ECRS") ?? string.Empty } },
- { "AWS_LAMBDA_PROD_ECRS",
- new BuildEnvironmentVariable { Type = BuildEnvironmentVariableType.PLAINTEXT, Value =
- System.Environment.GetEnvironmentVariable("AWS_LAMBDA_PROD_ECRS") ?? string.Empty } },
- { "AWS_LAMBDA_ECR_REPOSITORY_NAME",
- new BuildEnvironmentVariable { Type = BuildEnvironmentVariableType.PLAINTEXT, Value =
- System.Environment.GetEnvironmentVariable("AWS_LAMBDA_ECR_REPOSITORY_NAME") ?? string.Empty } },
- { "AWS_LAMBDA_DOTNET_FRAMEWORK_VERSION",
- new BuildEnvironmentVariable { Type = BuildEnvironmentVariableType.PLAINTEXT, Value =
- System.Environment.GetEnvironmentVariable("AWS_LAMBDA_DOTNET_FRAMEWORK_VERSION") ?? string.Empty } },
- { "AWS_LAMBDA_DOTNET_FRAMEWORK_CHANNEL",
- new BuildEnvironmentVariable { Type = BuildEnvironmentVariableType.PLAINTEXT, Value =
- System.Environment.GetEnvironmentVariable("AWS_LAMBDA_DOTNET_FRAMEWORK_CHANNEL") ?? string.Empty } },
- { "AWS_LAMBDA_GITHUB_REPO_OWNER_STAGING",
- new BuildEnvironmentVariable { Type = BuildEnvironmentVariableType.PLAINTEXT, Value =
- System.Environment.GetEnvironmentVariable("AWS_LAMBDA_GITHUB_REPO_OWNER_STAGING") ?? string.Empty } },
- { "AWS_LAMBDA_GITHUB_REPO_NAME_STAGING",
- new BuildEnvironmentVariable { Type = BuildEnvironmentVariableType.PLAINTEXT, Value =
- System.Environment.GetEnvironmentVariable("AWS_LAMBDA_GITHUB_REPO_NAME_STAGING") ?? string.Empty } },
- { "AWS_LAMBDA_GITHUB_REPO_BRANCH_STAGING",
- new BuildEnvironmentVariable { Type = BuildEnvironmentVariableType.PLAINTEXT, Value =
- System.Environment.GetEnvironmentVariable("AWS_LAMBDA_GITHUB_REPO_BRANCH_STAGING") ?? string.Empty } },
- };
-
- // Self mutation
-
- var pipeline = new CodePipeline(this, "SelfMutatingPipeline", new CodePipelineProps
- {
- PipelineName = id,
- PipelineType = PipelineType.V2,
- // It synthesizes CDK code to cdk.out directory which is picked by SelfMutate stage to mutate the pipeline
- Synth = new ShellStep("Synth", new ShellStepProps
- {
- Input = CodePipelineSource.GitHub(
- $"{configuration.GitHubOwner}/{configuration.GitHubRepository}",
- configuration.GitHubBranch,
- new GitHubSourceOptions
- {
- Authentication = SecretValue.SecretsManager(configuration.GitHubTokenSecretName, new SecretsManagerSecretOptions
- {
- JsonField = configuration.GitHubTokenSecretKey
- })
- }),
- InstallCommands = new[] { $"npm install -g aws-cdk@{CDK_CLI_VERSION}" },
- Commands = new[] { $"dotnet build {Configuration.ProjectRoot}", "cdk synth" }
- }),
- CodeBuildDefaults = new CodeBuildOptions
- {
- BuildEnvironment = new BuildEnvironment
- {
- EnvironmentVariables = environmentVariables
- },
- PartialBuildSpec = BuildSpec.FromObject(new Dictionary
- {
- { "phases", new Dictionary
- {
- { "install", new Dictionary
- {
- { "runtime-versions", new Dictionary
- {
- { "dotnet", "8.x"}
- }
- }
- }
- }
- }
- }
- })
- }
- });
-
- // Add a stage in the pipeline to deploy the Lambda container pipelines
- pipeline.AddStage(new PipelinesStage(this, configuration.ProjectName, configuration));
- }
-}
diff --git a/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/SmokeTests/build.ps1 b/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/SmokeTests/build.ps1
deleted file mode 100644
index 5552be636..000000000
--- a/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/SmokeTests/build.ps1
+++ /dev/null
@@ -1,25 +0,0 @@
-param (
- [Parameter(HelpMessage = "Source ECR containing source docker image.")]
- [string] $SourceEcr,
-
- [Parameter(HelpMessage = "Tag of the source image.")]
- [string] $SourceImageTag,
-
- [Parameter(HelpMessage = "ECR repository name of source docker image.")]
- [string] $EcrRepositoryName,
-
- [Parameter(HelpMessage = "The .NET SDK docker build image.")]
- [string] $DotnetDockerBuildImage,
-
- [Parameter(HelpMessage = "The .NET SDK target framework.")]
- [string] $DotnetTargetFramework
-)
-
-$BASE_IMAGE = "${SourceEcr}/${EcrRepositoryName}:${SourceImageTag}"
-
-& "./LambdaRuntimeDockerfiles/SmokeTests/test/ImageFunction.SmokeTests/build.ps1" -BaseImage $BASE_IMAGE -BuildImage "${DotnetDockerBuildImage}" -TargetFramework "${DotnetTargetFramework}"
-
-if (!$?)
-{
- throw "Smoke tests failed."
-}
\ No newline at end of file
diff --git a/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/SmokeTests/buildspec.yml b/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/SmokeTests/buildspec.yml
deleted file mode 100644
index cd197a2fb..000000000
--- a/LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/SmokeTests/buildspec.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-version: 0.2
-phases:
- pre_build:
- commands:
- # Find and delete the global.json files that were added by CodeBuild. This causes issues when multiple SDKs are installed.
- - find / -type f -name 'global.json' -delete
- - |
- if [ "$AWS_LAMBDA_DOTNET_SDK_VERSION" = "" ]; then
- curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --channel $AWS_LAMBDA_DOTNET_FRAMEWORK_CHANNEL
- else
- curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --version $AWS_LAMBDA_DOTNET_SDK_VERSION
- fi
- - export PATH="$PATH:$HOME/.dotnet"
- - export DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
- - rm -rf /usr/bin/pwsh
- - dotnet tool install --global PowerShell --version $AWS_LAMBDA_POWERSHELL_VERSION
- build:
- commands:
- - pwsh LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/SmokeTests/build.ps1
- -SourceEcr $AWS_LAMBDA_SOURCE_ECR
- -EcrRepositoryName $AWS_LAMBDA_ECR_REPOSITORY_NAME
- -SourceImageTag $AWS_LAMBDA_SOURCE_IMAGE_TAG
- -DotnetDockerBuildImage $AWS_LAMBDA_DOTNET_BUILD_IMAGE
- -DotnetTargetFramework "net${AWS_LAMBDA_DOTNET_FRAMEWORK_CHANNEL}"
diff --git a/LambdaRuntimeDockerfiles/SmokeTests/SmokeTests.sln b/LambdaRuntimeDockerfiles/SmokeTests/SmokeTests.sln
deleted file mode 100644
index 91135e85b..000000000
--- a/LambdaRuntimeDockerfiles/SmokeTests/SmokeTests.sln
+++ /dev/null
@@ -1,39 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.30711.63
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{97D76F0B-452A-40B1-81C8-D4255EB71178}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{F05B9ED2-5A40-4234-8C4E-C5018D3D5438}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImageFunction.SmokeTests", "test\ImageFunction.SmokeTests\ImageFunction.SmokeTests.csproj", "{C71AFDCA-5184-4A64-9FAB-0722BEC37CC5}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImageFunction", "test\ImageFunction\ImageFunction.csproj", "{3944F01D-FCDE-4885-83EC-0C2F4BF7AC67}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {C71AFDCA-5184-4A64-9FAB-0722BEC37CC5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {C71AFDCA-5184-4A64-9FAB-0722BEC37CC5}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {C71AFDCA-5184-4A64-9FAB-0722BEC37CC5}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {C71AFDCA-5184-4A64-9FAB-0722BEC37CC5}.Release|Any CPU.Build.0 = Release|Any CPU
- {3944F01D-FCDE-4885-83EC-0C2F4BF7AC67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {3944F01D-FCDE-4885-83EC-0C2F4BF7AC67}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {3944F01D-FCDE-4885-83EC-0C2F4BF7AC67}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {3944F01D-FCDE-4885-83EC-0C2F4BF7AC67}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(NestedProjects) = preSolution
- {C71AFDCA-5184-4A64-9FAB-0722BEC37CC5} = {F05B9ED2-5A40-4234-8C4E-C5018D3D5438}
- {3944F01D-FCDE-4885-83EC-0C2F4BF7AC67} = {F05B9ED2-5A40-4234-8C4E-C5018D3D5438}
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {D9CCAD4C-C183-4F2B-8CC6-67FC29D5250D}
- EndGlobalSection
-EndGlobal
diff --git a/LambdaRuntimeDockerfiles/SmokeTests/src/AWSSDK.Core.dll b/LambdaRuntimeDockerfiles/SmokeTests/src/AWSSDK.Core.dll
deleted file mode 100755
index 6583601a9..000000000
Binary files a/LambdaRuntimeDockerfiles/SmokeTests/src/AWSSDK.Core.dll and /dev/null differ
diff --git a/LambdaRuntimeDockerfiles/SmokeTests/src/AWSSDK.ECR.dll b/LambdaRuntimeDockerfiles/SmokeTests/src/AWSSDK.ECR.dll
deleted file mode 100755
index dcae6646d..000000000
Binary files a/LambdaRuntimeDockerfiles/SmokeTests/src/AWSSDK.ECR.dll and /dev/null differ
diff --git a/LambdaRuntimeDockerfiles/SmokeTests/src/AWSSDK.IdentityManagement.dll b/LambdaRuntimeDockerfiles/SmokeTests/src/AWSSDK.IdentityManagement.dll
deleted file mode 100755
index 0b0ace3d3..000000000
Binary files a/LambdaRuntimeDockerfiles/SmokeTests/src/AWSSDK.IdentityManagement.dll and /dev/null differ
diff --git a/LambdaRuntimeDockerfiles/SmokeTests/src/AWSSDK.Lambda.dll b/LambdaRuntimeDockerfiles/SmokeTests/src/AWSSDK.Lambda.dll
deleted file mode 100755
index 043ec12e8..000000000
Binary files a/LambdaRuntimeDockerfiles/SmokeTests/src/AWSSDK.Lambda.dll and /dev/null differ
diff --git a/LambdaRuntimeDockerfiles/SmokeTests/test/ImageFunction.SmokeTests/ImageFunction.SmokeTests.csproj b/LambdaRuntimeDockerfiles/SmokeTests/test/ImageFunction.SmokeTests/ImageFunction.SmokeTests.csproj
deleted file mode 100644
index a2ce353a8..000000000
--- a/LambdaRuntimeDockerfiles/SmokeTests/test/ImageFunction.SmokeTests/ImageFunction.SmokeTests.csproj
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
- false
-
-
-
- net8.0
-
-
- net9.0
-
-
- net10.0
-
-
-
-
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
-
-
-
-
diff --git a/LambdaRuntimeDockerfiles/SmokeTests/test/ImageFunction.SmokeTests/ImageFunctionTests.cs b/LambdaRuntimeDockerfiles/SmokeTests/test/ImageFunction.SmokeTests/ImageFunctionTests.cs
deleted file mode 100644
index fcbee64a9..000000000
--- a/LambdaRuntimeDockerfiles/SmokeTests/test/ImageFunction.SmokeTests/ImageFunctionTests.cs
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Net;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using Amazon;
-using Amazon.ECR;
-using Amazon.ECR.Model;
-using Amazon.IdentityManagement;
-using Amazon.IdentityManagement.Model;
-using Amazon.Lambda;
-using Amazon.Lambda.Model;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-using Xunit;
-using Environment = System.Environment;
-
-namespace ImageFunction.SmokeTests
-{
- public class ImageFunctionTests : IDisposable
- {
- private static readonly RegionEndpoint TestRegion = RegionEndpoint.USWest2;
- private readonly AmazonLambdaClient _lambdaClient;
- private readonly AmazonIdentityManagementServiceClient _iamClient;
- private string _executionRoleArn;
-
- private readonly string _functionName;
- private readonly string _imageUri;
- private const string TestIdentifier = "image-function-tests";
- private bool _disposed = false;
-
- public ImageFunctionTests()
- {
- _functionName = $"{TestIdentifier}-{Guid.NewGuid()}";
- var lambdaConfig = new AmazonLambdaConfig()
- {
- RegionEndpoint = TestRegion
- };
- _lambdaClient = new AmazonLambdaClient(lambdaConfig);
- _iamClient = new AmazonIdentityManagementServiceClient(TestRegion);
- _executionRoleArn = Environment.GetEnvironmentVariable("AWS_LAMBDA_SMOKETESTS_LAMBDA_ROLE");
- _imageUri = Environment.GetEnvironmentVariable("AWS_LAMBDA_IMAGE_URI");
-
- Assert.NotNull(_executionRoleArn);
- Assert.NotNull(_imageUri);
-
- SetupAsync().GetAwaiter().GetResult();
- }
-
- [Theory]
- [InlineData("ImageFunction::ImageFunction.Function::ToUpper", "message", "MESSAGE")]
- [InlineData("ImageFunction::ImageFunction.Function::Ping", "ping", "pong")]
- [InlineData("ImageFunction::ImageFunction.Function::HttpsWorksAsync", "", "SUCCESS")]
- [InlineData("ImageFunction::ImageFunction.Function::VerifyLambdaContext", "", "SUCCESS")]
- [InlineData("ImageFunction::ImageFunction.Function::VerifyTzData", "", "SUCCESS")]
- public async Task SuccessfulTests(string handler, string input, string expectedResponse)
- {
- await UpdateHandlerAsync(handler);
-
- var payload = JsonConvert.SerializeObject(input);
- var invokeResponse = await InvokeFunctionAsync(payload);
-
- Assert.True(invokeResponse.HttpStatusCode == HttpStatusCode.OK);
- if(invokeResponse.FunctionError != null)
- {
- throw new Exception($"Lambda function {handler} failed: {invokeResponse.FunctionError}");
- }
-
- await using var responseStream = invokeResponse.Payload;
- using var sr = new StreamReader(responseStream);
- var responseString = JsonConvert.DeserializeObject(await sr.ReadToEndAsync());
- Assert.Equal(expectedResponse, responseString);
- }
-
- [Theory]
- [InlineData("ImageFunction::ImageFunction.Function::ThrowExceptionAsync", "", "Exception", "Exception thrown from an async handler.")]
- [InlineData("ImageFunction::ImageFunction.Function::ThrowException", "", "Exception", "Exception thrown from a synchronous handler.")]
- [InlineData("ImageFunction::ImageFunction.Function::AggregateExceptionNotUnwrappedAsync", "", "AggregateException", "AggregateException thrown from an async handler.")]
- [InlineData("ImageFunction::ImageFunction.Function::AggregateExceptionNotUnwrapped", "", "AggregateException", "AggregateException thrown from a synchronous handler.")]
- [InlineData("ImageFunction::ImageFunction.Function::TooLargeResponseBody", "", "Function.ResponseSizeTooLarge",
- "Response payload size exceeded maximum allowed payload size (6291556 bytes).")]
- public async Task ExceptionTests(string handler, string input, string expectedErrorType, string expectedErrorMessage)
- {
- await UpdateHandlerAsync(handler);
-
- var payload = JsonConvert.SerializeObject(input);
- var invokeResponse = await InvokeFunctionAsync(payload);
- Assert.True(invokeResponse.HttpStatusCode == System.Net.HttpStatusCode.OK);
- Assert.True(invokeResponse.FunctionError != null);
-
- await using var responseStream = invokeResponse.Payload;
- using var sr = new StreamReader(responseStream);
- var exception = (JObject)JsonConvert.DeserializeObject(await sr.ReadToEndAsync());
- Assert.Equal(expectedErrorType, exception["errorType"].ToString());
- Assert.Equal(expectedErrorMessage, exception["errorMessage"].ToString());
- }
-
- ///
- /// This test is checking the logic added to the bootstrap.sh to change the SSL_CERT_FILE
- /// environment variable for AL2023.
- ///
- ///
- ///
- ///
- ///
- [Theory]
-#if NET8_0_OR_GREATER && !NET10_0_OR_GREATER
- [InlineData("SSL_CERT_FILE", "\"/var/runtime/empty-certificates.crt\"", null)]
- [InlineData("SSL_CERT_FILE", "\"/tmp/my-bundle\"", "/tmp/my-bundle")]
-#else
- [InlineData("SSL_CERT_FILE", "\"\"", null)]
- [InlineData("SSL_CERT_FILE", "\"/tmp/my-bundle\"", "/tmp/my-bundle")]
-#endif
- public async Task CheckEnvironmentVariable(string envName, string expectedValue, string setValue)
- {
- var envVariables = new Dictionary();
- if(setValue != null)
- {
- envVariables[envName] = setValue;
- }
-
- await UpdateHandlerAsync("ImageFunction::ImageFunction.Function::GetEnvironmentVariable", envVariables);
-
- var payload = JsonConvert.SerializeObject(envName);
- var invokeResponse = await InvokeFunctionAsync(payload);
-
- Assert.True(invokeResponse.HttpStatusCode == System.Net.HttpStatusCode.OK);
- Assert.True(invokeResponse.FunctionError == null, "Failed invoke with error: " + invokeResponse.FunctionError);
-
- await using var responseStream = invokeResponse.Payload;
- var actualValue = new StreamReader(responseStream).ReadToEnd();
-
- Assert.Equal(expectedValue, actualValue);
- }
-
- private async Task UpdateHandlerAsync(string handler, Dictionary environmentVariables = null)
- {
- var updateFunctionConfigurationRequest = new UpdateFunctionConfigurationRequest
- {
- FunctionName = _functionName,
- ImageConfig = new ImageConfig()
- {
- Command = [handler],
- },
- Environment = new Amazon.Lambda.Model.Environment
- {
- Variables = environmentVariables ?? new Dictionary()
- }
- };
- await _lambdaClient.UpdateFunctionConfigurationAsync(updateFunctionConfigurationRequest);
-
- await WaitUntilHelper.WaitUntil(async () =>
- {
- var getFunctionRequest = new GetFunctionRequest()
- {
- FunctionName = _functionName
- };
- var getFunctionResponse = await _lambdaClient.GetFunctionAsync(getFunctionRequest);
- return getFunctionResponse.Configuration.LastUpdateStatus != LastUpdateStatus.Successful;
- }, TimeSpan.Zero, TimeSpan.FromMinutes(5), CancellationToken.None);
- }
-
- private async Task InvokeFunctionAsync(string payload)
- {
- var request = new InvokeRequest
- {
- FunctionName = _functionName,
- Payload = string.IsNullOrEmpty(payload) ? null : payload
- };
- return await _lambdaClient.InvokeAsync(request);
- }
-
- #region Setup
-
- private async Task SetupAsync()
- {
- await CreateFunctionAsync();
- }
-
- private async Task CreateFunctionAsync()
- {
- var tryCount = 3;
- while (true)
- {
- try
- {
- await _lambdaClient.CreateFunctionAsync(new CreateFunctionRequest
- {
- FunctionName = _functionName,
- Code = new FunctionCode
- {
- ImageUri = _imageUri
- },
- MemorySize = 512,
- Role = _executionRoleArn,
- PackageType = PackageType.Image,
- Timeout = 30,
- Architectures = new List {GetArchitecture()}
- });
- break;
- }
- catch (InvalidParameterValueException)
- {
- tryCount--;
- if (tryCount == 0)
- {
- throw;
- }
-
- // Wait another 5 seconds to let execution role propagate
- await Task.Delay(5000);
- }
- }
-
- var endTime = DateTime.Now.AddSeconds(30);
- var isActive = false;
- while (DateTime.Now < endTime)
- {
- var response = await _lambdaClient.GetFunctionConfigurationAsync(new GetFunctionConfigurationRequest
- {
- FunctionName = _functionName
- });
- if (response.State == State.Active)
- {
- isActive = true;
- break;
- }
-
- await Task.Delay(2000);
- }
-
- if (!isActive)
- {
- throw new Exception($"Timed out trying to create Lambda function {_functionName}");
- }
- }
-
- private static string GetArchitecture()
- {
- switch (RuntimeInformation.ProcessArchitecture)
- {
- case System.Runtime.InteropServices.Architecture.X86:
- case System.Runtime.InteropServices.Architecture.X64:
- return Amazon.Lambda.Architecture.X86_64;
- case System.Runtime.InteropServices.Architecture.Arm:
- case System.Runtime.InteropServices.Architecture.Arm64:
- return Amazon.Lambda.Architecture.Arm64;
- default:
- throw new NotImplementedException(RuntimeInformation.ProcessArchitecture.ToString());
- }
- }
-
- #endregion
-
- #region TearDown
-
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- protected virtual void Dispose(bool disposing)
- {
- if (_disposed)
- {
- return;
- }
-
- // Dispose of managed resources here.
- if (disposing)
- {
- TearDownAsync().GetAwaiter().GetResult();
-
- _lambdaClient?.Dispose();
- _iamClient?.Dispose();
- }
-
- // Dispose of any unmanaged resources not wrapped in safe handles.
- _disposed = true;
- }
-
- private async Task TearDownAsync()
- {
- await DeleteFunctionIfExistsAsync();
- }
-
- private async Task DeleteFunctionIfExistsAsync()
- {
- try
- {
- await _lambdaClient.DeleteFunctionAsync(new DeleteFunctionRequest
- {
- FunctionName = _functionName
- });
- }
- catch (ResourceNotFoundException)
- {
- // No action required
- }
- }
-
- #endregion
- }
-}
\ No newline at end of file
diff --git a/LambdaRuntimeDockerfiles/SmokeTests/test/ImageFunction.SmokeTests/WaitUntilHelper.cs b/LambdaRuntimeDockerfiles/SmokeTests/test/ImageFunction.SmokeTests/WaitUntilHelper.cs
deleted file mode 100644
index 502e09202..000000000
--- a/LambdaRuntimeDockerfiles/SmokeTests/test/ImageFunction.SmokeTests/WaitUntilHelper.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-using System;
-using System.Collections.Generic;
-using System.Threading;
-using System.Threading.Tasks;
-using Xunit;
-
-namespace ImageFunction.SmokeTests
-{
- public static class WaitUntilHelper
- {
- public static async Task WaitUntil(Func> predicate, TimeSpan frequency, TimeSpan timeout, CancellationToken cancellationToken)
- {
- var waitTask = Task.Run(async () =>
- {
- while (await predicate())
- {
- await Task.Delay(frequency, cancellationToken);
- }
- });
-
- if (waitTask != await Task.WhenAny(waitTask, Task.Delay(timeout, cancellationToken)))
- {
- throw new TimeoutException();
- }
- }
- }
-}
\ No newline at end of file
diff --git a/LambdaRuntimeDockerfiles/SmokeTests/test/ImageFunction.SmokeTests/build.ps1 b/LambdaRuntimeDockerfiles/SmokeTests/test/ImageFunction.SmokeTests/build.ps1
deleted file mode 100644
index c542fd2b5..000000000
--- a/LambdaRuntimeDockerfiles/SmokeTests/test/ImageFunction.SmokeTests/build.ps1
+++ /dev/null
@@ -1,95 +0,0 @@
-param (
- [Parameter()]
- [string] $Region = "us-west-2",
-
- [Parameter()]
- [string] $RepositoryName = 'image-function-tests',
-
- [Parameter()]
- [string] $AWSPowerShellVersion = '4.1.5.0',
-
- [Parameter()]
- [bool] $DeleteRepository = $false,
-
- [Parameter()]
- [string] $TargetFramework,
-
- [Parameter()]
- [string] $BaseImage,
-
- [Parameter()]
- [string] $BuildImage
-)
-
-# Check whether the repository exists or not, if not create one
-aws ecr describe-repositories --repository-names ${RepositoryName} --region $Region
-if (!$?) {
- aws ecr create-repository --repository-name ${RepositoryName} --region $Region
-}
-
-# Get AccountId required for building Image URI
-$AccountId = aws sts get-caller-identity --query Account --output text
-
-$Ecr = "$AccountId.dkr.ecr.$Region.amazonaws.com"
-
-# Get login credential and login to docker
-aws ecr get-login-password --region $Region | docker login --username AWS --password-stdin $Ecr
-if (!$?)
-{
- throw "Failed to login in $Ecr"
-}
-
-# Generate a random tag to make sure multiple test runs don't conflict
-$Tag = New-Guid
-$SourceNameTagPair = "${RepositoryName}:latest"
-$DestinationUri = "${Ecr}/${repositoryName}:${Tag}"
-
-# Build and push Docker Image to ECR
-try {
- Write-Host "Building and pushing ImageFunction to $RepositoryName ECR repository"
- Push-Location "$PSScriptRoot\..\ImageFunction"
-
- docker build -t ${SourceNameTagPair} --build-arg BASE_IMAGE=$BaseImage --build-arg BUILD_IMAGE=$BuildImage --build-arg TARGET_FRAMEWORK=$TargetFramework .
-
- docker tag "${SourceNameTagPair}" $DestinationUri
- if (!$?)
- {
- throw "Failed to tag. SourceTag: ${SourceNameTagPair}, TargetTag: ${DestinationUri}"
- }
-
- docker push $DestinationUri
- if (!$?)
- {
- throw "Failed to push at ${DestinationUri}"
- }
-}
-finally {
- Pop-Location
-}
-
-# Set environment variable to be consumed in tests
-$env:AWS_LAMBDA_IMAGE_URI = $DestinationUri
-
-# Run Smoke Tests against pushed Image
-try {
- Write-Host "Running Smoke Tests"
- Push-Location $PSScriptRoot
-
- dotnet test .\ImageFunction.SmokeTests.csproj -v n /p:Framework=$TargetFramework
-
- if (!$?)
- {
- throw "Smoke tests failed."
- }
-}
-finally {
- Pop-Location
-
- # Delete image pushed for testing
- aws ecr batch-delete-image --repository-name $RepositoryName --image-ids imageTag=$Tag
-}
-
-If ($DeleteRepository) {
- Write-Host "Deleting $RepositoryName ECR repository"
- Remove-ECRRepository -RepositoryName $RepositoryName -IgnoreExistingImages $True -Force -Region $Region
-}
\ No newline at end of file
diff --git a/LambdaRuntimeDockerfiles/SmokeTests/test/ImageFunction/Dockerfile b/LambdaRuntimeDockerfiles/SmokeTests/test/ImageFunction/Dockerfile
deleted file mode 100644
index 426c41642..000000000
--- a/LambdaRuntimeDockerfiles/SmokeTests/test/ImageFunction/Dockerfile
+++ /dev/null
@@ -1,22 +0,0 @@
-ARG BASE_IMAGE=aws-lambda-dotnet:local
-ARG BUILD_IMAGE=6.0-bullseye-slim
-ARG TARGET_FRAMEWORK=net6.0
-
-FROM $BASE_IMAGE AS base
-ARG TARGET_FRAMEWORK
-
-FROM mcr.microsoft.com/dotnet/sdk:$BUILD_IMAGE as build
-ARG TARGET_FRAMEWORK
-COPY . /src
-WORKDIR /src
-RUN echo $TARGET_FRAMEWORK
-RUN dotnet build "ImageFunction.csproj" -o /app/build /p:Framework=$TARGET_FRAMEWORK
-
-FROM build AS publish
-ARG TARGET_FRAMEWORK
-RUN echo $TARGET_FRAMEWORK
-RUN dotnet publish "ImageFunction.csproj" -c Release -o /app/publish /p:Framework=$TARGET_FRAMEWORK
-
-FROM base AS final
-WORKDIR /var/task
-COPY --from=publish /app/publish .
diff --git a/LambdaRuntimeDockerfiles/SmokeTests/test/ImageFunction/Function.cs b/LambdaRuntimeDockerfiles/SmokeTests/test/ImageFunction/Function.cs
deleted file mode 100644
index c331b2e7d..000000000
--- a/LambdaRuntimeDockerfiles/SmokeTests/test/ImageFunction/Function.cs
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-using System;
-using System.Net.Http;
-using System.Threading.Tasks;
-
-using Amazon.Lambda.Core;
-
-// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
-[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
-
-namespace ImageFunction
-{
- internal class Function
- {
- private const string FailureResult = "FAILURE";
- private const string SuccessResult = "SUCCESS";
- private const string TestUrl = "https://www.amazon.com";
- private static readonly Lazy SevenMbString = new Lazy(() => new string('X', 1024 * 1024 * 7));
-
- #region Test methods
-
- public string ToUpper(string input, ILambdaContext context)
- {
- return input?.ToUpper();
- }
-
- public string Ping(string input)
- {
- if (input == "ping")
- {
- return "pong";
- }
- else
- {
- throw new Exception($"Expected input: ping but recevied {input}");
- }
- }
-
- public async Task HttpsWorksAsync()
- {
- var isSuccess = false;
-
- using (var httpClient = new HttpClient())
- {
- var response = await httpClient.GetAsync(TestUrl);
- if (response.IsSuccessStatusCode)
- {
- isSuccess = true;
- }
- Console.WriteLine($"Response from HTTP get: {response}");
- }
-
- return GetResponse(isSuccess);
- }
-
- public async Task ThrowExceptionAsync()
- {
- // do something async so this function is compiled as async
- var dummy = await Task.FromResult("xyz");
- throw new Exception("Exception thrown from an async handler.");
- }
-
- public void ThrowException()
- {
- throw new Exception("Exception thrown from a synchronous handler.");
- }
-
- public async Task AggregateExceptionNotUnwrappedAsync()
- {
- // do something async so this function is compiled as async
- var dummy = await Task.FromResult("xyz");
- throw new AggregateException("AggregateException thrown from an async handler.");
- }
-
- public void AggregateExceptionNotUnwrapped()
- {
- throw new AggregateException("AggregateException thrown from a synchronous handler.");
- }
-
- public string TooLargeResponseBody()
- {
- return SevenMbString.Value;
- }
-
- public string VerifyLambdaContext(ILambdaContext lambdaContext)
- {
- AssertNotNull(lambdaContext.AwsRequestId, nameof(lambdaContext.AwsRequestId));
- AssertNotNull(lambdaContext.ClientContext, nameof(lambdaContext.ClientContext));
- AssertNotNull(lambdaContext.FunctionName, nameof(lambdaContext.FunctionName));
- AssertNotNull(lambdaContext.FunctionVersion, nameof(lambdaContext.FunctionVersion));
- AssertNotNull(lambdaContext.Identity, nameof(lambdaContext.Identity));
- AssertNotNull(lambdaContext.InvokedFunctionArn, nameof(lambdaContext.InvokedFunctionArn));
- AssertNotNull(lambdaContext.Logger, nameof(lambdaContext.Logger));
- AssertNotNull(lambdaContext.LogGroupName, nameof(lambdaContext.LogGroupName));
- AssertNotNull(lambdaContext.LogStreamName, nameof(lambdaContext.LogStreamName));
-
- AssertTrue(lambdaContext.MemoryLimitInMB >= 128,
- $"{nameof(lambdaContext.MemoryLimitInMB)}={lambdaContext.MemoryLimitInMB} is not >= 128");
- AssertTrue(lambdaContext.RemainingTime > TimeSpan.Zero,
- $"{nameof(lambdaContext.RemainingTime)}={lambdaContext.RemainingTime} is not >= 0");
-
- return GetResponse(true);
- }
-
- // .NET on Linux uses the tzdata system package to get time zone information.
- // If TzData is not installed/available in the Linux environment the
- // TimeZoneInfo.GetSystemTimeZones() will return an empty collection.
- // For futher information: https://github.com/aws/aws-lambda-dotnet/issues/1620
- public string VerifyTzData(ILambdaContext lambdaContext)
- {
- AssertTrue(TimeZoneInfo.GetSystemTimeZones().Count > 0, "No time zones were found");
- AssertNotNull(TimeZoneInfo.FindSystemTimeZoneById("Europe/London"), "Failed to find Europe/London timezone");
-
- return SuccessResult;
- }
-
- public string GetEnvironmentVariable(string name)
- {
- return Environment.GetEnvironmentVariable(name) ?? string.Empty;
- }
-
- #endregion
-
- #region Private methods
-
- private static string GetResponse(bool isSuccess)
- {
- return $"{(isSuccess ? SuccessResult : FailureResult)}";
- }
-
- private static void AssertNotNull(object value, string valueName)
- {
- if (value == null)
- {
- throw new Exception($"{valueName} cannot be null.");
- }
- }
-
- private static void AssertTrue(bool value, string errorMessage)
- {
- if (!value)
- {
- throw new Exception(errorMessage);
- }
- }
-
- #endregion
- }
-}
diff --git a/LambdaRuntimeDockerfiles/SmokeTests/test/ImageFunction/ImageFunction.csproj b/LambdaRuntimeDockerfiles/SmokeTests/test/ImageFunction/ImageFunction.csproj
deleted file mode 100644
index 9002fda8d..000000000
--- a/LambdaRuntimeDockerfiles/SmokeTests/test/ImageFunction/ImageFunction.csproj
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
- true
- Lambda
- latest
-
-
- net8.0
-
-
- net9.0
-
-
- net10.0
-
-
-
-
-
\ No newline at end of file
diff --git a/Libraries/src/Amazon.Lambda.APIGatewayEvents/Amazon.Lambda.APIGatewayEvents.csproj b/Libraries/src/Amazon.Lambda.APIGatewayEvents/Amazon.Lambda.APIGatewayEvents.csproj
index 6b7ee52d8..b7c2d1739 100644
--- a/Libraries/src/Amazon.Lambda.APIGatewayEvents/Amazon.Lambda.APIGatewayEvents.csproj
+++ b/Libraries/src/Amazon.Lambda.APIGatewayEvents/Amazon.Lambda.APIGatewayEvents.csproj
@@ -1,4 +1,4 @@
-
+
@@ -6,11 +6,18 @@
netstandard2.0;netcoreapp3.1;net8.0
Amazon Lambda .NET Core support - API Gateway package.
Amazon.Lambda.APIGatewayEvents
- 2.7.1
+ 2.7.2
Amazon.Lambda.APIGatewayEvents
Amazon.Lambda.APIGatewayEvents
AWS;Amazon;Lambda
- README.md
+ README.md
+
+
+ false
@@ -18,16 +25,16 @@
-
+
-
- IL2026,IL2067,IL2075
- true
+
+ IL2026,IL2067,IL2075
+ true
true
-
+
diff --git a/Libraries/src/Amazon.Lambda.ApplicationLoadBalancerEvents/Amazon.Lambda.ApplicationLoadBalancerEvents.csproj b/Libraries/src/Amazon.Lambda.ApplicationLoadBalancerEvents/Amazon.Lambda.ApplicationLoadBalancerEvents.csproj
index a67646ea1..15d8e3f1c 100644
--- a/Libraries/src/Amazon.Lambda.ApplicationLoadBalancerEvents/Amazon.Lambda.ApplicationLoadBalancerEvents.csproj
+++ b/Libraries/src/Amazon.Lambda.ApplicationLoadBalancerEvents/Amazon.Lambda.ApplicationLoadBalancerEvents.csproj
@@ -10,11 +10,17 @@
Amazon.Lambda.ApplicationLoadBalancerEvents
Amazon.Lambda.ApplicationLoadBalancerEvents
AWS;Amazon;Lambda
+
+ false
-
- IL2026,IL2067,IL2075
- true
- true
+
+ IL2026,IL2067,IL2075
+ true
+ true
diff --git a/Libraries/src/Amazon.Lambda.AspNetCoreServer.Hosting/Amazon.Lambda.AspNetCoreServer.Hosting.csproj b/Libraries/src/Amazon.Lambda.AspNetCoreServer.Hosting/Amazon.Lambda.AspNetCoreServer.Hosting.csproj
index 89bc352b6..852a70a62 100644
--- a/Libraries/src/Amazon.Lambda.AspNetCoreServer.Hosting/Amazon.Lambda.AspNetCoreServer.Hosting.csproj
+++ b/Libraries/src/Amazon.Lambda.AspNetCoreServer.Hosting/Amazon.Lambda.AspNetCoreServer.Hosting.csproj
@@ -7,10 +7,16 @@
net6.0;net8.0
enable
enable
- 1.9.0
- README.md
+ 1.9.0
+ README.md
Amazon.Lambda.AspNetCoreServer.Hosting
- Amazon.Lambda.AspNetCoreServer.Hosting
+ Amazon.Lambda.AspNetCoreServer.Hosting
+
+ false
IL2104,IL2026,IL2067,IL2075
true
diff --git a/Libraries/src/Amazon.Lambda.AspNetCoreServer/Amazon.Lambda.AspNetCoreServer.csproj b/Libraries/src/Amazon.Lambda.AspNetCoreServer/Amazon.Lambda.AspNetCoreServer.csproj
index 143bdff28..b8ece4445 100644
--- a/Libraries/src/Amazon.Lambda.AspNetCoreServer/Amazon.Lambda.AspNetCoreServer.csproj
+++ b/Libraries/src/Amazon.Lambda.AspNetCoreServer/Amazon.Lambda.AspNetCoreServer.csproj
@@ -13,6 +13,12 @@
Latest
false
README.md
+
+ false
IL2026,IL2067,IL2075,IL2091
true
diff --git a/Libraries/src/Amazon.Lambda.CognitoEvents/Amazon.Lambda.CognitoEvents.csproj b/Libraries/src/Amazon.Lambda.CognitoEvents/Amazon.Lambda.CognitoEvents.csproj
index 2eed29543..f8c17ffe9 100644
--- a/Libraries/src/Amazon.Lambda.CognitoEvents/Amazon.Lambda.CognitoEvents.csproj
+++ b/Libraries/src/Amazon.Lambda.CognitoEvents/Amazon.Lambda.CognitoEvents.csproj
@@ -1,4 +1,4 @@
-
+
@@ -6,7 +6,7 @@
Amazon Lambda .NET Core support - CognitoEvents package.
netstandard2.0;netcoreapp3.1;net8.0
Amazon.Lambda.CognitoEvents
- 4.0.0
+ 4.0.1
Amazon.Lambda.CognitoEvents
Amazon.Lambda.CognitoEvents
AWS;Amazon;Lambda
diff --git a/Libraries/src/Amazon.Lambda.Core/Amazon.Lambda.Core.csproj b/Libraries/src/Amazon.Lambda.Core/Amazon.Lambda.Core.csproj
index 78695601d..7627b7992 100644
--- a/Libraries/src/Amazon.Lambda.Core/Amazon.Lambda.Core.csproj
+++ b/Libraries/src/Amazon.Lambda.Core/Amazon.Lambda.Core.csproj
@@ -6,7 +6,7 @@
netstandard2.0;net6.0;net8.0
Amazon Lambda .NET Core support - Core package.
Amazon.Lambda.Core
- 2.7.1
+ 2.8.0
Amazon.Lambda.Core
Amazon.Lambda.Core
AWS;Amazon;Lambda
@@ -21,6 +21,9 @@
<_Parameter1>Amazon.Lambda.RuntimeSupport.UnitTests, PublicKey="0024000004800000940000000602000000240000525341310004000001000100db5f59f098d27276c7833875a6263a3cc74ab17ba9a9df0b52aedbe7252745db7274d5271fd79c1f08f668ecfa8eaab5626fa76adc811d3c8fc55859b0d09d3bc0a84eecd0ba891f2b8a2fc55141cdcc37c2053d53491e650a479967c3622762977900eddbf1252ed08a2413f00a28f3a0752a81203f03ccb7f684db373518b4"
+
+ <_Parameter1>Amazon.Lambda.Core.Tests, PublicKey="0024000004800000940000000602000000240000525341310004000001000100db5f59f098d27276c7833875a6263a3cc74ab17ba9a9df0b52aedbe7252745db7274d5271fd79c1f08f668ecfa8eaab5626fa76adc811d3c8fc55859b0d09d3bc0a84eecd0ba891f2b8a2fc55141cdcc37c2053d53491e650a479967c3622762977900eddbf1252ed08a2413f00a28f3a0752a81203f03ccb7f684db373518b4"
+
diff --git a/Libraries/src/Amazon.Lambda.Core/Constants.cs b/Libraries/src/Amazon.Lambda.Core/Constants.cs
new file mode 100644
index 000000000..32d2a9417
--- /dev/null
+++ b/Libraries/src/Amazon.Lambda.Core/Constants.cs
@@ -0,0 +1,15 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Amazon.Lambda.Core
+{
+ internal class Constants
+ {
+ internal const string ENV_VAR_AWS_LAMBDA_MAX_CONCURRENCY = "AWS_LAMBDA_MAX_CONCURRENCY";
+ internal const string ENV_VAR_AWS_LAMBDA_TRACE_ID = "_X_AMZN_TRACE_ID";
+ }
+}
diff --git a/Libraries/src/Amazon.Lambda.Core/LambdaTraceProvider.cs b/Libraries/src/Amazon.Lambda.Core/LambdaTraceProvider.cs
new file mode 100644
index 000000000..469bd4513
--- /dev/null
+++ b/Libraries/src/Amazon.Lambda.Core/LambdaTraceProvider.cs
@@ -0,0 +1,48 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+
+using System;
+using System.Threading;
+
+namespace Amazon.Lambda.Core
+{
+ ///
+ /// Provides global access to the current trace id for the current Lambda event invocation.
+ ///
+ public class LambdaTraceProvider
+ {
+ // Use separate backing fields based on if multi-concurrency is being used or not.
+ // This is done because accessing from the AsyncLocal is slower then a backing string field
+ // so only use AsyncLocal when we have to in a multi-concurrency scenario.
+ private static string _traceIdField;
+ private readonly static AsyncLocal _traceIdStorage = new AsyncLocal();
+
+ internal static void SetCurrentTraceId(string traceId)
+ {
+ if (Utils.IsUsingMultiConcurrency)
+ _traceIdStorage.Value = traceId;
+ else
+ _traceIdField = traceId;
+ }
+
+ ///
+ /// The current trace id for the current Lambda event invocation.
+ ///
+ public static string CurrentTraceId
+ {
+ get
+ {
+ if (Utils.IsUsingMultiConcurrency)
+ return _traceIdStorage.Value;
+ else if (_traceIdField != null)
+ return _traceIdField;
+
+ // Fallback to the environment variable if the backing field is not set.
+ // This would happen if the version of Amazon.Lambda.RuntimeSupport being used is out of date
+ // and doesn't call SetCurrentTraceId.
+ return Environment.GetEnvironmentVariable(Constants.ENV_VAR_AWS_LAMBDA_TRACE_ID);
+ }
+ }
+ }
+}
diff --git a/Libraries/src/Amazon.Lambda.Core/Utils.cs b/Libraries/src/Amazon.Lambda.Core/Utils.cs
new file mode 100644
index 000000000..3b7298042
--- /dev/null
+++ b/Libraries/src/Amazon.Lambda.Core/Utils.cs
@@ -0,0 +1,20 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Amazon.Lambda.Core
+{
+ internal static class Utils
+ {
+ internal static bool IsUsingMultiConcurrency
+ {
+ get
+ {
+ return !string.IsNullOrEmpty(Environment.GetEnvironmentVariable(Constants.ENV_VAR_AWS_LAMBDA_MAX_CONCURRENCY));
+ }
+ }
+ }
+}
diff --git a/Libraries/src/Amazon.Lambda.DynamoDBEvents.SDK.Convertor/Amazon.Lambda.DynamoDBEvents.SDK.Convertor.csproj b/Libraries/src/Amazon.Lambda.DynamoDBEvents.SDK.Convertor/Amazon.Lambda.DynamoDBEvents.SDK.Convertor.csproj
index f8bd4433d..1387bfde0 100644
--- a/Libraries/src/Amazon.Lambda.DynamoDBEvents.SDK.Convertor/Amazon.Lambda.DynamoDBEvents.SDK.Convertor.csproj
+++ b/Libraries/src/Amazon.Lambda.DynamoDBEvents.SDK.Convertor/Amazon.Lambda.DynamoDBEvents.SDK.Convertor.csproj
@@ -9,7 +9,7 @@
Amazon.Lambda.DynamoDBEvents.SDK.Convertor
Amazon.Lambda.DynamoDBEvents.SDK.Convertor
AWS;Amazon;Lambda
- 2.0.0
+ 2.0.1
diff --git a/Libraries/src/Amazon.Lambda.DynamoDBEvents.SDK.Convertor/DynamodbAttributeValueConvertor.cs b/Libraries/src/Amazon.Lambda.DynamoDBEvents.SDK.Convertor/DynamodbAttributeValueConvertor.cs
index d32af79bf..f45856edb 100644
--- a/Libraries/src/Amazon.Lambda.DynamoDBEvents.SDK.Convertor/DynamodbAttributeValueConvertor.cs
+++ b/Libraries/src/Amazon.Lambda.DynamoDBEvents.SDK.Convertor/DynamodbAttributeValueConvertor.cs
@@ -21,7 +21,7 @@ public static Amazon.DynamoDBv2.Model.AttributeValue ConvertToSdkAttribute(this
var sdkAttribute = new Amazon.DynamoDBv2.Model.AttributeValue();
// String
- if (!string.IsNullOrEmpty(lambdaAttribute.S))
+ if (lambdaAttribute.S!=null)
sdkAttribute.S = lambdaAttribute.S;
// Number
@@ -112,7 +112,7 @@ public static Amazon.DynamoDBStreams.Model.AttributeValue ConvertToSdkStreamAttr
var sdkAttribute = new Amazon.DynamoDBStreams.Model.AttributeValue();
// String
- if (!string.IsNullOrEmpty(lambdaAttribute.S))
+ if (lambdaAttribute.S != null)
sdkAttribute.S = lambdaAttribute.S;
// Number
diff --git a/Libraries/src/Amazon.Lambda.RuntimeSupport/Amazon.Lambda.RuntimeSupport.csproj b/Libraries/src/Amazon.Lambda.RuntimeSupport/Amazon.Lambda.RuntimeSupport.csproj
index 0d52c2728..b921afb9b 100644
--- a/Libraries/src/Amazon.Lambda.RuntimeSupport/Amazon.Lambda.RuntimeSupport.csproj
+++ b/Libraries/src/Amazon.Lambda.RuntimeSupport/Amazon.Lambda.RuntimeSupport.csproj
@@ -4,7 +4,7 @@
netstandard2.0;net6.0;net8.0;net9.0;net10.0
- 1.13.4
+ 1.14.1
Provides a bootstrap and Lambda Runtime API Client to help you to develop custom .NET Core Lambda Runtimes.
Amazon.Lambda.RuntimeSupport
Amazon.Lambda.RuntimeSupport
@@ -16,6 +16,12 @@
true
NU5048;NU1903;NU1902
9.0
+
+ false
diff --git a/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/Constants.cs b/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/Constants.cs
index e810908c2..5ce238804 100644
--- a/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/Constants.cs
+++ b/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/Constants.cs
@@ -24,6 +24,15 @@ internal class Constants
// variable should never be set when function is deployed to Lambda.
internal const string ENVIRONMENT_VARIABLE_AWS_LAMBDA_DOTNET_DEBUG_RUN_ONCE = "AWS_LAMBDA_DOTNET_DEBUG_RUN_ONCE";
+ // Lambda Environment variable used to check if user has configured the function to run in multi concurrency mode.
+ // To be in multi concurrency mode the environment has to exist and have an int value greater then 1.
+ internal const string ENVIRONMENT_VARIABLE_AWS_LAMBDA_MAX_CONCURRENCY = "AWS_LAMBDA_MAX_CONCURRENCY";
+
+ // .NET Lambda runtime specific environment variable used to override the number of .NET Tasks started
+ // that will reach out to the Lambda Runtime API for new events to process. This environment variable is only
+ // used if AWS_LAMBDA_MAX_CONCURRENCY environment variable is set.
+ internal const string ENVIRONMENT_VARIABLE_AWS_LAMBDA_DOTNET_PROCESSING_TASKS = "AWS_LAMBDA_DOTNET_PROCESSING_TASKS";
+
internal const string ENVIRONMENT_VARIABLE_DISABLE_HEAP_MEMORY_LIMIT = "AWS_LAMBDA_DOTNET_DISABLE_MEMORY_LIMIT_CHECK";
internal const string ENVIRONMENT_VARIABLE_AWS_LAMBDA_DOTNET_PREJIT = "AWS_LAMBDA_DOTNET_PREJIT";
@@ -60,4 +69,4 @@ internal enum AwsLambdaDotNetPreJit
internal const BindingFlags DefaultFlags = BindingFlags.DeclaredOnly | BindingFlags.NonPublic | BindingFlags.Public
| BindingFlags.Instance | BindingFlags.Static;
}
-}
\ No newline at end of file
+}
diff --git a/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/HandlerWrapper.cs b/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/HandlerWrapper.cs
index 3b05f646e..e3a74d04b 100644
--- a/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/HandlerWrapper.cs
+++ b/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/HandlerWrapper.cs
@@ -29,7 +29,7 @@ public class HandlerWrapper : IDisposable
private static readonly InvocationResponse EmptyInvocationResponse =
new InvocationResponse(new MemoryStream(0), false);
- private readonly MemoryStream OutputStream = new MemoryStream();
+ private readonly IOutputStreamFactory _outputStreamFactory;
///
/// The handler that will be called for each event.
@@ -39,9 +39,20 @@ public class HandlerWrapper : IDisposable
private HandlerWrapper(LambdaBootstrapHandler handler)
{
Handler = handler;
+
+ if (Helpers.Utils.IsUsingMultiConcurrency(new SystemEnvironmentVariables()))
+ _outputStreamFactory = new MultiConcurrencyOutputStreamFactory();
+ else
+ _outputStreamFactory = new OnDemandOutputStreamFactory();
}
- private HandlerWrapper() { }
+ private HandlerWrapper()
+ {
+ if (Helpers.Utils.IsUsingMultiConcurrency(new SystemEnvironmentVariables()))
+ _outputStreamFactory = new MultiConcurrencyOutputStreamFactory();
+ else
+ _outputStreamFactory = new OnDemandOutputStreamFactory();
+ }
///
/// Get a HandlerWrapper that will call the given delegate on function invocation.
@@ -54,10 +65,10 @@ public static HandlerWrapper GetHandlerWrapper(Action
{
- handlerWrapper.OutputStream.SetLength(0);
- invokeDelegate(invocation.InputStream, invocation.LambdaContext, handlerWrapper.OutputStream);
- handlerWrapper.OutputStream.Position = 0;
- var response = new InvocationResponse(handlerWrapper.OutputStream, false);
+ var outputStream = handlerWrapper._outputStreamFactory.CreateOutputStream();
+ invokeDelegate(invocation.InputStream, invocation.LambdaContext, outputStream);
+ outputStream.Position = 0;
+ var response = new InvocationResponse(outputStream, false);
return Task.FromResult(response);
};
return handlerWrapper;
@@ -271,10 +282,10 @@ public static HandlerWrapper GetHandlerWrapper(Func> hand
handlerWrapper.Handler = async (invocation) =>
{
TOutput output = await handler();
- handlerWrapper.OutputStream.SetLength(0);
- serializer.Serialize(output, handlerWrapper.OutputStream);
- handlerWrapper.OutputStream.Position = 0;
- return new InvocationResponse(handlerWrapper.OutputStream, false);
+ var outputStream = handlerWrapper._outputStreamFactory.CreateOutputStream();
+ serializer.Serialize(output, outputStream);
+ outputStream.Position = 0;
+ return new InvocationResponse(outputStream, false);
};
return handlerWrapper;
}
@@ -293,10 +304,10 @@ public static HandlerWrapper GetHandlerWrapper(Func
{
TOutput output = await handler(invocation.InputStream);
- handlerWrapper.OutputStream.SetLength(0);
- serializer.Serialize(output, handlerWrapper.OutputStream);
- handlerWrapper.OutputStream.Position = 0;
- return new InvocationResponse(handlerWrapper.OutputStream, false);
+ var outputStream = handlerWrapper._outputStreamFactory.CreateOutputStream();
+ serializer.Serialize(output, outputStream);
+ outputStream.Position = 0;
+ return new InvocationResponse(outputStream, false);
};
return handlerWrapper;
}
@@ -316,10 +327,10 @@ public static HandlerWrapper GetHandlerWrapper(Func(invocation.InputStream);
TOutput output = await handler(input);
- handlerWrapper.OutputStream.SetLength(0);
- serializer.Serialize(output, handlerWrapper.OutputStream);
- handlerWrapper.OutputStream.Position = 0;
- return new InvocationResponse(handlerWrapper.OutputStream, false);
+ var outputStream = handlerWrapper._outputStreamFactory.CreateOutputStream();
+ serializer.Serialize(output, outputStream);
+ outputStream.Position = 0;
+ return new InvocationResponse(outputStream, false);
};
return handlerWrapper;
}
@@ -338,10 +349,10 @@ public static HandlerWrapper GetHandlerWrapper(Func
{
TOutput output = await handler(invocation.LambdaContext);
- handlerWrapper.OutputStream.SetLength(0);
- serializer.Serialize(output, handlerWrapper.OutputStream);
- handlerWrapper.OutputStream.Position = 0; ;
- return new InvocationResponse(handlerWrapper.OutputStream, false);
+ var outputStream = handlerWrapper._outputStreamFactory.CreateOutputStream();
+ serializer.Serialize(output, outputStream);
+ outputStream.Position = 0; ;
+ return new InvocationResponse(outputStream, false);
};
return handlerWrapper;
}
@@ -360,10 +371,10 @@ public static HandlerWrapper GetHandlerWrapper(Func
{
TOutput output = await handler(invocation.InputStream, invocation.LambdaContext);
- handlerWrapper.OutputStream.SetLength(0);
- serializer.Serialize(output, handlerWrapper.OutputStream);
- handlerWrapper.OutputStream.Position = 0;
- return new InvocationResponse(handlerWrapper.OutputStream, false);
+ var outputStream = handlerWrapper._outputStreamFactory.CreateOutputStream();
+ serializer.Serialize(output, outputStream);
+ outputStream.Position = 0;
+ return new InvocationResponse(outputStream, false);
};
return handlerWrapper;
}
@@ -383,10 +394,10 @@ public static HandlerWrapper GetHandlerWrapper(Func(invocation.InputStream);
TOutput output = await handler(input, invocation.LambdaContext);
- handlerWrapper.OutputStream.SetLength(0);
- serializer.Serialize(output, handlerWrapper.OutputStream);
- handlerWrapper.OutputStream.Position = 0;
- return new InvocationResponse(handlerWrapper.OutputStream, false);
+ var outputStream = handlerWrapper._outputStreamFactory.CreateOutputStream();
+ serializer.Serialize(output, outputStream);
+ outputStream.Position = 0;
+ return new InvocationResponse(outputStream, false);
};
return handlerWrapper;
}
@@ -599,10 +610,10 @@ public static HandlerWrapper GetHandlerWrapper(Func handler, I
handlerWrapper.Handler = (invocation) =>
{
TOutput output = handler();
- handlerWrapper.OutputStream.SetLength(0);
- serializer.Serialize(output, handlerWrapper.OutputStream);
- handlerWrapper.OutputStream.Position = 0;
- return Task.FromResult(new InvocationResponse(handlerWrapper.OutputStream, false));
+ var outputStream = handlerWrapper._outputStreamFactory.CreateOutputStream();
+ serializer.Serialize(output, outputStream);
+ outputStream.Position = 0;
+ return Task.FromResult(new InvocationResponse(outputStream, false));
};
return handlerWrapper;
}
@@ -621,10 +632,10 @@ public static HandlerWrapper GetHandlerWrapper(Func ha
handlerWrapper.Handler = (invocation) =>
{
TOutput output = handler(invocation.InputStream);
- handlerWrapper.OutputStream.SetLength(0);
- serializer.Serialize(output, handlerWrapper.OutputStream);
- handlerWrapper.OutputStream.Position = 0;
- return Task.FromResult(new InvocationResponse(handlerWrapper.OutputStream, false));
+ var outputStream = handlerWrapper._outputStreamFactory.CreateOutputStream();
+ serializer.Serialize(output, outputStream);
+ outputStream.Position = 0;
+ return Task.FromResult(new InvocationResponse(outputStream, false));
};
return handlerWrapper;
}
@@ -644,10 +655,10 @@ public static HandlerWrapper GetHandlerWrapper(Func(invocation.InputStream);
TOutput output = handler(input);
- handlerWrapper.OutputStream.SetLength(0);
- serializer.Serialize(output, handlerWrapper.OutputStream);
- handlerWrapper.OutputStream.Position = 0;
- return Task.FromResult(new InvocationResponse(handlerWrapper.OutputStream, false));
+ var outputStream = handlerWrapper._outputStreamFactory.CreateOutputStream();
+ serializer.Serialize(output, outputStream);
+ outputStream.Position = 0;
+ return Task.FromResult(new InvocationResponse(outputStream, false));
};
return handlerWrapper;
}
@@ -666,10 +677,10 @@ public static HandlerWrapper GetHandlerWrapper(Func
{
TOutput output = handler(invocation.LambdaContext);
- handlerWrapper.OutputStream.SetLength(0);
- serializer.Serialize(output, handlerWrapper.OutputStream);
- handlerWrapper.OutputStream.Position = 0; ;
- return Task.FromResult(new InvocationResponse(handlerWrapper.OutputStream, false));
+ var outputStream = handlerWrapper._outputStreamFactory.CreateOutputStream();
+ serializer.Serialize(output, outputStream);
+ outputStream.Position = 0; ;
+ return Task.FromResult(new InvocationResponse(outputStream, false));
};
return handlerWrapper;
}
@@ -688,10 +699,10 @@ public static HandlerWrapper GetHandlerWrapper(Func
{
TOutput output = handler(invocation.InputStream, invocation.LambdaContext);
- handlerWrapper.OutputStream.SetLength(0);
- serializer.Serialize(output, handlerWrapper.OutputStream);
- handlerWrapper.OutputStream.Position = 0;
- return Task.FromResult(new InvocationResponse(handlerWrapper.OutputStream, false));
+ var outputStream = handlerWrapper._outputStreamFactory.CreateOutputStream();
+ serializer.Serialize(output, outputStream);
+ outputStream.Position = 0;
+ return Task.FromResult(new InvocationResponse(outputStream, false));
};
return handlerWrapper;
}
@@ -711,10 +722,10 @@ public static HandlerWrapper GetHandlerWrapper(Func(invocation.InputStream);
TOutput output = handler(input, invocation.LambdaContext);
- handlerWrapper.OutputStream.SetLength(0);
- serializer.Serialize(output, handlerWrapper.OutputStream);
- handlerWrapper.OutputStream.Position = 0;
- return Task.FromResult(new InvocationResponse(handlerWrapper.OutputStream, false));
+ var outputStream = handlerWrapper._outputStreamFactory.CreateOutputStream();
+ serializer.Serialize(output, outputStream);
+ outputStream.Position = 0;
+ return Task.FromResult(new InvocationResponse(outputStream, false));
};
return handlerWrapper;
}
@@ -731,7 +742,7 @@ protected virtual void Dispose(bool disposing)
{
if (disposing)
{
- OutputStream.Dispose();
+ _outputStreamFactory.Dispose();
}
disposedValue = true;
@@ -746,5 +757,65 @@ public void Dispose()
Dispose(true);
}
#endregion
+
+ interface IOutputStreamFactory : IDisposable
+ {
+ MemoryStream CreateOutputStream();
+ }
+
+ ///
+ /// In on demand mode there is never a more then one invocation happening at a time within the process
+ /// so the same memory stream can be reused.
+ ///
+ class OnDemandOutputStreamFactory : IOutputStreamFactory
+ {
+ private readonly MemoryStream OutputStream = new MemoryStream();
+ private bool _disposedValue;
+
+ public MemoryStream CreateOutputStream()
+ {
+ OutputStream.SetLength(0);
+ return OutputStream;
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ if (disposing)
+ {
+ OutputStream.Dispose();
+ }
+
+ _disposedValue = true;
+ }
+ }
+
+ public void Dispose()
+ {
+ // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
+ Dispose(disposing: true);
+ GC.SuppressFinalize(this);
+ }
+ }
+
+ ///
+ /// In multi concurrency mode multiple invocations can happen at the same time within the process
+ /// so we need to make sure each invocation gets its own output stream.
+ ///
+ class MultiConcurrencyOutputStreamFactory : IOutputStreamFactory
+ {
+ public MemoryStream CreateOutputStream()
+ {
+ return new MemoryStream();
+ }
+
+ public void Dispose()
+ {
+ // Technically we are creating MemoryStreams that have a Dispose method but that is inherited from the base
+ // class. A MemoryStream is fully managed and doesn't have anything to dispose so it is okay to not worry
+ // about disposing any of the MemoryStreams created from the CreateOutputStream call.
+ }
+ }
}
}
diff --git a/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/LambdaBootstrap.cs b/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/LambdaBootstrap.cs
index 987349f54..68247f7a8 100644
--- a/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/LambdaBootstrap.cs
+++ b/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/LambdaBootstrap.cs
@@ -14,11 +14,11 @@
*/
using System;
+using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
-using Amazon.Lambda.Core;
using Amazon.Lambda.RuntimeSupport.Bootstrap;
using Amazon.Lambda.RuntimeSupport.Helpers;
@@ -49,15 +49,19 @@ public class LambdaBootstrap : IDisposable
///
private static readonly TimeSpan RuntimeApiHttpTimeout = TimeSpan.FromHours(12);
- private LambdaBootstrapInitializer _initializer;
- private LambdaBootstrapHandler _handler;
- private bool _ownsHttpClient;
- private InternalLogger _logger = InternalLogger.GetDefaultLogger();
+ private readonly LambdaBootstrapInitializer _initializer;
+ private readonly LambdaBootstrapHandler _handler;
+ private readonly bool _ownsHttpClient;
+ private readonly InternalLogger _logger = InternalLogger.GetDefaultLogger();
private readonly HttpClient _httpClient;
- private LambdaBootstrapConfiguration _configuration;
+ private readonly LambdaBootstrapConfiguration _configuration;
+ private readonly Action _awsSdkTraceIdSetter;
+ private readonly IEnvironmentVariables _environmentVariables;
+
internal IRuntimeApiClient Client { get; set; }
+
///
/// Create a LambdaBootstrap that will call the given initializer and handler.
///
@@ -140,7 +144,19 @@ public LambdaBootstrap(HttpClient httpClient, HandlerWrapper handlerWrapper, Lam
///
internal LambdaBootstrap(LambdaBootstrapHandler handler,
LambdaBootstrapInitializer initializer,
- LambdaBootstrapConfiguration configuration) : this(ConstructHttpClient(), handler, initializer, false, configuration)
+ LambdaBootstrapConfiguration configuration) : this(ConstructHttpClient(), handler, initializer, true, configuration)
+ { }
+
+ ///
+ /// Create a LambdaBootstrap that will call the given initializer and handler with custom configuration.
+ ///
+ ///
+ /// Delegate called for each invocation of the Lambda function.
+ /// Delegate called to initialize the Lambda function. If not provided the initialization step is skipped.
+ /// Get configuration to check if Invoke is with Pre JIT or SnapStart enabled
+ ///
+ internal LambdaBootstrap(LambdaBootstrapHandler handler, LambdaBootstrapInitializer initializer, LambdaBootstrapConfiguration configuration, IEnvironmentVariables environmentVariables)
+ : this(ConstructHttpClient(), handler, initializer, true, configuration, environmentVariables: environmentVariables)
{ }
///
@@ -152,15 +168,24 @@ internal LambdaBootstrap(LambdaBootstrapHandler handler,
/// Whether the instance owns the HTTP client and should dispose of it.
/// Get configuration to check if Invoke is with Pre JIT or SnapStart enabled
/// Lambda bootstrap configuration options.
- private LambdaBootstrap(HttpClient httpClient, LambdaBootstrapHandler handler, LambdaBootstrapInitializer initializer, bool ownsHttpClient, LambdaBootstrapConfiguration configuration = null, LambdaBootstrapOptions lambdaBootstrapOptions = null)
+ ///
+ internal LambdaBootstrap(HttpClient httpClient, LambdaBootstrapHandler handler, LambdaBootstrapInitializer initializer, bool ownsHttpClient, LambdaBootstrapConfiguration configuration = null, LambdaBootstrapOptions lambdaBootstrapOptions = null, IEnvironmentVariables environmentVariables = null)
{
+ if (ownsHttpClient && httpClient == null)
+ {
+ httpClient = ConstructHttpClient();
+ }
+
_httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
_handler = handler ?? throw new ArgumentNullException(nameof(handler));
_ownsHttpClient = ownsHttpClient;
_initializer = initializer;
_httpClient.Timeout = RuntimeApiHttpTimeout;
- Client = new RuntimeApiClient(new SystemEnvironmentVariables(), _httpClient, lambdaBootstrapOptions);
- _configuration = configuration ?? LambdaBootstrapConfiguration.GetDefaultConfiguration();
+ _environmentVariables = environmentVariables ?? new SystemEnvironmentVariables();
+ Client = new RuntimeApiClient(_environmentVariables, _httpClient, lambdaBootstrapOptions);
+ _configuration = configuration ?? LambdaBootstrapConfiguration.GetDefaultConfiguration(_environmentVariables);
+
+ _awsSdkTraceIdSetter = Utils.FindAWSSDKTraceIdSetter(_environmentVariables);
}
///
@@ -183,7 +208,7 @@ private LambdaBootstrap(HttpClient httpClient, LambdaBootstrapHandler handler, L
if (_configuration.IsCallPreJit)
{
_logger.LogInformation("PreJit: CultureInfo");
- UserCodeInit.LoadStringCultureInfo();
+ UserCodeInit.LoadStringCultureInfo(_environmentVariables);
_logger.LogInformation("PreJit: Amazon.Lambda.Core");
UserCodeInit.PreJitAssembly(typeof(Amazon.Lambda.Core.ILambdaContext).Assembly);
@@ -192,7 +217,7 @@ private LambdaBootstrap(HttpClient httpClient, LambdaBootstrapHandler handler, L
// For local debugging purposes this environment variable can be set to run a Lambda executable assembly and process one event
// and then shut down cleanly. Useful for profiling or running local tests with the .NET Lambda Test Tool. This environment
// variable should never be set when function is deployed to Lambda.
- var runOnce = string.Equals(Environment.GetEnvironmentVariable(Constants.ENVIRONMENT_VARIABLE_AWS_LAMBDA_DOTNET_DEBUG_RUN_ONCE), "true", StringComparison.OrdinalIgnoreCase);
+ var runOnce = string.Equals(_environmentVariables.GetEnvironmentVariable(Constants.ENVIRONMENT_VARIABLE_AWS_LAMBDA_DOTNET_DEBUG_RUN_ONCE), "true", StringComparison.OrdinalIgnoreCase);
if (_initializer != null && !(await InitializeAsync()))
@@ -227,12 +252,33 @@ private LambdaBootstrap(HttpClient httpClient, LambdaBootstrapHandler handler, L
}
#endif
+ var processingTasksCount = Utils.DetermineProcessingTaskCount(_environmentVariables, Environment.ProcessorCount);
+ _logger.LogInformation($"Using {processingTasksCount} tasks for invoke processing loops");
+
+ if (processingTasksCount == 1)
+ {
+ await ProcessingLoop(runOnce, cancellationToken);
+ }
+ else
+ {
+ var tasks = new List();
+ for (int i = 0; i < processingTasksCount; i++)
+ {
+ tasks.Add(ProcessingLoop(runOnce, cancellationToken));
+ }
+
+ await Task.WhenAll(tasks);
+ }
+ }
+
+ private async Task ProcessingLoop(bool runOnce, CancellationToken cancellationToken)
+ {
while (!cancellationToken.IsCancellationRequested)
{
try
{
await InvokeOnceAsync(cancellationToken);
- if(runOnce)
+ if (runOnce)
{
_logger.LogInformation("Exiting Lambda processing loop because the run once environment variable was set.");
return;
@@ -240,7 +286,28 @@ private LambdaBootstrap(HttpClient httpClient, LambdaBootstrapHandler handler, L
}
catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
{
- // Loop cancelled
+ // The user starting RuntimeSupport has request to end processing. This would really only be
+ // for testing scenarios.
+ return;
+ }
+ catch (OperationCanceledException)
+ {
+ // There was a timeout waiting for the next invocation. In that case the poller should attempt again.
+ continue;
+ }
+ catch (Exception ex)
+ {
+ // Only capture and continue for multi concurrency because we do not want to change
+ // the existing behavior for on demand mode.
+ if (Utils.IsUsingMultiConcurrency(_environmentVariables))
+ {
+ // In multi concurrency mode we want to avoid one processing task having an issue and
+ // taking down the whole process. Log the error and continue.
+ _logger.LogError(ex, "Unknown error running Lambda processing loop, continuing.");
+ continue;
+ }
+
+ throw;
}
}
}
@@ -268,45 +335,120 @@ internal async Task InitializeAsync()
internal async Task InvokeOnceAsync(CancellationToken cancellationToken = default)
{
_logger.LogInformation("Starting InvokeOnceAsync");
- using (var invocation = await Client.GetNextInvocationAsync(cancellationToken))
- {
- InvocationResponse response = null;
- bool invokeSucceeded = false;
- try
- {
- _logger.LogInformation("Starting invoking handler");
- response = await _handler(invocation);
- invokeSucceeded = true;
- }
- catch (Exception exception)
- {
- WriteUnhandledExceptionToLog(exception);
- await Client.ReportInvocationErrorAsync(invocation.LambdaContext.AwsRequestId, exception);
- }
- finally
+ var invocation = await Client.GetNextInvocationAsync(cancellationToken);
+
+ Func processingFunc = async () =>
+ {
+ if (invocation.LambdaContext is LambdaContext impl)
{
- _logger.LogInformation("Finished invoking handler");
+ Client.ConsoleLogger.SetRuntimeHeaders(impl.RuntimeApiHeaders);
+ SetInvocationTraceId(impl.RuntimeApiHeaders.TraceId);
}
- if (invokeSucceeded)
+ try
{
- _logger.LogInformation("Starting sending response");
+ InvocationResponse response = null;
+ bool invokeSucceeded = false;
+
try
{
- await Client.SendResponseAsync(invocation.LambdaContext.AwsRequestId, response?.OutputStream);
+ _logger.LogInformation("Starting invoking handler");
+ response = await _handler(invocation);
+ invokeSucceeded = true;
+ }
+ catch (Exception exception)
+ {
+ WriteUnhandledExceptionToLog(exception);
+ await Client.ReportInvocationErrorAsync(invocation.LambdaContext.AwsRequestId, exception, cancellationToken);
}
finally
{
- if (response != null && response.DisposeOutputStream)
+ _logger.LogInformation("Finished invoking handler");
+ }
+
+ if (invokeSucceeded)
+ {
+ _logger.LogInformation("Starting sending response");
+ try
+ {
+ await Client.SendResponseAsync(invocation.LambdaContext.AwsRequestId, response?.OutputStream, cancellationToken);
+ }
+ finally
{
- response.OutputStream?.Dispose();
+ if (response != null && response.DisposeOutputStream)
+ {
+ response.OutputStream?.Dispose();
+ }
+
+ _logger.LogInformation("Finished sending response");
}
+ }
- _logger.LogInformation("Finished sending response");
+ _logger.LogInformation("Finished InvokeOnceAsync");
+ }
+ catch(Exception ex)
+ {
+ // Only capture and continue for multi concurrency because we do not want to change
+ // the existing behavior for on demand mode.
+ if (Utils.IsUsingMultiConcurrency(_environmentVariables))
+ {
+ // In multi concurrency mode we want to avoid one processing task having an issue and
+ // taking down the whole process. Log the error and continue.
+ _logger.LogError(ex, "Unknown error running Lambda processing loop, continuing.");
+ return;
}
+
+ throw;
+ }
+ finally
+ {
+ invocation.Dispose();
+ }
+ };
+
+ // In multi concurrency mode we always need to block on the GetNextInvocationAsync call getting the next event but
+ // return back to the caller as soon as we start processing the event. That way another event
+ // can be looked for from the runtime API allowing the events to run concurrently.
+ if (Utils.IsUsingMultiConcurrency(_environmentVariables))
+ {
+ _ = Task.Run(processingFunc, cancellationToken);
+ }
+ else
+ {
+ // This is the default Lambda runtime mode blocking till the event has been
+ // fully processed and then another event will be asked for.
+ await processingFunc();
+ }
+ }
+
+ volatile bool _disableTraceProvider = false;
+ private void SetInvocationTraceId(string traceId)
+ {
+ // In an on demand mode where only one invocation is processed at a time
+ // it is safe to set the environment per request.
+ if (!Utils.IsUsingMultiConcurrency(_environmentVariables))
+ {
+ _environmentVariables.SetEnvironmentVariable(LambdaEnvironment.EnvVarTraceId, traceId);
+ }
+
+ // Save the trace id in the AWS SDK for .NET
+ _awsSdkTraceIdSetter?.Invoke(traceId);
+
+ if (!_disableTraceProvider)
+ {
+ try
+ {
+ TraceProviderIsolated.SetCurrentTraceId(traceId);
+ }
+ catch (TypeLoadException)
+ {
+ // Disable attempting to set trace id in the future. If we got a TypeLoadException then setting the
+ // trace id will never work in the future. Avoid triggering exceptions for every invocation.
+ _disableTraceProvider = true;
+ _logger.LogInformation("Failed to set the trace id on Amazon.Lambda.Core.LambdaTraceProvider due to the version of " +
+ "Amazon.Lambda.Core being provided by Lambda Function being out of date.");
}
- _logger.LogInformation("Finished InvokeOnceAsync");
}
}
@@ -332,7 +474,7 @@ public static HttpClient ConstructHttpClient()
};
// If we are running in an AOT environment, mark it as such.
- var userAgentString = NativeAotHelper.IsRunningNativeAot() ? $"aws-lambda-dotnet/{dotnetRuntimeVersion}-{amazonLambdaRuntimeSupport}-aot"
+ var userAgentString = Utils.IsRunningNativeAot() ? $"aws-lambda-dotnet/{dotnetRuntimeVersion}-{amazonLambdaRuntimeSupport}-aot"
: $"aws-lambda-dotnet/{dotnetRuntimeVersion}-{amazonLambdaRuntimeSupport}";
var client = new HttpClient(handler);
@@ -370,13 +512,13 @@ private void AdjustMemorySettings()
// the heap memory limit to match the Lambda configured environment. This can be useful for situations
// where the Lambda environment is being emulated for testing and more then just single Lambda function
// is running in the process. For example running a test runner over a series of Lambda emulated invocations.
- var value = Environment.GetEnvironmentVariable(Constants.ENVIRONMENT_VARIABLE_DISABLE_HEAP_MEMORY_LIMIT);
+ var value = _environmentVariables.GetEnvironmentVariable(Constants.ENVIRONMENT_VARIABLE_DISABLE_HEAP_MEMORY_LIMIT);
if (string.Equals(value, "true", StringComparison.OrdinalIgnoreCase))
return;
int lambdaMemoryInMb;
- if (!int.TryParse(Environment.GetEnvironmentVariable(LambdaEnvironment.EnvVarFunctionMemorySize), out lambdaMemoryInMb))
+ if (!int.TryParse(_environmentVariables.GetEnvironmentVariable(LambdaEnvironment.EnvVarFunctionMemorySize), out lambdaMemoryInMb))
return;
ulong memoryInBytes = (ulong)lambdaMemoryInMb * LambdaEnvironment.OneMegabyte;
diff --git a/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/UserCodeInit.cs b/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/UserCodeInit.cs
index 9ef8e0e8d..b59ba67f5 100644
--- a/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/UserCodeInit.cs
+++ b/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/UserCodeInit.cs
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
@@ -29,19 +29,19 @@ namespace Amazon.Lambda.RuntimeSupport.Bootstrap
{
internal class UserCodeInit
{
- public static bool IsCallPreJit()
+ public static bool IsCallPreJit(IEnvironmentVariables environmentVariables)
{
#if NET6_0_OR_GREATER
// If we are running in an AOT environment, there is no point in doing any prejit optmization
// and will most likely cause errors using APIs that are not supported in AOT.
- if(NativeAotHelper.IsRunningNativeAot())
+ if(Utils.IsRunningNativeAot())
{
return false;
}
#endif
- string awsLambdaDotNetPreJitStr = Environment.GetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_DOTNET_PREJIT);
- string awsLambdaInitTypeStr = Environment.GetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_INITIALIZATION_TYPE);
+ string awsLambdaDotNetPreJitStr = environmentVariables.GetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_DOTNET_PREJIT);
+ string awsLambdaInitTypeStr = environmentVariables.GetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_INITIALIZATION_TYPE);
AwsLambdaDotNetPreJit awsLambdaDotNetPreJit;
bool isParsed = Enum.TryParse(awsLambdaDotNetPreJitStr, true, out awsLambdaDotNetPreJit);
if (!isParsed)
@@ -110,11 +110,11 @@ public static void InitSerializationAssembly(Expression outputExpression, Parame
}
}
- public static void LoadStringCultureInfo()
+ public static void LoadStringCultureInfo(IEnvironmentVariables environmentVariables)
{
try
{
- string locale = Environment.GetEnvironmentVariable(ENVIRONMENT_VARIABLE_LANG);
+ string locale = environmentVariables.GetEnvironmentVariable(ENVIRONMENT_VARIABLE_LANG);
if (!string.IsNullOrEmpty(locale))
{
@@ -205,4 +205,4 @@ void LoadReferencedAssemblies(Assembly assembly)
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/UserCodeLoader.cs b/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/UserCodeLoader.cs
index f20dfe7af..340648405 100644
--- a/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/UserCodeLoader.cs
+++ b/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/UserCodeLoader.cs
@@ -40,6 +40,7 @@ internal class UserCodeLoader
internal const string LambdaCoreAssemblyName = "Amazon.Lambda.Core";
+ private readonly IEnvironmentVariables _environmentVariables;
private readonly InternalLogger _logger;
private readonly string _handlerString;
private bool _customerLoggerSetUpComplete;
@@ -50,15 +51,18 @@ internal class UserCodeLoader
///
/// Initializes UserCodeLoader with a given handler and internal logger.
///
+ ///
///
///
- public UserCodeLoader(string handler, InternalLogger logger)
+ public UserCodeLoader(IEnvironmentVariables environmentVariables, string handler, InternalLogger logger)
{
if (string.IsNullOrEmpty(handler))
{
throw new ArgumentNullException(nameof(handler));
}
+ _environmentVariables = environmentVariables;
+
_logger = logger;
_handlerString = handler;
}
@@ -129,7 +133,7 @@ public void Init(Action customerLoggingAction)
var customerSerializerInstance = GetSerializerObject(customerAssembly);
_logger.LogDebug($"UCL : Constructing invoke delegate");
- var isPreJit = UserCodeInit.IsCallPreJit();
+ var isPreJit = UserCodeInit.IsCallPreJit(_environmentVariables);
var builder = new InvokeDelegateBuilder(_logger, _handler, CustomerMethodInfo);
_invokeDelegate = builder.ConstructInvokeDelegate(customerObject, customerSerializerInstance, isPreJit);
if (isPreJit)
diff --git a/Libraries/src/Amazon.Lambda.RuntimeSupport/Client/RuntimeApiClient.cs b/Libraries/src/Amazon.Lambda.RuntimeSupport/Client/RuntimeApiClient.cs
index aef6a5bbd..daa9fff24 100644
--- a/Libraries/src/Amazon.Lambda.RuntimeSupport/Client/RuntimeApiClient.cs
+++ b/Libraries/src/Amazon.Lambda.RuntimeSupport/Client/RuntimeApiClient.cs
@@ -32,9 +32,9 @@ public class RuntimeApiClient : IRuntimeApiClient
private readonly IInternalRuntimeApiClient _internalClient;
#if NET6_0_OR_GREATER
- private readonly IConsoleLoggerWriter _consoleLoggerRedirector = new LogLevelLoggerWriter();
+ private readonly IConsoleLoggerWriter _consoleLoggerRedirector;
#else
- private readonly IConsoleLoggerWriter _consoleLoggerRedirector = new SimpleLoggerWriter();
+ private readonly IConsoleLoggerWriter _consoleLoggerRedirector;
#endif
internal Func ExceptionConverter { get; set; }
@@ -54,6 +54,12 @@ public RuntimeApiClient(HttpClient httpClient)
internal RuntimeApiClient(IEnvironmentVariables environmentVariables, HttpClient httpClient, LambdaBootstrapOptions lambdaBootstrapOptions = null)
{
+#if NET6_0_OR_GREATER
+ _consoleLoggerRedirector = new LogLevelLoggerWriter(environmentVariables);
+#else
+ _consoleLoggerRedirector = new SimpleLoggerWriter(environmentVariables);
+#endif
+
ExceptionConverter = ExceptionInfo.GetExceptionInfo;
_httpClient = httpClient;
LambdaEnvironment = new LambdaEnvironment(environmentVariables, lambdaBootstrapOptions);
@@ -110,13 +116,11 @@ public async Task GetNextInvocationAsync(CancellationToken ca
SwaggerResponse response = await _internalClient.NextAsync(cancellationToken);
var headers = new RuntimeApiHeaders(response.Headers);
- _consoleLoggerRedirector.SetRuntimeHeaders(headers);
-
var lambdaContext = new LambdaContext(headers, LambdaEnvironment, _consoleLoggerRedirector);
return new InvocationRequest
{
InputStream = response.Result,
- LambdaContext = lambdaContext,
+ LambdaContext = lambdaContext
};
}
diff --git a/Libraries/src/Amazon.Lambda.RuntimeSupport/Context/IEnvironmentVariables.cs b/Libraries/src/Amazon.Lambda.RuntimeSupport/Context/IEnvironmentVariables.cs
index 4d97576d1..f22517854 100644
--- a/Libraries/src/Amazon.Lambda.RuntimeSupport/Context/IEnvironmentVariables.cs
+++ b/Libraries/src/Amazon.Lambda.RuntimeSupport/Context/IEnvironmentVariables.cs
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
@@ -20,10 +20,26 @@ namespace Amazon.Lambda.RuntimeSupport
/// Interface to access environment variables.
/// Allows for unit testing without changing the real System environment variables.
///
- internal interface IEnvironmentVariables
+ public interface IEnvironmentVariables
{
+ ///
+ /// Sets the value for an environment variable.
+ ///
+ ///
+ ///
void SetEnvironmentVariable(string variable, string value);
+
+ ///
+ /// Get the value for an environment variable.
+ ///
+ ///
+ ///
string GetEnvironmentVariable(string variable);
+
+ ///
+ /// Get all environment variables.
+ ///
+ ///
IDictionary GetEnvironmentVariables();
}
}
diff --git a/Libraries/src/Amazon.Lambda.RuntimeSupport/Context/LambdaBootstrapConfiguration.cs b/Libraries/src/Amazon.Lambda.RuntimeSupport/Context/LambdaBootstrapConfiguration.cs
index c76588bc3..96e913312 100644
--- a/Libraries/src/Amazon.Lambda.RuntimeSupport/Context/LambdaBootstrapConfiguration.cs
+++ b/Libraries/src/Amazon.Lambda.RuntimeSupport/Context/LambdaBootstrapConfiguration.cs
@@ -18,13 +18,13 @@ internal LambdaBootstrapConfiguration(bool isCallPreJit, bool isInitTypeSnapstar
IsInitTypeSnapstart = isInitTypeSnapstart;
}
- internal static LambdaBootstrapConfiguration GetDefaultConfiguration()
+ internal static LambdaBootstrapConfiguration GetDefaultConfiguration(IEnvironmentVariables environmentVariables)
{
- bool isCallPreJit = UserCodeInit.IsCallPreJit();
+ bool isCallPreJit = UserCodeInit.IsCallPreJit(environmentVariables);
#if NET8_0_OR_GREATER
bool isInitTypeSnapstart =
string.Equals(
- Environment.GetEnvironmentVariable(Constants.ENVIRONMENT_VARIABLE_AWS_LAMBDA_INITIALIZATION_TYPE),
+ environmentVariables.GetEnvironmentVariable(Constants.ENVIRONMENT_VARIABLE_AWS_LAMBDA_INITIALIZATION_TYPE),
Constants.AWS_LAMBDA_INITIALIZATION_TYPE_SNAP_START);
return new LambdaBootstrapConfiguration(isCallPreJit, isInitTypeSnapstart);
diff --git a/Libraries/src/Amazon.Lambda.RuntimeSupport/Context/LambdaContext.cs b/Libraries/src/Amazon.Lambda.RuntimeSupport/Context/LambdaContext.cs
index 516b681f1..cca6f4e5d 100644
--- a/Libraries/src/Amazon.Lambda.RuntimeSupport/Context/LambdaContext.cs
+++ b/Libraries/src/Amazon.Lambda.RuntimeSupport/Context/LambdaContext.cs
@@ -23,14 +23,14 @@ internal class LambdaContext : ILambdaContext
{
internal static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
- private LambdaEnvironment _lambdaEnvironment;
- private RuntimeApiHeaders _runtimeApiHeaders;
- private IDateTimeHelper _dateTimeHelper;
- private long _deadlineMs;
- private int _memoryLimitInMB;
+ private readonly LambdaEnvironment _lambdaEnvironment;
+ private readonly RuntimeApiHeaders _runtimeApiHeaders;
+ private readonly IDateTimeHelper _dateTimeHelper;
+ private readonly long _deadlineMs;
+ private readonly int _memoryLimitInMB;
private readonly Lazy _cognitoIdentityLazy;
private readonly Lazy _cognitoClientContextLazy;
- private IConsoleLoggerWriter _consoleLogger;
+ private readonly IConsoleLoggerWriter _consoleLogger;
public LambdaContext(RuntimeApiHeaders runtimeApiHeaders, LambdaEnvironment lambdaEnvironment, IConsoleLoggerWriter consoleLogger)
: this(runtimeApiHeaders, lambdaEnvironment, new DateTimeHelper(), consoleLogger)
@@ -49,9 +49,6 @@ public LambdaContext(RuntimeApiHeaders runtimeApiHeaders, LambdaEnvironment lamb
long.TryParse(_runtimeApiHeaders.DeadlineMs, out _deadlineMs);
_cognitoIdentityLazy = new Lazy(() => CognitoIdentity.FromJson(runtimeApiHeaders.CognitoIdentityJson));
_cognitoClientContextLazy = new Lazy(() => CognitoClientContext.FromJson(runtimeApiHeaders.ClientContextJson));
-
- // set environment variable so that if the function uses the XRay client it will work correctly
- _lambdaEnvironment.SetXAmznTraceId(_runtimeApiHeaders.TraceId);
}
public string TraceId => _runtimeApiHeaders.TraceId;
@@ -79,5 +76,7 @@ public LambdaContext(RuntimeApiHeaders runtimeApiHeaders, LambdaEnvironment lamb
public TimeSpan RemainingTime => TimeSpan.FromMilliseconds(_deadlineMs - (_dateTimeHelper.UtcNow - UnixEpoch).TotalMilliseconds);
public string TenantId => _runtimeApiHeaders.TenantId;
+
+ internal IRuntimeApiHeaders RuntimeApiHeaders => _runtimeApiHeaders;
}
}
diff --git a/Libraries/src/Amazon.Lambda.RuntimeSupport/Context/LambdaEnvironment.cs b/Libraries/src/Amazon.Lambda.RuntimeSupport/Context/LambdaEnvironment.cs
index ffa553cc7..68e2a70a3 100644
--- a/Libraries/src/Amazon.Lambda.RuntimeSupport/Context/LambdaEnvironment.cs
+++ b/Libraries/src/Amazon.Lambda.RuntimeSupport/Context/LambdaEnvironment.cs
@@ -81,11 +81,6 @@ private void SetExecutionEnvironment()
}
}
- internal void SetXAmznTraceId(string xAmznTraceId)
- {
- _environmentVariables.SetEnvironmentVariable(EnvVarTraceId, xAmznTraceId);
- }
-
///
/// Gets the FunctionMemorySize
///
diff --git a/Libraries/src/Amazon.Lambda.RuntimeSupport/Helpers/ConsoleLoggerWriter.cs b/Libraries/src/Amazon.Lambda.RuntimeSupport/Helpers/ConsoleLoggerWriter.cs
index d57d3e306..2caa708e3 100644
--- a/Libraries/src/Amazon.Lambda.RuntimeSupport/Helpers/ConsoleLoggerWriter.cs
+++ b/Libraries/src/Amazon.Lambda.RuntimeSupport/Helpers/ConsoleLoggerWriter.cs
@@ -73,16 +73,16 @@ public class SimpleLoggerWriter : IConsoleLoggerWriter
///
/// Default Constructor
///
- public SimpleLoggerWriter()
+ public SimpleLoggerWriter(IEnvironmentVariables environmentVariables)
{
// Look to see if Lambda's telemetry log file descriptor is available. If so use that for logging.
// This will make sure multiline log messages use a single CloudWatch Logs record.
- var fileDescriptorLogId = Environment.GetEnvironmentVariable(Constants.ENVIRONMENT_VARIABLE_TELEMETRY_LOG_FD);
+ var fileDescriptorLogId = environmentVariables.GetEnvironmentVariable(Constants.ENVIRONMENT_VARIABLE_TELEMETRY_LOG_FD);
if (fileDescriptorLogId != null)
{
try
{
- _writer = FileDescriptorLogFactory.GetWriter(fileDescriptorLogId);
+ _writer = FileDescriptorLogFactory.GetWriter(environmentVariables, fileDescriptorLogId);
InternalLogger.GetDefaultLogger().LogInformation("Using file descriptor stream writer for logging");
}
catch (Exception ex)
@@ -170,6 +170,7 @@ public enum LogLevel
Critical = 5
}
+ readonly IEnvironmentVariables _environmentVariables;
WrapperTextWriter _wrappedStdOutWriter;
WrapperTextWriter _wrappedStdErrorWriter;
@@ -180,17 +181,19 @@ public enum LogLevel
/// Stdout will default log messages to be Information
/// Stderror will default log messages to be Error
///
- public LogLevelLoggerWriter()
+ /// Environment variables interface.
+ public LogLevelLoggerWriter(IEnvironmentVariables environmentVariables)
{
+ _environmentVariables = environmentVariables;
// Look to see if Lambda's telemetry log file descriptor is available. If so use that for logging.
// This will make sure multiline log messages use a single CloudWatch Logs record.
- var fileDescriptorLogId = Environment.GetEnvironmentVariable(Constants.ENVIRONMENT_VARIABLE_TELEMETRY_LOG_FD);
+ var fileDescriptorLogId = environmentVariables.GetEnvironmentVariable(Constants.ENVIRONMENT_VARIABLE_TELEMETRY_LOG_FD);
if (fileDescriptorLogId != null)
{
try
{
- var stdOutWriter = FileDescriptorLogFactory.GetWriter(fileDescriptorLogId);
- var stdErrorWriter = FileDescriptorLogFactory.GetWriter(fileDescriptorLogId);
+ var stdOutWriter = FileDescriptorLogFactory.GetWriter(environmentVariables, fileDescriptorLogId);
+ var stdErrorWriter = FileDescriptorLogFactory.GetWriter(environmentVariables, fileDescriptorLogId);
Initialize(stdOutWriter, stdErrorWriter);
InternalLogger.GetDefaultLogger().LogInformation("Using file descriptor stream writer for logging.");
}
@@ -229,8 +232,8 @@ public LogLevelLoggerWriter(TextWriter stdOutWriter, TextWriter stdErrorWriter)
private void Initialize(TextWriter stdOutWriter, TextWriter stdErrorWriter)
{
- _wrappedStdOutWriter = new WrapperTextWriter(stdOutWriter, LogLevel.Information.ToString());
- _wrappedStdErrorWriter = new WrapperTextWriter(stdErrorWriter, LogLevel.Error.ToString());
+ _wrappedStdOutWriter = new WrapperTextWriter(_environmentVariables, stdOutWriter, LogLevel.Information.ToString());
+ _wrappedStdErrorWriter = new WrapperTextWriter(_environmentVariables, stdErrorWriter, LogLevel.Error.ToString());
}
///
@@ -300,6 +303,7 @@ public void FormattedWriteLine(string level, Exception exception, string message
///
class WrapperTextWriter : TextWriter
{
+ private readonly IEnvironmentVariables _environmentVariables;
private readonly TextWriter _innerWriter;
private readonly string _defaultLogLevel;
@@ -311,7 +315,34 @@ enum LogFormatType { Default, Unformatted, Json }
private readonly ILogMessageFormatter _logMessageFormatter;
- public IRuntimeApiHeaders CurrentRuntimeApiHeaders { get; set; }
+ // If running in multi concurrency mode we need to store the current aws request id in Task
+ // local storage to avoid the wrong request id being logged for a log statement. If not using
+ // multi concurrency mode we use the quicker to access string member variable.
+ private readonly AsyncLocal _currentRuntimeApiHeadersStorage;
+ private IRuntimeApiHeaders _currentRuntimeApiHeaders;
+
+ public IRuntimeApiHeaders CurrentRuntimeApiHeaders
+ {
+ get
+ {
+ if (Utils.IsUsingMultiConcurrency(_environmentVariables))
+ {
+ return _currentRuntimeApiHeadersStorage.Value;
+ }
+ return _currentRuntimeApiHeaders;
+ }
+ set
+ {
+ if (Utils.IsUsingMultiConcurrency(_environmentVariables))
+ {
+ _currentRuntimeApiHeadersStorage.Value = value;
+ }
+ else
+ {
+ _currentRuntimeApiHeaders = value;
+ }
+ }
+ }
///
/// This is typically set to either Console.Out or Console.Error to make sure we acquiring a lock
@@ -324,13 +355,20 @@ enum LogFormatType { Default, Unformatted, Json }
///
/// Create an instance
///
+ ///
///
///
- public WrapperTextWriter(TextWriter innerWriter, string defaultLogLevel)
+ public WrapperTextWriter(IEnvironmentVariables environmentVariables, TextWriter innerWriter, string defaultLogLevel)
{
+ _environmentVariables = environmentVariables;
_innerWriter = innerWriter;
_defaultLogLevel = defaultLogLevel;
+ if(Utils.IsUsingMultiConcurrency(environmentVariables))
+ {
+ _currentRuntimeApiHeadersStorage = new AsyncLocal();
+ }
+
var envLogLevel = GetEnvironmentVariable(Constants.NET_RIC_LOG_LEVEL_ENVIRONMENT_VARIABLE, Constants.LAMBDA_LOG_LEVEL_ENVIRONMENT_VARIABLE);
if (!string.IsNullOrEmpty(envLogLevel))
{
@@ -374,10 +412,10 @@ public WrapperTextWriter(TextWriter innerWriter, string defaultLogLevel)
private string GetEnvironmentVariable(string envName, string fallbackEnvName)
{
- var value = Environment.GetEnvironmentVariable(envName);
+ var value = _environmentVariables.GetEnvironmentVariable(envName);
if(string.IsNullOrEmpty(value) && fallbackEnvName != null)
{
- value = Environment.GetEnvironmentVariable(fallbackEnvName);
+ value = _environmentVariables.GetEnvironmentVariable(fallbackEnvName);
}
return value;
@@ -407,11 +445,14 @@ internal void FormattedWriteLine(string level, Exception exception, string messa
messageState.Level = levelEnum;
messageState.Exception = exception;
- if (CurrentRuntimeApiHeaders != null)
+ // Capture the IRuntimeApiHeaders into a local variable to avoid repeatedly accessing the backing AsyncLocal
+ // or having AsyncLocal change in between accessing.
+ var runtimeApiHeaders = CurrentRuntimeApiHeaders;
+ if (runtimeApiHeaders != null)
{
- messageState.AwsRequestId = CurrentRuntimeApiHeaders.AwsRequestId;
- messageState.TenantId = CurrentRuntimeApiHeaders.TenantId;
- messageState.TraceId = CurrentRuntimeApiHeaders.TraceId;
+ messageState.AwsRequestId = runtimeApiHeaders.AwsRequestId;
+ messageState.TenantId = runtimeApiHeaders.TenantId;
+ messageState.TraceId = runtimeApiHeaders.TraceId;
}
var message = _logMessageFormatter.FormatMessage(messageState);
diff --git a/Libraries/src/Amazon.Lambda.RuntimeSupport/Helpers/FileDescriptorLogStream.cs b/Libraries/src/Amazon.Lambda.RuntimeSupport/Helpers/FileDescriptorLogStream.cs
index 2510c421a..2612f3b22 100644
--- a/Libraries/src/Amazon.Lambda.RuntimeSupport/Helpers/FileDescriptorLogStream.cs
+++ b/Libraries/src/Amazon.Lambda.RuntimeSupport/Helpers/FileDescriptorLogStream.cs
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
@@ -41,14 +41,15 @@ public static class FileDescriptorLogFactory
///
/// Get the StreamWriter for the particular file descriptor ID. If the same ID is passed the same StreamWriter instance is returned.
///
+ ///
///
///
- public static StreamWriter GetWriter(string fileDescriptorId)
+ public static StreamWriter GetWriter(IEnvironmentVariables environmentVariables, string fileDescriptorId)
{
var writer = _writers.GetOrAdd(fileDescriptorId,
(x) => {
SafeFileHandle handle = new SafeFileHandle(new IntPtr(int.Parse(fileDescriptorId)), false);
- return InitializeWriter(new FileStream(handle, FileAccess.Write));
+ return InitializeWriter(environmentVariables, new FileStream(handle, FileAccess.Write));
});
return writer;
}
@@ -57,15 +58,16 @@ public static StreamWriter GetWriter(string fileDescriptorId)
/// Initialize a StreamWriter for the given Stream.
/// This method is internal as it is tested in Amazon.RuntimeSupport.Tests
///
+ ///
///
///
- internal static StreamWriter InitializeWriter(Stream fileDescriptorStream)
+ internal static StreamWriter InitializeWriter(IEnvironmentVariables environmentVariables, Stream fileDescriptorStream)
{
// AutoFlush must be turned out otherwise the StreamWriter might not send the data to the stream before the Lambda function completes.
// Set the buffer size to the same max size as CloudWatch Logs records.
// Encoder has encoderShouldEmitUTF8Identifier = false as Lambda FD will assume UTF-8 so there is no need to emit an extra log entry.
// In fact this extra log entry is cast to UTF-8 and results in an empty log entry which will be rejected by CloudWatch Logs.
- return new NonDisposableStreamWriter(new FileDescriptorLogStream(fileDescriptorStream),
+ return new NonDisposableStreamWriter(new FileDescriptorLogStream(environmentVariables, fileDescriptorStream),
new UTF8Encoding(false), MaxCloudWatchLogEventSize)
{ AutoFlush = true };
}
@@ -88,9 +90,9 @@ private class FileDescriptorLogStream : Stream
private readonly byte[] _frameTypeBytes;
private readonly uint _frameType;
- public FileDescriptorLogStream(Stream logStream)
+ public FileDescriptorLogStream(IEnvironmentVariables environmentVariables, Stream logStream)
{
- var logFormat = Environment.GetEnvironmentVariable(Constants.LAMBDA_LOG_FORMAT_ENVIRONMENT_VARIABLE);
+ var logFormat = environmentVariables.GetEnvironmentVariable(Constants.LAMBDA_LOG_FORMAT_ENVIRONMENT_VARIABLE);
_frameType = string.Equals(logFormat, Constants.LAMBDA_LOG_FORMAT_JSON, StringComparison.InvariantCultureIgnoreCase)
? LambdaTelemetryLogHeaderFrameTypeJson : LambdaTelemetryLogHeaderFrameTypeText;
diff --git a/Libraries/src/Amazon.Lambda.RuntimeSupport/Helpers/NativeAotHelper.cs b/Libraries/src/Amazon.Lambda.RuntimeSupport/Helpers/NativeAotHelper.cs
deleted file mode 100644
index 2c8b66f55..000000000
--- a/Libraries/src/Amazon.Lambda.RuntimeSupport/Helpers/NativeAotHelper.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-using System.Runtime.CompilerServices;
-
-namespace Amazon.Lambda.RuntimeSupport.Helpers
-{
- internal static class NativeAotHelper
- {
- public static bool IsRunningNativeAot()
- {
- // If dynamic code is not supported we are most likely running in an AOT environment.
-#if NET6_0_OR_GREATER
- return !RuntimeFeature.IsDynamicCodeSupported;
-#else
- return false;
-#endif
- }
- }
-}
diff --git a/Libraries/src/Amazon.Lambda.RuntimeSupport/Helpers/TraceProviderIsolated.cs b/Libraries/src/Amazon.Lambda.RuntimeSupport/Helpers/TraceProviderIsolated.cs
new file mode 100644
index 000000000..48748d419
--- /dev/null
+++ b/Libraries/src/Amazon.Lambda.RuntimeSupport/Helpers/TraceProviderIsolated.cs
@@ -0,0 +1,32 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+namespace Amazon.Lambda.RuntimeSupport.Helpers
+{
+ ///
+ /// This wrapper class is used to add a layer of protection around calling LambdaTraceProvider.SetCurrentTraceId
+ /// from Amazon.Lambda.Core. If the provided Lambda function code does not include a version of Amazon.Lambda.Core
+ /// that has Amazon.Lambda.Core.LambdaTraceProvider.SetCurrentTraceId a
+ /// will be thrown when parent calling method is called.
+ ///
+ /// For example if Amazon.Lambda.Core.LambdaTraceProvider.SetCurrentTraceId was called directly in the bootstrap's main
+ /// invoke method the TypeLoadException would be thrown when the invoke method is called giving the invoke method
+ /// no time to recover. By having this wrapper the invoke method can call this method if the Core version is out of date
+ /// and the TypeLoadException will be thrown at the point of calling this method allowing the main invoke method to
+ /// catch the exception and handle it appropriately.
+ ///
+ internal class TraceProviderIsolated
+ {
+ ///
+ /// Set the trace id on the LambdaTraceProvider in Amazon.Lambda.Core.
+ ///
+ ///
+ /// If the version of Amazon.Lambda.Core used does not contain the SetCurrentTraceId method.
+ internal static void SetCurrentTraceId(string traceId)
+ {
+#if !ANALYZER_UNIT_TESTS // This precompiler directive is used to avoid the unit tests from needing a dependency on Amazon.Lambda.Core.
+ Amazon.Lambda.Core.LambdaTraceProvider.SetCurrentTraceId(traceId);
+#endif
+ }
+ }
+}
diff --git a/Libraries/src/Amazon.Lambda.RuntimeSupport/Helpers/Utils.cs b/Libraries/src/Amazon.Lambda.RuntimeSupport/Helpers/Utils.cs
new file mode 100644
index 000000000..e23c0e588
--- /dev/null
+++ b/Libraries/src/Amazon.Lambda.RuntimeSupport/Helpers/Utils.cs
@@ -0,0 +1,113 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+using System;
+using System.Runtime.CompilerServices;
+using Amazon.Lambda.RuntimeSupport.Bootstrap;
+
+namespace Amazon.Lambda.RuntimeSupport.Helpers
+{
+ internal static class Utils
+ {
+ public static bool IsRunningNativeAot()
+ {
+ // If dynamic code is not supported we are most likely running in an AOT environment.
+#if NET6_0_OR_GREATER
+ return !RuntimeFeature.IsDynamicCodeSupported;
+#else
+ return false;
+#endif
+
+ }
+
+ ///
+ /// Determines if the Lambda function is running in multi concurrency mode.
+ ///
+ internal static bool IsUsingMultiConcurrency(IEnvironmentVariables environmentVariables)
+ {
+ return !string.IsNullOrEmpty(environmentVariables.GetEnvironmentVariable(Constants.ENVIRONMENT_VARIABLE_AWS_LAMBDA_MAX_CONCURRENCY));
+ }
+
+ ///
+ /// Determines the number of .NET Tasks that should be created that will iterate a loop polling the Lambda runtime for new events.
+ ///
+ ///
+ ///
+ internal static int DetermineProcessingTaskCount(IEnvironmentVariables environmentVariables, int processorCount)
+ {
+ var processingTaskCount = 1;
+ if (IsUsingMultiConcurrency(environmentVariables))
+ {
+ // Check the .NET specific environment variable that allows customers the option to override our default computed value.
+ var overrideCount = environmentVariables.GetEnvironmentVariable(Constants.ENVIRONMENT_VARIABLE_AWS_LAMBDA_DOTNET_PROCESSING_TASKS);
+ if (!string.IsNullOrEmpty(overrideCount))
+ {
+ if (!int.TryParse(overrideCount, out processingTaskCount) || processingTaskCount <= 0)
+ {
+ throw new ArgumentException($"Value {overrideCount} for environment variable {Constants.ENVIRONMENT_VARIABLE_AWS_LAMBDA_DOTNET_PROCESSING_TASKS} failed to parse as an integer greater then 0");
+ }
+ }
+ else
+ {
+ processingTaskCount = Math.Max(2, processorCount);
+ }
+ }
+
+ return processingTaskCount;
+ }
+
+ ///
+ /// Create an Action callback that can be used for setting the trace id on the AWS SDK for .NET if the SDK is present.
+ /// If the AWS .NET SDK is not found then null is returned.
+ ///
+ ///
+#if NET8_0_OR_GREATER
+ [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026",
+ Justification = "Loading the type is okay to fail if the user is not using the AWS SDK for .NET or it is an old version. If they are using an SDK with the SDKTaskContext the SDK has the attributes to avoid the Set method being trimmed.")]
+#endif
+ internal static Action FindAWSSDKTraceIdSetter(IEnvironmentVariables environmentVariables)
+ {
+ if (!Utils.IsUsingMultiConcurrency(environmentVariables))
+ return null;
+
+ // Since the AWSSDK.Core is strongly named we need to check the assembly version for
+ // both V3 and V4. The assembly version is only changed on major releases.
+ // In V3 the assembly version was updated to 3.3.0.0 when .NET Core support was added and then was never
+ // updated again that major version.
+ var sdkTaskContextType = Type.GetType("Amazon.Runtime.SDKTaskContext, AWSSDK.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=885c28607f98e604") ??
+ Type.GetType("Amazon.Runtime.SDKTaskContext, AWSSDK.Core, Version=3.3.0.0, Culture=neutral, PublicKeyToken=885c28607f98e604");
+
+ if (sdkTaskContextType == null)
+ return null;
+
+ var defaultProperty = sdkTaskContextType.GetProperty("Default", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
+ if (defaultProperty == null)
+ return null;
+
+ var defaultInstance = defaultProperty.GetValue(null);
+ if (defaultInstance == null)
+ return null;
+
+ var setMethod = sdkTaskContextType.GetMethod("Set", new Type[] { typeof(string), typeof(object) });
+ if (setMethod == null)
+ return null;
+
+ return (string traceId) =>
+ {
+ setMethod.Invoke(defaultInstance, new object[] { "_X_AMZN_TRACE_ID", traceId });
+ };
+ }
+ }
+}
diff --git a/Libraries/src/Amazon.Lambda.RuntimeSupport/RuntimeSupportInitializer.cs b/Libraries/src/Amazon.Lambda.RuntimeSupport/RuntimeSupportInitializer.cs
index 11623c4b7..b7f36cc31 100644
--- a/Libraries/src/Amazon.Lambda.RuntimeSupport/RuntimeSupportInitializer.cs
+++ b/Libraries/src/Amazon.Lambda.RuntimeSupport/RuntimeSupportInitializer.cs
@@ -62,10 +62,17 @@ public async Task RunLambdaBootstrap()
{
await _debugAttacher.TryAttachDebugger();
- var userCodeLoader = new UserCodeLoader(_handler, _logger);
+ var environmentVariables = new SystemEnvironmentVariables();
+ var userCodeLoader = new UserCodeLoader(environmentVariables, _handler, _logger);
var initializer = new UserCodeInitializer(userCodeLoader, _logger);
using (var handlerWrapper = HandlerWrapper.GetHandlerWrapper(userCodeLoader.Invoke))
- using (var bootstrap = new LambdaBootstrap(handlerWrapper, _lambdaBootstrapOptions, initializer.InitializeAsync))
+ using (var bootstrap = new LambdaBootstrap(
+ httpClient: null,
+ handler: handlerWrapper.Handler,
+ initializer: initializer.InitializeAsync,
+ ownsHttpClient: true,
+ lambdaBootstrapOptions: _lambdaBootstrapOptions,
+ environmentVariables: environmentVariables))
{
await bootstrap.RunAsync();
}
diff --git a/Libraries/src/Amazon.Lambda.Serialization.SystemTextJson/Amazon.Lambda.Serialization.SystemTextJson.csproj b/Libraries/src/Amazon.Lambda.Serialization.SystemTextJson/Amazon.Lambda.Serialization.SystemTextJson.csproj
index 1129dd34b..5fe26ce3c 100644
--- a/Libraries/src/Amazon.Lambda.Serialization.SystemTextJson/Amazon.Lambda.Serialization.SystemTextJson.csproj
+++ b/Libraries/src/Amazon.Lambda.Serialization.SystemTextJson/Amazon.Lambda.Serialization.SystemTextJson.csproj
@@ -10,7 +10,13 @@
Amazon.Lambda.Serialization.SystemTextJson
AWS;Amazon;Lambda
2.4.4
- README.md
+ README.md
+
+ false
diff --git a/Libraries/src/SnapshotRestore.Registry/SnapshotRestore.Registry.csproj b/Libraries/src/SnapshotRestore.Registry/SnapshotRestore.Registry.csproj
index 455edf22d..0664c1214 100644
--- a/Libraries/src/SnapshotRestore.Registry/SnapshotRestore.Registry.csproj
+++ b/Libraries/src/SnapshotRestore.Registry/SnapshotRestore.Registry.csproj
@@ -21,6 +21,12 @@
true
true
NU5048;NU1903
+
+ false
diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/CSharpSourceGeneratorVerifier.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/CSharpSourceGeneratorVerifier.cs
index 7f42bb85b..fa55b0e48 100644
--- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/CSharpSourceGeneratorVerifier.cs
+++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/CSharpSourceGeneratorVerifier.cs
@@ -30,9 +30,13 @@ public enum ReferencesMode {All, NoApiGatewayEvents}
public enum TargetFramework { Net60, Net80 }
+ private ImmutableArray PreprocessorSymbols { get; set; } = ImmutableArray.Empty;
+
public Test(ReferencesMode referencesMode = ReferencesMode.All, TargetFramework targetFramework = TargetFramework.Net60)
{
- if(referencesMode == ReferencesMode.NoApiGatewayEvents)
+ PreprocessorSymbols = ImmutableArray.Create("ANALYZER_UNIT_TESTS");
+
+ if (referencesMode == ReferencesMode.NoApiGatewayEvents)
{
this.SolutionTransforms.Add((solution, projectId) =>
{
@@ -129,7 +133,9 @@ private static ImmutableDictionary EnableNullability()
protected override ParseOptions CreateParseOptions()
{
- return ((CSharpParseOptions)base.CreateParseOptions()).WithLanguageVersion(LanguageVersion);
+ return ((CSharpParseOptions)base.CreateParseOptions())
+ .WithLanguageVersion(LanguageVersion)
+ .WithPreprocessorSymbols(PreprocessorSymbols);
}
}
}
diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/SourceGeneratorTests.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/SourceGeneratorTests.cs
index f3d622232..640da8e9e 100644
--- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/SourceGeneratorTests.cs
+++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/SourceGeneratorTests.cs
@@ -706,7 +706,7 @@ public async Task VerifySourceGeneratorSerializerWithHttpResultsBody()
if (file.EndsWith("Program.cs") && content.Contains("Task Main(string[] args)"))
continue;
- test.TestState.Sources.Add((file, await File.ReadAllTextAsync(file)));
+ test.TestState.Sources.Add((file, content));
}
await test.RunAsync();
diff --git a/Libraries/test/Amazon.Lambda.Core.Tests/Amazon.Lambda.Core.Tests.csproj b/Libraries/test/Amazon.Lambda.Core.Tests/Amazon.Lambda.Core.Tests.csproj
index 0c1665b85..755b6b95e 100644
--- a/Libraries/test/Amazon.Lambda.Core.Tests/Amazon.Lambda.Core.Tests.csproj
+++ b/Libraries/test/Amazon.Lambda.Core.Tests/Amazon.Lambda.Core.Tests.csproj
@@ -5,6 +5,8 @@
Amazon.Lambda.Core.Tests
Amazon.Lambda.Core.Tests
true
+ ..\..\..\buildtools\public.snk
+ true
diff --git a/Libraries/test/Amazon.Lambda.Core.Tests/TraveProviderTests.cs b/Libraries/test/Amazon.Lambda.Core.Tests/TraveProviderTests.cs
new file mode 100644
index 000000000..43ed454ce
--- /dev/null
+++ b/Libraries/test/Amazon.Lambda.Core.Tests/TraveProviderTests.cs
@@ -0,0 +1,55 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Xunit;
+
+
+namespace Amazon.Lambda.Core.Tests
+{
+ public class TraveProviderTests
+ {
+ [Fact]
+ public void SetTraceIdNoMultiConcurrency()
+ {
+ LambdaTraceProvider.SetCurrentTraceId("trace-id-123");
+ Assert.Equal("trace-id-123", LambdaTraceProvider.CurrentTraceId);
+ }
+
+ [Fact]
+ public async Task SetTraceIdWithMultiConcurrency()
+ {
+ Environment.SetEnvironmentVariable(Constants.ENV_VAR_AWS_LAMBDA_MAX_CONCURRENCY, "2");
+ try
+ {
+ var successCount = 0;
+ Func action = async (sleep, traceId) =>
+ {
+ LambdaTraceProvider.SetCurrentTraceId(traceId);
+ await Task.Delay(sleep);
+ Assert.Equal(traceId, LambdaTraceProvider.CurrentTraceId);
+ Interlocked.Increment(ref successCount);
+ };
+
+ var tasks = new List
+ {
+ Task.Run(async () => await action(500, "trace-id-1")),
+ Task.Run(async () => await action(200, "trace-id-2")),
+ Task.Run(async () => await action(350, "trace-id-3"))
+ };
+
+ await Task.WhenAll(tasks);
+ Assert.Equal(3, successCount);
+ }
+ finally
+ {
+ Environment.SetEnvironmentVariable(Constants.ENV_VAR_AWS_LAMBDA_MAX_CONCURRENCY, null);
+ }
+ }
+ }
+}
diff --git a/Libraries/test/Amazon.Lambda.DynamoDBEvents.SDK.Convertor.Tests/DynamodbAttributeValueConvertorTests.cs b/Libraries/test/Amazon.Lambda.DynamoDBEvents.SDK.Convertor.Tests/DynamodbAttributeValueConvertorTests.cs
index 2e49c354e..2b78af0e8 100644
--- a/Libraries/test/Amazon.Lambda.DynamoDBEvents.SDK.Convertor.Tests/DynamodbAttributeValueConvertorTests.cs
+++ b/Libraries/test/Amazon.Lambda.DynamoDBEvents.SDK.Convertor.Tests/DynamodbAttributeValueConvertorTests.cs
@@ -12,6 +12,16 @@ public void ConvertToSdkAttribute_StringValue_ReturnsSdkAttribute()
Assert.Equal("TestString", sdkAttribute.S);
}
+ [Fact]
+ public void ConvertToSdkAttribute_EmptyStringValue_ReturnsSdkAttribute()
+ {
+ var lambdaAttribute = new DynamoDBEvent.AttributeValue { S = string.Empty };
+ var sdkAttribute = lambdaAttribute.ConvertToSdkAttribute();
+
+ Assert.NotNull(sdkAttribute);
+ Assert.Equal(string.Empty, sdkAttribute.S);
+ }
+
[Fact]
public void ConvertToSdkAttribute_NumberValue_ReturnsSdkAttribute()
{
diff --git a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/Amazon.Lambda.RuntimeSupport.IntegrationTests.csproj b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/Amazon.Lambda.RuntimeSupport.IntegrationTests.csproj
index 7f816e917..86a3b5c1e 100644
--- a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/Amazon.Lambda.RuntimeSupport.IntegrationTests.csproj
+++ b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/Amazon.Lambda.RuntimeSupport.IntegrationTests.csproj
@@ -2,7 +2,6 @@
net8.0
- SKIP_RUNTIME_SUPPORT_INTEG_TESTS
diff --git a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/BaseCustomRuntimeTest.cs b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/BaseCustomRuntimeTest.cs
index e8eb5225d..44286d8bd 100644
--- a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/BaseCustomRuntimeTest.cs
+++ b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/BaseCustomRuntimeTest.cs
@@ -44,8 +44,11 @@ public class BaseCustomRuntimeTest
protected string ExecutionRoleArn { get; set; }
private const string TestsProjectDirectoryName = "Amazon.Lambda.RuntimeSupport.Tests";
- protected BaseCustomRuntimeTest(string functionName, string deploymentZipKey, string deploymentPackageZipRelativePath, string handler)
+ private IntegrationTestFixture _fixture;
+
+ protected BaseCustomRuntimeTest(IntegrationTestFixture fixture, string functionName, string deploymentZipKey, string deploymentPackageZipRelativePath, string handler)
{
+ _fixture = fixture;
FunctionName = functionName;
ExecutionRoleName = FunctionName;
Handler = handler;
@@ -329,13 +332,7 @@ protected async Task DeleteFunctionIfExistsAsync(IAmazonLambda lambdaClient)
///
private string GetDeploymentZipPath()
{
- var testsProjectDirectory = FindUp(System.Environment.CurrentDirectory, TestsProjectDirectoryName, true);
- if (string.IsNullOrEmpty(testsProjectDirectory))
- {
- throw new NoDeploymentPackageFoundException();
- }
-
- var deploymentZipFile = Path.Combine(testsProjectDirectory, DeploymentPackageZipRelativePath.Replace('\\', Path.DirectorySeparatorChar));
+ var deploymentZipFile = _fixture.TestAppPaths[DeploymentPackageZipRelativePath];
if (!File.Exists(deploymentZipFile))
{
diff --git a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest.cs b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest.cs
index 2661e4d1e..d8bb17103 100644
--- a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest.cs
+++ b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest.cs
@@ -1,4 +1,4 @@
-using Amazon.IdentityManagement;
+using Amazon.IdentityManagement;
using Amazon.IdentityManagement.Model;
using Amazon.Lambda.Model;
using Amazon.S3;
@@ -21,17 +21,13 @@ namespace Amazon.Lambda.RuntimeSupport.IntegrationTests
[Collection("Integration Tests")]
public class CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest : BaseCustomRuntimeTest
{
- public CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest()
- : base("CustomRuntimeMinimalApiCustomSerializerTest-" + DateTime.Now.Ticks, "CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest.zip", @"CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest\bin\Release\net6.0\CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest.zip", "bootstrap")
+ public CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest(IntegrationTestFixture fixture)
+ : base(fixture, "CustomRuntimeMinimalApiCustomSerializerTest-" + DateTime.Now.Ticks, "CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest.zip", @"CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest\bin\Release\net8.0\CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest.zip", "bootstrap")
{
}
-#if SKIP_RUNTIME_SUPPORT_INTEG_TESTS
- [Fact(Skip = "Skipped intentionally by setting the SkipRuntimeSupportIntegTests build parameter.")]
-#else
[Fact]
-#endif
public async Task TestMinimalApi()
{
// run all test cases in one test to ensure they run serially
@@ -61,11 +57,7 @@ public async Task TestMinimalApi()
}
}
-#if SKIP_RUNTIME_SUPPORT_INTEG_TESTS
- [Fact(Skip = "Skipped intentionally by setting the SkipRuntimeSupportIntegTests build parameter.")]
-#else
[Fact]
-#endif
public async Task TestThreadingLogging()
{
// run all test cases in one test to ensure they run serially
diff --git a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/CustomRuntimeAspNetCoreMinimalApiTest.cs b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/CustomRuntimeAspNetCoreMinimalApiTest.cs
index 52f433b09..53fd92608 100644
--- a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/CustomRuntimeAspNetCoreMinimalApiTest.cs
+++ b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/CustomRuntimeAspNetCoreMinimalApiTest.cs
@@ -1,4 +1,4 @@
-using Amazon.IdentityManagement;
+using Amazon.IdentityManagement;
using Amazon.IdentityManagement.Model;
using Amazon.Lambda.Model;
using Amazon.S3;
@@ -21,17 +21,13 @@ namespace Amazon.Lambda.RuntimeSupport.IntegrationTests
[Collection("Integration Tests")]
public class CustomRuntimeAspNetCoreMinimalApiTest : BaseCustomRuntimeTest
{
- public CustomRuntimeAspNetCoreMinimalApiTest()
- : base("CustomRuntimeAspNetCoreMinimalApiTest-" + DateTime.Now.Ticks, "CustomRuntimeAspNetCoreMinimalApiTest.zip", @"CustomRuntimeAspNetCoreMinimalApiTest\bin\Release\net6.0\CustomRuntimeAspNetCoreMinimalApiTest.zip", "bootstrap")
+ public CustomRuntimeAspNetCoreMinimalApiTest(IntegrationTestFixture fixture)
+ : base(fixture, "CustomRuntimeAspNetCoreMinimalApiTest-" + DateTime.Now.Ticks, "CustomRuntimeAspNetCoreMinimalApiTest.zip", @"CustomRuntimeAspNetCoreMinimalApiTest\bin\Release\net8.0\CustomRuntimeAspNetCoreMinimalApiTest.zip", "bootstrap")
{
}
-#if SKIP_RUNTIME_SUPPORT_INTEG_TESTS
- [Fact(Skip = "Skipped intentionally by setting the SkipRuntimeSupportIntegTests build parameter.")]
-#else
[Fact]
-#endif
public async Task TestMinimalApi()
{
// run all test cases in one test to ensure they run serially
@@ -61,11 +57,7 @@ public async Task TestMinimalApi()
}
}
-#if SKIP_RUNTIME_SUPPORT_INTEG_TESTS
- [Fact(Skip = "Skipped intentionally by setting the SkipRuntimeSupportIntegTests build parameter.")]
-#else
[Fact]
-#endif
public async Task TestThreadingLogging()
{
// run all test cases in one test to ensure they run serially
diff --git a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/CustomRuntimeTests.cs b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/CustomRuntimeTests.cs
index 066428f21..b548d5ba0 100644
--- a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/CustomRuntimeTests.cs
+++ b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/CustomRuntimeTests.cs
@@ -31,38 +31,15 @@
namespace Amazon.Lambda.RuntimeSupport.IntegrationTests
{
- [Collection("Integration Tests")]
- public class CustomRuntimeNET6Tests : CustomRuntimeTests
- {
- public CustomRuntimeNET6Tests()
- : base("CustomRuntimeNET6FunctionTest-" + DateTime.Now.Ticks, "CustomRuntimeFunctionTest.zip", @"CustomRuntimeFunctionTest\bin\Release\net6.0\CustomRuntimeFunctionTest.zip", "CustomRuntimeFunctionTest", TargetFramework.NET6)
- {
- }
-
-#if SKIP_RUNTIME_SUPPORT_INTEG_TESTS
- [Fact(Skip = "Skipped intentionally by setting the SkipRuntimeSupportIntegTests build parameter.")]
-#else
- [Fact]
-#endif
- public async Task TestAllNET6HandlersAsync()
- {
- await base.TestAllHandlersAsync();
- }
- }
-
[Collection("Integration Tests")]
public class CustomRuntimeNET8Tests : CustomRuntimeTests
{
- public CustomRuntimeNET8Tests()
- : base("CustomRuntimeNET8FunctionTest-" + DateTime.Now.Ticks, "CustomRuntimeFunctionTest.zip", @"CustomRuntimeFunctionTest\bin\Release\net8.0\CustomRuntimeFunctionTest.zip", "CustomRuntimeFunctionTest", TargetFramework.NET8)
+ public CustomRuntimeNET8Tests(IntegrationTestFixture fixture)
+ : base(fixture, "CustomRuntimeNET8FunctionTest-" + DateTime.Now.Ticks, "CustomRuntimeFunctionTest.zip", @"CustomRuntimeFunctionTest\bin\Release\net8.0\CustomRuntimeFunctionTest.zip", "CustomRuntimeFunctionTest", TargetFramework.NET8)
{
}
-#if SKIP_RUNTIME_SUPPORT_INTEG_TESTS
- [Fact(Skip = "Skipped intentionally by setting the SkipRuntimeSupportIntegTests build parameter.")]
-#else
[Fact]
-#endif
public async Task TestAllNET8HandlersAsync()
{
await base.TestAllHandlersAsync();
@@ -75,8 +52,8 @@ public enum TargetFramework { NET6, NET8}
private TargetFramework _targetFramework;
- public CustomRuntimeTests(string functionName, string deploymentZipKey, string deploymentPackageZipRelativePath, string handler, TargetFramework targetFramework)
- : base(functionName, deploymentZipKey, deploymentPackageZipRelativePath, handler)
+ public CustomRuntimeTests(IntegrationTestFixture fixture, string functionName, string deploymentZipKey, string deploymentPackageZipRelativePath, string handler, TargetFramework targetFramework)
+ : base(fixture, functionName, deploymentZipKey, deploymentPackageZipRelativePath, handler)
{
_targetFramework = targetFramework;
}
@@ -129,7 +106,6 @@ protected virtual async Task TestAllHandlersAsync()
await RunTestSuccessAsync(lambdaClient, "PingAsync", "ping", "PingAsync-pong");
await RunTestSuccessAsync(lambdaClient, "HttpsWorksAsync", "", "HttpsWorksAsync-SUCCESS");
await RunTestSuccessAsync(lambdaClient, "CertificateCallbackWorksAsync", "", "CertificateCallbackWorksAsync-SUCCESS");
- await RunTestSuccessAsync(lambdaClient, "NetworkingProtocolsAsync", "", "NetworkingProtocolsAsync-SUCCESS");
await RunTestSuccessAsync(lambdaClient, "HandlerEnvVarAsync", "", "HandlerEnvVarAsync-CustomRuntimeFunctionTest");
await RunTestExceptionAsync(lambdaClient, "AggregateExceptionUnwrappedAsync", "", "Exception", "Exception thrown from an async handler.");
await RunTestExceptionAsync(lambdaClient, "AggregateExceptionUnwrapped", "", "Exception", "Exception thrown from a synchronous handler.");
diff --git a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/IntegrationTestFixture.cs b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/IntegrationTestFixture.cs
index bc6ddad99..89d62d61f 100644
--- a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/IntegrationTestFixture.cs
+++ b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/IntegrationTestFixture.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using System.IO;
using System.Threading.Tasks;
using Amazon.Lambda.RuntimeSupport.IntegrationTests.Helpers;
using Xunit;
@@ -8,7 +9,9 @@ namespace Amazon.Lambda.RuntimeSupport.IntegrationTests;
public class IntegrationTestFixture : IAsyncLifetime
{
private readonly List _tempPaths = new();
-
+
+ public IDictionary TestAppPaths { get; } = new Dictionary();
+
public async Task InitializeAsync()
{
var testAppPath = LambdaToolsHelper.GetTempTestAppDirectory(
@@ -16,22 +19,24 @@ public async Task InitializeAsync()
"Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/CustomRuntimeFunctionTest");
var toolPath = await LambdaToolsHelper.InstallLambdaTools();
_tempPaths.AddRange([testAppPath, toolPath] );
- await LambdaToolsHelper.LambdaPackage(toolPath, "net6.0", testAppPath);
await LambdaToolsHelper.LambdaPackage(toolPath, "net8.0", testAppPath);
-
+ TestAppPaths[@"CustomRuntimeFunctionTest\bin\Release\net8.0\CustomRuntimeFunctionTest.zip"] = Path.Combine(testAppPath, @"bin\Release\net8.0\CustomRuntimeFunctionTest.zip");
+
testAppPath = LambdaToolsHelper.GetTempTestAppDirectory(
"../../../../../../..",
"Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/CustomRuntimeAspNetCoreMinimalApiTest");
toolPath = await LambdaToolsHelper.InstallLambdaTools();
_tempPaths.AddRange([testAppPath, toolPath] );
- await LambdaToolsHelper.LambdaPackage(toolPath, "net6.0", testAppPath);
-
+ await LambdaToolsHelper.LambdaPackage(toolPath, "net8.0", testAppPath);
+ TestAppPaths[@"CustomRuntimeAspNetCoreMinimalApiTest\bin\Release\net8.0\CustomRuntimeAspNetCoreMinimalApiTest.zip"] = Path.Combine(testAppPath, @"bin\Release\net8.0\CustomRuntimeAspNetCoreMinimalApiTest.zip");
+
testAppPath = LambdaToolsHelper.GetTempTestAppDirectory(
"../../../../../../..",
"Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest");
toolPath = await LambdaToolsHelper.InstallLambdaTools();
_tempPaths.AddRange([testAppPath, toolPath] );
- await LambdaToolsHelper.LambdaPackage(toolPath, "net6.0", testAppPath);
+ await LambdaToolsHelper.LambdaPackage(toolPath, "net8.0", testAppPath);
+ TestAppPaths[@"CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest\bin\Release\net8.0\CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest.zip"] = Path.Combine(testAppPath, @"bin\Release\net8.0\CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest.zip");
}
@@ -44,4 +49,4 @@ public Task DisposeAsync()
return Task.CompletedTask;
}
-}
\ No newline at end of file
+}
diff --git a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/Amazon.Lambda.RuntimeSupport.UnitTests.csproj b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/Amazon.Lambda.RuntimeSupport.UnitTests.csproj
index 51b2e9fba..cc96b0a0b 100644
--- a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/Amazon.Lambda.RuntimeSupport.UnitTests.csproj
+++ b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/Amazon.Lambda.RuntimeSupport.UnitTests.csproj
@@ -4,6 +4,8 @@
net8.0
..\..\..\..\buildtools\public.snk
true
+
+ IDE0060
diff --git a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/FileDescriptorLogStreamTests.cs b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/FileDescriptorLogStreamTests.cs
index e152a2813..1b461eb5b 100644
--- a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/FileDescriptorLogStreamTests.cs
+++ b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/FileDescriptorLogStreamTests.cs
@@ -31,7 +31,7 @@ public void MultilineLoggingInSingleLogEntryWithTlvFormat()
offsets.Add(offset);
counts.Add(count);
});
- TextWriter writer = FileDescriptorLogFactory.InitializeWriter(stream);
+ TextWriter writer = FileDescriptorLogFactory.InitializeWriter(new SystemEnvironmentVariables(), stream);
// assert that initializing the stream does not result in UTF-8 preamble log entry
Assert.Empty(counts);
Assert.Empty(offsets);
@@ -79,7 +79,7 @@ public void MaxSizeProducesOneLogFrame()
offsets.Add(offset);
counts.Add(count);
});
- TextWriter writer = FileDescriptorLogFactory.InitializeWriter(stream);
+ TextWriter writer = FileDescriptorLogFactory.InitializeWriter(new SystemEnvironmentVariables(), stream);
// assert that initializing the stream does not result in UTF-8 preamble log entry
Assert.Empty(counts);
Assert.Empty(offsets);
@@ -126,7 +126,7 @@ public void LogEntryAboveMaxSizeProducesMultipleLogFrames()
offsets.Add(offset);
counts.Add(count);
});
- TextWriter writer = FileDescriptorLogFactory.InitializeWriter(stream);
+ TextWriter writer = FileDescriptorLogFactory.InitializeWriter(new SystemEnvironmentVariables(), stream);
// assert that initializing the stream does not result in UTF-8 preamble log entry
Assert.Empty(counts);
Assert.Empty(offsets);
diff --git a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/HandlerTests.cs b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/HandlerTests.cs
index 42e0d6957..80f9d13d0 100644
--- a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/HandlerTests.cs
+++ b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/HandlerTests.cs
@@ -134,7 +134,7 @@ public async Task PositiveHandlerTestsAsync()
[Trait("Category", "UserCodeLoader")]
public async Task NegativeBootstrapInitTestsAsync()
{
- var ucl = new UserCodeLoader("NonExistentAssembly::HandlerTest.CustomerType::ZeroInZeroOut", _internalLogger);
+ var ucl = new UserCodeLoader(new SystemEnvironmentVariables(), "NonExistentAssembly::HandlerTest.CustomerType::ZeroInZeroOut", _internalLogger);
var ex = Assert.Throws(() => ucl.Init(NoOpLoggingAction));
Assert.Contains("Could not find the specified handler", ex.Message);
@@ -247,7 +247,7 @@ private async Task TestHandlerFailAsync(string handler, string expect
var testRuntimeApiClient = new TestRuntimeApiClient(_environmentVariables, _headers);
- var userCodeLoader = new UserCodeLoader(handler, _internalLogger);
+ var userCodeLoader = new UserCodeLoader(new SystemEnvironmentVariables(), handler, _internalLogger);
var initializer = new UserCodeInitializer(userCodeLoader, _internalLogger);
var handlerWrapper = HandlerWrapper.GetHandlerWrapper(userCodeLoader.Invoke);
var bootstrap = new LambdaBootstrap(handlerWrapper, initializer.InitializeAsync)
@@ -385,7 +385,7 @@ private async Task ExecHandlerAsync(string handler, string dataIn
var testRuntimeApiClient = new TestRuntimeApiClient(_environmentVariables, _headers);
- var userCodeLoader = new UserCodeLoader(handler, _internalLogger);
+ var userCodeLoader = new UserCodeLoader(new SystemEnvironmentVariables(), handler, _internalLogger);
var handlerWrapper = HandlerWrapper.GetHandlerWrapper(userCodeLoader.Invoke);
var initializer = new UserCodeInitializer(userCodeLoader, _internalLogger);
var bootstrap = new LambdaBootstrap(handlerWrapper, initializer.InitializeAsync)
diff --git a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/HandlerWrapperTests.cs b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/HandlerWrapperTests.cs
index f0660017c..88e93834f 100644
--- a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/HandlerWrapperTests.cs
+++ b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/HandlerWrapperTests.cs
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
@@ -87,9 +87,9 @@ static HandlerWrapperTests()
tempStream.Read(PocoOutputBytes, 0, PocoOutputBytes.Length);
}
- private LambdaEnvironment _lambdaEnvironment;
- private RuntimeApiHeaders _runtimeApiHeaders;
- private Checkpoint _checkpoint;
+ private readonly LambdaEnvironment _lambdaEnvironment;
+ private readonly RuntimeApiHeaders _runtimeApiHeaders;
+ private readonly Checkpoint _checkpoint;
public HandlerWrapperTests()
{
@@ -633,6 +633,49 @@ public async Task TestSerializtionOfString()
}
}
+ [Theory]
+ [InlineData(true)]
+ [InlineData(false)]
+ public async Task TestOutputStreamReuse(bool onDemand)
+ {
+ if (!onDemand)
+ {
+ Environment.SetEnvironmentVariable(Constants.ENV_VAR_AWS_LAMBDA_MAX_CONCURRENCY, "10");
+ }
+ try
+ {
+ using (var handlerWrapper = HandlerWrapper.GetHandlerWrapper((input) =>
+ {
+ return input.ToUpper();
+ }, Serializer))
+ {
+ var invocation1 = new InvocationRequest
+ {
+ InputStream = new MemoryStream(UTF8Encoding.UTF8.GetBytes("\"Hello\"")),
+ LambdaContext = new LambdaContext(_runtimeApiHeaders, _lambdaEnvironment, new Helpers.SimpleLoggerWriter(new SystemEnvironmentVariables()))
+ };
+
+ var invocationResponse1 = await handlerWrapper.Handler(invocation1);
+
+ var invocation2 = new InvocationRequest
+ {
+ InputStream = new MemoryStream(UTF8Encoding.UTF8.GetBytes("\"World\"")),
+ LambdaContext = new LambdaContext(_runtimeApiHeaders, _lambdaEnvironment, new Helpers.SimpleLoggerWriter(new SystemEnvironmentVariables()))
+ };
+
+ var invocationResponse2 = await handlerWrapper.Handler(invocation2);
+ if (onDemand)
+ Assert.True(object.ReferenceEquals(invocationResponse1.OutputStream, invocationResponse2.OutputStream));
+ else
+ Assert.False(object.ReferenceEquals(invocationResponse1.OutputStream, invocationResponse2.OutputStream));
+ }
+ }
+ finally
+ {
+ Environment.SetEnvironmentVariable(Constants.ENV_VAR_AWS_LAMBDA_MAX_CONCURRENCY, null);
+ }
+ }
+
private async Task TestHandlerWrapper(HandlerWrapper handlerWrapper, byte[] input, byte[] expectedOutput, bool expectedDisposeOutputStream)
{
// run twice to make sure wrappers that reuse the output stream work correctly
@@ -641,7 +684,7 @@ private async Task TestHandlerWrapper(HandlerWrapper handlerWrapper, byte[] inpu
var invocation = new InvocationRequest
{
InputStream = new MemoryStream(input ?? new byte[0]),
- LambdaContext = new LambdaContext(_runtimeApiHeaders, _lambdaEnvironment, new Helpers.SimpleLoggerWriter())
+ LambdaContext = new LambdaContext(_runtimeApiHeaders, _lambdaEnvironment, new Helpers.SimpleLoggerWriter(new SystemEnvironmentVariables()))
};
var invocationResponse = await handlerWrapper.Handler(invocation);
diff --git a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/LambdaBootstrapMultiConcurrencyTests.cs b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/LambdaBootstrapMultiConcurrencyTests.cs
new file mode 100644
index 000000000..2bee73286
--- /dev/null
+++ b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/LambdaBootstrapMultiConcurrencyTests.cs
@@ -0,0 +1,153 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+using Amazon.Lambda.Core;
+using Amazon.Lambda.RuntimeSupport.UnitTests.TestHelpers;
+using Amazon.Lambda.Serialization.Json;
+using Xunit;
+
+namespace Amazon.Lambda.RuntimeSupport.UnitTests
+{
+ public class LambdaBootstrapMultiConcurrencyTests
+ {
+ JsonSerializer _serializer = new JsonSerializer();
+
+ public LambdaBootstrapMultiConcurrencyTests()
+ {
+
+ }
+
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public async Task ConfirmConcurrentInvocations(bool useAsyncHandler)
+ {
+ TestEnvironmentVariables environmentVariables = new TestEnvironmentVariables();
+ environmentVariables.SetEnvironmentVariable(Amazon.Lambda.RuntimeSupport.Bootstrap.Constants.ENVIRONMENT_VARIABLE_AWS_LAMBDA_MAX_CONCURRENCY, "2");
+
+ var testRuntimeApiClient = new TestMultiConcurrencyRuntimeApiClient(environmentVariables,
+ new TestMultiConcurrencyRuntimeApiClient.InvocationEvent
+ {
+ Headers = CreateDefaultHeaders("request1", "trace1"),
+ FunctionInput = CreateFunctionInput(new SleepTimeEvent(0, 2000))
+ },
+ new TestMultiConcurrencyRuntimeApiClient.InvocationEvent
+ {
+ Headers = CreateDefaultHeaders("request2", "trace2"),
+ FunctionInput = CreateFunctionInput(new SleepTimeEvent(200, 200))
+ }
+ );
+
+ var handlerEvents = new List();
+
+ LambdaBootstrapHandler handler;
+ if (useAsyncHandler)
+ {
+ handler = HandlerWrapper.GetHandlerWrapper(async (SleepTimeEvent sleepTime, ILambdaContext context) =>
+ {
+ await Task.Delay(sleepTime.StartSleep);
+
+ lock (handlerEvents)
+ {
+ handlerEvents.Add($"start-{context.AwsRequestId},traceId-{context.TraceId}");
+ }
+ await Task.Delay(sleepTime.ProcessSleep);
+
+ lock (handlerEvents)
+ {
+ handlerEvents.Add($"end-{context.AwsRequestId},traceId-{context.TraceId}");
+ }
+ }, _serializer).Handler;
+ }
+ else
+ {
+ handler = HandlerWrapper.GetHandlerWrapper((SleepTimeEvent sleepTime, ILambdaContext context) =>
+ {
+ Thread.Sleep(sleepTime.StartSleep);
+
+ lock (handlerEvents)
+ {
+ handlerEvents.Add($"start-{context.AwsRequestId},traceId-{context.TraceId}");
+ }
+ Thread.Sleep(sleepTime.ProcessSleep);
+
+ lock (handlerEvents)
+ {
+ handlerEvents.Add($"end-{context.AwsRequestId},traceId-{context.TraceId}");
+ }
+ }, _serializer).Handler;
+ }
+
+
+ var lambdaBootstrap = new LambdaBootstrap(
+ httpClient: null,
+ handler: handler,
+ initializer: null,
+ ownsHttpClient: true,
+ environmentVariables: environmentVariables);
+ lambdaBootstrap.Client = testRuntimeApiClient;
+
+ try
+ {
+ CancellationTokenSource cts = new CancellationTokenSource();
+ cts.CancelAfter(TimeSpan.FromSeconds(3));
+ await lambdaBootstrap.RunAsync(cts.Token);
+ }
+ catch (OperationCanceledException)
+ {
+ // Expected when the cancellation token is triggered.
+ }
+
+ Assert.Equal(2, testRuntimeApiClient.ProcessInvocationEvents.Count);
+ Assert.Empty(testRuntimeApiClient.InvocationEvents);
+ Assert.Equal(4, handlerEvents.Count);
+
+ Assert.Equal("start-request1,traceId-trace1", handlerEvents[0]);
+ Assert.Equal("start-request2,traceId-trace2", handlerEvents[1]);
+ Assert.Equal("end-request2,traceId-trace2", handlerEvents[2]);
+ Assert.Equal("end-request1,traceId-trace1", handlerEvents[3]);
+ }
+
+ private Dictionary> CreateDefaultHeaders(string requestId, string traceId)
+ {
+ return new Dictionary>
+ {
+ {
+ RuntimeApiHeaders.HeaderAwsRequestId, new List { requestId }
+ },
+ {
+ RuntimeApiHeaders.HeaderInvokedFunctionArn, new List {"invoked_function_arn"}
+ },
+ {
+ RuntimeApiHeaders.HeaderTraceId, new List { traceId }
+ }
+ };
+ }
+
+ private byte[] CreateFunctionInput(object input)
+ {
+ using (var ms = new System.IO.MemoryStream())
+ {
+ _serializer.Serialize(input, ms);
+ return ms.ToArray();
+ }
+ }
+
+ public class SleepTimeEvent
+ {
+ public int StartSleep { get; set; }
+
+ public int ProcessSleep { get; set; }
+
+ public SleepTimeEvent(int startSleep, int processSleep)
+ {
+ StartSleep = startSleep;
+ ProcessSleep = processSleep;
+ }
+ }
+ }
+}
diff --git a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/LambdaBootstrapTests.cs b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/LambdaBootstrapTests.cs
index f17705072..e1636ff16 100644
--- a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/LambdaBootstrapTests.cs
+++ b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/LambdaBootstrapTests.cs
@@ -31,11 +31,11 @@ namespace Amazon.Lambda.RuntimeSupport.UnitTests
///
public class LambdaBootstrapTests
{
- TestHandler _testFunction;
- TestInitializer _testInitializer;
- TestRuntimeApiClient _testRuntimeApiClient;
- TestEnvironmentVariables _environmentVariables;
- HandlerWrapper _testWrapper;
+ readonly TestHandler _testFunction;
+ readonly TestInitializer _testInitializer;
+ readonly TestRuntimeApiClient _testRuntimeApiClient;
+ readonly TestEnvironmentVariables _environmentVariables;
+ readonly HandlerWrapper _testWrapper;
public LambdaBootstrapTests()
{
@@ -147,7 +147,7 @@ public async Task InitializerReturnsTrueAndHandlerLoopRuns()
[Fact]
public async Task TraceIdEnvironmentVariableIsSet()
{
- using (var bootstrap = new LambdaBootstrap(_testFunction.BaseHandlerAsync, null))
+ using (var bootstrap = new LambdaBootstrap(_testFunction.BaseHandlerAsync, null, null, _environmentVariables))
{
bootstrap.Client = _testRuntimeApiClient;
Assert.Null(_environmentVariables.GetEnvironmentVariable(LambdaEnvironment.EnvVarTraceId));
@@ -242,44 +242,46 @@ public void VerifyUserAgentStringSet()
[Fact]
public void IsCallPreJitTest()
{
- Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_DOTNET_PREJIT, "ProvisionedConcurrency");
- Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_INITIALIZATION_TYPE,
+ var environmentVariables = new TestEnvironmentVariables();
+
+ environmentVariables.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_DOTNET_PREJIT, "ProvisionedConcurrency");
+ environmentVariables.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_INITIALIZATION_TYPE,
AWS_LAMBDA_INITIALIZATION_TYPE_PC);
- Assert.True(UserCodeInit.IsCallPreJit());
- Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_DOTNET_PREJIT, "ProvisionedConcurrency");
- Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_INITIALIZATION_TYPE,
+ Assert.True(UserCodeInit.IsCallPreJit(environmentVariables));
+ environmentVariables.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_DOTNET_PREJIT, "ProvisionedConcurrency");
+ environmentVariables.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_INITIALIZATION_TYPE,
AWS_LAMBDA_INITIALIZATION_TYPE_ON_DEMAND);
- Assert.False(UserCodeInit.IsCallPreJit());
+ Assert.False(UserCodeInit.IsCallPreJit(environmentVariables));
- Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_DOTNET_PREJIT, "ProvisionedConcurrency");
- Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_INITIALIZATION_TYPE, null);
- Assert.False(UserCodeInit.IsCallPreJit());
+ environmentVariables.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_DOTNET_PREJIT, "ProvisionedConcurrency");
+ environmentVariables.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_INITIALIZATION_TYPE, null);
+ Assert.False(UserCodeInit.IsCallPreJit(environmentVariables));
- Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_DOTNET_PREJIT, "Always");
- Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_INITIALIZATION_TYPE, null);
- Assert.True(UserCodeInit.IsCallPreJit());
+ environmentVariables.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_DOTNET_PREJIT, "Always");
+ environmentVariables.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_INITIALIZATION_TYPE, null);
+ Assert.True(UserCodeInit.IsCallPreJit(environmentVariables));
- Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_DOTNET_PREJIT, "Never");
- Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_INITIALIZATION_TYPE, null);
- Assert.False(UserCodeInit.IsCallPreJit());
+ environmentVariables.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_DOTNET_PREJIT, "Never");
+ environmentVariables.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_INITIALIZATION_TYPE, null);
+ Assert.False(UserCodeInit.IsCallPreJit(environmentVariables));
- Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_DOTNET_PREJIT, null);
- Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_INITIALIZATION_TYPE, null);
- Assert.False(UserCodeInit.IsCallPreJit());
+ environmentVariables.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_DOTNET_PREJIT, null);
+ environmentVariables.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_INITIALIZATION_TYPE, null);
+ Assert.False(UserCodeInit.IsCallPreJit(environmentVariables));
- Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_DOTNET_PREJIT, null);
- Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_INITIALIZATION_TYPE, AWS_LAMBDA_INITIALIZATION_TYPE_ON_DEMAND);
- Assert.False(UserCodeInit.IsCallPreJit());
+ environmentVariables.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_DOTNET_PREJIT, null);
+ environmentVariables.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_INITIALIZATION_TYPE, AWS_LAMBDA_INITIALIZATION_TYPE_ON_DEMAND);
+ Assert.False(UserCodeInit.IsCallPreJit(environmentVariables));
- Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_DOTNET_PREJIT, "Never");
- Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_INITIALIZATION_TYPE, null);
- Assert.False(UserCodeInit.IsCallPreJit());
+ environmentVariables.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_DOTNET_PREJIT, "Never");
+ environmentVariables.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_INITIALIZATION_TYPE, null);
+ Assert.False(UserCodeInit.IsCallPreJit(environmentVariables));
- Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_DOTNET_PREJIT, null);
- Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_INITIALIZATION_TYPE, AWS_LAMBDA_INITIALIZATION_TYPE_PC);
- Assert.True(UserCodeInit.IsCallPreJit());
+ environmentVariables.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_DOTNET_PREJIT, null);
+ environmentVariables.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_LAMBDA_INITIALIZATION_TYPE, AWS_LAMBDA_INITIALIZATION_TYPE_PC);
+ Assert.True(UserCodeInit.IsCallPreJit(environmentVariables));
}
}
}
diff --git a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/LambdaContextTests.cs b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/LambdaContextTests.cs
index 58dec0856..d8964b912 100644
--- a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/LambdaContextTests.cs
+++ b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/LambdaContextTests.cs
@@ -31,7 +31,7 @@ public void RemainingTimeIsPositive()
var runtimeApiHeaders = new RuntimeApiHeaders(headers);
var lambdaEnvironment = new LambdaEnvironment(_environmentVariables);
- var context = new LambdaContext(runtimeApiHeaders, lambdaEnvironment, new Helpers.SimpleLoggerWriter());
+ var context = new LambdaContext(runtimeApiHeaders, lambdaEnvironment, new Helpers.SimpleLoggerWriter(new SystemEnvironmentVariables()));
Assert.True(context.RemainingTime >= TimeSpan.Zero, $"Remaining time is not a positive value: {context.RemainingTime}");
}
@@ -49,7 +49,7 @@ public void RuntimeApiHeadersAddedToContext()
var runtimeApiHeaders = new RuntimeApiHeaders(headers);
var lambdaEnvironment = new LambdaEnvironment(_environmentVariables);
- var context = new LambdaContext(runtimeApiHeaders, lambdaEnvironment, new Helpers.SimpleLoggerWriter());
+ var context = new LambdaContext(runtimeApiHeaders, lambdaEnvironment, new Helpers.SimpleLoggerWriter(new SystemEnvironmentVariables()));
Assert.Equal("request-generated-id", context.AwsRequestId);
Assert.Equal("my-function-arn", context.InvokedFunctionArn);
diff --git a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/LambdaEnvironmentTests.cs b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/LambdaEnvironmentTests.cs
index 7e5df993c..bd9ca49c2 100644
--- a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/LambdaEnvironmentTests.cs
+++ b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/LambdaEnvironmentTests.cs
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
@@ -21,7 +21,7 @@ namespace Amazon.Lambda.RuntimeSupport.UnitTests
public class LambdaEnvironmentTests
{
private const string LambdaExecutionEnvironment = "AWS_Lambda_dotnet_custom";
- TestEnvironmentVariables _environmentVariables;
+ private readonly TestEnvironmentVariables _environmentVariables;
public LambdaEnvironmentTests()
{
@@ -31,18 +31,17 @@ public LambdaEnvironmentTests()
[Fact]
public void SetsExecutionEnvironmentButNotTwice()
{
- var expectedValueRegex = new Regex($"{LambdaExecutionEnvironment}_amazonlambdaruntimesupport_[0-9]+\\.[0-9]+\\.[0-9]+");
+ var expectedValueRegex = $"{LambdaExecutionEnvironment}_amazonlambdaruntimesupport_[0-9]+\\.[0-9]+\\.[0-9]+";
_environmentVariables.SetEnvironmentVariable(LambdaEnvironment.EnvVarExecutionEnvironment, LambdaExecutionEnvironment);
var lambdaEnvironment = new LambdaEnvironment(_environmentVariables);
- Assert.True(expectedValueRegex.IsMatch(lambdaEnvironment.ExecutionEnvironment));
- Assert.True(expectedValueRegex.IsMatch(_environmentVariables.GetEnvironmentVariable(LambdaEnvironment.EnvVarExecutionEnvironment)));
+ Assert.Matches(expectedValueRegex, lambdaEnvironment.ExecutionEnvironment);
+ Assert.Matches(expectedValueRegex, _environmentVariables.GetEnvironmentVariable(LambdaEnvironment.EnvVarExecutionEnvironment));
// Make sure that creating another LambdaEnvironment instance won't change the value.
lambdaEnvironment = new LambdaEnvironment(_environmentVariables);
- Assert.True(expectedValueRegex.IsMatch(lambdaEnvironment.ExecutionEnvironment));
- Assert.True(expectedValueRegex.IsMatch(_environmentVariables.GetEnvironmentVariable(LambdaEnvironment.EnvVarExecutionEnvironment)));
-
+ Assert.Matches(expectedValueRegex, lambdaEnvironment.ExecutionEnvironment);
+ Assert.Matches(expectedValueRegex, _environmentVariables.GetEnvironmentVariable(LambdaEnvironment.EnvVarExecutionEnvironment));
}
[Fact]
diff --git a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/TestHelpers/PocoInput.cs b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/TestHelpers/PocoInput.cs
index 3ac0c0afe..c1297f44e 100644
--- a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/TestHelpers/PocoInput.cs
+++ b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/TestHelpers/PocoInput.cs
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
@@ -41,7 +41,7 @@ public override int GetHashCode()
int hash = hashBase;
hash = (hash * hashMultiplier) ^ (!Object.ReferenceEquals(null, InputString) ? InputString.GetHashCode() : 0);
- hash = (hash * hashMultiplier) ^ (!Object.ReferenceEquals(null, InputInt) ? InputInt.GetHashCode() : 0);
+ hash = (hash * hashMultiplier) ^ InputInt.GetHashCode();
return hash;
}
}
diff --git a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/TestHelpers/PocoOutput.cs b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/TestHelpers/PocoOutput.cs
index 8d0b26e31..166d190f2 100644
--- a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/TestHelpers/PocoOutput.cs
+++ b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/TestHelpers/PocoOutput.cs
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
@@ -41,7 +41,7 @@ public override int GetHashCode()
int hash = hashBase;
hash = (hash * hashMultiplier) ^ (!Object.ReferenceEquals(null, OutputString) ? OutputString.GetHashCode() : 0);
- hash = (hash * hashMultiplier) ^ (!Object.ReferenceEquals(null, OutputInt) ? OutputInt.GetHashCode() : 0);
+ hash = (hash * hashMultiplier) ^ OutputInt.GetHashCode();
return hash;
}
}
diff --git a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/TestHelpers/TestMultiConcurrencyRuntimeApiClient.cs b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/TestHelpers/TestMultiConcurrencyRuntimeApiClient.cs
new file mode 100644
index 000000000..f7c85dd15
--- /dev/null
+++ b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/TestHelpers/TestMultiConcurrencyRuntimeApiClient.cs
@@ -0,0 +1,131 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+using Amazon.Lambda.RuntimeSupport.Helpers;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace Amazon.Lambda.RuntimeSupport.UnitTests.TestHelpers
+{
+ internal class TestMultiConcurrencyRuntimeApiClient : IRuntimeApiClient
+ {
+ private readonly IEnvironmentVariables _environmentVariables;
+
+ public Queue InvocationEvents { get; } = new Queue();
+ public Dictionary ProcessInvocationEvents { get; } = new Dictionary();
+
+ public TestMultiConcurrencyRuntimeApiClient(IEnvironmentVariables environmentVariables, params InvocationEvent[] invocationEvents)
+ {
+ _environmentVariables = environmentVariables;
+ foreach (var invocationEvent in invocationEvents)
+ {
+ InvocationEvents.Enqueue(invocationEvent);
+ }
+
+ ConsoleLogger = new LogLevelLoggerWriter(environmentVariables);
+ }
+
+ public IConsoleLoggerWriter ConsoleLogger { get; }
+
+ public class InvocationEvent
+ {
+ public Dictionary> Headers { get; init; }
+ public byte[] FunctionInput { get; init; }
+
+ public Stream OutputStream { get; set; }
+
+ public bool Complete { get; set; }
+
+ public string AwsRequestId
+ {
+ get
+ {
+ if (Headers != null &&
+ Headers.TryGetValue(RuntimeApiHeaders.HeaderAwsRequestId, out var values))
+ {
+ return values?.FirstOrDefault();
+ }
+ return null;
+ }
+ }
+ }
+
+ public async Task GetNextInvocationAsync(CancellationToken cancellationToken = default)
+ {
+ // If InvocationEvents is empty then all of the test events have been processed.
+ // At this point we just need to wait for the test verification to run and then the
+ // cancellationToken will be triggered to end delay.
+ if (InvocationEvents.Count == 0)
+ {
+ await Task.Delay(TimeSpan.FromMinutes(10), cancellationToken);
+ }
+
+ var data = InvocationEvents.Dequeue();
+ ProcessInvocationEvents[data.AwsRequestId] = data;
+
+ var inputStream = new MemoryStream(data.FunctionInput == null ? new byte[0] : data.FunctionInput);
+ inputStream.Position = 0;
+
+ return new InvocationRequest()
+ {
+ InputStream = inputStream,
+ LambdaContext = new LambdaContext(
+ new RuntimeApiHeaders(data.Headers),
+ new LambdaEnvironment(_environmentVariables),
+ new TestDateTimeHelper(), new Helpers.SimpleLoggerWriter(_environmentVariables))
+ };
+ }
+
+ public Task SendResponseAsync(string awsRequestId, Stream outputStream, CancellationToken cancellationToken = default)
+ {
+ var data = ProcessInvocationEvents[awsRequestId];
+ data.Complete = true;
+ if (outputStream != null)
+ {
+ // copy the stream because it gets disposed by the bootstrap
+ data.OutputStream = new MemoryStream((int)outputStream.Length);
+ outputStream.CopyTo(data.OutputStream);
+ data.OutputStream.Position = 0;
+ }
+
+ return Task.Run(() => { });
+ }
+
+
+ public Task RestoreNextInvocationAsync(CancellationToken cancellationToken = default)
+ {
+ return Task.Run(() => { });
+ }
+
+ public Task ReportInitializationErrorAsync(Exception exception, String errorType = null, CancellationToken cancellationToken = default)
+ {
+ return Task.Run(() => { });
+ }
+
+ public Task ReportInitializationErrorAsync(string errorType, CancellationToken cancellationToken = default)
+ {
+ return Task.Run(() => { });
+ }
+
+ public Task ReportInvocationErrorAsync(string awsRequestId, Exception exception, CancellationToken cancellationToken = default)
+ {
+ return Task.Run(() => { });
+ }
+
+ public Task ReportInvocationErrorAsync(string awsRequestId, string errorType, CancellationToken cancellationToken = default)
+ {
+ return Task.Run(() => { });
+ }
+
+ public Task ReportRestoreErrorAsync(Exception exception, String errorType = null, CancellationToken cancellationToken = default)
+ {
+ return Task.Run(() => { });
+ }
+ }
+}
diff --git a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/TestHelpers/TestRuntimeApiClient.cs b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/TestHelpers/TestRuntimeApiClient.cs
index ef500e746..50bfa7254 100644
--- a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/TestHelpers/TestRuntimeApiClient.cs
+++ b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/TestHelpers/TestRuntimeApiClient.cs
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
@@ -26,10 +26,10 @@ namespace Amazon.Lambda.RuntimeSupport.UnitTests
{
internal class TestRuntimeApiClient : IRuntimeApiClient
{
- private IEnvironmentVariables _environmentVariables;
- private Dictionary> _headers;
+ readonly private IEnvironmentVariables _environmentVariables;
+ readonly private Dictionary> _headers;
- public IConsoleLoggerWriter ConsoleLogger { get; } = new LogLevelLoggerWriter();
+ public IConsoleLoggerWriter ConsoleLogger { get; } = new LogLevelLoggerWriter(new SystemEnvironmentVariables());
public TestRuntimeApiClient(IEnvironmentVariables environmentVariables, Dictionary> headers)
{
@@ -99,7 +99,7 @@ public Task GetNextInvocationAsync(CancellationToken cancella
LambdaContext = new LambdaContext(
new RuntimeApiHeaders(_headers),
new LambdaEnvironment(_environmentVariables),
- new TestDateTimeHelper(), new Helpers.SimpleLoggerWriter())
+ new TestDateTimeHelper(), new Helpers.SimpleLoggerWriter(_environmentVariables))
});
}
diff --git a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/UtilsTest.cs b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/UtilsTest.cs
new file mode 100644
index 000000000..8068920be
--- /dev/null
+++ b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/UtilsTest.cs
@@ -0,0 +1,70 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+using System;
+using Amazon.Lambda.RuntimeSupport.Helpers;
+using Xunit;
+using Amazon.Lambda.RuntimeSupport.Bootstrap;
+
+namespace Amazon.Lambda.RuntimeSupport.UnitTests;
+
+
+public class UtilsTest
+{
+ [Theory]
+ [InlineData("5", true)]
+ [InlineData("", false)]
+ [InlineData(null, false)]
+ public void IsUsingMultiConcurrency(string concurrency, bool isMultiConcurrency)
+ {
+ var envVars = new TestEnvironmentVariables();
+
+ if (concurrency != null)
+ envVars.SetEnvironmentVariable(Constants.ENVIRONMENT_VARIABLE_AWS_LAMBDA_MAX_CONCURRENCY, concurrency);
+
+ var result = Utils.IsUsingMultiConcurrency(envVars);
+
+ Assert.Equal(isMultiConcurrency, result);
+ }
+
+ [Theory]
+ [InlineData(null, 4, 1)]
+ [InlineData("5", 4, 4)]
+ [InlineData("5", 1, 2)]
+ public void DetermineProcessingTaskCount(string concurrency, int processCount, int expected)
+ {
+ var envVars = new TestEnvironmentVariables();
+
+ if (concurrency != null)
+ envVars.SetEnvironmentVariable(Constants.ENVIRONMENT_VARIABLE_AWS_LAMBDA_MAX_CONCURRENCY, concurrency);
+
+ var result = Utils.DetermineProcessingTaskCount(envVars, processCount);
+
+ Assert.Equal(expected, result);
+ }
+
+ [Fact]
+ public void DetermineProcessingTaskCount_WhenOverrideSet_ReturnsOverrideValue()
+ {
+ var envVars = new TestEnvironmentVariables();
+ envVars.SetEnvironmentVariable(Constants.ENVIRONMENT_VARIABLE_AWS_LAMBDA_MAX_CONCURRENCY, "5");
+ envVars.SetEnvironmentVariable(Constants.ENVIRONMENT_VARIABLE_AWS_LAMBDA_DOTNET_PROCESSING_TASKS, "8");
+
+ var result = Utils.DetermineProcessingTaskCount(envVars, 4);
+
+ Assert.Equal(8, result);
+ }
+
+ [Theory]
+ [InlineData("0")]
+ [InlineData("-1")]
+ [InlineData("invalid")]
+ public void DetermineProcessingTaskCount_ThrowsArgumentException(string processingTasksOverride)
+ {
+ var envVars = new TestEnvironmentVariables();
+ envVars.SetEnvironmentVariable(Constants.ENVIRONMENT_VARIABLE_AWS_LAMBDA_MAX_CONCURRENCY, "5");
+ envVars.SetEnvironmentVariable(Constants.ENVIRONMENT_VARIABLE_AWS_LAMBDA_DOTNET_PROCESSING_TASKS, processingTasksOverride);
+
+ Assert.Throws(() => Utils.DetermineProcessingTaskCount(envVars, 4));
+ }
+}
diff --git a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest/CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest.csproj b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest/CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest.csproj
index 500a7cdd8..849e21461 100644
--- a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest/CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest.csproj
+++ b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest/CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net8.0
enable
enable
bootstrap
diff --git a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/CustomRuntimeAspNetCoreMinimalApiTest/CustomRuntimeAspNetCoreMinimalApiTest.csproj b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/CustomRuntimeAspNetCoreMinimalApiTest/CustomRuntimeAspNetCoreMinimalApiTest.csproj
index 500a7cdd8..849e21461 100644
--- a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/CustomRuntimeAspNetCoreMinimalApiTest/CustomRuntimeAspNetCoreMinimalApiTest.csproj
+++ b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/CustomRuntimeAspNetCoreMinimalApiTest/CustomRuntimeAspNetCoreMinimalApiTest.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net8.0
enable
enable
bootstrap
diff --git a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/CustomRuntimeFunctionTest/CustomRuntimeFunction.cs b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/CustomRuntimeFunctionTest/CustomRuntimeFunction.cs
index 6d9c80f91..955b1b3d8 100644
--- a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/CustomRuntimeFunctionTest/CustomRuntimeFunction.cs
+++ b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/CustomRuntimeFunctionTest/CustomRuntimeFunction.cs
@@ -22,9 +22,9 @@ class CustomRuntimeFunction
private static readonly Lazy SixMBString = new Lazy(() => { return new string('X', 1024 * 1024 * 6); });
private static readonly Lazy SevenMBString = new Lazy(() => { return new string('X', 1024 * 1024 * 7); });
- private static MemoryStream ResponseStream = new MemoryStream();
- private static DefaultLambdaJsonSerializer JsonSerializer = new DefaultLambdaJsonSerializer();
- private static LambdaEnvironment LambdaEnvironment = new LambdaEnvironment();
+ private static readonly MemoryStream ResponseStream = new MemoryStream();
+ private static readonly DefaultLambdaJsonSerializer JsonSerializer = new DefaultLambdaJsonSerializer();
+ private static readonly LambdaEnvironment LambdaEnvironment = new LambdaEnvironment();
private static async Task Main(string[] args)
{
@@ -69,9 +69,6 @@ private static async Task Main(string[] args)
case nameof(CertificateCallbackWorksAsync):
bootstrap = new LambdaBootstrap(CertificateCallbackWorksAsync);
break;
- case nameof(NetworkingProtocolsAsync):
- bootstrap = new LambdaBootstrap(NetworkingProtocolsAsync);
- break;
case nameof(HandlerEnvVarAsync):
bootstrap = new LambdaBootstrap(HandlerEnvVarAsync);
break;
@@ -217,7 +214,7 @@ private static Task UnintendedDisposeTest(InvocationRequest
public class WrapTextWriter : TextWriter
{
- TextWriter _textWriter;
+ readonly TextWriter _textWriter;
public WrapTextWriter(TextWriter textWriter)
{
_textWriter = textWriter;
@@ -302,67 +299,6 @@ private static async Task CertificateCallbackWorksAsync(Invo
return GetInvocationResponse(nameof(CertificateCallbackWorksAsync), isSuccess);
}
- private static Task NetworkingProtocolsAsync(InvocationRequest invocation)
- {
- var type = typeof(Socket).GetTypeInfo().Assembly.GetType("System.Net.SocketProtocolSupportPal");
- var method = type.GetMethod("IsSupported", BindingFlags.NonPublic | BindingFlags.Static);
- var ipv4Supported = method.Invoke(null, new object[] { AddressFamily.InterNetwork });
- var ipv6Supported = method.Invoke(null, new object[] { AddressFamily.InterNetworkV6 });
-
- Exception ipv4SocketCreateException = null;
- try
- {
- using (Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { }
- }
- catch (Exception e)
- {
- ipv4SocketCreateException = e;
- }
-
- Exception ipv6SocketCreateException = null;
- try
- {
- using (Socket s = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp)) { }
- }
- catch (Exception e)
- {
- ipv6SocketCreateException = e;
- }
-
- string returnValue = "";
- if (!(bool)ipv4Supported)
- {
- returnValue += "For System.Net.SocketProtocolSupportPal.IsProtocolSupported(AddressFamily.InterNetwork) Expected true, Actual false" + Environment.NewLine;
- }
-
- if ((bool)ipv6Supported)
- {
- returnValue += "For System.Net.SocketProtocolSupportPal.IsProtocolSupported(AddressFamily.InterNetworkV6) Expected false, Actual true" + Environment.NewLine;
- }
-
- if (ipv4SocketCreateException != null)
- {
- returnValue += "Error creating IPV4 Socket: " + ipv4SocketCreateException + Environment.NewLine;
- }
-
- if (ipv6SocketCreateException == null)
- {
- returnValue += "When creating IPV6 Socket expected exception, got none." + Environment.NewLine;
- }
-
- if (ipv6SocketCreateException != null && ipv6SocketCreateException.Message != "Address family not supported by protocol")
- {
- returnValue += "When creating IPV6 Socket expected exception 'Address family not supported by protocol', actual '" + ipv6SocketCreateException.Message + "'" + Environment.NewLine;
- }
-
- if (String.IsNullOrEmpty(returnValue))
- {
- returnValue = "SUCCESS";
- }
-
- return Task.FromResult(GetInvocationResponse(nameof(NetworkingProtocolsAsync), returnValue));
- }
-
private static Task HandlerEnvVarAsync(InvocationRequest invocation)
{
return Task.FromResult(GetInvocationResponse(nameof(HandlerEnvVarAsync), LambdaEnvironment.Handler));
@@ -459,9 +395,9 @@ private static Task GetTimezoneNameAsync(InvocationRequest i
return Task.FromResult(GetInvocationResponse(nameof(GetTimezoneNameAsync), TimeZoneInfo.Local.Id));
}
- private static async Task GetTotalAvailableMemoryBytes(InvocationRequest invocation)
+ private static Task GetTotalAvailableMemoryBytes(InvocationRequest invocation)
{
- return GetInvocationResponse(nameof(GetTotalAvailableMemoryBytes), GC.GetGCMemoryInfo().TotalAvailableMemoryBytes.ToString());
+ return Task.FromResult(GetInvocationResponse(nameof(GetTotalAvailableMemoryBytes), GC.GetGCMemoryInfo().TotalAvailableMemoryBytes.ToString()));
}
#region Helpers
diff --git a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/CustomRuntimeFunctionTest/CustomRuntimeFunctionTest.csproj b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/CustomRuntimeFunctionTest/CustomRuntimeFunctionTest.csproj
index 3671a75cc..e38db03d4 100644
--- a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/CustomRuntimeFunctionTest/CustomRuntimeFunctionTest.csproj
+++ b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/CustomRuntimeFunctionTest/CustomRuntimeFunctionTest.csproj
@@ -3,6 +3,8 @@
Exe
net6.0;net8.0
+
+ IDE0060
diff --git a/bootstrap.ps1 b/bootstrap.ps1
deleted file mode 100644
index d68182226..000000000
--- a/bootstrap.ps1
+++ /dev/null
@@ -1,65 +0,0 @@
-param (
- [Parameter(Mandatory = $true, HelpMessage = "Pipeline Account ID.")]
- [string] $PipelineAccountId,
-
- [Parameter(Mandatory = $false, HelpMessage = "Pipeline name suffix.")]
- [string] $PipelineNameSuffix,
-
- [Parameter(Mandatory = $true, HelpMessage = "Region.")]
- [string] $Region,
-
- [Parameter(Mandatory = $true, HelpMessage = "The name of the secret in Secret Manager that contains the GitHub Access Token.")]
- [string] $GitHubTokenSecretName,
-
- [Parameter(Mandatory = $true, HelpMessage = "The secret key in Secret Manager that contains the GitHub Access Token.")]
- [string] $GitHubTokenSecretKey,
-
- [Parameter(Mandatory = $true, HelpMessage = "GitHub repository owner name.")]
- [string] $GitHubRepoOwner,
-
- [Parameter(Mandatory = $true, HelpMessage = "GitHub repository name.")]
- [string] $GitHubRepoName,
-
- [Parameter(Mandatory = $true, HelpMessage = "GitHub repository branch name.")]
- [string] $GitHubRepoBranch,
-
- [Parameter(Mandatory = $true, HelpMessage = "GitHub staging repository owner name.")]
- [string] $GitHubRepoOwnerStaging,
-
- [Parameter(Mandatory = $true, HelpMessage = "GitHub staging repository name.")]
- [string] $GitHubRepoNameStaging,
-
- [Parameter(Mandatory = $true, HelpMessage = "GitHub staging repository branch name.")]
- [string] $GitHubRepoBranchStaging,
-
- [Parameter(Mandatory = $false, HelpMessage = "ECR URI to store Stage images.")]
- [string] $StageEcr,
-
- [Parameter(Mandatory = $false, HelpMessage = "Semicolon separated ECR URIs to store Beta images.")]
- [string] $BetaEcrs,
-
- [Parameter(Mandatory = $false, HelpMessage = "Semicolon separated ECR URIs to store Prod images.")]
- [string] $ProdEcrs
-)
-
-$env:AWS_LAMBDA_PIPELINE_ACCOUNT_ID = $PipelineAccountId
-$env:AWS_LAMBDA_PIPELINE_REGION = $Region
-$env:AWS_LAMBDA_PIPELINE_NAME_SUFFIX = $PipelineNameSuffix
-
-$env:AWS_LAMBDA_GITHUB_TOKEN_SECRET_NAME = $GitHubTokenSecretName
-$env:AWS_LAMBDA_GITHUB_TOKEN_SECRET_KEY = $GitHubTokenSecretKey
-
-$env:AWS_LAMBDA_GITHUB_REPO_OWNER = $GitHubRepoOwner
-$env:AWS_LAMBDA_GITHUB_REPO_NAME = $GitHubRepoName
-$env:AWS_LAMBDA_GITHUB_REPO_BRANCH = $GitHubRepoBranch
-
-$env:AWS_LAMBDA_GITHUB_REPO_OWNER_STAGING = $GitHubRepoOwnerStaging
-$env:AWS_LAMBDA_GITHUB_REPO_NAME_STAGING = $GitHubRepoNameStaging
-$env:AWS_LAMBDA_GITHUB_REPO_BRANCH_STAGING = $GitHubRepoBranchStaging
-
-$env:AWS_LAMBDA_STAGE_ECR = $StageEcr
-$env:AWS_LAMBDA_BETA_ECRS = $BetaEcrs
-$env:AWS_LAMBDA_PROD_ECRS = $ProdEcrs
-
-npx cdk bootstrap --cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess aws://$PipelineAccountId/$Region
-npx cdk deploy --require-approval never --all
diff --git a/cdk.json b/cdk.json
deleted file mode 100644
index c1a1e7782..000000000
--- a/cdk.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "app": "dotnet run --project LambdaRuntimeDockerfiles/Infrastructure/src/Infrastructure/Infrastructure.csproj",
- "watch": {
- "include": [
- "**"
- ],
- "exclude": [
- "README.md",
- "cdk*.json",
- "src/*/obj",
- "src/*/bin",
- "src/*.sln",
- "src/*/GlobalSuppressions.cs",
- "src/*/*.csproj"
- ]
- },
- "context": {
- "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": false,
- "@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": false,
- "@aws-cdk/aws-rds:lowercaseDbIdentifier": false,
- "@aws-cdk/core:stackRelativeExports": false
- }
-}
\ No newline at end of file