Skip to content

Commit

Permalink
Merge pull request #21 from aws-samples/dev
Browse files Browse the repository at this point in the history
upgrade to lambda_http v0.5.1
  • Loading branch information
bnusunny authored Mar 20, 2022
2 parents a88510c + 19750c2 commit c595b98
Show file tree
Hide file tree
Showing 10 changed files with 462 additions and 354 deletions.
712 changes: 426 additions & 286 deletions Cargo.lock

Large diffs are not rendered by default.

16 changes: 7 additions & 9 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
[package]
name = "aws-lambda-adapter"
version = "0.1.2"
version = "0.3.0"
authors = ["Harold Sun <sunhua@amazon.com>"]
edition = "2018"

[dependencies]
log = "0.4.14"
env_logger = "0.8.3"
tokio = { version = "1.4", features = ["macros", "io-util", "sync", "rt-multi-thread", "process"] }
tokio-retry = "0.3"
lambda_http = {git = "https://github.com/bnusunny/aws-lambda-rust-runtime", branch = "extensions"}
reqwest = { version = "0.11", default-features = false, features = ["blocking", "json"] }
http = "0.2.4"
lambda-extension = "0.5.0"
lambda_http = "0.5.1"
log = "0.4.14"
once_cell = "1.7.2"
futures = "0.3.16"
url = "2.1.1"
serde_json = "1.0"
reqwest = { version = "0.11", default-features = false, features = ["blocking", "json"] }
tokio = { version = "1.0", features = ["macros", "io-util", "sync", "rt-multi-thread"] }
tokio-retry = "0.3"

[[bin]]
name = "lambda-adapter"
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.mac
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
FROM scratch
ARG ARCH=x86_64
COPY target/${ARCH}-unknown-linux-musl/release/bootstrap /opt/bootstrap
COPY target/${ARCH}-unknown-linux-musl/release/lambda-adapter /opt/extensions/lambda-adapter
2 changes: 1 addition & 1 deletion examples/expressjs-zip/hello-world/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const app = express()
const port = process.env['PORT'] || 8080


app.get('/', (req, res) => {
app.get('/Prod', (req, res) => {
res.send('Hi there!')
})

Expand Down
2 changes: 1 addition & 1 deletion examples/expressjs/app/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
FROM public.ecr.aws/docker/library/node:16.13.2-stretch-slim
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.2.0 /opt/extensions/lambda-adapter /opt/extensions/lambda-adapter
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.3.0 /opt/extensions/lambda-adapter /opt/extensions/lambda-adapter
EXPOSE 8080
WORKDIR "/var/task"
ADD src/package.json /var/task/package.json
Expand Down
2 changes: 1 addition & 1 deletion examples/flask/app/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
FROM public.ecr.aws/docker/library/python:3.8.12-slim-buster
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.2.0 /opt/extensions/lambda-adapter /opt/extensions/lambda-adapter
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.3.0 /opt/extensions/lambda-adapter /opt/extensions/lambda-adapter
WORKDIR /var/task
COPY app.py requirements.txt ./
RUN python -m pip install -r requirements.txt
Expand Down
2 changes: 1 addition & 1 deletion examples/nginx/app/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
FROM public.ecr.aws/docker/library/nginx:1.21.6
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.2.0 /opt/extensions/lambda-adapter /opt/extensions/lambda-adapter
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.3.0 /opt/extensions/lambda-adapter /opt/extensions/lambda-adapter
WORKDIR "/tmp"
ADD config/ /etc/nginx/
ADD images/ /usr/share/nginx/html/images
Expand Down
2 changes: 1 addition & 1 deletion examples/php/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM public.ecr.aws/amazonlinux/amazonlinux:2.0.20220121.0

COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.2.0 /opt/extensions/lambda-adapter /opt/extensions/lambda-adapter
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.3.0 /opt/extensions/lambda-adapter /opt/extensions/lambda-adapter

RUN amazon-linux-extras install -y nginx1 php7.4 && yum clean all && rm -rf /var/cache/yum

Expand Down
2 changes: 1 addition & 1 deletion examples/springboot/app/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ COPY pom.xml ./
RUN mvn -q clean package

FROM public.ecr.aws/docker/library/amazoncorretto:8u322-al2
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.2.0 /opt/extensions/lambda-adapter /opt/extensions/lambda-adapter
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.3.0 /opt/extensions/lambda-adapter /opt/extensions/lambda-adapter
EXPOSE 8080
WORKDIR /opt
COPY --from=build-image /task/target/petstore-0.0.1-SNAPSHOT.jar /opt
Expand Down
74 changes: 22 additions & 52 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

use lambda_http::{
handler,
lambda_runtime::{self, Context},
Body, IntoResponse, Request, RequestExt, Response,
};
use lambda_extension::{service_fn as extension_handler, Extension};
use lambda_http::{service_fn as http_handler, Body, IntoResponse, Request, Response};
use log::*;
use once_cell::sync::OnceCell;
use reqwest::{redirect, Client};
use serde_json::json;
use std::{env, mem, thread};
use tokio_retry::strategy::FixedInterval;
use tokio_retry::Retry;
use url::form_urlencoded::Serializer;
use std::{env, mem};
use tokio::runtime::Handle;
use tokio_retry::{strategy::FixedInterval, Retry};

type Error = Box<dyn std::error::Error + Send + Sync + 'static>;
static HTTP_CLIENT: OnceCell<Client> = OnceCell::new();
Expand All @@ -23,25 +18,16 @@ async fn main() -> Result<(), Error> {
env_logger::init();

// register as an external extension
let aws_lambda_runtime_api = env::var("AWS_LAMBDA_RUNTIME_API").unwrap();
let extension_next_url = format!("http://{}/2020-01-01/extension/event/next", aws_lambda_runtime_api);
let extension_register_url = format!("http://{}/2020-01-01/extension/register", aws_lambda_runtime_api);
let executable_name = env::current_exe().unwrap().file_name().unwrap().to_string_lossy().to_string();
let client = reqwest::blocking::ClientBuilder::new().timeout(None).build().unwrap();
let resp = client
.post(extension_register_url)
.header("Lambda-Extension-Name", executable_name)
.json(&json!({"events": []}))
.send()?;
let extension_id = resp.headers().get("Lambda-Extension-Identifier").unwrap().clone();
thread::spawn(move || {
let extension_id_str = extension_id.to_str().unwrap();
debug!("[extension] enter event loop for extension id: '{}'", extension_id_str);
client
.get(extension_next_url)
.header("Lambda-Extension-Identifier", extension_id_str)
.send()
.unwrap();
let handle = Handle::current();
tokio::task::spawn_blocking(move || {
handle.spawn(async {
Extension::new()
.with_events(&[])
.with_events_processor(extension_handler(|_| async { Ok::<(), Error>(()) }))
.run()
.await
.expect("extension thread error");
})
});

// check if the application is ready every 10 milliseconds
Expand All @@ -57,30 +43,15 @@ async fn main() -> Result<(), Error> {

// start lambda runtime
HTTP_CLIENT.set(Client::builder().redirect(redirect::Policy::none()).build().unwrap()).unwrap();
lambda_runtime::run(handler(http_proxy_handler)).await?;
lambda_http::run(http_handler(http_proxy_handler)).await?;
Ok(())
}

async fn http_proxy_handler(event: Request, _: Context) -> Result<impl IntoResponse, Error> {
async fn http_proxy_handler(event: Request) -> Result<impl IntoResponse, Error> {
let port = env::var("PORT").unwrap_or_else(|_| "8080".to_string());
let app_host = format!("http://127.0.0.1:{}", port);
let query_params = event.query_string_parameters();
debug!("query_params are {:#?}", query_params);

let (parts, body) = event.into_parts();
let mut app_url = app_host + parts.uri.path();

// append query parameters to app_url
if !query_params.is_empty() {
app_url.push('?');
let mut serializer = Serializer::new(&mut app_url);
for (key, _) in query_params.iter() {
for value in query_params.get_all(key).unwrap().iter() {
serializer.append_pair(key, value);
}
}
serializer.finish();
}
let app_url = app_host + parts.uri.path_and_query().unwrap().as_str();
debug!("app_url is {:#?}", app_url);
debug!("request headers are {:#?}", parts.headers);

Expand All @@ -102,7 +73,6 @@ async fn http_proxy_handler(event: Request, _: Context) -> Result<impl IntoRespo
}

async fn convert_body(app_response: reqwest::Response) -> Result<Body, Error> {
let content_type;
debug!("app response headers are {:#?}", app_response.headers());

if app_response.headers().get(http::header::CONTENT_ENCODING).is_some() {
Expand All @@ -111,11 +81,11 @@ async fn convert_body(app_response: reqwest::Response) -> Result<Body, Error> {
return Ok(Body::Binary(content.to_vec()));
}

if let Some(value) = app_response.headers().get(http::header::CONTENT_TYPE) {
content_type = value.to_str().unwrap_or_default();
let content_type = if let Some(value) = app_response.headers().get(http::header::CONTENT_TYPE) {
value.to_str().unwrap_or_default()
} else {
content_type = "";
}
""
};
debug!("content_type is {:?}", content_type);

if content_type.starts_with("text")
Expand Down

0 comments on commit c595b98

Please sign in to comment.