From 4d7d3cecf4643ae9569a4f9ee02d8b0a49ca5e17 Mon Sep 17 00:00:00 2001 From: sapessi Date: Tue, 26 Feb 2019 12:46:32 -0800 Subject: [PATCH 1/4] Changed the X-Ray trace id header to be optional since X-Ray is not support in GovCloud. This addresses issue #89. Also bumped version for patch release. --- Cargo.lock | 11 +++--- lambda-runtime-client/Cargo.toml | 7 ++-- lambda-runtime-client/src/client.rs | 53 +++++++++++++++++++++++++++-- lambda-runtime-core/Cargo.toml | 2 +- lambda-runtime-core/src/context.rs | 6 ++-- lambda-runtime/src/lib.rs | 2 +- 6 files changed, 67 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bcb4f5e0..d7b613ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -326,7 +326,7 @@ name = "lambda_runtime" version = "0.2.0" dependencies = [ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "lambda_runtime_core 0.1.0", + "lambda_runtime_core 0.1.1", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.87 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.87 (registry+https://github.com/rust-lang/crates.io-index)", @@ -338,8 +338,9 @@ dependencies = [ [[package]] name = "lambda_runtime_client" -version = "0.2.0" +version = "0.2.1" dependencies = [ + "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.12.24 (registry+https://github.com/rust-lang/crates.io-index)", @@ -353,13 +354,13 @@ dependencies = [ [[package]] name = "lambda_runtime_core" -version = "0.1.0" +version = "0.1.1" dependencies = [ "backtrace 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.12.24 (registry+https://github.com/rust-lang/crates.io-index)", - "lambda_runtime_client 0.2.0", + "lambda_runtime_client 0.2.1", "lambda_runtime_errors 0.1.0", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -372,7 +373,7 @@ name = "lambda_runtime_errors" version = "0.1.0" dependencies = [ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "lambda_runtime_core 0.1.0", + "lambda_runtime_core 0.1.1", "lambda_runtime_errors_derive 0.1.0", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/lambda-runtime-client/Cargo.toml b/lambda-runtime-client/Cargo.toml index 906fb2f0..d108db20 100644 --- a/lambda-runtime-client/Cargo.toml +++ b/lambda-runtime-client/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "lambda_runtime_client" -version = "0.2.0" +version = "0.2.1" authors = ["Stefano Buliani", "David Barsky"] edition = "2018" description = "Client SDK for AWS Lambda's runtime APIs" @@ -24,4 +24,7 @@ serde_json = "^1" serde_derive = "^1" log = "0.4" lambda_runtime_errors = { path = "../lambda-runtime-errors", version = "^0.1" } -failure = "^0.1" \ No newline at end of file +failure = "^0.1" + +[dev-dependencies] +chrono = "^0.4" \ No newline at end of file diff --git a/lambda-runtime-client/src/client.rs b/lambda-runtime-client/src/client.rs index 16a7ec4e..ed68292f 100644 --- a/lambda-runtime-client/src/client.rs +++ b/lambda-runtime-client/src/client.rs @@ -109,7 +109,7 @@ pub struct EventContext { /// The AWS request ID generated by the Lambda service. pub aws_request_id: String, /// The X-Ray trace ID for the current invocation. - pub xray_trace_id: String, + pub xray_trace_id: Option, /// The execution deadline for the current invocation in milliseconds. pub deadline: i64, /// The client context object sent by the AWS mobile SDK. This field is @@ -404,7 +404,17 @@ impl<'ev> RuntimeClient { headers.get(LambdaHeaders::FunctionArn.as_str()), &LambdaHeaders::FunctionArn, )?; - let xray_trace_id = header_string(headers.get(LambdaHeaders::TraceId.as_str()), &LambdaHeaders::TraceId)?; + let xray_trace_id = match headers.get(LambdaHeaders::TraceId.as_str()) { + Some(trace_id) => match trace_id.to_str() { + Ok(trace_str) => Some(trace_str.to_owned()), + Err(e) => { + // we do not fail on this error. + error!("Could not parse X-Ray trace id as string: {}", e); + None + } + }, + None => None + }; let deadline = header_string(headers.get(LambdaHeaders::Deadline.as_str()), &LambdaHeaders::Deadline)? .parse::() .context(ApiErrorKind::Recoverable( @@ -461,3 +471,42 @@ fn header_string(value: Option<&HeaderValue>, header_type: &LambdaHeaders) -> Re } } } + +#[cfg(test)] +pub(crate) mod tests { + use super::*; + use chrono::{Utc, Duration}; + + fn get_headers() -> HeaderMap { + let mut headers: HeaderMap = HeaderMap::new(); + headers.insert(LambdaHeaders::RequestId.as_str(), HeaderValue::from_str("req_id").unwrap()); + headers.insert(LambdaHeaders::FunctionArn.as_str(), HeaderValue::from_str("func_arn").unwrap()); + headers.insert(LambdaHeaders::TraceId.as_str(), HeaderValue::from_str("trace").unwrap()); + let deadline = Utc::now() + Duration::seconds(10); + headers.insert(LambdaHeaders::Deadline.as_str(), HeaderValue::from_str(&deadline.timestamp_millis().to_string()).unwrap()); + //headers.insert(LambdaHeaders::ClientContext.as_str(), HeaderValue::from_str("{}").unwrap()); + //headers.insert(LambdaHeaders::CognitoIdentity.as_str(), HeaderValue::from_str("{}").unwrap()); + headers + } + + #[test] + fn get_event_context_with_empty_trace_id() { + let client = RuntimeClient::new("localhost:8081", None, None).expect("Could not initialize runtime client"); + let mut headers = get_headers(); + headers.remove(LambdaHeaders::TraceId.as_str()); + let headers_result = client.get_event_context(&headers); + assert_eq!(false, headers_result.is_err()); + let ok_result = headers_result.unwrap(); + assert_eq!(None, ok_result.xray_trace_id); + assert_eq!("req_id", ok_result.aws_request_id); + } + + #[test] + fn get_event_context_populates_trace_id_when_present() { + let client = RuntimeClient::new("localhost:8081", None, None).expect("Could not initialize runtime client"); + let headers = get_headers(); + let headers_result = client.get_event_context(&headers); + assert_eq!(false, headers_result.is_err()); + assert_eq!(Some("trace".to_owned()), headers_result.unwrap().xray_trace_id); + } +} \ No newline at end of file diff --git a/lambda-runtime-core/Cargo.toml b/lambda-runtime-core/Cargo.toml index 459d3e41..e883325f 100644 --- a/lambda-runtime-core/Cargo.toml +++ b/lambda-runtime-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "lambda_runtime_core" -version = "0.1.0" +version = "0.1.1" authors = ["Stefano Buliani", "David Barsky"] description = "Rust runtime for AWS Lambda" keywords = ["AWS", "Lambda", "Runtime", "Rust"] diff --git a/lambda-runtime-core/src/context.rs b/lambda-runtime-core/src/context.rs index 4e472076..658a29f6 100644 --- a/lambda-runtime-core/src/context.rs +++ b/lambda-runtime-core/src/context.rs @@ -32,7 +32,7 @@ pub struct Context { /// by the Lambda Runtime APIs as a header. Developers can use this value /// with the AWS SDK to create new, custom sub-segments to the current /// invocation. - pub xray_trace_id: String, + pub xray_trace_id: Option, /// The name of the CloudWatch log stream for the current execution /// environment. This value is extracted from the `AWS_LAMBDA_LOG_STREAM_NAME` /// environment variable set by the Lambda service. @@ -72,7 +72,7 @@ impl Context { /// A new, populated `Context` object. pub(super) fn new(local_settings: lambda_env::FunctionSettings) -> Context { Context { - xray_trace_id: String::from(""), + xray_trace_id: None, memory_limit_in_mb: local_settings.memory_size, function_name: local_settings.function_name, function_version: local_settings.version, @@ -107,7 +107,7 @@ pub(crate) mod tests { function_version: "$LATEST".to_string(), invoked_function_arn: "arn:aws:lambda".to_string(), aws_request_id: "123".to_string(), - xray_trace_id: "123".to_string(), + xray_trace_id: Some("123".to_string()), log_stream_name: "logStream".to_string(), log_group_name: "logGroup".to_string(), client_context: Option::default(), diff --git a/lambda-runtime/src/lib.rs b/lambda-runtime/src/lib.rs index b8e0a597..2ef78f4e 100644 --- a/lambda-runtime/src/lib.rs +++ b/lambda-runtime/src/lib.rs @@ -142,7 +142,7 @@ pub(crate) mod tests { function_version: "$LATEST".to_string(), invoked_function_arn: "arn:aws:lambda".to_string(), aws_request_id: "123".to_string(), - xray_trace_id: "123".to_string(), + xray_trace_id: Some("123".to_string()), log_stream_name: "logStream".to_string(), log_group_name: "logGroup".to_string(), client_context: Option::default(), From b0ec3bd08f844cdaed1515c94a5129f99e67ddfe Mon Sep 17 00:00:00 2001 From: sapessi Date: Tue, 26 Feb 2019 13:04:27 -0800 Subject: [PATCH 2/4] Cargo fmt run --- lambda-runtime-client/src/client.rs | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/lambda-runtime-client/src/client.rs b/lambda-runtime-client/src/client.rs index ed68292f..099d7ea2 100644 --- a/lambda-runtime-client/src/client.rs +++ b/lambda-runtime-client/src/client.rs @@ -413,7 +413,7 @@ impl<'ev> RuntimeClient { None } }, - None => None + None => None, }; let deadline = header_string(headers.get(LambdaHeaders::Deadline.as_str()), &LambdaHeaders::Deadline)? .parse::() @@ -475,15 +475,24 @@ fn header_string(value: Option<&HeaderValue>, header_type: &LambdaHeaders) -> Re #[cfg(test)] pub(crate) mod tests { use super::*; - use chrono::{Utc, Duration}; + use chrono::{Duration, Utc}; fn get_headers() -> HeaderMap { let mut headers: HeaderMap = HeaderMap::new(); - headers.insert(LambdaHeaders::RequestId.as_str(), HeaderValue::from_str("req_id").unwrap()); - headers.insert(LambdaHeaders::FunctionArn.as_str(), HeaderValue::from_str("func_arn").unwrap()); + headers.insert( + LambdaHeaders::RequestId.as_str(), + HeaderValue::from_str("req_id").unwrap(), + ); + headers.insert( + LambdaHeaders::FunctionArn.as_str(), + HeaderValue::from_str("func_arn").unwrap(), + ); headers.insert(LambdaHeaders::TraceId.as_str(), HeaderValue::from_str("trace").unwrap()); let deadline = Utc::now() + Duration::seconds(10); - headers.insert(LambdaHeaders::Deadline.as_str(), HeaderValue::from_str(&deadline.timestamp_millis().to_string()).unwrap()); + headers.insert( + LambdaHeaders::Deadline.as_str(), + HeaderValue::from_str(&deadline.timestamp_millis().to_string()).unwrap(), + ); //headers.insert(LambdaHeaders::ClientContext.as_str(), HeaderValue::from_str("{}").unwrap()); //headers.insert(LambdaHeaders::CognitoIdentity.as_str(), HeaderValue::from_str("{}").unwrap()); headers @@ -509,4 +518,4 @@ pub(crate) mod tests { assert_eq!(false, headers_result.is_err()); assert_eq!(Some("trace".to_owned()), headers_result.unwrap().xray_trace_id); } -} \ No newline at end of file +} From 9ce41c556ddbc3863b83e2279ba484de51879d55 Mon Sep 17 00:00:00 2001 From: sapessi Date: Tue, 26 Feb 2019 13:51:16 -0800 Subject: [PATCH 3/4] clippy run --- lambda-runtime-client/src/error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lambda-runtime-client/src/error.rs b/lambda-runtime-client/src/error.rs index b8627d77..0d778135 100644 --- a/lambda-runtime-client/src/error.rs +++ b/lambda-runtime-client/src/error.rs @@ -60,7 +60,7 @@ impl ErrorResponse { err.stack_trace = Some( format!("{:?}", stack) .lines() - .map(|s| s.to_string()) + .map(std::string::ToString::to_string) .collect::>(), ); trace!("Completed backtrace collection"); From c6b4a61cddf1d0681e62dbaeb4f617e77adbca01 Mon Sep 17 00:00:00 2001 From: sapessi Date: Tue, 26 Feb 2019 13:51:37 -0800 Subject: [PATCH 4/4] CR feedback --- Cargo.lock | 2 ++ lambda-runtime-client/src/client.rs | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d7b613ac..230b62fb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,3 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. [[package]] name = "arrayvec" version = "0.4.10" diff --git a/lambda-runtime-client/src/client.rs b/lambda-runtime-client/src/client.rs index 099d7ea2..11e70dd2 100644 --- a/lambda-runtime-client/src/client.rs +++ b/lambda-runtime-client/src/client.rs @@ -493,8 +493,6 @@ pub(crate) mod tests { LambdaHeaders::Deadline.as_str(), HeaderValue::from_str(&deadline.timestamp_millis().to_string()).unwrap(), ); - //headers.insert(LambdaHeaders::ClientContext.as_str(), HeaderValue::from_str("{}").unwrap()); - //headers.insert(LambdaHeaders::CognitoIdentity.as_str(), HeaderValue::from_str("{}").unwrap()); headers }