Skip to content

Commit 1cf868c

Browse files
authored
Add support for Lambda-Extesion-Accept-Feature header (#887)
- Use this header to read the account id that the extesion is installed in. - Keep the account id as optional just in case we make this feature optional in the future. - Users should not rely on it being always present. - Extract all the information that the register call provides.
1 parent 0fcba16 commit 1cf868c

File tree

2 files changed

+58
-8
lines changed

2 files changed

+58
-8
lines changed

lambda-extension/src/extension.rs

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use hyper::service::service_fn;
66

77
use hyper_util::rt::tokio::TokioIo;
88
use lambda_runtime_api_client::Client;
9+
use serde::Deserialize;
910
use std::{
1011
convert::Infallible, fmt, future::ready, future::Future, net::SocketAddr, path::PathBuf, pin::Pin, sync::Arc,
1112
};
@@ -230,8 +231,7 @@ where
230231
pub async fn register(self) -> Result<RegisteredExtension<E>, Error> {
231232
let client = &Client::builder().build()?;
232233

233-
let extension_id = register(client, self.extension_name, self.events).await?;
234-
let extension_id = extension_id.to_str()?;
234+
let register_res = register(client, self.extension_name, self.events).await?;
235235

236236
// Logs API subscriptions must be requested during the Lambda init phase (see
237237
// https://docs.aws.amazon.com/lambda/latest/dg/runtimes-logs-api.html#runtimes-logs-api-subscribing).
@@ -266,7 +266,7 @@ where
266266
// Call Logs API to start receiving events
267267
let req = requests::subscribe_request(
268268
Api::LogsApi,
269-
extension_id,
269+
&register_res.extension_id,
270270
self.log_types,
271271
self.log_buffering,
272272
self.log_port_number,
@@ -312,7 +312,7 @@ where
312312
// Call Telemetry API to start receiving events
313313
let req = requests::subscribe_request(
314314
Api::TelemetryApi,
315-
extension_id,
315+
&register_res.extension_id,
316316
self.telemetry_types,
317317
self.telemetry_buffering,
318318
self.telemetry_port_number,
@@ -326,7 +326,11 @@ where
326326
}
327327

328328
Ok(RegisteredExtension {
329-
extension_id: extension_id.to_string(),
329+
extension_id: register_res.extension_id,
330+
function_name: register_res.function_name,
331+
function_version: register_res.function_version,
332+
handler: register_res.handler,
333+
account_id: register_res.account_id,
330334
events_processor: self.events_processor,
331335
})
332336
}
@@ -339,7 +343,17 @@ where
339343

340344
/// An extension registered by calling [`Extension::register`].
341345
pub struct RegisteredExtension<E> {
342-
extension_id: String,
346+
/// The ID of the registered extension. This ID is unique per extension and remains constant
347+
pub extension_id: String,
348+
/// The ID of the account the extension was registered to.
349+
/// This will be `None` if the register request doesn't send the Lambda-Extension-Accept-Feature header
350+
pub account_id: Option<String>,
351+
/// The name of the Lambda function that the extension is registered with
352+
pub function_name: String,
353+
/// The version of the Lambda function that the extension is registered with
354+
pub function_version: String,
355+
/// The Lambda function handler that AWS Lambda invokes
356+
pub handler: String,
343357
events_processor: E,
344358
}
345359

@@ -468,12 +482,30 @@ where
468482
}
469483
}
470484

485+
#[derive(Debug, Deserialize)]
486+
#[serde(rename_all = "camelCase")]
487+
struct RegisterResponseBody {
488+
function_name: String,
489+
function_version: String,
490+
handler: String,
491+
account_id: Option<String>,
492+
}
493+
494+
#[derive(Debug)]
495+
struct RegisterResponse {
496+
extension_id: String,
497+
function_name: String,
498+
function_version: String,
499+
handler: String,
500+
account_id: Option<String>,
501+
}
502+
471503
/// Initialize and register the extension in the Extensions API
472504
async fn register<'a>(
473505
client: &'a Client,
474506
extension_name: Option<&'a str>,
475507
events: Option<&'a [&'a str]>,
476-
) -> Result<http::HeaderValue, Error> {
508+
) -> Result<RegisterResponse, Error> {
477509
let name = match extension_name {
478510
Some(name) => name.into(),
479511
None => {
@@ -501,5 +533,17 @@ async fn register<'a>(
501533
.get(requests::EXTENSION_ID_HEADER)
502534
.ok_or_else(|| ExtensionError::boxed("missing extension id header"))
503535
.map_err(|e| ExtensionError::boxed(e.to_string()))?;
504-
Ok(header.clone())
536+
let extension_id = header.to_str()?.to_string();
537+
538+
let (_, body) = res.into_parts();
539+
let body = body.collect().await?.to_bytes();
540+
let response: RegisterResponseBody = serde_json::from_slice(&body)?;
541+
542+
Ok(RegisterResponse {
543+
extension_id,
544+
function_name: response.function_name,
545+
function_version: response.function_version,
546+
handler: response.handler,
547+
account_id: response.account_id,
548+
})
505549
}

lambda-extension/src/requests.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ const EXTENSION_ERROR_TYPE_HEADER: &str = "Lambda-Extension-Function-Error-Type"
99
const CONTENT_TYPE_HEADER_NAME: &str = "Content-Type";
1010
const CONTENT_TYPE_HEADER_VALUE: &str = "application/json";
1111

12+
// Comma separated list of features the extension supports.
13+
// `accountId` is currently the only supported feature.
14+
const EXTENSION_ACCEPT_FEATURE: &str = "Lambda-Extension-Accept-Feature";
15+
const EXTENSION_ACCEPT_FEATURE_VALUE: &str = "accountId";
16+
1217
pub(crate) fn next_event_request(extension_id: &str) -> Result<Request<Body>, Error> {
1318
let req = build_request()
1419
.method(Method::GET)
@@ -25,6 +30,7 @@ pub(crate) fn register_request(extension_name: &str, events: &[&str]) -> Result<
2530
.method(Method::POST)
2631
.uri("/2020-01-01/extension/register")
2732
.header(EXTENSION_NAME_HEADER, extension_name)
33+
.header(EXTENSION_ACCEPT_FEATURE, EXTENSION_ACCEPT_FEATURE_VALUE)
2834
.header(CONTENT_TYPE_HEADER_NAME, CONTENT_TYPE_HEADER_VALUE)
2935
.body(Body::from(serde_json::to_string(&events)?))?;
3036

0 commit comments

Comments
 (0)