Skip to main content

greentic_runner_host/runner/
mod.rs

1pub mod adapt_messaging;
2pub mod adapt_slack;
3pub mod adapt_teams;
4pub mod adapt_timer;
5pub mod adapt_webchat;
6pub mod adapt_webex;
7pub mod adapt_webhook;
8pub mod adapt_whatsapp;
9pub mod engine;
10pub mod flow_adapter;
11pub mod ingress_util;
12pub mod invocation;
13pub mod mocks;
14pub mod operator;
15pub mod templating;
16
17use std::net::SocketAddr;
18use std::sync::Arc;
19
20use anyhow::Result;
21use axum::routing::{any, get, post};
22use axum::{Router, serve};
23use tokio::net::TcpListener;
24
25use crate::http::{self, admin, auth::AdminAuth, health::HealthState};
26use crate::routing::TenantRouting;
27use crate::runtime::ActivePacks;
28use crate::watcher::PackReloadHandle;
29
30pub struct HostServer {
31    addr: SocketAddr,
32    router: Router,
33    _state: ServerState,
34}
35
36impl HostServer {
37    pub fn new(
38        port: u16,
39        active: Arc<ActivePacks>,
40        routing: TenantRouting,
41        health: Arc<HealthState>,
42        reload: Option<PackReloadHandle>,
43        admin: AdminAuth,
44    ) -> Result<Self> {
45        let addr = SocketAddr::from(([0, 0, 0, 0], port));
46        let state = ServerState {
47            active,
48            routing,
49            health,
50            reload,
51            admin,
52        };
53        let router = Router::new()
54            .route(
55                "/messaging/telegram/webhook",
56                post(adapt_messaging::telegram_webhook),
57            )
58            .route("/webchat/activities", post(adapt_webchat::activities))
59            .route("/teams/activities", post(adapt_teams::activities))
60            .route("/slack/events", post(adapt_slack::events))
61            .route("/slack/interactive", post(adapt_slack::interactive))
62            .route("/webex/webhook", post(adapt_webex::webhook))
63            .route(
64                "/whatsapp/webhook",
65                get(adapt_whatsapp::verify).post(adapt_whatsapp::webhook),
66            )
67            .route("/webhook/{flow_id}", any(adapt_webhook::dispatch))
68            .route("/operator/op/invoke", post(operator::invoke))
69            .route("/healthz", get(http::health::handler))
70            .route("/admin/packs/status", get(admin::status))
71            .route("/admin/packs/reload", post(admin::reload))
72            .with_state(state.clone());
73        Ok(Self {
74            addr,
75            router,
76            _state: state,
77        })
78    }
79
80    pub async fn serve(self) -> Result<()> {
81        tracing::info!(addr = %self.addr, "starting host server");
82        let listener = TcpListener::bind(self.addr).await?;
83        serve(
84            listener,
85            self.router
86                .into_make_service_with_connect_info::<SocketAddr>(),
87        )
88        .await?;
89        Ok(())
90    }
91}
92
93#[derive(Clone)]
94pub struct ServerState {
95    pub active: Arc<ActivePacks>,
96    pub routing: TenantRouting,
97    pub health: Arc<HealthState>,
98    pub reload: Option<PackReloadHandle>,
99    pub admin: AdminAuth,
100}