remote_mcp_kernel/microkernel/
core.rs

1//! Core microkernel server implementation
2//!
3//! This module contains the main MicrokernelServer implementation
4//! demonstrating the microkernel design pattern.
5
6use axum::Router;
7use std::net::SocketAddr;
8
9use crate::{
10    error::AppResult,
11    handlers::{SseHandler, SseHandlerConfig, StreamableHttpHandler},
12};
13use oauth_provider_rs::{DefaultClientManager, OAuthProvider, OAuthProviderTrait, OAuthStorage};
14
15/// Microkernel server builder that composes independent handlers
16///
17/// This builder demonstrates the microkernel principle where services
18/// are composed from independent, single-responsibility components.
19/// Now supports any OAuth provider and storage backend through trait abstraction.
20pub struct MicrokernelServer<
21    P: OAuthProviderTrait<S, DefaultClientManager<S>> + 'static,
22    S: OAuthStorage + Clone + 'static,
23> {
24    oauth_provider: Option<OAuthProvider<P, S>>,
25    streamable_handler: Option<StreamableHttpHandler<P, S>>,
26    sse_handler: Option<SseHandler<P, S>>,
27    sse_config: SseHandlerConfig,
28}
29
30impl<P: OAuthProviderTrait<S, DefaultClientManager<S>> + 'static, S: OAuthStorage + Clone + 'static>
31    MicrokernelServer<P, S>
32{
33    /// Create a new microkernel server builder
34    pub fn new() -> Self {
35        Self {
36            oauth_provider: None,
37            streamable_handler: None,
38            sse_handler: None,
39            sse_config: SseHandlerConfig::default(),
40        }
41    }
42
43    /// Add OAuth provider handler
44    pub fn with_oauth_provider(mut self, oauth_provider: OAuthProvider<P, S>) -> Self {
45        self.oauth_provider = Some(oauth_provider);
46        self
47    }
48
49    /// Add streamable HTTP handler
50    pub fn with_streamable_handler(
51        mut self,
52        streamable_handler: StreamableHttpHandler<P, S>,
53    ) -> Self {
54        self.streamable_handler = Some(streamable_handler);
55        self
56    }
57
58    /// Add SSE handler with configuration
59    pub fn with_sse_handler(
60        mut self,
61        sse_handler: SseHandler<P, S>,
62        config: SseHandlerConfig,
63    ) -> Self {
64        self.sse_handler = Some(sse_handler);
65        self.sse_config = config;
66        self
67    }
68
69    /// Build the composed router from all registered handlers
70    ///
71    /// This method demonstrates the microkernel composition principle
72    /// where independent components are combined into a unified service.
73    pub fn build_router(self) -> AppResult<Router> {
74        let mut router = Router::new();
75
76        // Compose OAuth handler if present
77        if let Some(oauth_provider) = self.oauth_provider {
78            let oauth_router = oauth_provider.router();
79            router = router.merge(oauth_router);
80            tracing::debug!("✓ OAuth provider router composed");
81        }
82
83        // Compose Streamable HTTP handler if present
84        if let Some(streamable_handler) = self.streamable_handler {
85            let streamable_router = streamable_handler.router();
86            router = router.merge(streamable_router);
87            tracing::debug!("✓ Streamable HTTP handler router composed");
88        }
89
90        // Compose SSE handler if present
91        if let Some(sse_handler) = self.sse_handler {
92            let sse_router = sse_handler.router(self.sse_config)?;
93            router = router.merge(sse_router);
94            tracing::debug!("✓ SSE handler router composed");
95        }
96
97        Ok(router)
98    }
99
100    /// Start the microkernel server
101    pub async fn serve(self, bind_address: SocketAddr) -> AppResult<()> {
102        let router = self.build_router()?;
103
104        let listener = tokio::net::TcpListener::bind(bind_address)
105            .await
106            .map_err(|e| crate::error::AppError::Internal(format!("Failed to bind: {}", e)))?;
107
108        tracing::info!("🏛️  Microkernel server listening on {}", bind_address);
109
110        axum::serve(listener, router)
111            .await
112            .map_err(|e| crate::error::AppError::Internal(format!("Server error: {}", e)))?;
113
114        Ok(())
115    }
116}
117
118impl<P: OAuthProviderTrait<S, DefaultClientManager<S>>, S: OAuthStorage + Clone + 'static> Default
119    for MicrokernelServer<P, S>
120{
121    fn default() -> Self {
122        Self::new()
123    }
124}