diff --git a/Libraries/src/Amazon.Lambda.RuntimeSupport/Amazon.Lambda.RuntimeSupport.csproj b/Libraries/src/Amazon.Lambda.RuntimeSupport/Amazon.Lambda.RuntimeSupport.csproj index e7b98093f..a719d89b1 100644 --- a/Libraries/src/Amazon.Lambda.RuntimeSupport/Amazon.Lambda.RuntimeSupport.csproj +++ b/Libraries/src/Amazon.Lambda.RuntimeSupport/Amazon.Lambda.RuntimeSupport.csproj @@ -1,4 +1,4 @@ - + @@ -13,7 +13,9 @@ README.md true true - 9.0 + true + NU5048;NU1903;NU1902 + 9.0 @@ -22,7 +24,6 @@ - IL2026,IL2067,IL2075 true true diff --git a/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/HandlerWrapper.cs b/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/HandlerWrapper.cs index 78efda915..3b05f646e 100644 --- a/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/HandlerWrapper.cs +++ b/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/HandlerWrapper.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"). @@ -29,8 +29,11 @@ public class HandlerWrapper : IDisposable private static readonly InvocationResponse EmptyInvocationResponse = new InvocationResponse(new MemoryStream(0), false); - private MemoryStream OutputStream = new MemoryStream(); + private readonly MemoryStream OutputStream = new MemoryStream(); + /// + /// The handler that will be called for each event. + /// public LambdaBootstrapHandler Handler { get; private set; } private HandlerWrapper(LambdaBootstrapHandler handler) @@ -163,7 +166,7 @@ public static HandlerWrapper GetHandlerWrapper(Func /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. - /// Example handler signature: Task<Stream> Handler() + /// Example handler signature: Task<Stream> Handler() /// /// Func called for each invocation of the Lambda function. /// A HandlerWrapper @@ -178,7 +181,7 @@ public static HandlerWrapper GetHandlerWrapper(Func> handler) /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. - /// Example handler signature: Task<Stream> Handler(Stream) + /// Example handler signature: Task<Stream> Handler(Stream) /// /// Func called for each invocation of the Lambda function. /// A HandlerWrapper @@ -193,7 +196,7 @@ public static HandlerWrapper GetHandlerWrapper(Func> handle /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. - /// Example handler signature: Task<Stream> Handler(PocoIn) + /// Example handler signature: Task<Stream> Handler(PocoIn) /// /// Func called for each invocation of the Lambda function. /// ILambdaSerializer to use when calling the handler @@ -210,7 +213,7 @@ public static HandlerWrapper GetHandlerWrapper(Func /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. - /// Example handler signature: Task<Stream> Handler(ILambdaContext) + /// Example handler signature: Task<Stream> Handler(ILambdaContext) /// /// Func called for each invocation of the Lambda function. /// A HandlerWrapper @@ -225,7 +228,7 @@ public static HandlerWrapper GetHandlerWrapper(Func /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. - /// Example handler signature: Task<Stream> Handler(Stream, ILambdaContext) + /// Example handler signature: Task<Stream> Handler(Stream, ILambdaContext) /// /// Func called for each invocation of the Lambda function. /// A HandlerWrapper @@ -240,7 +243,7 @@ public static HandlerWrapper GetHandlerWrapper(Func /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. - /// Example handler signature: Task<Stream> Handler(PocoIn, ILambdaContext) + /// Example handler signature: Task<Stream> Handler(PocoIn, ILambdaContext) /// /// Func called for each invocation of the Lambda function. /// ILambdaSerializer to use when calling the handler @@ -257,7 +260,7 @@ public static HandlerWrapper GetHandlerWrapper(Func /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. - /// Example handler signature: Task<PocoOut> Handler() + /// Example handler signature: Task<PocoOut> Handler() /// /// Func called for each invocation of the Lambda function. /// ILambdaSerializer to use when calling the handler @@ -279,7 +282,7 @@ public static HandlerWrapper GetHandlerWrapper(Func> hand /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. - /// Example handler signature: Task<PocoOut> Handler(Stream) + /// Example handler signature: Task<PocoOut> Handler(Stream) /// /// Func called for each invocation of the Lambda function. /// ILambdaSerializer to use when calling the handler @@ -301,7 +304,7 @@ public static HandlerWrapper GetHandlerWrapper(Func /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. - /// Example handler signature: Task<PocoOut> Handler(PocoIn) + /// Example handler signature: Task<PocoOut> Handler(PocoIn) /// /// Func called for each invocation of the Lambda function. /// ILambdaSerializer to use when calling the handler @@ -324,7 +327,7 @@ public static HandlerWrapper GetHandlerWrapper(Func /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. - /// Example handler signature: Task<PocoOut> Handler(ILambdaContext) + /// Example handler signature: Task<PocoOut> Handler(ILambdaContext) /// /// Func called for each invocation of the Lambda function. /// ILambdaSerializer to use when calling the handler @@ -346,7 +349,7 @@ public static HandlerWrapper GetHandlerWrapper(Func /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. - /// Example handler signature: Task<PocoOut> Handler(Stream, ILambdaContext) + /// Example handler signature: Task<PocoOut> Handler(Stream, ILambdaContext) /// /// Func called for each invocation of the Lambda function. /// ILambdaSerializer to use when calling the handler @@ -368,7 +371,7 @@ public static HandlerWrapper GetHandlerWrapper(Func /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. - /// Example handler signature: Task<PocoOut> Handler(PocoIn, ILambdaContext) + /// Example handler signature: Task<PocoOut> Handler(PocoIn, ILambdaContext) /// /// Func called for each invocation of the Lambda function. /// ILambdaSerializer to use when calling the handler @@ -719,6 +722,9 @@ public static HandlerWrapper GetHandlerWrapper(Func + /// Dispose the HandlerWrapper + /// protected virtual void Dispose(bool disposing) { if (!disposedValue) @@ -732,6 +738,9 @@ protected virtual void Dispose(bool disposing) } } + /// + /// Dispose the HandlerWrapper + /// public void Dispose() { Dispose(true); diff --git a/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/InvokeDelegateBuilder.cs b/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/InvokeDelegateBuilder.cs index 0cbbe1829..316f2ee78 100644 --- a/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/InvokeDelegateBuilder.cs +++ b/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/InvokeDelegateBuilder.cs @@ -49,7 +49,7 @@ public InvokeDelegateBuilder(InternalLogger logger, HandlerInfo handler, MethodI /// /// Constructs the invoke delegate using Expressions /// - /// Serialize & Deserialize calls are only made when a serializer is provided. + /// Serialize and Deserialize calls are only made when a serializer is provided. /// Context is only passed when customer method has context parameter. /// Lambda return type can be void. /// @@ -62,7 +62,8 @@ public InvokeDelegateBuilder(InternalLogger logger, HandlerInfo handler, MethodI /// /// /// Wrapped customer object. - /// Instance of lambda input & output serializer. + /// Instance of lambda input & output serializer. + /// If true forces more .NET code to get loaded during startup for jitting. /// Action delegate pointing to customer's handler. #if NET8_0_OR_GREATER [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("ConstructInvokeDelegate does not support trimming and is meant to be used in class library based Lambda functions.")] @@ -73,7 +74,7 @@ public Action ConstructInvokeDelegate(object cus var outStreamParameter = Expression.Parameter(Types.StreamType, "outStream"); var contextParameter = Expression.Parameter(typeof(ILambdaContext), "context"); - _logger.LogDebug($"UCL : Constructing input expression"); + _logger.LogDebug("UCL : Constructing input expression"); var inputExpression = BuildInputExpressionOrNull(customerSerializerInstance, inStreamParameter, out var iLambdaContextType); if (isPreJit) { @@ -81,13 +82,13 @@ public Action ConstructInvokeDelegate(object cus UserCodeInit.InitDeserializationAssembly(inputExpression, inStreamParameter); } - _logger.LogDebug($"UCL : Constructing context expression"); + _logger.LogDebug("UCL : Constructing context expression"); var contextExpression = BuildContextExpressionOrNull(iLambdaContextType, contextParameter); - _logger.LogDebug($"UCL : Constructing handler expression"); + _logger.LogDebug("UCL : Constructing handler expression"); var handlerExpression = CreateHandlerCallExpression(customerObject, inputExpression, contextExpression); - _logger.LogDebug($"UCL : Constructing output expression"); + _logger.LogDebug("UCL : Constructing output expression"); var outputExpression = CreateOutputExpression(customerSerializerInstance, outStreamParameter, handlerExpression); if (isPreJit) { @@ -95,7 +96,7 @@ public Action ConstructInvokeDelegate(object cus UserCodeInit.InitSerializationAssembly(outputExpression, outStreamParameter, CustomerOutputType); } - _logger.LogDebug($"UCL : Constructing final expression"); + _logger.LogDebug("UCL : Constructing final expression"); var finalExpression = Expression.Lambda>(outputExpression, inStreamParameter, contextParameter, outStreamParameter); #if DEBUG @@ -103,10 +104,10 @@ public Action ConstructInvokeDelegate(object cus .GetTypeInfo() .GetProperty("DebugView", BindingFlags.Instance | BindingFlags.NonPublic) .GetValue(finalExpression); - _logger.LogDebug($"UCL : Constructed final expression:\n'{finalExpressionDebugView}'"); + _logger.LogDebug("UCL : Constructed final expression:\n'{finalExpressionDebugView}'"); #endif - _logger.LogDebug($"UCL : Compiling final expression"); + _logger.LogDebug("UCL : Compiling final expression"); return finalExpression.Compile(); } @@ -114,13 +115,13 @@ public Action ConstructInvokeDelegate(object cus /// Creates an expression to convert incoming Stream to the customer method inputs. /// If customer method takes no inputs or only takes ILambdaContext, return null. /// - /// Instance of lambda input & output serializer. + /// Instance of lambda input and output serializer. /// Input stream parameter. /// Type of context passed for the invocation. /// Expression that deserializes incoming stream to the customer method inputs or null if customer method takes no input. /// Thrown when customer method inputs don't meet lambda requirements. #if NET8_0_OR_GREATER - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("BuildInputExpressionOrNull does not support trimming and is meant to be used in class library based Lambda functions.")] + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("BuildInputExpressionOrNull does not support trimming and is meant to be used in class library based Lambda functions.")] #endif private Expression BuildInputExpressionOrNull(object customerSerializerInstance, Expression inStreamParameter, out Type iLambdaContextType) { @@ -171,7 +172,7 @@ private Expression BuildInputExpressionOrNull(object customerSerializerInstance, if (iLambdaContextType != null) { - _logger.LogDebug($"UCL : Validating iLambdaContextType"); + _logger.LogDebug("UCL : Validating iLambdaContextType"); UserCodeValidator.ValidateILambdaContextType(iLambdaContextType); } @@ -257,7 +258,7 @@ private Expression CreateHandlerCallExpression(object customerObject, Expression /// is just the handler call expression. Otherwise, the final expression is the /// serialization expression operating on the handler call expression. /// - /// Instance of lambda input & output serializer. + /// Instance of lambda input and output serializer. /// Expression that defines customer output. /// Expression that defines customer handler call. /// Expression that serializes customer method output to outgoing stream. @@ -313,12 +314,12 @@ private static Type GetTaskTSubclassOrNull(Type type) /// /// Generates an expression to serialize customer method result into the output stream /// - /// Instance of lambda input & output serializer. + /// Instance of lambda input and output serializer. /// Customer input type. /// Expression that define customer object. /// Expression that defines customer output. /// Expression that serializes returned object to output stream. - /// Thrown when customer input is serializable & serializer instance is null. + /// Thrown when customer input is serializable & serializer instance is null. #if NET8_0_OR_GREATER [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("CreateSerializeExpression does not support trimming and is meant to be used in class library based Lambda functions.")] #endif @@ -371,7 +372,7 @@ private Expression CreateSerializeExpression(object customerSerializerInstance, /// /// Generates an expression to deserialize incoming data to customer method input /// - /// Instance of lambda input & output serializer. + /// Instance of lambda input and output serializer. /// Customer input type. /// Input expression that defines customer input. /// Expression that deserializes incoming data to customer method input. @@ -411,4 +412,4 @@ private Expression CreateDeserializeExpression(object customerSerializerInstance return deserializeCall; } } -} \ No newline at end of file +} diff --git a/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/LambdaBootstrap.cs b/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/LambdaBootstrap.cs index 1c59178fe..987349f54 100644 --- a/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/LambdaBootstrap.cs +++ b/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/LambdaBootstrap.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"). @@ -24,7 +24,17 @@ namespace Amazon.Lambda.RuntimeSupport { + /// + /// Delegate for the handler that will be invoked for each event. + /// + /// + /// public delegate Task LambdaBootstrapHandler(InvocationRequest invocation); + + /// + /// Delegate for an initializer run during startup. + /// + /// public delegate Task LambdaBootstrapInitializer(); /// @@ -44,7 +54,7 @@ public class LambdaBootstrap : IDisposable private bool _ownsHttpClient; private InternalLogger _logger = InternalLogger.GetDefaultLogger(); - private HttpClient _httpClient; + private readonly HttpClient _httpClient; private LambdaBootstrapConfiguration _configuration; internal IRuntimeApiClient Client { get; set; } @@ -172,10 +182,10 @@ private LambdaBootstrap(HttpClient httpClient, LambdaBootstrapHandler handler, L if (_configuration.IsCallPreJit) { - this._logger.LogInformation("PreJit: CultureInfo"); + _logger.LogInformation("PreJit: CultureInfo"); UserCodeInit.LoadStringCultureInfo(); - this._logger.LogInformation("PreJit: Amazon.Lambda.Core"); + _logger.LogInformation("PreJit: Amazon.Lambda.Core"); UserCodeInit.PreJitAssembly(typeof(Amazon.Lambda.Core.ILambdaContext).Assembly); } @@ -193,7 +203,7 @@ private LambdaBootstrap(HttpClient httpClient, LambdaBootstrapHandler handler, L // Check if Initialization type is SnapStart, and invoke the snapshot restore logic. if (_configuration.IsInitTypeSnapstart) { - InternalLogger.GetDefaultLogger().LogInformation($"In LambdaBootstrap, Initializing with SnapStart."); + InternalLogger.GetDefaultLogger().LogInformation("In LambdaBootstrap, Initializing with SnapStart."); object registry = null; try @@ -204,7 +214,7 @@ private LambdaBootstrap(HttpClient httpClient, LambdaBootstrapHandler handler, L { Client.ConsoleLogger.FormattedWriteLine( Amazon.Lambda.RuntimeSupport.Helpers.LogLevelLoggerWriter.LogLevel.Error.ToString(), - $"Failed to retrieve snapshot hooks from Amazon.Lambda.Core.SnapshotRestore, " + + "Failed to retrieve snapshot hooks from Amazon.Lambda.Core.SnapshotRestore, " + $"this can be fixed by updating the version of Amazon.Lambda.Core: {ex}", null); } @@ -257,7 +267,7 @@ internal async Task InitializeAsync() internal async Task InvokeOnceAsync(CancellationToken cancellationToken = default) { - this._logger.LogInformation($"Starting InvokeOnceAsync"); + _logger.LogInformation("Starting InvokeOnceAsync"); using (var invocation = await Client.GetNextInvocationAsync(cancellationToken)) { InvocationResponse response = null; @@ -265,7 +275,7 @@ internal async Task InvokeOnceAsync(CancellationToken cancellationToken = defaul try { - this._logger.LogInformation($"Starting invoking handler"); + _logger.LogInformation("Starting invoking handler"); response = await _handler(invocation); invokeSucceeded = true; } @@ -276,12 +286,12 @@ internal async Task InvokeOnceAsync(CancellationToken cancellationToken = defaul } finally { - this._logger.LogInformation($"Finished invoking handler"); + _logger.LogInformation("Finished invoking handler"); } if (invokeSucceeded) { - this._logger.LogInformation($"Starting sending response"); + _logger.LogInformation("Starting sending response"); try { await Client.SendResponseAsync(invocation.LambdaContext.AwsRequestId, response?.OutputStream); @@ -293,10 +303,10 @@ internal async Task InvokeOnceAsync(CancellationToken cancellationToken = defaul response.OutputStream?.Dispose(); } - this._logger.LogInformation($"Finished sending response"); + _logger.LogInformation("Finished sending response"); } } - this._logger.LogInformation($"Finished InvokeOnceAsync"); + _logger.LogInformation("Finished InvokeOnceAsync"); } } @@ -392,6 +402,10 @@ private void AdjustMemorySettings() #region IDisposable Support private bool disposedValue = false; // To detect redundant calls + /// + /// Dispose the LambdaBootstrap. If the bootstrap owns the HttpClient it will dispose the client. + /// + /// protected virtual void Dispose(bool disposing) { if (!disposedValue) @@ -404,7 +418,9 @@ protected virtual void Dispose(bool disposing) } } - // This code added to correctly implement the disposable pattern. + /// + /// Dispose the LambdaBootstrap + /// public void Dispose() { // Do not change this code. Put cleanup code in Dispose(bool disposing) above. diff --git a/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/LambdaBootstrapBuilder.cs b/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/LambdaBootstrapBuilder.cs index 50b9a69ba..b24d76b4c 100644 --- a/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/LambdaBootstrapBuilder.cs +++ b/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/LambdaBootstrapBuilder.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"). @@ -465,6 +465,10 @@ public LambdaBootstrapBuilder ConfigureOptions(Action op return this; } + /// + /// Build the LambdaBootstrap from the builder configuration. + /// + /// The LambdaBootstrap instance that can be run to start the Lambda runtime client. public LambdaBootstrap Build() { if(_httpClient == null) diff --git a/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/UserCodeLoader.cs b/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/UserCodeLoader.cs index ff61ff2f5..f20dfe7af 100644 --- a/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/UserCodeLoader.cs +++ b/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/UserCodeLoader.cs @@ -296,7 +296,7 @@ internal static void SetCustomerLoggerLogAction(Assembly coreAssembly, Action Types.IsLambdaSerializerAttribute(a.GetType())); _logger.LogDebug($"UCL : LambdaSerializerAttribute at method level {(customerSerializerAttribute != null ? "found" : "not found")}"); @@ -304,7 +304,7 @@ private object GetSerializerObject(Assembly customerAssembly) // only check the assembly if the LambdaSerializerAttribute does not exist on the method if (customerSerializerAttribute == null) { - _logger.LogDebug($"UCL : Searching for LambdaSerializerAttribute at assembly level"); + _logger.LogDebug("UCL : Searching for LambdaSerializerAttribute at assembly level"); customerSerializerAttribute = customerAssembly.GetCustomAttributes() .SingleOrDefault(a => Types.IsLambdaSerializerAttribute(a.GetType())); _logger.LogDebug($"UCL : LambdaSerializerAttribute at assembly level {(customerSerializerAttribute != null ? "found" : "not found")}"); @@ -315,7 +315,7 @@ private object GetSerializerObject(Assembly customerAssembly) if (serializerAttributeExists) { - _logger.LogDebug($"UCL : Constructing custom serializer"); + _logger.LogDebug("UCL : Constructing custom serializer"); return ConstructCustomSerializer(customerSerializerAttribute); } else @@ -435,7 +435,6 @@ private Exception GetMultipleMethodsValidationException(TypeInfo typeInfo) /// Serializer attribute used to define the input/output serializer. /// /// Thrown when serializer doesn't satisfy serializer type requirements. - /// Thrown when failed to instantiate serializer type. private object ConstructCustomSerializer(Attribute serializerAttribute) { var attributeType = serializerAttribute.GetType(); @@ -487,7 +486,6 @@ private object ConstructCustomSerializer(Attribute serializerAttribute) /// /// Type of the customer handler container. /// Instance of customer handler container type - /// Thrown when failed to instantiate customer type. private object GetCustomerObject(Type customerType) { _logger.LogDebug($"UCL : Validating type '{_handler.TypeName}'"); diff --git a/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/UserCodeValidator.cs b/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/UserCodeValidator.cs index 879c308b5..5f6100770 100644 --- a/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/UserCodeValidator.cs +++ b/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/UserCodeValidator.cs @@ -233,7 +233,7 @@ private static string CheckILambdaSerializerType(TypeInfo typeInfo) /// it will break existing Lambda deployment packages which still use older version of ILambdaContext. /// /// Type of context passed for the invocation. - /// Thrown when context doesn't contain required properties & methods. + /// Thrown when context doesn't contain required properties and methods. internal static void ValidateILambdaContextType(Type iLambdaContextType) { if (iLambdaContextType == null) @@ -295,4 +295,4 @@ private static PropertyInfo ValidateInterfaceProperty(Type type, string propName return propertyInfo; } } -} \ No newline at end of file +} diff --git a/Libraries/src/Amazon.Lambda.RuntimeSupport/Client/InternalClientAdapted.cs b/Libraries/src/Amazon.Lambda.RuntimeSupport/Client/InternalClientAdapted.cs index a3eeff854..0ea7fdbbd 100644 --- a/Libraries/src/Amazon.Lambda.RuntimeSupport/Client/InternalClientAdapted.cs +++ b/Libraries/src/Amazon.Lambda.RuntimeSupport/Client/InternalClientAdapted.cs @@ -97,7 +97,7 @@ public partial class RuntimeApiSerializationContext : JsonSerializerContext private const string ErrorContentType = "application/vnd.aws.lambda.error+json"; private string _baseUrl = "/2018-06-01"; - private System.Net.Http.HttpClient _httpClient; + private readonly System.Net.Http.HttpClient _httpClient; private InternalLogger _logger; public InternalRuntimeApiClient(System.Net.Http.HttpClient httpClient) @@ -257,7 +257,7 @@ public async Task> RestoreErrorAsync(string lamb /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. public async System.Threading.Tasks.Task> NextAsync(String endpointUrl, CancellationToken cancellationToken) { - this._logger.LogInformation("Starting InternalClient.NextAsync"); + _logger.LogInformation("Starting InternalClient.NextAsync"); var client_ = _httpClient; try @@ -323,7 +323,7 @@ public async Task> RestoreErrorAsync(string lamb } finally { - this._logger.LogInformation("Finished InternalClient.NextAsync"); + _logger.LogInformation("Finished InternalClient.NextAsync"); } } @@ -343,7 +343,7 @@ public System.Threading.Tasks.Task> ResponseAsyn /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. public async System.Threading.Tasks.Task> ResponseAsync(string awsRequestId, System.IO.Stream outputStream, System.Threading.CancellationToken cancellationToken) { - this._logger.LogInformation("Starting InternalClient.ResponseAsync"); + _logger.LogInformation("Starting InternalClient.ResponseAsync"); if (awsRequestId == null) throw new System.ArgumentNullException("awsRequestId"); @@ -368,7 +368,7 @@ public async System.Threading.Tasks.Task> Respon request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); - this._logger.LogInformation("Return from SendAsync"); + _logger.LogInformation("Return from SendAsync"); try { var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value); @@ -468,7 +468,7 @@ public async System.Threading.Tasks.Task> Respon } finally { - this._logger.LogInformation("Finished InternalClient.ResponseAsync"); + _logger.LogInformation("Finished InternalClient.ResponseAsync"); } } @@ -659,14 +659,34 @@ public SwaggerResponse(int statusCode, System.Collections.Generic.Dictionary + /// Exception when an error occurs when communicating with the Lambda runtime API. + /// public partial class RuntimeApiClientException : System.Exception { + /// + /// Http status code from the Lambda runtime API. + /// public int StatusCode { get; private set; } + /// + /// Response from the Lambda runtime API. + /// public string Response { get; private set; } + /// + /// Headers from the Lambda runtime API error response. + /// public System.Collections.Generic.Dictionary> Headers { get; private set; } + /// + /// Instructs an instance of RuntimeApiClientException + /// + /// + /// + /// + /// + /// public RuntimeApiClientException(string message, int statusCode, string response, System.Collections.Generic.Dictionary> headers, System.Exception innerException) : base(message + "\n\nStatus: " + statusCode + "\nResponse: \n" + response.Substring(0, response.Length >= 512 ? 512 : response.Length), innerException) { @@ -675,16 +695,35 @@ public RuntimeApiClientException(string message, int statusCode, string response Headers = headers; } + /// + /// Returns a formatted string containing the HTTP response and base exception information. + /// + /// public override string ToString() { return string.Format("HTTP Response: \n\n{0}\n\n{1}", Response, base.ToString()); } } + /// + /// Exception when an error occurs when communicating with the Lambda runtime API. + /// public partial class RuntimeApiClientException : RuntimeApiClientException { + /// + /// The structured error response + /// public TResult Result { get; private set; } + /// + /// Instructs an instance of RuntimeApiClientException + /// + /// + /// + /// + /// + /// + /// public RuntimeApiClientException(string message, int statusCode, string response, System.Collections.Generic.Dictionary> headers, TResult result, System.Exception innerException) : base(message, statusCode, response, headers, innerException) { @@ -692,4 +731,4 @@ public RuntimeApiClientException(string message, int statusCode, string response } } -} \ No newline at end of file +} diff --git a/Libraries/src/Amazon.Lambda.RuntimeSupport/Client/InvocationRequest.cs b/Libraries/src/Amazon.Lambda.RuntimeSupport/Client/InvocationRequest.cs index 93d5bf151..8c323c397 100644 --- a/Libraries/src/Amazon.Lambda.RuntimeSupport/Client/InvocationRequest.cs +++ b/Libraries/src/Amazon.Lambda.RuntimeSupport/Client/InvocationRequest.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"). @@ -35,6 +35,9 @@ public class InvocationRequest : IDisposable internal InvocationRequest() { } + /// + /// Dispose the instance + /// public void Dispose() { InputStream?.Dispose(); diff --git a/Libraries/src/Amazon.Lambda.RuntimeSupport/Client/InvocationResponse.cs b/Libraries/src/Amazon.Lambda.RuntimeSupport/Client/InvocationResponse.cs index 581423b07..1894b0521 100644 --- a/Libraries/src/Amazon.Lambda.RuntimeSupport/Client/InvocationResponse.cs +++ b/Libraries/src/Amazon.Lambda.RuntimeSupport/Client/InvocationResponse.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"). @@ -34,10 +34,20 @@ public class InvocationResponse /// public bool DisposeOutputStream { get; private set; } = true; + /// + /// Construct a InvocationResponse with an output stream that will be disposed by the Lambda Runtime Client. + /// + /// public InvocationResponse(Stream outputStream) : this(outputStream, true) { } + /// + /// Construct a InvocationResponse + /// + /// + /// + /// public InvocationResponse(Stream outputStream, bool disposeOutputStream) { OutputStream = outputStream ?? throw new ArgumentNullException(nameof(outputStream)); diff --git a/Libraries/src/Amazon.Lambda.RuntimeSupport/Context/LambdaBootstrapConfiguration.cs b/Libraries/src/Amazon.Lambda.RuntimeSupport/Context/LambdaBootstrapConfiguration.cs index 84ea76615..c76588bc3 100644 --- a/Libraries/src/Amazon.Lambda.RuntimeSupport/Context/LambdaBootstrapConfiguration.cs +++ b/Libraries/src/Amazon.Lambda.RuntimeSupport/Context/LambdaBootstrapConfiguration.cs @@ -28,8 +28,9 @@ internal static LambdaBootstrapConfiguration GetDefaultConfiguration() Constants.AWS_LAMBDA_INITIALIZATION_TYPE_SNAP_START); return new LambdaBootstrapConfiguration(isCallPreJit, isInitTypeSnapstart); -#endif +#else return new LambdaBootstrapConfiguration(isCallPreJit, false); +#endif } } -} \ No newline at end of file +} diff --git a/Libraries/src/Amazon.Lambda.RuntimeSupport/Context/LambdaContext.cs b/Libraries/src/Amazon.Lambda.RuntimeSupport/Context/LambdaContext.cs index e778dc858..0cc76fdc6 100644 --- a/Libraries/src/Amazon.Lambda.RuntimeSupport/Context/LambdaContext.cs +++ b/Libraries/src/Amazon.Lambda.RuntimeSupport/Context/LambdaContext.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"). @@ -28,8 +28,8 @@ internal class LambdaContext : ILambdaContext private IDateTimeHelper _dateTimeHelper; private long _deadlineMs; private int _memoryLimitInMB; - private Lazy _cognitoIdentityLazy; - private Lazy _cognitoClientContextLazy; + private readonly Lazy _cognitoIdentityLazy; + private readonly Lazy _cognitoClientContextLazy; private IConsoleLoggerWriter _consoleLogger; public LambdaContext(RuntimeApiHeaders runtimeApiHeaders, LambdaEnvironment lambdaEnvironment, IConsoleLoggerWriter consoleLogger) diff --git a/Libraries/src/Amazon.Lambda.RuntimeSupport/Context/LambdaEnvironment.cs b/Libraries/src/Amazon.Lambda.RuntimeSupport/Context/LambdaEnvironment.cs index eb10769b7..ffa553cc7 100644 --- a/Libraries/src/Amazon.Lambda.RuntimeSupport/Context/LambdaEnvironment.cs +++ b/Libraries/src/Amazon.Lambda.RuntimeSupport/Context/LambdaEnvironment.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"). @@ -38,10 +38,13 @@ public class LambdaEnvironment internal const string AwsLambdaDotnetCustomRuntime = "AWS_Lambda_dotnet_custom"; internal const string AmazonLambdaRuntimeSupportMarker = "amazonlambdaruntimesupport"; - private IEnvironmentVariables _environmentVariables; + private readonly IEnvironmentVariables _environmentVariables; internal const int OneMegabyte = 1024 * 1024; + /// + /// Construct an instance of LambdaEnvironment + /// public LambdaEnvironment() : this(new SystemEnvironmentVariables()) { } internal LambdaEnvironment(IEnvironmentVariables environmentVariables, LambdaBootstrapOptions lambdaBootstrapOptions = null) @@ -83,13 +86,44 @@ internal void SetXAmznTraceId(string xAmznTraceId) _environmentVariables.SetEnvironmentVariable(EnvVarTraceId, xAmznTraceId); } + /// + /// Gets the FunctionMemorySize + /// public string FunctionMemorySize { get; private set; } + + /// + /// Gets the FunctionName + /// public string FunctionName { get; private set; } + + /// + /// Gets the FunctionVersion + /// public string FunctionVersion { get; private set; } + + /// + /// Gets the LogGroupName + /// public string LogGroupName { get; private set; } + + /// + /// Gets the LogStreamName + /// public string LogStreamName { get; private set; } + + /// + /// Gets the RuntimeServerHostAndPort + /// public string RuntimeServerHostAndPort { get; private set; } + + /// + /// Gets the Handler + /// public string Handler { get; private set; } + + /// + /// Gets the XAmznTraceId + /// public string XAmznTraceId { get @@ -97,6 +131,10 @@ public string XAmznTraceId return _environmentVariables.GetEnvironmentVariable(EnvVarTraceId); } } + + /// + /// Gets the ExecutionEnvironment + /// public string ExecutionEnvironment { get diff --git a/Libraries/src/Amazon.Lambda.RuntimeSupport/Helpers/ConsoleLoggerWriter.cs b/Libraries/src/Amazon.Lambda.RuntimeSupport/Helpers/ConsoleLoggerWriter.cs index 95004dd2e..d1cce94ee 100644 --- a/Libraries/src/Amazon.Lambda.RuntimeSupport/Helpers/ConsoleLoggerWriter.cs +++ b/Libraries/src/Amazon.Lambda.RuntimeSupport/Helpers/ConsoleLoggerWriter.cs @@ -68,7 +68,7 @@ public interface IConsoleLoggerWriter /// public class SimpleLoggerWriter : IConsoleLoggerWriter { - TextWriter _writer; + readonly TextWriter _writer; /// /// Default Constructor @@ -301,15 +301,15 @@ public void FormattedWriteLine(string level, Exception exception, string message class WrapperTextWriter : TextWriter { private readonly TextWriter _innerWriter; - private string _defaultLogLevel; + private readonly string _defaultLogLevel; - private LogLevel _minmumLogLevel = LogLevel.Information; + private readonly LogLevel _minmumLogLevel = LogLevel.Information; enum LogFormatType { Default, Unformatted, Json } - private LogFormatType _logFormatType = LogFormatType.Default; + private readonly LogFormatType _logFormatType = LogFormatType.Default; - private ILogMessageFormatter _logMessageFormatter; + private readonly ILogMessageFormatter _logMessageFormatter; public string CurrentAwsRequestId { get; set; } = string.Empty; @@ -421,10 +421,8 @@ private Task FormattedWriteLineAsync(string message) } #region WriteLine redirects to formatting - [CLSCompliant(false)] public override void WriteLine(ulong value) => FormattedWriteLine(value.ToString(FormatProvider)); - [CLSCompliant(false)] public override void WriteLine(uint value) => FormattedWriteLine(value.ToString(FormatProvider)); @@ -463,8 +461,6 @@ private Task FormattedWriteLineAsync(string message) public override Task WriteLineAsync(char value) => FormattedWriteLineAsync(value.ToString()); - public Task WriteLineAsync(char[] buffer) => FormattedWriteLineAsync(buffer == null ? String.Empty : new string(buffer)); - public override Task WriteLineAsync(char[] buffer, int index, int count) => FormattedWriteLineAsync(new string(buffer, index, count)); @@ -472,10 +468,10 @@ private Task FormattedWriteLineAsync(string message) public override Task WriteLineAsync() => FormattedWriteLineAsync(string.Empty); - public override void WriteLine(StringBuilder? value) => FormattedWriteLine(value?.ToString()); + public override void WriteLine(StringBuilder value) => FormattedWriteLine(value?.ToString()); public override void WriteLine(ReadOnlySpan buffer) => FormattedWriteLine(new string(buffer)); public override Task WriteLineAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) => FormattedWriteLineAsync(new string(buffer.Span)); - public override Task WriteLineAsync(StringBuilder? value, CancellationToken cancellationToken = default) => FormattedWriteLineAsync(value?.ToString()); + public override Task WriteLineAsync(StringBuilder value, CancellationToken cancellationToken = default) => FormattedWriteLineAsync(value?.ToString()); #endregion @@ -498,10 +494,8 @@ public override string NewLine public override Task FlushAsync() => _innerWriter.FlushAsync(); - [CLSCompliant(false)] public override void Write(ulong value) => _innerWriter.Write(value); - [CLSCompliant(false)] public override void Write(uint value) => _innerWriter.Write(value); @@ -540,18 +534,16 @@ public override string NewLine public override Task WriteAsync(char[] buffer, int index, int count) => _innerWriter.WriteAsync(buffer, index, count); - public Task WriteAsync(char[] buffer) => _innerWriter.WriteAsync(buffer); - public override Task WriteAsync(char value) => _innerWriter.WriteAsync(value); protected override void Dispose(bool disposing) => _innerWriter.Dispose(); - public override void Write(StringBuilder? value) => _innerWriter.Write(value); + public override void Write(StringBuilder value) => _innerWriter.Write(value); public override void Write(ReadOnlySpan buffer) => _innerWriter.Write(buffer); - public override Task WriteAsync(StringBuilder? value, CancellationToken cancellationToken = default) => _innerWriter.WriteAsync(value, cancellationToken); + public override Task WriteAsync(StringBuilder value, CancellationToken cancellationToken = default) => _innerWriter.WriteAsync(value, cancellationToken); public override Task WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) => _innerWriter.WriteAsync(buffer, cancellationToken); diff --git a/Libraries/src/Amazon.Lambda.RuntimeSupport/Program.cs b/Libraries/src/Amazon.Lambda.RuntimeSupport/Program.cs index 6303245da..d51dc0ea7 100644 --- a/Libraries/src/Amazon.Lambda.RuntimeSupport/Program.cs +++ b/Libraries/src/Amazon.Lambda.RuntimeSupport/Program.cs @@ -25,6 +25,9 @@ namespace Amazon.Lambda.RuntimeSupport { class Program { + // .NET 10 considers adding RequiresUnreferencedCode on the entry point a warning. Our situation is different then the normal use case in that the only time + // the Main exists in the Lambda class library mode which will never be used for Native AOT. +#pragma warning disable IL2123 #if ExecutableOutputType #if NET8_0_OR_GREATER [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode( @@ -48,6 +51,7 @@ private static async Task Main(string[] args) await runtimeSupportInitializer.RunLambdaBootstrap(); } #endif +#pragma warning restore IL2123 #if NET8_0_OR_GREATER [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("This code is only exercised in the class library programming model. Native AOT will not use this code path.")] diff --git a/Libraries/src/SnapshotRestore.Registry/SnapshotRestore.Registry.csproj b/Libraries/src/SnapshotRestore.Registry/SnapshotRestore.Registry.csproj index f95dcd80b..455edf22d 100644 --- a/Libraries/src/SnapshotRestore.Registry/SnapshotRestore.Registry.csproj +++ b/Libraries/src/SnapshotRestore.Registry/SnapshotRestore.Registry.csproj @@ -1,4 +1,4 @@ - + @@ -19,6 +19,8 @@ Amazon Web Services ..\..\..\buildtools\snapshotrestore.snk true + true + NU5048;NU1903