Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions .autover/changes/9e75413c-9cb6-4521-aaca-09b557fff2b3.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"Projects": [
{
"Name": "Amazon.Lambda.Core",
"Type": "Minor",
"ChangelogMessages": [
"Lambda response streaming is now available as GA. The RequiresPreviewFeatures attribute has been removed",
"The LambdaLogger.ConfigureStructuredLogging API has been deployed to the managed runtime. The RequiresPreviewFeatures attribute has been removed"
]
},
{
"Name": "Amazon.Lambda.Annotations",
"Type": "Minor",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i dont see any annotation changes in this pr but i see it in the changefile?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The csproj files have the project reference to Amazon.Lambda.Core. So when we do the release the project reference will cause the dependency version for the generated nuspec file to have the new version of Amazon.Lambda.Core. So there is nothing to change in the csproj file. If it was a package reference then you would see a csrpoj change.

"ChangelogMessages": [
"Updated Amazon.Lambda.Core dependency to include Lambda Response Streaming support."
]
},
{
"Name": "Amazon.Lambda.AspNetCoreServer",
"Type": "Minor",
"ChangelogMessages": [
"Removed RequiresPreviewFeatures attribute for Lambda Response Streaming.",
"Updated Amazon.Lambda.Core dependency to include Lambda Response Streaming support.",
"Updated the base class AbstractAspNetCoreFunction to implement IDisposable. This is mostly needed for unit tests. In the Lambda environment there will only be one instance of AbstractAspNetCoreFunction subclass created."
]
},
{
"Name": "Amazon.Lambda.AspNetCoreServer.Hosting",
"Type": "Minor",
"ChangelogMessages": [
"Removed RequiresPreviewFeatures attribute for Lambda Response Streaming.",
"Updated Amazon.Lambda.Core dependency to include Lambda Response Streaming support."
]
},
{
"Name": "Amazon.Lambda.PowerShellHost",
"Type": "Minor",
"ChangelogMessages": [
"Updated Amazon.Lambda.Core dependency to include Lambda Response Streaming support."

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are you missing some csproj updates or somthing somewhere?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The csproj files have the project reference to Amazon.Lambda.Core. So when we do the release the project reference will cause the dependency version for the generated nuspec file to have the new version of Amazon.Lambda.Core. So there is nothing to change in the csproj file. If it was a package reference then you would see a csrpoj change.

]
},
{
"Name": "Amazon.Lambda.RuntimeSupport",
"Type": "Minor",
"ChangelogMessages": [
"Updated Amazon.Lambda.Core dependency to include Lambda Response Streaming support."
]
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ public class HostingOptions
/// <c>FunctionHandlerAsync</c> writes directly to the Lambda response stream and
/// returns <c>null</c>. Requires net8.0 or later.
/// </summary>
[System.Runtime.Versioning.RequiresPreviewFeatures(ParameterizedPreviewMessage)]
public bool EnableResponseStreaming { get; set; } = false;

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ private protected override void InternalCustomResponseExceptionHandling(APIGatew
/// instead of <c>multiValueHeaders</c>. API Gateway HTTP API v2 expects the <c>headers</c>
/// format; using <c>multiValueHeaders</c> causes a 500 Internal Server Error.
/// </summary>
[System.Runtime.Versioning.RequiresPreviewFeatures(ParameterizedPreviewMessage)]
protected override Amazon.Lambda.Core.ResponseStreaming.HttpResponseStreamPrelude BuildStreamingPrelude(IHttpResponseFeature responseFeature)
{
var prelude = new Amazon.Lambda.Core.ResponseStreaming.HttpResponseStreamPrelude
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ private protected override void InternalCustomResponseExceptionHandling(APIGatew
/// </summary>
/// <param name="responseFeature">The ASP.NET Core response feature for the current invocation.</param>
/// <returns>A populated <see cref="Amazon.Lambda.Core.ResponseStreaming.HttpResponseStreamPrelude"/>.</returns>
[System.Runtime.Versioning.RequiresPreviewFeatures(ParameterizedPreviewMessage)]
protected override Amazon.Lambda.Core.ResponseStreaming.HttpResponseStreamPrelude BuildStreamingPrelude(IHttpResponseFeature responseFeature)
{
var prelude = new Amazon.Lambda.Core.ResponseStreaming.HttpResponseStreamPrelude
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,6 @@ namespace Amazon.Lambda.AspNetCoreServer
/// </summary>
public abstract class AbstractAspNetCoreFunction
{
internal const string ParameterizedPreviewMessage =
"Response streaming is in preview till a new version of .NET Lambda runtime client that supports response streaming " +
"has been deployed to the .NET Lambda managed runtime. Till deployment has been made the feature can be used by deploying as an " +
"executable including the latest version of Amazon.Lambda.RuntimeSupport and setting the \"EnablePreviewFeatures\" in the Lambda " +
"project file to \"true\"";

/// <summary>
/// Key to access the ILambdaContext object from the HttpContext.Items collection.
/// </summary>
Expand All @@ -47,13 +41,21 @@ public abstract class AbstractAspNetCoreFunction
/// </summary>
/// <typeparam name="TREQUEST"></typeparam>
/// <typeparam name="TRESPONSE"></typeparam>
public abstract class AbstractAspNetCoreFunction<TREQUEST, TRESPONSE> : AbstractAspNetCoreFunction
public abstract class AbstractAspNetCoreFunction<TREQUEST, TRESPONSE> : AbstractAspNetCoreFunction, IDisposable
{
private protected IServiceProvider _hostServices;
private protected LambdaServer _server;
private protected ILogger _logger;
private protected StartupMode _startupMode;

// The IHost created and owned by this instance in Start(). Retained so it can be disposed,
// releasing resources such as the configuration file-change watchers (inotify instances on Linux)
// that Host.CreateDefaultBuilder registers. Null when the function is constructed from an
// externally-owned IServiceProvider, in which case this instance does not own the host.
private IHost _host;

private bool _disposed;

// Defines a mapping from registered content types to the response encoding format
// which dictates what transformations should be applied before returning response content
private readonly Dictionary<string, ResponseContentEncoding> _responseContentEncodingForContentType = new Dictionary<string, ResponseContentEncoding>
Expand Down Expand Up @@ -206,7 +208,6 @@ public void RegisterResponseContentEncodingForContentEncoding(string contentEnco
/// buffering it and returning a typed response object (which will be <c>null</c>).
/// Requires net8.0 or later.
/// </summary>
[System.Runtime.Versioning.RequiresPreviewFeatures(ParameterizedPreviewMessage)]
public virtual bool EnableResponseStreaming { get; set; } = false;


Expand Down Expand Up @@ -364,6 +365,7 @@ protected void Start()
});

var host = builder.Build();
_host = host;
PostCreateHost(host);

host.Start();
Expand Down Expand Up @@ -678,7 +680,6 @@ protected virtual void PostMarshallResponseFeature(IHttpResponseFeature aspNetCo
/// </summary>
/// <param name="responseFeature">The ASP.NET Core response feature for the current invocation.</param>
/// <returns>A populated <see cref="Amazon.Lambda.Core.ResponseStreaming.HttpResponseStreamPrelude"/>.</returns>
[System.Runtime.Versioning.RequiresPreviewFeatures(ParameterizedPreviewMessage)]
protected abstract Amazon.Lambda.Core.ResponseStreaming.HttpResponseStreamPrelude BuildStreamingPrelude(IHttpResponseFeature responseFeature);

/// <summary>
Expand All @@ -689,7 +690,6 @@ protected virtual void PostMarshallResponseFeature(IHttpResponseFeature aspNetCo
/// </summary>
/// <param name="prelude">The HTTP response prelude containing status code and headers.</param>
/// <returns>A writable <see cref="System.IO.Stream"/> for the response body.</returns>
[System.Runtime.Versioning.RequiresPreviewFeatures(ParameterizedPreviewMessage)]
protected virtual System.IO.Stream CreateLambdaResponseStream(
Amazon.Lambda.Core.ResponseStreaming.HttpResponseStreamPrelude prelude)
{
Expand All @@ -701,7 +701,6 @@ protected virtual System.IO.Stream CreateLambdaResponseStream(
/// <see cref="EnableResponseStreaming"/> is <c>true</c>. Writes the response directly to a
/// <see cref="Amazon.Lambda.Core.ResponseStreaming.LambdaResponseStream"/>.
/// </summary>
[System.Runtime.Versioning.RequiresPreviewFeatures(ParameterizedPreviewMessage)]
private async Task ExecuteStreamingRequestAsync(InvokeFeatures features)
{
var responseFeature = (IHttpResponseFeature)features;
Expand Down Expand Up @@ -824,5 +823,37 @@ private async Task RunPipelineAsync(object context, InvokeFeatures features)
throw;
}
}

/// <summary>
/// Disposes the IHost created and owned by this instance in <see cref="Start"/>, releasing
/// resources it holds such as the configuration file-change watchers (inotify instances on Linux)
/// registered by Host.CreateDefaultBuilder. When the function was constructed from an
/// externally-owned IServiceProvider this instance does not own a host and disposal is a no-op.
/// </summary>
/// <param name="disposing"><c>true</c> when called from <see cref="Dispose()"/>.</param>
protected virtual void Dispose(bool disposing)
{
if (_disposed)
{
return;
}

if (disposing)
{
_host?.Dispose();
_host = null;
}

_disposed = true;
}

/// <summary>
/// Disposes the resources owned by this function, including the IHost created in <see cref="Start"/>.
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,6 @@ private protected override void InternalCustomResponseExceptionHandling(Applicat
}

/// <inheritdoc/>
[System.Runtime.Versioning.RequiresPreviewFeatures(ParameterizedPreviewMessage)]
protected override HttpResponseStreamPrelude BuildStreamingPrelude(IHttpResponseFeature responseFeature) => throw new NotImplementedException();

private string GetSingleHeaderValue(ApplicationLoadBalancerRequest request, string headerName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using System;
using System.IO;
using System.IO.Pipelines;
using System.Runtime.Versioning;
using System.Threading;
using System.Threading.Tasks;

Expand All @@ -20,7 +19,6 @@ namespace Amazon.Lambda.AspNetCoreServer.Internal
/// <see cref="MemoryStream"/>; after <see cref="StartAsync"/> all writes go directly to the
/// <see cref="LambdaResponseStream"/> obtained from the stream opener delegate.
/// </summary>
[RequiresPreviewFeatures(AbstractAspNetCoreFunction.ParameterizedPreviewMessage)]
internal class StreamingResponseBodyFeature : IHttpResponseBodyFeature
{
private readonly ILogger _logger;
Expand Down
6 changes: 3 additions & 3 deletions Libraries/src/Amazon.Lambda.Core/LambdaLogger.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

using System;
using System.Reflection.Emit;
using System.Runtime.Versioning;
using System.Text;

namespace Amazon.Lambda.Core
Expand Down Expand Up @@ -139,7 +140,6 @@ public static void Log(string level, Exception exception, string message, params
/// When structured logging is enabled this method will allow overriding the default configuration the Lambda runtime uses for structured logging.
/// </summary>
/// <param name="options">The options to use for configuring structured logging.</param>
[RequiresPreviewFeatures("This method is in preview until the latest changes of the .NET Lambda runtime client have been deployed to the Lambda managed runtimes")]
public static void ConfigureStructuredLogging(StructuredLoggingOptions options) => _configureStructuredLoggingAction(options);

internal static void SetConfigureStructuredLoggingAction(Action<StructuredLoggingOptions> configureStructuredLoggingAction)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Runtime.Versioning;
using System.Text.Json;

namespace Amazon.Lambda.Core.ResponseStreaming
Expand All @@ -15,7 +14,6 @@ namespace Amazon.Lambda.Core.ResponseStreaming
/// headers, and cookies for the response. The prelude must be sent as the first chunk of the response stream, followed by the response body chunks.
/// This allows you to set the status code and headers for the response before sending any of the response body.
/// </summary>
[RequiresPreviewFeatures(LambdaResponseStreamFactory.PreviewMessage)]
public class HttpResponseStreamPrelude
{
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

using System;
using System.IO;
using System.Runtime.Versioning;
using System.Threading;
using System.Threading.Tasks;

Expand All @@ -15,7 +14,6 @@ namespace Amazon.Lambda.Core.ResponseStreaming
/// to the Lambda Runtime API. Returned by <see cref="LambdaResponseStreamFactory.CreateStream"/>.
/// Integrates with standard .NET stream consumers such as <see cref="System.IO.StreamWriter"/>.
/// </summary>
[RequiresPreviewFeatures(LambdaResponseStreamFactory.PreviewMessage)]
public class LambdaResponseStream : Stream
{
private readonly ILambdaResponseStream _responseStream;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,14 @@
#if NET8_0_OR_GREATER
using System;
using System.IO;
using System.Runtime.Versioning;

namespace Amazon.Lambda.Core.ResponseStreaming
{
/// <summary>
/// Factory to create Lambda response streams for writing streaming responses in AWS Lambda functions. The created streams are write-only and non-seekable.
/// </summary>
[RequiresPreviewFeatures(LambdaResponseStreamFactory.PreviewMessage)]
public class LambdaResponseStreamFactory
{
Comment thread
normj marked this conversation as resolved.
internal const string PreviewMessage =
"Response streaming is in preview till a new version of .NET Lambda runtime client that supports response streaming " +
"has been deployed to the .NET Lambda managed runtime. Till deployment has been made the feature can be used by deploying as an " +
"executable including the latest version of Amazon.Lambda.RuntimeSupport and setting the \"EnablePreviewFeatures\" in the Lambda " +
"project file to \"true\"";

internal const string UninitializedFactoryMessage =
"LambdaResponseStreamFactory is not initialized. This is caused by mismatch versions of Amazon.Lambda.Core and Amazon.Lambda.RuntimeSupport. " +
"Update both packages to the current version to address the issue.";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<NoWarn>1701;1702;1705;CS0618;CS1591</NoWarn>
<!-- Applied automatically by "dotnet test" so DOTNET_USE_POLLING_FILE_WATCHER is set before the test host starts. See test.runsettings. -->
<RunSettingsFilePath>$(MSBuildProjectDirectory)\test.runsettings</RunSettingsFilePath>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0


using System.Runtime.Versioning;
using Amazon.Lambda.AspNetCoreServer.Hosting.Internal;
using Amazon.Lambda.AspNetCoreServer.Test;
using Amazon.Lambda.Core;
Expand All @@ -16,7 +14,6 @@ namespace Amazon.Lambda.AspNetCoreServer.Hosting.Tests;
/// <summary>
/// Tests for response streaming integration in hosting (Requirement 10).
/// </summary>
[RequiresPreviewFeatures]
public class ResponseStreamingHostingTests
{
Comment thread
normj marked this conversation as resolved.
[Fact]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

using System.Runtime.Versioning;

using Amazon.Lambda.AspNetCoreServer.Hosting.Internal;
using Amazon.Lambda.Core;
using Amazon.Lambda.RuntimeSupport;
Expand All @@ -14,7 +12,6 @@

namespace Amazon.Lambda.AspNetCoreServer.Hosting.Tests;

[RequiresPreviewFeatures]
public class ResponseStreamingPropertyTests
{
Comment thread
normj marked this conversation as resolved.
private static IServiceProvider BuildServiceProvider(HostingOptions hostingOptions)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,26 +135,6 @@ public void AddAWSLambdaHosting_ApplicationLoadBalancer_RegistersHostingOptions(
Assert.True(hostingOptions.ContentTypeEncodings.ContainsKey("image/png"));
}

[Fact]
public void AddAWSLambdaHosting_NotInLambda_DoesNotRegisterHostingOptions()
{
// Arrange
var services = new ServiceCollection();
// No AWS_LAMBDA_FUNCTION_NAME environment variable set

// Act
services.AddAWSLambdaHosting(LambdaEventSource.HttpApi, options =>
{
options.DefaultResponseContentEncoding = ResponseContentEncoding.Base64;
});

var serviceProvider = services.BuildServiceProvider();

// Assert
var hostingOptions = serviceProvider.GetService<HostingOptions>();
Assert.Null(hostingOptions);
}

[Fact]
public void AddAWSLambdaHosting_ConfigurationIsApplied()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<RunSettings>
<RunConfiguration>
<!--
Force ASP.NET Core / Microsoft.Extensions configuration to use a polling file watcher instead of
the OS file-system watcher. On Linux the OS watcher is backed by inotify, and each host built via
Host.CreateDefaultBuilder / WebApplication registers several reloadOnChange watchers on appsettings*.json.
These tests construct many ASP.NET Core hosts and xUnit runs test classes in parallel; when this assembly
runs alongside Amazon.Lambda.AspNetCoreServer.Test in a single solution-wide test run, the concurrent number
of inotify instances exceeds the per-user limit (fs.inotify.max_user_instances, 128 by default on the CI
hosts), producing "The configured user limit (128) on the number of inotify instances has been reached".

The polling watcher uses a timer instead of inotify, so no inotify instances are consumed. VSTest sets
these variables before the test host process starts, so they take effect before any host is built.
-->
<EnvironmentVariables>
<DOTNET_USE_POLLING_FILE_WATCHER>1</DOTNET_USE_POLLING_FILE_WATCHER>
</EnvironmentVariables>
</RunConfiguration>
</RunSettings>
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<NoWarn>1701;1702;1705;CS0618;CS1591</NoWarn>
<!-- Applied automatically by "dotnet test" so DOTNET_USE_POLLING_FILE_WATCHER is set before the test host starts. See test.runsettings. -->
<RunSettingsFilePath>$(MSBuildProjectDirectory)\test.runsettings</RunSettingsFilePath>
</PropertyGroup>

<ItemGroup>
Expand Down
Loading
Loading