Skip to main content

greentic_runner_host/runner/
mod.rs

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