5
5
using System . Net ;
6
6
using System . Text ;
7
7
using System . Text . Json ;
8
+ using System . Text . Json . Serialization ;
8
9
using Amazon . Lambda . APIGatewayEvents ;
9
10
using Amazon . Lambda . ApplicationLoadBalancerEvents ;
10
11
using Amazon . Lambda . RuntimeSupport ;
14
15
15
16
namespace Amazon . Lambda . AspNetCoreServer . Hosting . Internal ;
16
17
18
+ #if NET8_0_OR_GREATER
19
+
17
20
/// <summary>
18
21
/// Contains the plumbing to register a user provided <see cref="Func{HttpClient, Task}"/> inside
19
22
/// <see cref="Amazon.Lambda.Core.SnapshotRestore.RegisterBeforeSnapshot"/>.
@@ -22,7 +25,7 @@ namespace Amazon.Lambda.AspNetCoreServer.Hosting.Internal;
22
25
/// performance gains offered by SnapStart.
23
26
/// <para />
24
27
/// 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 " />.
26
29
/// <para />
27
30
/// Intercepted requests are then be processed later by <see cref="SnapstartHelperLambdaRequests.ExecuteSnapstartInitRequests"/>
28
31
/// which will route them correctly through a simulated asp.net/lambda pipeline.
@@ -37,11 +40,8 @@ public LambdaSnapstartExecuteRequestsBeforeSnapshotHelper(LambdaEventSource lamb
37
40
}
38
41
39
42
/// <inheritdoc cref="RegisterInitializerRequests"/>
40
- [ RequiresUnreferencedCode ( "Serializes object to json" ) ]
41
43
public void RegisterInitializerRequests ( HandlerWrapper handlerWrapper )
42
44
{
43
- #if NET8_0_OR_GREATER
44
-
45
45
Amazon . Lambda . Core . SnapshotRestore . RegisterBeforeSnapshot ( async ( ) =>
46
46
{
47
47
// Construct specialized HttpClient that will intercept requests and saved them inside
@@ -60,39 +60,36 @@ public void RegisterInitializerRequests(HandlerWrapper handlerWrapper)
60
60
61
61
// Request are now in CapturedHttpRequests. Serialize each one into a json object
62
62
// and execute the request through the lambda pipeline (ie handlerWrapper).
63
- foreach ( var req in LambdaSnapstartInitializerHttpMessageHandler . CapturedHttpRequests )
63
+ foreach ( var json in LambdaSnapstartInitializerHttpMessageHandler . CapturedHttpRequestsJson )
64
64
{
65
- var json = JsonSerializer . Serialize ( req ) ;
66
-
67
65
await SnapstartHelperLambdaRequests . ExecuteSnapstartInitRequests ( json , times : 5 , handlerWrapper ) ;
68
66
}
69
67
} ) ;
70
-
71
- #endif
72
68
}
73
69
70
+
74
71
/// <inheritdoc cref="ServiceCollectionExtensions.AddAWSLambdaBeforeSnapshotRequest"/>
75
72
internal static BeforeSnapstartRequestRegistrar Registrar = new ( ) ;
76
73
77
74
internal class BeforeSnapstartRequestRegistrar
78
75
{
79
- private List < Func < HttpClient , Task > > beforeSnapstartFuncs = new ( ) ;
76
+ private readonly List < Func < HttpClient , Task > > _beforeSnapstartFuncs = new ( ) ;
80
77
81
78
public void Register ( Func < HttpClient , Task > beforeSnapstartRequest )
82
79
{
83
- beforeSnapstartFuncs . Add ( beforeSnapstartRequest ) ;
80
+ _beforeSnapstartFuncs . Add ( beforeSnapstartRequest ) ;
84
81
}
85
82
86
83
internal async Task Execute ( HttpClient client )
87
84
{
88
- foreach ( var f in beforeSnapstartFuncs )
85
+ foreach ( var f in _beforeSnapstartFuncs )
89
86
await f ( client ) ;
90
87
}
91
88
}
92
89
93
90
private static class SnapstartHelperLambdaRequests
94
91
{
95
- private static InternalLogger _logger = InternalLogger . GetDefaultLogger ( ) ;
92
+ private static readonly InternalLogger _logger = InternalLogger . GetDefaultLogger ( ) ;
96
93
97
94
private static readonly RuntimeApiHeaders _fakeRuntimeApiHeaders = new ( new Dictionary < string , IEnumerable < string > >
98
95
{
@@ -136,7 +133,7 @@ private class LambdaSnapstartInitializerHttpMessageHandler : HttpMessageHandler
136
133
137
134
public static Uri BaseUri { get ; } = new Uri ( "http://localhost" ) ;
138
135
139
- public static List < object > CapturedHttpRequests { get ; } = new ( ) ;
136
+ public static List < string > CapturedHttpRequestsJson { get ; } = new ( ) ;
140
137
141
138
public LambdaSnapstartInitializerHttpMessageHandler ( LambdaEventSource lambdaEventSource )
142
139
{
@@ -162,49 +159,60 @@ protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage
162
159
Query = QueryHelpers . ParseNullableQuery ( request . RequestUri ? . Query )
163
160
} ;
164
161
165
- object translatedRequest = _lambdaEventSource switch
162
+ string translatedRequestJson = _lambdaEventSource switch
166
163
{
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
183
167
{
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 ) ,
203
209
_ => throw new NotImplementedException (
204
210
$ "Unknown { nameof ( LambdaEventSource ) } : { Enum . GetName ( _lambdaEventSource ) } ")
205
211
} ;
206
212
207
- CapturedHttpRequests . Add ( translatedRequest ) ;
213
+ // NOTE: Any object added to CapturedHttpRequests must have it's type added
214
+ // to the
215
+ CapturedHttpRequestsJson . Add ( translatedRequestJson ) ;
208
216
209
217
return new HttpResponseMessage ( HttpStatusCode . OK ) ;
210
218
}
@@ -218,3 +226,14 @@ private async Task<string> ReadContent(HttpRequestMessage r)
218
226
}
219
227
}
220
228
}
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