1
1
use crate :: { Error , RefConfig } ;
2
2
use base64:: prelude:: * ;
3
3
use bytes:: Bytes ;
4
- use http:: { HeaderMap , HeaderValue , StatusCode } ;
4
+ use http:: { header :: ToStrError , HeaderMap , HeaderValue , StatusCode } ;
5
5
use serde:: { Deserialize , Serialize } ;
6
6
use std:: {
7
7
collections:: HashMap ,
8
- convert :: TryFrom ,
8
+ env ,
9
9
fmt:: Debug ,
10
10
time:: { Duration , SystemTime } ,
11
11
} ;
12
12
use tokio_stream:: Stream ;
13
+ use tracing:: Span ;
13
14
14
15
#[ derive( Debug , Eq , PartialEq , Clone , Serialize , Deserialize ) ]
15
16
#[ serde( rename_all = "camelCase" ) ]
@@ -120,11 +121,10 @@ pub struct Context {
120
121
pub env_config : RefConfig ,
121
122
}
122
123
123
- impl TryFrom < ( RefConfig , HeaderMap ) > for Context {
124
- type Error = Error ;
125
- fn try_from ( data : ( RefConfig , HeaderMap ) ) -> Result < Self , Self :: Error > {
126
- let env_config = data. 0 ;
127
- let headers = data. 1 ;
124
+ impl Context {
125
+ /// Create a new [Context] struct based on the fuction configuration
126
+ /// and the incoming request data.
127
+ pub fn new ( request_id : & str , env_config : RefConfig , headers : & HeaderMap ) -> Result < Self , Error > {
128
128
let client_context: Option < ClientContext > = if let Some ( value) = headers. get ( "lambda-runtime-client-context" ) {
129
129
serde_json:: from_str ( value. to_str ( ) ?) ?
130
130
} else {
@@ -138,11 +138,7 @@ impl TryFrom<(RefConfig, HeaderMap)> for Context {
138
138
} ;
139
139
140
140
let ctx = Context {
141
- request_id : headers
142
- . get ( "lambda-runtime-aws-request-id" )
143
- . expect ( "missing lambda-runtime-aws-request-id header" )
144
- . to_str ( ) ?
145
- . to_owned ( ) ,
141
+ request_id : request_id. to_owned ( ) ,
146
142
deadline : headers
147
143
. get ( "lambda-runtime-deadline-ms" )
148
144
. expect ( "missing lambda-runtime-deadline-ms header" )
@@ -165,13 +161,37 @@ impl TryFrom<(RefConfig, HeaderMap)> for Context {
165
161
166
162
Ok ( ctx)
167
163
}
168
- }
169
164
170
- impl Context {
171
165
/// The execution deadline for the current invocation.
172
166
pub fn deadline ( & self ) -> SystemTime {
173
167
SystemTime :: UNIX_EPOCH + Duration :: from_millis ( self . deadline )
174
168
}
169
+
170
+ /// Create a new [`tracing::Span`] for an incoming invocation.
171
+ pub ( crate ) fn request_span ( & self ) -> Span {
172
+ match & self . xray_trace_id {
173
+ Some ( trace_id) => {
174
+ env:: set_var ( "_X_AMZN_TRACE_ID" , trace_id) ;
175
+ tracing:: info_span!(
176
+ "Lambda runtime invoke" ,
177
+ requestId = & self . request_id,
178
+ xrayTraceId = trace_id
179
+ )
180
+ }
181
+ None => {
182
+ env:: remove_var ( "_X_AMZN_TRACE_ID" ) ;
183
+ tracing:: info_span!( "Lambda runtime invoke" , requestId = & self . request_id)
184
+ }
185
+ }
186
+ }
187
+ }
188
+
189
+ /// Extract the invocation request id from the incoming request.
190
+ pub ( crate ) fn invoke_request_id ( headers : & HeaderMap ) -> Result < & str , ToStrError > {
191
+ headers
192
+ . get ( "lambda-runtime-aws-request-id" )
193
+ . expect ( "missing lambda-runtime-aws-request-id header" )
194
+ . to_str ( )
175
195
}
176
196
177
197
/// Incoming Lambda request containing the event payload and context.
@@ -313,7 +333,7 @@ mod test {
313
333
HeaderValue :: from_static ( "arn::myarn" ) ,
314
334
) ;
315
335
headers. insert ( "lambda-runtime-trace-id" , HeaderValue :: from_static ( "arn::myarn" ) ) ;
316
- let tried = Context :: try_from ( ( config, headers) ) ;
336
+ let tried = Context :: new ( "id" , config, & headers) ;
317
337
assert ! ( tried. is_ok( ) ) ;
318
338
}
319
339
@@ -324,7 +344,7 @@ mod test {
324
344
let mut headers = HeaderMap :: new ( ) ;
325
345
headers. insert ( "lambda-runtime-aws-request-id" , HeaderValue :: from_static ( "my-id" ) ) ;
326
346
headers. insert ( "lambda-runtime-deadline-ms" , HeaderValue :: from_static ( "123" ) ) ;
327
- let tried = Context :: try_from ( ( config, headers) ) ;
347
+ let tried = Context :: new ( "id" , config, & headers) ;
328
348
assert ! ( tried. is_ok( ) ) ;
329
349
}
330
350
@@ -355,7 +375,7 @@ mod test {
355
375
) ;
356
376
357
377
let config = Arc :: new ( Config :: default ( ) ) ;
358
- let tried = Context :: try_from ( ( config, headers) ) ;
378
+ let tried = Context :: new ( "id" , config, & headers) ;
359
379
assert ! ( tried. is_ok( ) ) ;
360
380
let tried = tried. unwrap ( ) ;
361
381
assert ! ( tried. client_context. is_some( ) ) ;
@@ -369,7 +389,7 @@ mod test {
369
389
headers. insert ( "lambda-runtime-aws-request-id" , HeaderValue :: from_static ( "my-id" ) ) ;
370
390
headers. insert ( "lambda-runtime-deadline-ms" , HeaderValue :: from_static ( "123" ) ) ;
371
391
headers. insert ( "lambda-runtime-client-context" , HeaderValue :: from_static ( "{}" ) ) ;
372
- let tried = Context :: try_from ( ( config, headers) ) ;
392
+ let tried = Context :: new ( "id" , config, & headers) ;
373
393
assert ! ( tried. is_ok( ) ) ;
374
394
assert ! ( tried. unwrap( ) . client_context. is_some( ) ) ;
375
395
}
@@ -390,7 +410,7 @@ mod test {
390
410
"lambda-runtime-cognito-identity" ,
391
411
HeaderValue :: from_str ( & cognito_identity_str) . unwrap ( ) ,
392
412
) ;
393
- let tried = Context :: try_from ( ( config, headers) ) ;
413
+ let tried = Context :: new ( "id" , config, & headers) ;
394
414
assert ! ( tried. is_ok( ) ) ;
395
415
let tried = tried. unwrap ( ) ;
396
416
assert ! ( tried. identity. is_some( ) ) ;
@@ -412,7 +432,7 @@ mod test {
412
432
HeaderValue :: from_static ( "arn::myarn" ) ,
413
433
) ;
414
434
headers. insert ( "lambda-runtime-trace-id" , HeaderValue :: from_static ( "arn::myarn" ) ) ;
415
- let tried = Context :: try_from ( ( config, headers) ) ;
435
+ let tried = Context :: new ( "id" , config, & headers) ;
416
436
assert ! ( tried. is_err( ) ) ;
417
437
}
418
438
@@ -427,7 +447,7 @@ mod test {
427
447
"lambda-runtime-client-context" ,
428
448
HeaderValue :: from_static ( "BAD-Type,not JSON" ) ,
429
449
) ;
430
- let tried = Context :: try_from ( ( config, headers) ) ;
450
+ let tried = Context :: new ( "id" , config, & headers) ;
431
451
assert ! ( tried. is_err( ) ) ;
432
452
}
433
453
@@ -439,7 +459,7 @@ mod test {
439
459
headers. insert ( "lambda-runtime-aws-request-id" , HeaderValue :: from_static ( "my-id" ) ) ;
440
460
headers. insert ( "lambda-runtime-deadline-ms" , HeaderValue :: from_static ( "123" ) ) ;
441
461
headers. insert ( "lambda-runtime-cognito-identity" , HeaderValue :: from_static ( "{}" ) ) ;
442
- let tried = Context :: try_from ( ( config, headers) ) ;
462
+ let tried = Context :: new ( "id" , config, & headers) ;
443
463
assert ! ( tried. is_err( ) ) ;
444
464
}
445
465
@@ -454,14 +474,13 @@ mod test {
454
474
"lambda-runtime-cognito-identity" ,
455
475
HeaderValue :: from_static ( "BAD-Type,not JSON" ) ,
456
476
) ;
457
- let tried = Context :: try_from ( ( config, headers) ) ;
477
+ let tried = Context :: new ( "id" , config, & headers) ;
458
478
assert ! ( tried. is_err( ) ) ;
459
479
}
460
480
461
481
#[ test]
462
482
#[ should_panic]
463
- #[ allow( unused_must_use) ]
464
- fn context_with_missing_request_id_should_panic ( ) {
483
+ fn context_with_missing_deadline_should_panic ( ) {
465
484
let config = Arc :: new ( Config :: default ( ) ) ;
466
485
467
486
let mut headers = HeaderMap :: new ( ) ;
@@ -471,22 +490,34 @@ mod test {
471
490
HeaderValue :: from_static ( "arn::myarn" ) ,
472
491
) ;
473
492
headers. insert ( "lambda-runtime-trace-id" , HeaderValue :: from_static ( "arn::myarn" ) ) ;
474
- Context :: try_from ( ( config, headers) ) ;
493
+ let _ = Context :: new ( "id" , config, & headers) ;
475
494
}
476
495
477
496
#[ test]
478
- #[ should_panic]
479
- #[ allow( unused_must_use) ]
480
- fn context_with_missing_deadline_should_panic ( ) {
481
- let config = Arc :: new ( Config :: default ( ) ) ;
497
+ fn invoke_request_id_should_not_panic ( ) {
498
+ let mut headers = HeaderMap :: new ( ) ;
499
+ headers. insert ( "lambda-runtime-aws-request-id" , HeaderValue :: from_static ( "my-id" ) ) ;
500
+ headers. insert ( "lambda-runtime-deadline-ms" , HeaderValue :: from_static ( "123" ) ) ;
501
+ headers. insert (
502
+ "lambda-runtime-invoked-function-arn" ,
503
+ HeaderValue :: from_static ( "arn::myarn" ) ,
504
+ ) ;
505
+ headers. insert ( "lambda-runtime-trace-id" , HeaderValue :: from_static ( "arn::myarn" ) ) ;
506
+
507
+ let _ = invoke_request_id ( & headers) ;
508
+ }
482
509
510
+ #[ test]
511
+ #[ should_panic]
512
+ fn invoke_request_id_should_panic ( ) {
483
513
let mut headers = HeaderMap :: new ( ) ;
484
514
headers. insert ( "lambda-runtime-deadline-ms" , HeaderValue :: from_static ( "123" ) ) ;
485
515
headers. insert (
486
516
"lambda-runtime-invoked-function-arn" ,
487
517
HeaderValue :: from_static ( "arn::myarn" ) ,
488
518
) ;
489
519
headers. insert ( "lambda-runtime-trace-id" , HeaderValue :: from_static ( "arn::myarn" ) ) ;
490
- Context :: try_from ( ( config, headers) ) ;
520
+
521
+ let _ = invoke_request_id ( & headers) ;
491
522
}
492
523
}
0 commit comments