From be4eda89b0ca0a26a4e2d0cfef7b8400ee96f061 Mon Sep 17 00:00:00 2001 From: Jonas Ha Date: Thu, 11 Dec 2025 14:32:30 -0500 Subject: [PATCH 1/7] refactor(opentelemetry): remove deprecated AWS Lambda tracing integrations - Deleted `LambdaOpenTelemetryAdapters` to eliminate redundant tracing extension methods. - Removed associated unit tests for deprecated methods in `LambdaOpenTelemetryServiceProviderExtensionsTests`. - Deprecated methods have been replaced by the `UseOpenTelemetryTracing` API. --- .../LambdaOpenTelemetryAdapters.cs | 231 --------- ...TelemetryServiceProviderExtensionsTests.cs | 459 ------------------ 2 files changed, 690 deletions(-) delete mode 100644 src/MinimalLambda.OpenTelemetry/LambdaOpenTelemetryAdapters.cs delete mode 100644 tests/MinimalLambda.OpenTelemetry.UnitTests/LambdaOpenTelemetryServiceProviderExtensionsTests.cs diff --git a/src/MinimalLambda.OpenTelemetry/LambdaOpenTelemetryAdapters.cs b/src/MinimalLambda.OpenTelemetry/LambdaOpenTelemetryAdapters.cs deleted file mode 100644 index f7663547..00000000 --- a/src/MinimalLambda.OpenTelemetry/LambdaOpenTelemetryAdapters.cs +++ /dev/null @@ -1,231 +0,0 @@ -using Amazon.Lambda.Core; -using MinimalLambda; -using OpenTelemetry.Instrumentation.AWSLambda; -using OpenTelemetry.Trace; - -namespace Microsoft.Extensions.DependencyInjection; - -/// -/// Provides extension methods for integrating OpenTelemetry tracing with AWS Lambda -/// invocations. -/// -public static class LambdaOpenTelemetryServiceProviderExtensions -{ - extension(IServiceProvider services) - { - /// - /// Creates a middleware function that traces Lambda invocations with both event and response - /// types. - /// - /// The type of the Lambda event expected in the context. - /// The type of the Lambda response expected in the context. - /// A middleware function that wraps the Lambda invocation with OpenTelemetry tracing. - /// - /// - /// Important: These methods are primarily intended to be used by source generators - /// and interceptors. Direct usage is not recommended. Source generation and interception are - /// the primary use cases for automatic tracing integration. - /// - /// - /// Uses the registered to wrap Lambda invocations with - /// distributed tracing capabilities through AWS Lambda instrumentation. This method is a - /// wrapper around from - /// the - /// OpenTelemetry.Instrumentation.AWSLambda - /// NuGet package. - /// - /// - /// The context must contain an event of type and the handler - /// must set a response of type . - /// - /// - /// TracerProvider Registration Required: A instance - /// must be registered in the dependency injection container before calling these methods. - /// Failure to register a will result in an - /// being thrown at startup. - /// - /// - /// - /// Thrown if the context event is not of type - /// or if the context response is not of type - /// , or if a instance is not - /// registered in the dependency injection container. - /// - [Obsolete( - "This method will be removed in v2.0.0 Use UseOpenTelemetryTracing directly instead." - )] - public Func GetOpenTelemetryTracer< - TEvent, - TResponse - >() - { - ArgumentNullException.ThrowIfNull(services); - - var tracerProvider = services.GetRequiredService(); - - return next => - { - return async context => - { - if ( - context.Features.Get()?.GetEvent(context) - is not TEvent eventT - ) - throw new InvalidOperationException( - $"Lambda event of type '{typeof(TEvent).FullName}' is not available in the context." - ); - - await AWSLambdaWrapper.TraceAsync( - tracerProvider, - async Task (_, _) => - { - await next(context); - - if ( - context.Features.Get()?.GetResponse() - is not TResponse responseT - ) - throw new InvalidOperationException( - $"Lambda response of type '{typeof(TResponse).FullName}' is not available in the context." - ); - - return responseT; - }, - eventT, - context - ); - }; - }; - } - - /// Creates a middleware function that traces Lambda invocations with only a response type. - /// The type of the Lambda response expected in the context. - /// - /// - /// The event - /// type is not relevant or known when using this overload. - /// - /// - /// Thrown if the context response is not of type - /// . - /// - [Obsolete( - "This method will be removed in v2.0.0 Use UseOpenTelemetryTracing directly instead." - )] - public Func< - LambdaInvocationDelegate, - LambdaInvocationDelegate - > GetOpenTelemetryTracerNoEvent() - { - ArgumentNullException.ThrowIfNull(services); - - var tracerProvider = services.GetRequiredService(); - - return next => - { - return async context => - { - await AWSLambdaWrapper.TraceAsync( - tracerProvider, - async Task (object? _, ILambdaContext _) => - { - await next(context); - - if ( - context.Features.Get()?.GetResponse() - is not TResponse responseT - ) - throw new InvalidOperationException( - $"Lambda response of type '{typeof(TResponse).FullName}' is not available in the context." - ); - - return responseT; - }, - null, - context - ); - }; - }; - } - - /// Creates a middleware function that traces Lambda invocations with only an event type. - /// The type of the Lambda event expected in the context. - /// - /// - /// The - /// response type is not relevant or known when using this overload. - /// - /// - /// Thrown if the context event is not of type - /// . - /// - [Obsolete( - "This method will be removed in v2.0.0 Use UseOpenTelemetryTracing directly instead." - )] - public Func< - LambdaInvocationDelegate, - LambdaInvocationDelegate - > GetOpenTelemetryTracerNoResponse() - { - ArgumentNullException.ThrowIfNull(services); - - var tracerProvider = services.GetRequiredService(); - - return next => - { - return async context => - { - if ( - context.Features.Get()?.GetEvent(context) - is not TEvent eventT - ) - throw new InvalidOperationException( - $"Lambda event of type '{typeof(TEvent).FullName}' is not available in the context." - ); - - await AWSLambdaWrapper.TraceAsync( - tracerProvider, - async Task (_, _) => await next(context), - eventT, - context - ); - }; - }; - } - - /// - /// Creates a middleware function that traces Lambda invocations without specific event or - /// response types. - /// - /// - /// - /// Neither - /// event nor response types are relevant or known when using this overload. - /// - [Obsolete( - "This method will be removed in v2.0.0 Use UseOpenTelemetryTracing directly instead." - )] - public Func< - LambdaInvocationDelegate, - LambdaInvocationDelegate - > GetOpenTelemetryTracerNoEventNoResponse() - { - ArgumentNullException.ThrowIfNull(services); - - var tracerProvider = services.GetRequiredService(); - - return next => - { - return async context => - { - await AWSLambdaWrapper.TraceAsync( - tracerProvider, - async Task (object? _, ILambdaContext _) => await next(context), - null, - context - ); - }; - }; - } - } -} diff --git a/tests/MinimalLambda.OpenTelemetry.UnitTests/LambdaOpenTelemetryServiceProviderExtensionsTests.cs b/tests/MinimalLambda.OpenTelemetry.UnitTests/LambdaOpenTelemetryServiceProviderExtensionsTests.cs deleted file mode 100644 index 22d5d446..00000000 --- a/tests/MinimalLambda.OpenTelemetry.UnitTests/LambdaOpenTelemetryServiceProviderExtensionsTests.cs +++ /dev/null @@ -1,459 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; -using MinimalLambda.UnitTests; -using OpenTelemetry.Trace; - -namespace MinimalLambda.OpenTelemetry.UnitTests; - -[TestSubject(typeof(LambdaOpenTelemetryServiceProviderExtensions))] -public class LambdaOpenTelemetryServiceProviderExtensionsTests -{ - [Fact] - public void GetOpenTelemetryTracer_WithNullServiceProvider_ThrowsArgumentNullException() - { - // Arrange - IServiceProvider? nullProvider = null; - - // Act - var action = () => nullProvider!.GetOpenTelemetryTracer(); - - // Assert - action.Should().ThrowExactly(); - } - - [Theory] - [AutoNSubstituteData] - public void GetOpenTelemetryTracer_WithoutTracerProvider_ThrowsInvalidOperationException( - [Frozen] IServiceProvider serviceProvider - ) - { - // Arrange - serviceProvider.GetService(typeof(TracerProvider)).Returns(null); - - // Act - var action = () => serviceProvider.GetOpenTelemetryTracer(); - - // Assert - action.Should().ThrowExactly(); - } - - [Theory] - [AutoNSubstituteData] - public void GetOpenTelemetryTracer_ReturnsMiddlewareFunction( - [Frozen] IServiceProvider serviceProvider, - TracerProvider tracerProvider - ) - { - // Arrange - serviceProvider.GetService(typeof(TracerProvider)).Returns(tracerProvider); - - // Act - var middleware = serviceProvider.GetOpenTelemetryTracer(); - - // Assert - middleware.Should().NotBeNull(); - middleware.Should().BeOfType>(); - } - - [Theory] - [AutoNSubstituteData] - public async Task GetOpenTelemetryTracer_WithIncorrectEventType_ThrowsInvalidOperationException( - [Frozen] IServiceProvider serviceProvider, - TracerProvider tracerProvider, - ILambdaHostContext context, - IFeatureCollection features, - IEventFeature eventFeature, - IResponseFeature responseFeature - ) - { - // Arrange - serviceProvider.GetService(typeof(TracerProvider)).Returns(tracerProvider); - var middleware = serviceProvider.GetOpenTelemetryTracer(); - var nextDelegate = Substitute.For(); - var wrappedDelegate = middleware(nextDelegate); - - context.Features.Returns(features); - features.Get().Returns(eventFeature); - features.Get().Returns(responseFeature); - eventFeature.GetEvent(context).Returns(new object()); - - // Act - var action = async () => await wrappedDelegate(context); - - // Assert - await action.Should().ThrowAsync(); - } - - [Theory] - [AutoNSubstituteData] - public async Task GetOpenTelemetryTracer_WithIncorrectResponseType_ThrowsInvalidOperationException( - [Frozen] IServiceProvider serviceProvider, - TracerProvider tracerProvider, - ILambdaHostContext context, - IFeatureCollection features, - IEventFeature eventFeature, - IResponseFeature responseFeature - ) - { - // Arrange - serviceProvider.GetService(typeof(TracerProvider)).Returns(tracerProvider); - var middleware = serviceProvider.GetOpenTelemetryTracer(); - var nextDelegate = Substitute.For(); - var wrappedDelegate = middleware(nextDelegate); - - context.Features.Returns(features); - features.Get().Returns(eventFeature); - features.Get().Returns(responseFeature); - eventFeature.GetEvent(context).Returns(new TestEvent()); - responseFeature.GetResponse().Returns(new object()); // Wrong type - - nextDelegate(Arg.Any()).Returns(Task.CompletedTask); - - // Act - var action = async () => await wrappedDelegate(context); - - // Assert - await action.Should().ThrowAsync(); - } - - [Theory] - [AutoNSubstituteData] - public async Task GetOpenTelemetryTracer_WithValidEventAndResponse_CallsNextDelegate( - [Frozen] IServiceProvider serviceProvider, - TracerProvider tracerProvider, - ILambdaHostContext context, - IFeatureCollection features, - IEventFeature eventFeature, - IResponseFeature responseFeature - ) - { - // Arrange - serviceProvider.GetService(typeof(TracerProvider)).Returns(tracerProvider); - var middleware = serviceProvider.GetOpenTelemetryTracer(); - var nextDelegate = Substitute.For(); - var wrappedDelegate = middleware(nextDelegate); - - var testEvent = new TestEvent(); - var testResponse = new TestResponse(); - - context.Features.Returns(features); - features.Get().Returns(eventFeature); - features.Get().Returns(responseFeature); - eventFeature.GetEvent(context).Returns(testEvent); - responseFeature.GetResponse().Returns(testResponse); - - nextDelegate(Arg.Any()).Returns(Task.CompletedTask); - - // Act - await wrappedDelegate(context); - - // Assert - await nextDelegate.Received(1)(Arg.Any()); - } - - [Fact] - public void GetOpenTelemetryTracerNoEvent_WithNullServiceProvider_ThrowsArgumentNullException() - { - // Arrange - IServiceProvider? nullProvider = null; - - // Act - var action = () => nullProvider!.GetOpenTelemetryTracerNoEvent(); - - // Assert - action.Should().ThrowExactly(); - } - - [Theory] - [AutoNSubstituteData] - public void GetOpenTelemetryTracerNoEvent_WithoutTracerProvider_ThrowsInvalidOperationException( - [Frozen] IServiceProvider serviceProvider - ) - { - // Arrange - serviceProvider.GetService(typeof(TracerProvider)).Returns(null); - - // Act - var action = () => serviceProvider.GetOpenTelemetryTracerNoEvent(); - - // Assert - action.Should().ThrowExactly(); - } - - [Theory] - [AutoNSubstituteData] - public void GetOpenTelemetryTracerNoEvent_ReturnsMiddlewareFunction( - [Frozen] IServiceProvider serviceProvider, - TracerProvider tracerProvider - ) - { - // Arrange - serviceProvider.GetService(typeof(TracerProvider)).Returns(tracerProvider); - - // Act - var middleware = serviceProvider.GetOpenTelemetryTracerNoEvent(); - - // Assert - middleware.Should().NotBeNull(); - middleware.Should().BeOfType>(); - } - - [Theory] - [AutoNSubstituteData] - public async Task GetOpenTelemetryTracerNoEvent_WithIncorrectResponseType_ThrowsInvalidOperationException( - [Frozen] IServiceProvider serviceProvider, - TracerProvider tracerProvider, - ILambdaHostContext context, - IFeatureCollection features, - IEventFeature eventFeature, - IResponseFeature responseFeature - ) - { - // Arrange - serviceProvider.GetService(typeof(TracerProvider)).Returns(tracerProvider); - var middleware = serviceProvider.GetOpenTelemetryTracerNoEvent(); - var nextDelegate = Substitute.For(); - var wrappedDelegate = middleware(nextDelegate); - - context.Features.Returns(features); - features.Get().Returns(eventFeature); - features.Get().Returns(responseFeature); - eventFeature.GetEvent(context).Returns(new object()); - responseFeature.GetResponse().Returns(new object()); // Wrong type - - nextDelegate(Arg.Any()).Returns(Task.CompletedTask); - - // Act - var action = async () => await wrappedDelegate(context); - - // Assert - await action.Should().ThrowAsync(); - } - - [Theory] - [AutoNSubstituteData] - public async Task GetOpenTelemetryTracerNoEvent_WithValidResponse_CallsNextDelegate( - [Frozen] IServiceProvider serviceProvider, - TracerProvider tracerProvider, - ILambdaHostContext context, - IFeatureCollection features, - IEventFeature eventFeature, - IResponseFeature responseFeature - ) - { - // Arrange - serviceProvider.GetService(typeof(TracerProvider)).Returns(tracerProvider); - var middleware = serviceProvider.GetOpenTelemetryTracerNoEvent(); - var nextDelegate = Substitute.For(); - var wrappedDelegate = middleware(nextDelegate); - - var testResponse = new TestResponse(); - - context.Features.Returns(features); - features.Get().Returns(eventFeature); - features.Get().Returns(responseFeature); - eventFeature.GetEvent(context).Returns(new object()); - responseFeature.GetResponse().Returns(testResponse); - - nextDelegate(Arg.Any()).Returns(Task.CompletedTask); - - // Act - await wrappedDelegate(context); - - // Assert - await nextDelegate.Received(1)(Arg.Any()); - } - - [Fact] - public void GetOpenTelemetryTracerNoResponse_WithNullServiceProvider_ThrowsArgumentNullException() - { - // Arrange - IServiceProvider? nullProvider = null; - - // Act - var action = () => nullProvider!.GetOpenTelemetryTracerNoResponse(); - - // Assert - action.Should().ThrowExactly(); - } - - [Theory] - [AutoNSubstituteData] - public void GetOpenTelemetryTracerNoResponse_WithoutTracerProvider_ThrowsInvalidOperationException( - [Frozen] IServiceProvider serviceProvider - ) - { - // Arrange - serviceProvider.GetService(typeof(TracerProvider)).Returns(null); - - // Act - var action = () => serviceProvider.GetOpenTelemetryTracerNoResponse(); - - // Assert - action.Should().ThrowExactly(); - } - - [Theory] - [AutoNSubstituteData] - public void GetOpenTelemetryTracerNoResponse_ReturnsMiddlewareFunction( - [Frozen] IServiceProvider serviceProvider, - TracerProvider tracerProvider - ) - { - // Arrange - serviceProvider.GetService(typeof(TracerProvider)).Returns(tracerProvider); - - // Act - var middleware = serviceProvider.GetOpenTelemetryTracerNoResponse(); - - // Assert - middleware.Should().NotBeNull(); - middleware.Should().BeOfType>(); - } - - [Theory] - [AutoNSubstituteData] - public async Task GetOpenTelemetryTracerNoResponse_WithIncorrectEventType_ThrowsInvalidOperationException( - [Frozen] IServiceProvider serviceProvider, - TracerProvider tracerProvider, - ILambdaHostContext context, - IFeatureCollection features, - IEventFeature eventFeature, - IResponseFeature responseFeature - ) - { - // Arrange - serviceProvider.GetService(typeof(TracerProvider)).Returns(tracerProvider); - var middleware = serviceProvider.GetOpenTelemetryTracerNoResponse(); - var nextDelegate = Substitute.For(); - var wrappedDelegate = middleware(nextDelegate); - - context.Features.Returns(features); - features.Get().Returns(eventFeature); - features.Get().Returns(responseFeature); - eventFeature.GetEvent(context).Returns(new object()); // Wrong type - responseFeature.GetResponse().Returns(new object()); - - // Act - var action = async () => await wrappedDelegate(context); - - // Assert - await action.Should().ThrowAsync(); - } - - [Theory] - [AutoNSubstituteData] - public async Task GetOpenTelemetryTracerNoResponse_WithValidEvent_CallsNextDelegate( - [Frozen] IServiceProvider serviceProvider, - TracerProvider tracerProvider, - ILambdaHostContext context, - IFeatureCollection features, - IEventFeature eventFeature, - IResponseFeature responseFeature - ) - { - // Arrange - serviceProvider.GetService(typeof(TracerProvider)).Returns(tracerProvider); - var middleware = serviceProvider.GetOpenTelemetryTracerNoResponse(); - var nextDelegate = Substitute.For(); - var wrappedDelegate = middleware(nextDelegate); - - var testEvent = new TestEvent(); - - context.Features.Returns(features); - features.Get().Returns(eventFeature); - features.Get().Returns(responseFeature); - eventFeature.GetEvent(context).Returns(testEvent); - responseFeature.GetResponse().Returns(new object()); - - nextDelegate(Arg.Any()).Returns(Task.CompletedTask); - - // Act - await wrappedDelegate(context); - - // Assert - await nextDelegate.Received(1)(Arg.Any()); - } - - [Fact] - public void GetOpenTelemetryTracerNoEventNoResponse_WithNullServiceProvider_ThrowsArgumentNullException() - { - // Arrange - IServiceProvider? nullProvider = null; - - // Act - var action = () => nullProvider!.GetOpenTelemetryTracerNoEventNoResponse(); - - // Assert - action.Should().ThrowExactly(); - } - - [Theory] - [AutoNSubstituteData] - public void GetOpenTelemetryTracerNoEventNoResponse_WithoutTracerProvider_ThrowsInvalidOperationException( - [Frozen] IServiceProvider serviceProvider - ) - { - // Arrange - serviceProvider.GetService(typeof(TracerProvider)).Returns(null); - - // Act - var action = () => serviceProvider.GetOpenTelemetryTracerNoEventNoResponse(); - - // Assert - action.Should().ThrowExactly(); - } - - [Theory] - [AutoNSubstituteData] - public void GetOpenTelemetryTracerNoEventNoResponse_ReturnsMiddlewareFunction( - [Frozen] IServiceProvider serviceProvider, - TracerProvider tracerProvider - ) - { - // Arrange - serviceProvider.GetService(typeof(TracerProvider)).Returns(tracerProvider); - - // Act - var middleware = serviceProvider.GetOpenTelemetryTracerNoEventNoResponse(); - - // Assert - middleware.Should().NotBeNull(); - middleware.Should().BeOfType>(); - } - - [Theory] - [AutoNSubstituteData] - public async Task GetOpenTelemetryTracerNoEventNoResponse_WithAnyEventAndResponse_CallsNextDelegate( - [Frozen] IServiceProvider serviceProvider, - TracerProvider tracerProvider, - ILambdaHostContext context, - IFeatureCollection features, - IEventFeature eventFeature, - IResponseFeature responseFeature - ) - { - // Arrange - serviceProvider.GetService(typeof(TracerProvider)).Returns(tracerProvider); - var middleware = serviceProvider.GetOpenTelemetryTracerNoEventNoResponse(); - var nextDelegate = Substitute.For(); - var wrappedDelegate = middleware(nextDelegate); - - context.Features.Returns(features); - features.Get().Returns(eventFeature); - features.Get().Returns(responseFeature); - eventFeature.GetEvent(context).Returns(new object()); - responseFeature.GetResponse().Returns(new object()); - - nextDelegate(Arg.Any()).Returns(Task.CompletedTask); - - // Act - await wrappedDelegate(context); - - // Assert - await nextDelegate.Received(1)(Arg.Any()); - } - - private class TestEvent { } - - private class TestResponse { } -} From fc062f95536e51320f65fc31d1d206e8629e0a7d Mon Sep 17 00:00:00 2001 From: Jonas Ha Date: Thu, 11 Dec 2025 14:33:01 -0500 Subject: [PATCH 2/7] refactor(lambda-host-options): remove obsolete `BootstrapHttpClient` property - Deleted `BootstrapHttpClient` property marked as obsolete. - The recommended replacement is `AddLambdaBootstrapHttpClient()` or `TryAddLambdaBootstrapHttpClient()`. - Aligns with planned removal in version 2.0.0. --- .../Core/Options/LambdaHostOptions.cs | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/MinimalLambda/Core/Options/LambdaHostOptions.cs b/src/MinimalLambda/Core/Options/LambdaHostOptions.cs index 9b50512d..c9d45807 100644 --- a/src/MinimalLambda/Core/Options/LambdaHostOptions.cs +++ b/src/MinimalLambda/Core/Options/LambdaHostOptions.cs @@ -6,22 +6,6 @@ namespace MinimalLambda.Options; /// Options for configuring Lambda hosting behavior. public class LambdaHostOptions { - /// Gets or sets an optional custom HTTP client for the Lambda bootstrap. - /// - /// When null, the bootstrap will create its own HTTP client for communicating with the Lambda - /// runtime API. This property will be overridden by keyed service registrations from - /// or - /// - /// extension methods. - /// - [Obsolete( - "This property will be removed in version 2.0.0. Use " - + "AddLambdaBootstrapHttpClient() or TryAddLambdaBootstrapHttpClient() extension methods " - + "instead.", - false - )] - public HttpClient? BootstrapHttpClient { get; set; } = null; - /// Gets or sets the options for configuring the Lambda bootstrap behavior. /// /// From 3ee73930809b73ed755cda721a59c983d331a675 Mon Sep 17 00:00:00 2001 From: Jonas Ha Date: Thu, 11 Dec 2025 14:33:40 -0500 Subject: [PATCH 3/7] refactor(lambda-bootstrap-adapter): remove obsolete `BootstrapHttpClient` handling - Eliminated code dependent on `BootstrapHttpClient` marked as obsolete. - Simplifies the constructor by directly using the injected `httpClient`. - Aligns with recent removal of `BootstrapHttpClient`. --- src/MinimalLambda/Runtime/LambdaBootstrapAdapter.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/MinimalLambda/Runtime/LambdaBootstrapAdapter.cs b/src/MinimalLambda/Runtime/LambdaBootstrapAdapter.cs index 3ed17e18..b9d4fff7 100644 --- a/src/MinimalLambda/Runtime/LambdaBootstrapAdapter.cs +++ b/src/MinimalLambda/Runtime/LambdaBootstrapAdapter.cs @@ -21,13 +21,7 @@ public LambdaBootstrapAdapter( { ArgumentNullException.ThrowIfNull(lambdaHostSettings); - // TODO: Remove this check once ILambdaBootstrapOrchestrator.BootstrapHttpClient is removed. - // until ILambdaBootstrapOrchestrator.BootstrapHttpClient is removed, we need to check for - // it if the keyed service is NOT present. -#pragma warning disable CS0618 // Type or member is obsolete - _httpClient = httpClient ?? lambdaHostSettings.Value.BootstrapHttpClient; -#pragma warning restore CS0618 // Type or member is obsolete - + _httpClient = httpClient; _settings = lambdaHostSettings.Value; } From 5910b760f70d7aef4d8c217b72fc59e74506d1ea Mon Sep 17 00:00:00 2001 From: Jonas Ha Date: Thu, 11 Dec 2025 14:34:27 -0500 Subject: [PATCH 4/7] refactor(source-generators): remove obsolete `UseOpenTelemetryTracingSyntaxProvider` - Deleted the `UseOpenTelemetryTracingSyntaxProvider` no longer in use. - Aligns with recent changes emphasizing simplified tracing integrations. - Ensures source generator code is streamlined and free of deprecated utilities. --- .../UseOpenTelemetryTracingSyntaxProvider.cs | 55 ------------------- 1 file changed, 55 deletions(-) delete mode 100644 src/MinimalLambda.SourceGenerators/SyntaxProviders/UseOpenTelemetryTracingSyntaxProvider.cs diff --git a/src/MinimalLambda.SourceGenerators/SyntaxProviders/UseOpenTelemetryTracingSyntaxProvider.cs b/src/MinimalLambda.SourceGenerators/SyntaxProviders/UseOpenTelemetryTracingSyntaxProvider.cs deleted file mode 100644 index 1ab88a45..00000000 --- a/src/MinimalLambda.SourceGenerators/SyntaxProviders/UseOpenTelemetryTracingSyntaxProvider.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System.Threading; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.Operations; -using MinimalLambda.SourceGenerators.Models; - -namespace MinimalLambda.SourceGenerators; - -internal static class UseOpenTelemetryTracingSyntaxProvider -{ - internal static bool Predicate(SyntaxNode node, CancellationToken _) => - node.TryGetMethodName(out var name) - && name == GeneratorConstants.UseOpenTelemetryTracingMethodName; - - internal static SimpleMethodInfo? Transformer( - GeneratorSyntaxContext context, - CancellationToken cancellationToken - ) - { - var operation = context.SemanticModel.GetOperation(context.Node, cancellationToken); - - if ( - operation - is IInvocationOperation - { - TargetMethod.ContainingNamespace: - { - Name: "Builder", - ContainingNamespace: - { - Name: "Host", - ContainingNamespace: - { Name: "AwsLambda", ContainingNamespace.IsGlobalNamespace: true }, - }, - }, - } targetOperation - && targetOperation.TargetMethod.ContainingAssembly.Name == "MinimalLambda.OpenTelemetry" - ) - { - var interceptableLocation = context.SemanticModel.GetInterceptableLocation( - (InvocationExpressionSyntax)targetOperation.Syntax, - cancellationToken - )!; - - return new SimpleMethodInfo( - targetOperation.TargetMethod.Name, - LocationInfo.CreateFrom(context.Node), - InterceptableLocationInfo.CreateFrom(interceptableLocation) - ); - } - - return null; - } -} From d8d41ac9597c670fecc9738abce6dc8500ca4038 Mon Sep 17 00:00:00 2001 From: Jonas Ha Date: Thu, 11 Dec 2025 14:34:34 -0500 Subject: [PATCH 5/7] refactor(source-generators): update namespace for LambdaApplicationBuilder syntax provider - Changed the `ContainingNamespace` from `AwsLambda.Host` to `MinimalLambda` for target operation. - Aligns with updated project structure and naming conventions. --- .../LambdaApplicationBuilderBuildSyntaxProvider.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/MinimalLambda.SourceGenerators/SyntaxProviders/LambdaApplicationBuilderBuildSyntaxProvider.cs b/src/MinimalLambda.SourceGenerators/SyntaxProviders/LambdaApplicationBuilderBuildSyntaxProvider.cs index ae329bd4..aec95558 100644 --- a/src/MinimalLambda.SourceGenerators/SyntaxProviders/LambdaApplicationBuilderBuildSyntaxProvider.cs +++ b/src/MinimalLambda.SourceGenerators/SyntaxProviders/LambdaApplicationBuilderBuildSyntaxProvider.cs @@ -30,11 +30,7 @@ is IInvocationOperation { Name: "Builder", ContainingNamespace: - { - Name: "Host", - ContainingNamespace: - { Name: "AwsLambda", ContainingNamespace.IsGlobalNamespace: true }, - }, + { Name: "MinimalLambda", ContainingNamespace.IsGlobalNamespace: true }, }, }, } targetOperation From 89ef18b18d60300e725557a2545e4aabd98dd136 Mon Sep 17 00:00:00 2001 From: Jonas Ha Date: Thu, 11 Dec 2025 14:36:26 -0500 Subject: [PATCH 6/7] refactor(source-generators): remove obsolete `UseOpenTelemetryTracing` handling - Removed `UseOpenTelemetryTracingInfos` from `CompilationInfo` model. - Deleted `UseOpenTelemetryTracingSyntaxProvider` references in `MapHandlerIncrementalGenerator`. - Cleaned up associated code to streamline source generator logic. - Aligns with recent tracing simplification efforts. --- .../MapHandlerIncrementalGenerator.cs | 17 ++--------------- .../Models/CompilationInfo.cs | 3 +-- 2 files changed, 3 insertions(+), 17 deletions(-) diff --git a/src/MinimalLambda.SourceGenerators/MapHandlerIncrementalGenerator.cs b/src/MinimalLambda.SourceGenerators/MapHandlerIncrementalGenerator.cs index 7484b1c1..09b1f8d9 100644 --- a/src/MinimalLambda.SourceGenerators/MapHandlerIncrementalGenerator.cs +++ b/src/MinimalLambda.SourceGenerators/MapHandlerIncrementalGenerator.cs @@ -77,15 +77,6 @@ is CSharpCompilation .Where(static m => m is not null) .Select(static (m, _) => m!.Value); - // find any calls to `UseOpenTelemetryTracing` and extract the location - var openTelemetryTracingCalls = context - .SyntaxProvider.CreateSyntaxProvider( - UseOpenTelemetryTracingSyntaxProvider.Predicate, - UseOpenTelemetryTracingSyntaxProvider.Transformer - ) - .Where(static m => m is not null) - .Select(static (m, _) => m!.Value); - // find LambdaApplicationBuilder.Build() calls var lambdaApplicationBuilderBuildCalls = context .SyntaxProvider.CreateSyntaxProvider( @@ -99,7 +90,6 @@ is CSharpCompilation var mapHandlerCallsCollected = mapHandlerCalls.Collect(); var onShutdownCallsCollected = onShutdownCalls.Collect(); var onInitCallsCollected = onInitCalls.Collect(); - var openTelemetryTracingCallsCollected = openTelemetryTracingCalls.Collect(); var lambdaApplicationBuilderBuildCallsCollected = lambdaApplicationBuilderBuildCalls.Collect(); @@ -107,14 +97,12 @@ is CSharpCompilation var combined = mapHandlerCallsCollected .Combine(onShutdownCallsCollected) .Combine(onInitCallsCollected) - .Combine(openTelemetryTracingCallsCollected) .Combine(lambdaApplicationBuilderBuildCallsCollected) .Select( CompilationInfo? (t, _) => { if ( - t.Left.Left.Left.Left.Length == 0 - && t.Left.Left.Left.Right.Length == 0 + t.Left.Left.Left.Length == 0 && t.Left.Left.Right.Length == 0 && t.Left.Right.Length == 0 && t.Right.Length == 0 @@ -122,8 +110,7 @@ is CSharpCompilation return null; return new CompilationInfo( - t.Left.Left.Left.Left.ToEquatableArray(), - t.Left.Left.Left.Right.ToEquatableArray(), + t.Left.Left.Left.ToEquatableArray(), t.Left.Left.Right.ToEquatableArray(), t.Left.Right.ToEquatableArray(), t.Right.ToEquatableArray() diff --git a/src/MinimalLambda.SourceGenerators/Models/CompilationInfo.cs b/src/MinimalLambda.SourceGenerators/Models/CompilationInfo.cs index 871699c8..f168b3e3 100644 --- a/src/MinimalLambda.SourceGenerators/Models/CompilationInfo.cs +++ b/src/MinimalLambda.SourceGenerators/Models/CompilationInfo.cs @@ -6,6 +6,5 @@ internal readonly record struct CompilationInfo( EquatableArray MapHandlerInvocationInfos, EquatableArray OnShutdownInvocationInfos, EquatableArray OnInitInvocationInfos, - EquatableArray UseOpenTelemetryTracingInfos, - EquatableArray BuilderInfos = default + EquatableArray BuilderInfos ); From baf8bdfd63399124662b9fd712a9ff79f063d408 Mon Sep 17 00:00:00 2001 From: Jonas Ha Date: Thu, 11 Dec 2025 14:38:17 -0500 Subject: [PATCH 7/7] refactor(unit-tests): update verify tests and add snapshot files - Updated `VerifyTests` in unit test cases to remove redundant string argument. - Added generated snapshot files for `OnInit`, `OnShutdown`, and `ExpressionLambdaVerifyTests`. - Streamlines testing process by incorporating auto-generated code snapshots. --- ...erializer_NoOp#LambdaHandler.g.verified.cs | 27 +++++++++++++++++++ ...nOverload_NoOp#LambdaHandler.g.verified.cs | 27 +++++++++++++++++++ ...BaseMethodCall#LambdaHandler.g.verified.cs | 27 +++++++++++++++++++ ...BaseMethodCall#LambdaHandler.g.verified.cs | 27 +++++++++++++++++++ .../ExpressionLambdaVerifyTests.cs | 6 ++--- .../VerifyTests/OnInitVerifyTests.cs | 3 +-- .../VerifyTests/OnShutdownVerifyTests.cs | 3 +-- 7 files changed, 112 insertions(+), 8 deletions(-) create mode 100644 tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_MainOverload_DeserializerSerializer_NoOp#LambdaHandler.g.verified.cs create mode 100644 tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_MainOverload_NoOp#LambdaHandler.g.verified.cs create mode 100644 tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/OnInitVerifyTests.Test_OnInit_BaseMethodCall#LambdaHandler.g.verified.cs create mode 100644 tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/OnShutdownVerifyTests.Test_OnShutdown_BaseMethodCall#LambdaHandler.g.verified.cs diff --git a/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_MainOverload_DeserializerSerializer_NoOp#LambdaHandler.g.verified.cs b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_MainOverload_DeserializerSerializer_NoOp#LambdaHandler.g.verified.cs new file mode 100644 index 00000000..a80f8bfe --- /dev/null +++ b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_MainOverload_DeserializerSerializer_NoOp#LambdaHandler.g.verified.cs @@ -0,0 +1,27 @@ +//HintName: LambdaHandler.g.cs +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously + +#nullable enable + +namespace System.Runtime.CompilerServices +{ + using System.CodeDom.Compiler; + + [GeneratedCode("MinimalLambda.SourceGenerators", "0.0.0")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : Attribute + { + public InterceptsLocationAttribute(int version, string data) + { + } + } +} diff --git a/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_MainOverload_NoOp#LambdaHandler.g.verified.cs b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_MainOverload_NoOp#LambdaHandler.g.verified.cs new file mode 100644 index 00000000..a80f8bfe --- /dev/null +++ b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_MainOverload_NoOp#LambdaHandler.g.verified.cs @@ -0,0 +1,27 @@ +//HintName: LambdaHandler.g.cs +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously + +#nullable enable + +namespace System.Runtime.CompilerServices +{ + using System.CodeDom.Compiler; + + [GeneratedCode("MinimalLambda.SourceGenerators", "0.0.0")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : Attribute + { + public InterceptsLocationAttribute(int version, string data) + { + } + } +} diff --git a/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/OnInitVerifyTests.Test_OnInit_BaseMethodCall#LambdaHandler.g.verified.cs b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/OnInitVerifyTests.Test_OnInit_BaseMethodCall#LambdaHandler.g.verified.cs new file mode 100644 index 00000000..a80f8bfe --- /dev/null +++ b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/OnInitVerifyTests.Test_OnInit_BaseMethodCall#LambdaHandler.g.verified.cs @@ -0,0 +1,27 @@ +//HintName: LambdaHandler.g.cs +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously + +#nullable enable + +namespace System.Runtime.CompilerServices +{ + using System.CodeDom.Compiler; + + [GeneratedCode("MinimalLambda.SourceGenerators", "0.0.0")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : Attribute + { + public InterceptsLocationAttribute(int version, string data) + { + } + } +} diff --git a/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/OnShutdownVerifyTests.Test_OnShutdown_BaseMethodCall#LambdaHandler.g.verified.cs b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/OnShutdownVerifyTests.Test_OnShutdown_BaseMethodCall#LambdaHandler.g.verified.cs new file mode 100644 index 00000000..a80f8bfe --- /dev/null +++ b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/OnShutdownVerifyTests.Test_OnShutdown_BaseMethodCall#LambdaHandler.g.verified.cs @@ -0,0 +1,27 @@ +//HintName: LambdaHandler.g.cs +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously + +#nullable enable + +namespace System.Runtime.CompilerServices +{ + using System.CodeDom.Compiler; + + [GeneratedCode("MinimalLambda.SourceGenerators", "0.0.0")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : Attribute + { + public InterceptsLocationAttribute(int version, string data) + { + } + } +} diff --git a/tests/MinimalLambda.SourceGenerators.UnitTests/VerifyTests/ExpressionLambdaVerifyTests.cs b/tests/MinimalLambda.SourceGenerators.UnitTests/VerifyTests/ExpressionLambdaVerifyTests.cs index 2c8efdad..648a77dd 100644 --- a/tests/MinimalLambda.SourceGenerators.UnitTests/VerifyTests/ExpressionLambdaVerifyTests.cs +++ b/tests/MinimalLambda.SourceGenerators.UnitTests/VerifyTests/ExpressionLambdaVerifyTests.cs @@ -18,8 +18,7 @@ await GeneratorTestHelpers.Verify( lambda.Handle(Task (ILambdaHostContext context) => Task.CompletedTask); await lambda.RunAsync(); - """, - 0 + """ ); [Fact] @@ -40,8 +39,7 @@ await GeneratorTestHelpers.Verify( lambda.Handle(Task (ILambdaHostContext context) => Task.CompletedTask); await lambda.RunAsync(); - """, - 0 + """ ); [Fact] diff --git a/tests/MinimalLambda.SourceGenerators.UnitTests/VerifyTests/OnInitVerifyTests.cs b/tests/MinimalLambda.SourceGenerators.UnitTests/VerifyTests/OnInitVerifyTests.cs index 7dbb1bc1..f4ba93ca 100644 --- a/tests/MinimalLambda.SourceGenerators.UnitTests/VerifyTests/OnInitVerifyTests.cs +++ b/tests/MinimalLambda.SourceGenerators.UnitTests/VerifyTests/OnInitVerifyTests.cs @@ -22,8 +22,7 @@ await GeneratorTestHelpers.Verify( ); await lambda.RunAsync(); - """, - 0 + """ ); [Fact] diff --git a/tests/MinimalLambda.SourceGenerators.UnitTests/VerifyTests/OnShutdownVerifyTests.cs b/tests/MinimalLambda.SourceGenerators.UnitTests/VerifyTests/OnShutdownVerifyTests.cs index 21f93c92..98a0e8ef 100644 --- a/tests/MinimalLambda.SourceGenerators.UnitTests/VerifyTests/OnShutdownVerifyTests.cs +++ b/tests/MinimalLambda.SourceGenerators.UnitTests/VerifyTests/OnShutdownVerifyTests.cs @@ -22,8 +22,7 @@ await GeneratorTestHelpers.Verify( ); await lambda.RunAsync(); - """, - 0 + """ ); [Fact]