55using System . Net ;
66using System . Text ;
77using System . Text . Json ;
8+ using System . Text . Json . Serialization ;
89using Amazon . Lambda . APIGatewayEvents ;
910using Amazon . Lambda . ApplicationLoadBalancerEvents ;
1011using Amazon . Lambda . RuntimeSupport ;
1415
1516namespace Amazon . Lambda . AspNetCoreServer . Hosting . Internal ;
1617
18+ #if NET8_0_OR_GREATER
19+
1720/// <summary>
1821/// Contains the plumbing to register a user provided <see cref="Func{HttpClient, Task}"/> inside
1922/// <see cref="Amazon.Lambda.Core.SnapshotRestore.RegisterBeforeSnapshot"/>.
@@ -22,7 +25,7 @@ namespace Amazon.Lambda.AspNetCoreServer.Hosting.Internal;
2225/// performance gains offered by SnapStart.
2326/// <para />
2427/// It works by construction a specialized <see cref="HttpClient" /> that will intercept requests
25- /// and saved them inside <see cref="LambdaSnapstartInitializerHttpMessageHandler.CapturedHttpRequests " />.
28+ /// and saved them inside <see cref="LambdaSnapstartInitializerHttpMessageHandler.CapturedHttpRequestsJson " />.
2629/// <para />
2730/// Intercepted requests are then be processed later by <see cref="SnapstartHelperLambdaRequests.ExecuteSnapstartInitRequests"/>
2831/// which will route them correctly through a simulated asp.net/lambda pipeline.
@@ -37,11 +40,8 @@ public LambdaSnapstartExecuteRequestsBeforeSnapshotHelper(LambdaEventSource lamb
3740 }
3841
3942 /// <inheritdoc cref="RegisterInitializerRequests"/>
40- [ RequiresUnreferencedCode ( "Serializes object to json" ) ]
4143 public void RegisterInitializerRequests ( HandlerWrapper handlerWrapper )
4244 {
43- #if NET8_0_OR_GREATER
44-
4545 Amazon . Lambda . Core . SnapshotRestore . RegisterBeforeSnapshot ( async ( ) =>
4646 {
4747 // Construct specialized HttpClient that will intercept requests and saved them inside
@@ -60,39 +60,36 @@ public void RegisterInitializerRequests(HandlerWrapper handlerWrapper)
6060
6161 // Request are now in CapturedHttpRequests. Serialize each one into a json object
6262 // and execute the request through the lambda pipeline (ie handlerWrapper).
63- foreach ( var req in LambdaSnapstartInitializerHttpMessageHandler . CapturedHttpRequests )
63+ foreach ( var json in LambdaSnapstartInitializerHttpMessageHandler . CapturedHttpRequestsJson )
6464 {
65- var json = JsonSerializer . Serialize ( req ) ;
66-
6765 await SnapstartHelperLambdaRequests . ExecuteSnapstartInitRequests ( json , times : 5 , handlerWrapper ) ;
6866 }
6967 } ) ;
70-
71- #endif
7268 }
7369
70+
7471 /// <inheritdoc cref="ServiceCollectionExtensions.AddAWSLambdaBeforeSnapshotRequest"/>
7572 internal static BeforeSnapstartRequestRegistrar Registrar = new ( ) ;
7673
7774 internal class BeforeSnapstartRequestRegistrar
7875 {
79- private List < Func < HttpClient , Task > > beforeSnapstartFuncs = new ( ) ;
76+ private readonly List < Func < HttpClient , Task > > _beforeSnapstartFuncs = new ( ) ;
8077
8178 public void Register ( Func < HttpClient , Task > beforeSnapstartRequest )
8279 {
83- beforeSnapstartFuncs . Add ( beforeSnapstartRequest ) ;
80+ _beforeSnapstartFuncs . Add ( beforeSnapstartRequest ) ;
8481 }
8582
8683 internal async Task Execute ( HttpClient client )
8784 {
88- foreach ( var f in beforeSnapstartFuncs )
85+ foreach ( var f in _beforeSnapstartFuncs )
8986 await f ( client ) ;
9087 }
9188 }
9289
9390 private static class SnapstartHelperLambdaRequests
9491 {
95- private static InternalLogger _logger = InternalLogger . GetDefaultLogger ( ) ;
92+ private static readonly InternalLogger _logger = InternalLogger . GetDefaultLogger ( ) ;
9693
9794 private static readonly RuntimeApiHeaders _fakeRuntimeApiHeaders = new ( new Dictionary < string , IEnumerable < string > >
9895 {
@@ -136,7 +133,7 @@ private class LambdaSnapstartInitializerHttpMessageHandler : HttpMessageHandler
136133
137134 public static Uri BaseUri { get ; } = new Uri ( "http://localhost" ) ;
138135
139- public static List < object > CapturedHttpRequests { get ; } = new ( ) ;
136+ public static List < string > CapturedHttpRequestsJson { get ; } = new ( ) ;
140137
141138 public LambdaSnapstartInitializerHttpMessageHandler ( LambdaEventSource lambdaEventSource )
142139 {
@@ -162,49 +159,60 @@ protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage
162159 Query = QueryHelpers . ParseNullableQuery ( request . RequestUri ? . Query )
163160 } ;
164161
165- object translatedRequest = _lambdaEventSource switch
162+ string translatedRequestJson = _lambdaEventSource switch
166163 {
167- LambdaEventSource . ApplicationLoadBalancer => new ApplicationLoadBalancerRequest
168- {
169- Body = duckRequest . Body ,
170- Headers = duckRequest . Headers ,
171- Path = duckRequest . Path ,
172- HttpMethod = duckRequest . HttpMethod ,
173- QueryStringParameters = duckRequest . Query ? . ToDictionary ( k => k . Key , v => v . Value . ToString ( ) )
174- } ,
175- LambdaEventSource . HttpApi => new APIGatewayHttpApiV2ProxyRequest
176- {
177- Body = duckRequest . Body ,
178- Headers = duckRequest . Headers ,
179- RawPath = duckRequest . Path ,
180- RequestContext = new APIGatewayHttpApiV2ProxyRequest . ProxyRequestContext
181- {
182- Http = new APIGatewayHttpApiV2ProxyRequest . HttpDescription
164+ LambdaEventSource . ApplicationLoadBalancer =>
165+ JsonSerializer . Serialize (
166+ new ApplicationLoadBalancerRequest
183167 {
184- Method = duckRequest . HttpMethod ,
185- Path = duckRequest . Path
186- }
187- } ,
188- QueryStringParameters = duckRequest . Query ? . ToDictionary ( k => k . Key , v => v . Value . ToString ( ) ) ,
189- RawQueryString = duckRequest . RawQuery
190- } ,
191- LambdaEventSource . RestApi => new APIGatewayProxyRequest
192- {
193- Body = duckRequest . Body ,
194- Headers = duckRequest . Headers ,
195- Path = duckRequest . Path ,
196- HttpMethod = duckRequest . HttpMethod ,
197- RequestContext = new APIGatewayProxyRequest . ProxyRequestContext
198- {
199- HttpMethod = duckRequest . HttpMethod
200- } ,
201- QueryStringParameters = duckRequest . Query ? . ToDictionary ( k => k . Key , v => v . Value . ToString ( ) )
202- } ,
168+ Body = duckRequest . Body ,
169+ Headers = duckRequest . Headers ,
170+ Path = duckRequest . Path ,
171+ HttpMethod = duckRequest . HttpMethod ,
172+ QueryStringParameters = duckRequest . Query ? . ToDictionary ( k => k . Key , v => v . Value . ToString ( ) )
173+ } ,
174+ LambdaRequestTypeClasses . Default . ApplicationLoadBalancerRequest ) ,
175+ LambdaEventSource . HttpApi =>
176+ JsonSerializer . Serialize (
177+ new APIGatewayHttpApiV2ProxyRequest
178+ {
179+ Body = duckRequest . Body ,
180+ Headers = duckRequest . Headers ,
181+ RawPath = duckRequest . Path ,
182+ RequestContext = new APIGatewayHttpApiV2ProxyRequest . ProxyRequestContext
183+ {
184+ Http = new APIGatewayHttpApiV2ProxyRequest . HttpDescription
185+ {
186+ Method = duckRequest . HttpMethod ,
187+ Path = duckRequest . Path
188+ }
189+ } ,
190+ QueryStringParameters = duckRequest . Query ? . ToDictionary ( k => k . Key , v => v . Value . ToString ( ) ) ,
191+ RawQueryString = duckRequest . RawQuery
192+ } ,
193+ LambdaRequestTypeClasses . Default . APIGatewayHttpApiV2ProxyRequest ) ,
194+ LambdaEventSource . RestApi =>
195+ JsonSerializer . Serialize (
196+ new APIGatewayProxyRequest
197+ {
198+ Body = duckRequest . Body ,
199+ Headers = duckRequest . Headers ,
200+ Path = duckRequest . Path ,
201+ HttpMethod = duckRequest . HttpMethod ,
202+ RequestContext = new APIGatewayProxyRequest . ProxyRequestContext
203+ {
204+ HttpMethod = duckRequest . HttpMethod
205+ } ,
206+ QueryStringParameters = duckRequest . Query ? . ToDictionary ( k => k . Key , v => v . Value . ToString ( ) )
207+ } ,
208+ LambdaRequestTypeClasses . Default . APIGatewayProxyRequest ) ,
203209 _ => throw new NotImplementedException (
204210 $ "Unknown { nameof ( LambdaEventSource ) } : { Enum . GetName ( _lambdaEventSource ) } ")
205211 } ;
206212
207- CapturedHttpRequests . Add ( translatedRequest ) ;
213+ // NOTE: Any object added to CapturedHttpRequests must have it's type added
214+ // to the
215+ CapturedHttpRequestsJson . Add ( translatedRequestJson ) ;
208216
209217 return new HttpResponseMessage ( HttpStatusCode . OK ) ;
210218 }
@@ -218,3 +226,14 @@ private async Task<string> ReadContent(HttpRequestMessage r)
218226 }
219227 }
220228}
229+
230+
231+ [ JsonSourceGenerationOptions ( WriteIndented = true ) ]
232+ [ JsonSerializable ( typeof ( ApplicationLoadBalancerRequest ) ) ]
233+ [ JsonSerializable ( typeof ( APIGatewayHttpApiV2ProxyRequest ) ) ]
234+ [ JsonSerializable ( typeof ( APIGatewayProxyRequest ) ) ]
235+
236+ internal partial class LambdaRequestTypeClasses : JsonSerializerContext
237+ {
238+ }
239+ #endif
0 commit comments