1use futures::TryFuture;
6use htsget_axum::server::ticket::TicketServer;
7use htsget_config::config::Config;
8use htsget_config::package_info;
9use lambda_http::request::LambdaRequest;
10use lambda_http::{
11 Error, IntoResponse, LambdaEvent, Request, RequestExt, Service, TransformResponse, lambda_runtime,
12};
13use std::marker::PhantomData;
14use std::path::Path;
15use std::task::{Context, Poll};
16use tracing::debug;
17
18pub struct Adapter<'a, R, S> {
20 service: S,
21 _phantom_data: PhantomData<&'a R>,
22}
23
24impl<'a, R, S, E> From<S> for Adapter<'a, R, S>
25where
26 S: Service<Request, Response = R, Error = E>,
27 S::Future: Send + 'a,
28 R: IntoResponse,
29{
30 fn from(service: S) -> Self {
31 Adapter {
32 service,
33 _phantom_data: PhantomData,
34 }
35 }
36}
37
38impl<'a, R, S, E> Service<LambdaEvent<serde_json::Value>> for Adapter<'a, R, S>
39where
40 S: Service<Request, Response = R, Error = E>,
41 S::Future: Send + 'a,
42 R: IntoResponse,
43{
44 type Response = <TransformResponse<'a, R, E> as TryFuture>::Ok;
45 type Error = E;
46 type Future = TransformResponse<'a, R, Self::Error>;
47
48 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
49 self.service.poll_ready(cx)
50 }
51
52 fn call(&mut self, req: LambdaEvent<serde_json::Value>) -> Self::Future {
53 let original_request = req.payload.clone();
55
56 let lambda_request: LambdaRequest =
57 serde_json::from_value(req.payload).expect("invalid payload when deserializing to json");
58 let request_origin = lambda_request.request_origin();
59 let mut event: Request = lambda_request.into();
60
61 debug!(original_request = ?original_request, "original_request");
63 event.extensions_mut().insert(original_request);
64
65 let fut = Box::pin(self.service.call(event.with_lambda_context(req.context)));
66 TransformResponse::Request(request_origin, fut)
67 }
68}
69
70pub async fn run_handler(path: &Path) -> Result<(), Error> {
72 let mut config = Config::from_path(path)?;
73 config.set_package_info(package_info!())?;
74 config.setup_tracing()?;
75
76 debug!(config = ?config, "config parsed");
77
78 let service_info = config.service_info().clone();
79 let cors = config.ticket_server().cors().clone();
80 let auth = config.ticket_server().auth().cloned();
81 let package_info = config.package_info().clone();
82 let router = TicketServer::router(
83 config.into_locations(),
84 service_info,
85 cors,
86 auth,
87 Some(package_info),
88 )?;
89
90 lambda_runtime::run(Adapter::from(router)).await
91}