aboutsummaryrefslogtreecommitdiffstats
path: root/crates/configuration/src/server.rs
blob: 11311448e7f997551bb1bd4046a4febb673abd67 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
mod error;
mod http_svc;
mod interceptor;
mod version;

use axum::http::header::CONTENT_TYPE;
use http_svc::build_router;
use interceptor::MyInterceptor;
use tonic::service::Routes;
use tower::{make::Shared, steer::Steer};
use warden_core::{
    FILE_DESCRIPTOR_SET,
    configuration::routing::{
        mutate_routing_server::MutateRoutingServer, query_routing_server::QueryRoutingServer,
    },
};

use crate::state::AppHandle;

pub async fn serve<S>(state: AppHandle) -> anyhow::Result<Shared<S>> {
    let app = build_router(state.clone());

    let service = QueryRoutingServer::with_interceptor(state.clone(), MyInterceptor);

    let routing_reflector = tonic_reflection::server::Builder::configure()
        .register_encoded_file_descriptor_set(FILE_DESCRIPTOR_SET)
        .build_v1()?;

    let grpc_server = Routes::new(service)
        .add_service(MutateRoutingServer::with_interceptor(
            state.clone(),
            MyInterceptor,
        ))
        .add_service(routing_reflector)
        .into_axum_router();

    let service = Steer::new(
        vec![app, grpc_server],
        |req: &axum::extract::Request, _services: &[_]| {
            if req
                .headers()
                .get(CONTENT_TYPE)
                .map(|content_type| content_type.as_bytes())
                .filter(|content_type| content_type.starts_with(b"application/grpc"))
                .is_some()
            {
                // grpc service
                1
            } else {
                // http service
                0
            }
        },
    );

    Ok(Shared::new(service))
}