greentic_runner_host/runner/
mod.rs1pub 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}