4
4
using Aspire . Hosting . AWS ;
5
5
using Aspire . Hosting . AWS . Lambda ;
6
6
using Microsoft . Extensions . Hosting ;
7
+ using Aspire . Hosting . AWS . Utils . Internal ;
8
+ using Aspire . Hosting . Lifecycle ;
9
+ using Microsoft . AspNetCore . Http ;
10
+ using Microsoft . Extensions . DependencyInjection . Extensions ;
7
11
using System . Diagnostics ;
8
12
using System . Net . Sockets ;
9
13
using System . Runtime . Versioning ;
@@ -54,6 +58,7 @@ public static class LambdaExtensions
54
58
// Add the Lambda function resource on the path so the emulator can distingish request
55
59
// for each Lambda function.
56
60
var apiPath = $ "{ serviceEmulatorEndpoint . Host } :{ serviceEmulatorEndpoint . Port } /{ name } ";
61
+ context . EnvironmentVariables [ "AWS_EXECUTION_ENV" ] = $ "aspire.hosting.aws#{ SdkUtilities . GetAssemblyVersion ( ) } ";
57
62
context . EnvironmentVariables [ "AWS_LAMBDA_RUNTIME_API" ] = apiPath ;
58
63
context . EnvironmentVariables [ "AWS_LAMBDA_FUNCTION_NAME" ] = name ;
59
64
context . EnvironmentVariables [ "_HANDLER" ] = lambdaHandler ;
@@ -96,6 +101,67 @@ public static class LambdaExtensions
96
101
return resource ;
97
102
}
98
103
104
+ /// <summary>
105
+ /// Add the Lambda service emulator resource. The <see cref="AddAWSLambdaFunction"/> method will automatically add the Lambda service emulator if it hasn't
106
+ /// already been added. This method only needs to be called if the emulator needs to be customized with the <see cref="LambdaEmulatorOptions"/>. If
107
+ /// this method is called it must be called only once and before any <see cref="AddAWSLambdaFunction"/> calls.
108
+ /// </summary>
109
+ /// <param name="builder"></param>
110
+ /// <param name="options">The options to configure the emulator with.</param>
111
+ /// <returns></returns>
112
+ /// <exception cref="InvalidOperationException">Thrown if the Lambda service emulator has already been added.</exception>
113
+ public static IResourceBuilder < LambdaEmulatorResource > AddAWSLambdaServiceEmulator ( this IDistributedApplicationBuilder builder , LambdaEmulatorOptions ? options = null )
114
+ {
115
+ if ( builder . Resources . FirstOrDefault ( x => x . TryGetAnnotationsOfType < LambdaEmulatorAnnotation > ( out _ ) ) is ExecutableResource serviceEmulator )
116
+ {
117
+ throw new InvalidOperationException ( "A Lambda service emulator has already been added. The AddAWSLambdaFunction will add the emulator " +
118
+ "if it hasn't already been added. This method must be called before AddAWSLambdaFunction if the Lambda service emulator needs to be customized." ) ;
119
+ }
120
+
121
+ builder . Services . TryAddSingleton < IProcessCommandService , ProcessCommandService > ( ) ;
122
+
123
+ var lambdaEmulator = builder . AddResource ( new LambdaEmulatorResource ( "LambdaServiceEmulator" ) ) . ExcludeFromManifest ( ) ;
124
+ lambdaEmulator . WithArgs ( context =>
125
+ {
126
+ lambdaEmulator . Resource . AddCommandLineArguments ( context . Args ) ;
127
+ } ) ;
128
+
129
+ var annotation = new EndpointAnnotation (
130
+ protocol : ProtocolType . Tcp ,
131
+ uriScheme : "http" ) ;
132
+
133
+ lambdaEmulator . WithAnnotation ( annotation ) ;
134
+ var endpointReference = new EndpointReference ( lambdaEmulator . Resource , annotation ) ;
135
+
136
+ lambdaEmulator . WithAnnotation ( new LambdaEmulatorAnnotation ( endpointReference )
137
+ {
138
+ DisableAutoInstall = options ? . DisableAutoInstall ?? false ,
139
+ OverrideMinimumInstallVersion = options ? . OverrideMinimumInstallVersion ,
140
+ AllowDowngrade = options ? . AllowDowngrade ?? false ,
141
+ } ) ;
142
+
143
+ lambdaEmulator . WithAnnotation ( new EnvironmentCallbackAnnotation ( context =>
144
+ {
145
+ context . EnvironmentVariables [ Constants . IsAspireHostedEnvVariable ] = "true" ;
146
+ context . EnvironmentVariables [ "LAMBDA_RUNTIME_API_PORT" ] = endpointReference . Property ( EndpointProperty . TargetPort ) ;
147
+ } ) ) ;
148
+
149
+ serviceEmulator = lambdaEmulator . Resource ;
150
+ builder . Services . TryAddLifecycleHook < LambdaLifecycleHook > ( ) ;
151
+
152
+ return lambdaEmulator ;
153
+ }
154
+
155
+ private static ExecutableResource AddOrGetLambdaServiceEmulatorResource ( IDistributedApplicationBuilder builder )
156
+ {
157
+ if ( builder . Resources . FirstOrDefault ( x => x . TryGetAnnotationsOfType < LambdaEmulatorAnnotation > ( out _ ) ) is not ExecutableResource serviceEmulator )
158
+ {
159
+ serviceEmulator = builder . AddAWSLambdaServiceEmulator ( ) . Resource ;
160
+ }
161
+
162
+ return serviceEmulator ;
163
+ }
164
+
99
165
/// <summary>
100
166
/// This method is adapted from the Aspire WithProjectDefaults method.
101
167
/// https://github.com/dotnet/aspire/blob/157f312e39300912b37a14f59beda217c8195e14/src/Aspire.Hosting/ProjectResourceBuilderExtensions.cs#L287
@@ -122,35 +188,4 @@ private static IResourceBuilder<LambdaProjectResource> WithOpenTelemetry(this IR
122
188
123
189
return builder ;
124
190
}
125
-
126
- private static ExecutableResource AddOrGetLambdaServiceEmulatorResource ( IDistributedApplicationBuilder builder )
127
- {
128
- if ( builder . Resources . FirstOrDefault ( x => x . TryGetAnnotationsOfType < LambdaEmulatorAnnotation > ( out _ ) ) is not ExecutableResource serviceEmulator )
129
- {
130
- var serviceEmulatorBuilder = builder . AddExecutable ( $ "Lambda-ServiceEmulator",
131
- "dotnet-lambda-test-tool" ,
132
- Environment . CurrentDirectory ,
133
- "--no-launch-window" )
134
- . ExcludeFromManifest ( ) ;
135
-
136
- var annotation = new EndpointAnnotation (
137
- protocol : ProtocolType . Tcp ,
138
- uriScheme : "http" ) ;
139
-
140
- serviceEmulatorBuilder . WithAnnotation ( annotation ) ;
141
- var endpointReference = new EndpointReference ( serviceEmulatorBuilder . Resource , annotation ) ;
142
-
143
- serviceEmulatorBuilder . WithAnnotation ( new LambdaEmulatorAnnotation ( endpointReference ) ) ;
144
-
145
- serviceEmulatorBuilder . WithAnnotation ( new EnvironmentCallbackAnnotation ( context =>
146
- {
147
- context . EnvironmentVariables [ Constants . IsAspireHostedEnvVariable ] = "true" ;
148
- context . EnvironmentVariables [ "LAMBDA_RUNTIME_API_PORT" ] = endpointReference . Property ( EndpointProperty . TargetPort ) ;
149
- } ) ) ;
150
-
151
- serviceEmulator = serviceEmulatorBuilder . Resource ;
152
- }
153
-
154
- return serviceEmulator ;
155
- }
156
191
}
0 commit comments