pub mod entity_service;
pub mod event_service;
pub mod link_service;
pub mod notification_service;
pub mod proto_generator;
mod convert;
pub mod proto {
tonic::include_proto!("this_grpc");
}
use crate::server::host::ServerHost;
use anyhow::Result;
use axum::Router;
use std::sync::Arc;
pub struct GrpcExposure;
impl GrpcExposure {
pub fn build_router(host: Arc<ServerHost>) -> Result<Router> {
use axum::routing::get;
use proto::entity_service_server::EntityServiceServer;
use proto::event_service_server::EventServiceServer;
use proto::link_service_server::LinkServiceServer;
use proto::notification_service_server::NotificationServiceServer;
use tonic::service::Routes;
let entity_svc = entity_service::EntityServiceImpl::new(host.clone());
let link_svc = link_service::LinkServiceImpl::new(host.clone());
let event_svc = event_service::EventServiceImpl::new(host.clone());
let mut builder = Routes::builder();
builder.add_service(EntityServiceServer::new(entity_svc));
builder.add_service(LinkServiceServer::new(link_svc));
builder.add_service(EventServiceServer::new(event_svc));
if host.notification_store().is_some() {
let notification_svc = notification_service::NotificationServiceImpl::new(host.clone());
builder.add_service(NotificationServiceServer::new(notification_svc));
}
let grpc_router = builder.routes().into_axum_router();
let proto_host = host.clone();
let proto_route =
Router::new().route("/grpc/proto", get(move || proto_export_handler(proto_host)));
Ok(grpc_router.merge(proto_route))
}
pub fn build_router_no_fallback(host: Arc<ServerHost>) -> Result<Router> {
use axum::routing::get;
use proto::entity_service_server::EntityServiceServer;
use proto::event_service_server::EventServiceServer;
use proto::link_service_server::LinkServiceServer;
use proto::notification_service_server::NotificationServiceServer;
use tonic::server::NamedService;
use tower::ServiceExt;
let entity_svc = entity_service::EntityServiceImpl::new(host.clone());
let link_svc = link_service::LinkServiceImpl::new(host.clone());
let event_svc = event_service::EventServiceImpl::new(host.clone());
let entity_server = EntityServiceServer::new(entity_svc);
let link_server = LinkServiceServer::new(link_svc);
let event_server = EventServiceServer::new(event_svc);
let mut grpc_router = Router::new()
.route_service(
&format!(
"/{}/{{*rest}}",
EntityServiceServer::<entity_service::EntityServiceImpl>::NAME
),
entity_server.map_request(|req: axum::http::Request<axum::body::Body>| {
req.map(tonic::body::Body::new)
}),
)
.route_service(
&format!(
"/{}/{{*rest}}",
LinkServiceServer::<link_service::LinkServiceImpl>::NAME
),
link_server.map_request(|req: axum::http::Request<axum::body::Body>| {
req.map(tonic::body::Body::new)
}),
)
.route_service(
&format!(
"/{}/{{*rest}}",
EventServiceServer::<event_service::EventServiceImpl>::NAME
),
event_server.map_request(|req: axum::http::Request<axum::body::Body>| {
req.map(tonic::body::Body::new)
}),
);
if host.notification_store().is_some() {
let notification_svc = notification_service::NotificationServiceImpl::new(host.clone());
let notification_server = NotificationServiceServer::new(notification_svc);
grpc_router = grpc_router.route_service(
&format!(
"/{}/{{*rest}}",
NotificationServiceServer::<notification_service::NotificationServiceImpl>::NAME
),
notification_server.map_request(|req: axum::http::Request<axum::body::Body>| {
req.map(tonic::body::Body::new)
}),
);
}
let proto_host = host.clone();
let proto_route =
Router::new().route("/grpc/proto", get(move || proto_export_handler(proto_host)));
Ok(grpc_router.merge(proto_route))
}
}
async fn proto_export_handler(host: Arc<ServerHost>) -> impl axum::response::IntoResponse {
let generator = proto_generator::ProtoGenerator::new(host);
let proto_content = generator.generate_proto().await;
(
[(
axum::http::header::CONTENT_TYPE,
"text/plain; charset=utf-8",
)],
proto_content,
)
}