diff --git a/Cargo.lock b/Cargo.lock index bcb4f5e0..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" @@ -326,7 +328,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 +340,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 +356,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 +375,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..11e70dd2 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,49 @@ fn header_string(value: Option<&HeaderValue>, header_type: &LambdaHeaders) -> Re } } } + +#[cfg(test)] +pub(crate) mod tests { + use super::*; + 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::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 + } + + #[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); + } +} 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"); 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(),