1- use crate :: { types:: ToStreamErrorTrailer , Diagnostic , Error , FunctionResponse , IntoFunctionResponse } ;
1+ use crate :: {
2+ constants:: LAMBDA_RUNTIME_INVOCATION_ID , types:: ToStreamErrorTrailer , Diagnostic , Error , FunctionResponse ,
3+ IntoFunctionResponse ,
4+ } ;
25use bytes:: Bytes ;
36use http:: { header:: CONTENT_TYPE , Method , Request , Uri } ;
47use lambda_runtime_api_client:: { body:: Body , build_request} ;
8891 E : Into < Error > + Send + Debug ,
8992{
9093 pub ( crate ) request_id : & ' a str ,
94+ pub ( crate ) invocation_id : Option < & ' a str > ,
9195 pub ( crate ) body : R ,
9296 pub ( crate ) _unused_b : PhantomData < B > ,
9397 pub ( crate ) _unused_s : PhantomData < S > ,
@@ -102,9 +106,14 @@ where
102106 E : Into < Error > + Send + Debug ,
103107{
104108 /// Initialize a new EventCompletionRequest
105- pub ( crate ) fn new ( request_id : & ' a str , body : R ) -> EventCompletionRequest < ' a , R , B , S , D , E > {
109+ pub ( crate ) fn new (
110+ request_id : & ' a str ,
111+ invocation_id : Option < & ' a str > ,
112+ body : R ,
113+ ) -> EventCompletionRequest < ' a , R , B , S , D , E > {
106114 EventCompletionRequest {
107115 request_id,
116+ invocation_id,
108117 body,
109118 _unused_b : PhantomData :: < B > ,
110119 _unused_s : PhantomData :: < S > ,
@@ -129,7 +138,16 @@ where
129138 let body = serde_json:: to_vec ( & body) ?;
130139 let body = Body :: from ( body) ;
131140
132- let req = build_request ( ) . method ( Method :: POST ) . uri ( uri) . body ( body) ?;
141+ let mut req = build_request ( )
142+ . method ( Method :: POST )
143+ . uri ( uri)
144+ . header ( LAMBDA_RUNTIME_INVOCATION_ID , self . request_id )
145+ . body ( body) ?;
146+
147+ if let Some ( id) = self . invocation_id {
148+ req. headers_mut ( ) . insert ( LAMBDA_RUNTIME_INVOCATION_ID , id. parse ( ) ?) ;
149+ }
150+
133151 Ok ( req)
134152 }
135153 FunctionResponse :: StreamingResponse ( mut response) => {
@@ -145,6 +163,11 @@ where
145163 // See the details in Lambda Developer Doc: https://docs.aws.amazon.com/lambda/latest/dg/runtimes-custom.html#runtimes-custom-response-streaming
146164 req_headers. append ( "Trailer" , "Lambda-Runtime-Function-Error-Type" . parse ( ) ?) ;
147165 req_headers. append ( "Trailer" , "Lambda-Runtime-Function-Error-Body" . parse ( ) ?) ;
166+
167+ if let Some ( id) = self . invocation_id {
168+ req_headers. append ( LAMBDA_RUNTIME_INVOCATION_ID , id. parse ( ) ?) ;
169+ }
170+
148171 req_headers. insert (
149172 "Content-Type" ,
150173 "application/vnd.awslambda.http-integration-response" . parse ( ) ?,
@@ -193,29 +216,22 @@ where
193216 }
194217}
195218
196- #[ test]
197- fn test_event_completion_request ( ) {
198- let req = EventCompletionRequest :: new ( "id" , "hello, world!" ) ;
199- let req = req. into_req ( ) . unwrap ( ) ;
200- let expected = Uri :: from_static ( "/2018-06-01/runtime/invocation/id/response" ) ;
201- assert_eq ! ( req. method( ) , Method :: POST ) ;
202- assert_eq ! ( req. uri( ) , & expected) ;
203- assert ! ( match req. headers( ) . get( "User-Agent" ) {
204- Some ( header) => header. to_str( ) . unwrap( ) . starts_with( "aws-lambda-rust/" ) ,
205- None => false ,
206- } ) ;
207- }
208-
209219// /runtime/invocation/{AwsRequestId}/error
210220pub ( crate ) struct EventErrorRequest < ' a > {
211221 pub ( crate ) request_id : & ' a str ,
222+ pub ( crate ) invocation_id : Option < & ' a str > ,
212223 pub ( crate ) diagnostic : Diagnostic ,
213224}
214225
215226impl < ' a > EventErrorRequest < ' a > {
216- pub ( crate ) fn new ( request_id : & ' a str , diagnostic : impl Into < Diagnostic > ) -> EventErrorRequest < ' a > {
227+ pub ( crate ) fn new (
228+ request_id : & ' a str ,
229+ invocation_id : Option < & ' a str > ,
230+ diagnostic : impl Into < Diagnostic > ,
231+ ) -> EventErrorRequest < ' a > {
217232 EventErrorRequest {
218233 request_id,
234+ invocation_id,
219235 diagnostic : diagnostic. into ( ) ,
220236 }
221237 }
@@ -228,11 +244,16 @@ impl IntoRequest for EventErrorRequest<'_> {
228244 let body = serde_json:: to_vec ( & self . diagnostic ) ?;
229245 let body = Body :: from ( body) ;
230246
231- let req = build_request ( )
247+ let mut req = build_request ( )
232248 . method ( Method :: POST )
233249 . uri ( uri)
234250 . header ( "lambda-runtime-function-error-type" , "unhandled" )
235251 . body ( body) ?;
252+
253+ if let Some ( id) = self . invocation_id {
254+ req. headers_mut ( ) . insert ( LAMBDA_RUNTIME_INVOCATION_ID , id. parse ( ) ?) ;
255+ }
256+
236257 Ok ( req)
237258 }
238259}
@@ -253,10 +274,41 @@ mod tests {
253274 } ) ;
254275 }
255276
277+ #[ test]
278+ fn test_event_completion_request ( ) {
279+ let req = EventCompletionRequest :: new ( "id" , Option :: Some ( "invocation_id" ) , "hello, world!" ) ;
280+ let req = req. into_req ( ) . unwrap ( ) ;
281+ let expected = Uri :: from_static ( "/2018-06-01/runtime/invocation/id/response" ) ;
282+ assert_eq ! ( req. method( ) , Method :: POST ) ;
283+ assert_eq ! ( req. uri( ) , & expected) ;
284+
285+ assert ! ( req
286+ . headers( )
287+ . get( "User-Agent" )
288+ . unwrap( )
289+ . to_str( )
290+ . unwrap( )
291+ . starts_with( "aws-lambda-rust/" ) ) ;
292+
293+ assert_eq ! (
294+ req. headers( ) . get( LAMBDA_RUNTIME_INVOCATION_ID ) . unwrap( ) ,
295+ "invocation_id"
296+ ) ;
297+ }
298+
299+ #[ test]
300+ fn test_event_completion_request_invocation_id_not_added_when_none ( ) {
301+ let req = EventCompletionRequest :: new ( "id" , Option :: None , "hello, world!" ) ;
302+ let req = req. into_req ( ) . unwrap ( ) ;
303+
304+ assert ! ( req. headers( ) . get( LAMBDA_RUNTIME_INVOCATION_ID ) . is_none( ) ) ;
305+ }
306+
256307 #[ test]
257308 fn test_event_error_request ( ) {
258309 let req = EventErrorRequest {
259310 request_id : "id" ,
311+ invocation_id : Option :: Some ( "invocation_id" ) ,
260312 diagnostic : Diagnostic {
261313 error_type : "InvalidEventDataError" . into ( ) ,
262314 error_message : "Error parsing event data" . into ( ) ,
@@ -270,6 +322,26 @@ mod tests {
270322 Some ( header) => header. to_str( ) . unwrap( ) . starts_with( "aws-lambda-rust/" ) ,
271323 None => false ,
272324 } ) ;
325+
326+ assert ! ( match req. headers( ) . get( LAMBDA_RUNTIME_INVOCATION_ID ) {
327+ Some ( header) => header. to_str( ) . unwrap( ) == "invocation_id" ,
328+ None => false ,
329+ } ) ;
330+ }
331+
332+ #[ test]
333+ fn test_event_error_request_invocation_id_not_added_when_none ( ) {
334+ let req = EventErrorRequest {
335+ request_id : "id" ,
336+ invocation_id : None ,
337+ diagnostic : Diagnostic {
338+ error_type : "InvalidEventDataError" . into ( ) ,
339+ error_message : "Error parsing event data" . into ( ) ,
340+ } ,
341+ } ;
342+ let req = req. into_req ( ) . unwrap ( ) ;
343+
344+ assert ! ( req. headers( ) . get( LAMBDA_RUNTIME_INVOCATION_ID ) . is_none( ) ) ;
273345 }
274346
275347 #[ test]
0 commit comments