custom_router_example/
custom_router_example.rs

1//! Example demonstrating how to attach custom routers to the microkernel server
2//!
3//! This example shows how to use the custom router functionality to extend
4//! the microkernel server with arbitrary endpoints while maintaining
5//! microkernel design principles.
6//!
7//! Run with:
8//! ```bash
9//! cargo run --example custom_router_example
10//! ```
11
12use axum::{
13    extract::Path,
14    response::{Html, Json},
15    routing::{get, post},
16    Router,
17};
18use oauth_provider_rs::{GitHubOAuthConfig, GitHubOAuthProvider, OAuthProvider};
19use remote_mcp_kernel::microkernel::{
20    core::CustomRouterConfig, GitHubMicrokernelServer, MicrokernelServer,
21};
22use serde_json::json;
23use std::net::SocketAddr;
24
25/// Custom health check endpoint
26async fn health_check() -> Json<serde_json::Value> {
27    Json(json!({
28        "status": "healthy",
29        "timestamp": std::time::SystemTime::now()
30            .duration_since(std::time::UNIX_EPOCH)
31            .unwrap()
32            .as_secs(),
33        "service": "custom-router-example"
34    }))
35}
36
37/// Custom metrics endpoint
38async fn metrics() -> Json<serde_json::Value> {
39    Json(json!({
40        "uptime": "5 minutes",
41        "requests": 42,
42        "memory_usage": "128MB"
43    }))
44}
45
46/// Custom API endpoint with path parameter
47async fn api_status(Path(version): Path<String>) -> Json<serde_json::Value> {
48    Json(json!({
49        "api_version": version,
50        "status": "operational",
51        "endpoints": [
52            "/health",
53            "/metrics",
54            "/api/v1/status"
55        ]
56    }))
57}
58
59/// Custom admin dashboard endpoint
60async fn admin_dashboard() -> Html<&'static str> {
61    Html(r#"
62        <!DOCTYPE html>
63        <html>
64        <head>
65            <title>Admin Dashboard</title>
66            <style>
67                body { font-family: Arial, sans-serif; margin: 40px; }
68                .card { border: 1px solid #ddd; padding: 20px; margin: 10px 0; border-radius: 5px; }
69                .header { color: #333; }
70            </style>
71        </head>
72        <body>
73            <h1 class="header">Microkernel Admin Dashboard</h1>
74            <div class="card">
75                <h3>Server Status</h3>
76                <p>āœ… Microkernel Server: Running</p>
77                <p>āœ… OAuth Provider: Connected</p>
78                <p>āœ… Custom Routers: 3 attached</p>
79            </div>
80            <div class="card">
81                <h3>Available Endpoints</h3>
82                <ul>
83                    <li><a href="/health">Health Check</a></li>
84                    <li><a href="/monitoring/metrics">Metrics</a></li>
85                    <li><a href="/api/v1/status">API Status</a></li>
86                    <li><a href="/admin">Admin Dashboard</a></li>
87                </ul>
88            </div>
89        </body>
90        </html>
91    "#)
92}
93
94/// Custom webhook endpoint
95async fn webhook_handler() -> Json<serde_json::Value> {
96    Json(json!({
97        "message": "Webhook received",
98        "processed": true,
99        "timestamp": std::time::SystemTime::now()
100            .duration_since(std::time::UNIX_EPOCH)
101            .unwrap()
102            .as_secs()
103    }))
104}
105
106#[tokio::main]
107async fn main() -> Result<(), Box<dyn std::error::Error>> {
108    // Initialize tracing for logging
109    tracing_subscriber::fmt::init();
110
111    // Create GitHub OAuth provider
112    let github_config = GitHubOAuthConfig {
113        client_id: std::env::var("GITHUB_CLIENT_ID").unwrap_or_else(|_| "demo_client_id".to_string()),
114        client_secret: std::env::var("GITHUB_CLIENT_SECRET").unwrap_or_else(|_| "demo_client_secret".to_string()),
115        redirect_uri: "http://localhost:8080/oauth/callback".to_string(),
116        scope: "read:user".to_string(),
117        provider_name: "github".to_string(),
118    };
119
120    let github_oauth_provider = GitHubOAuthProvider::new_github(github_config);
121    let oauth_provider = OAuthProvider::new(github_oauth_provider);
122
123    // Create custom routers
124    
125    // 1. Health and basic endpoints router
126    let health_router = Router::new()
127        .route("/health", get(health_check))
128        .route("/webhooks", post(webhook_handler));
129
130    // 2. Monitoring router with path prefix
131    let monitoring_router = Router::new()
132        .route("/metrics", get(metrics));
133
134    // 3. API router with versioned endpoints
135    let api_router = Router::new()
136        .route("/v1/status", get(api_status))
137        .route("/{version}/status", get(api_status));
138
139    // 4. Admin router with HTML interface
140    let admin_router = Router::new()
141        .route("/", get(admin_dashboard));
142
143    // Configure custom routers with different configurations
144    let custom_routers = vec![
145        // Health router without prefix (attached to root)
146        (health_router, CustomRouterConfig::default()),
147        
148        // Monitoring router with prefix and name
149        (
150            monitoring_router,
151            CustomRouterConfig::with_name_and_prefix("Monitoring", "/monitoring"),
152        ),
153        
154        // API router with prefix
155        (
156            api_router,
157            CustomRouterConfig::with_name_and_prefix("API", "/api"),
158        ),
159        
160        // Admin router with prefix
161        (
162            admin_router,
163            CustomRouterConfig::with_name_and_prefix("Admin Dashboard", "/admin"),
164        ),
165    ];
166
167    // Build the microkernel server with OAuth provider and custom routers
168    let microkernel: GitHubMicrokernelServer = MicrokernelServer::new()
169        .with_oauth_provider(oauth_provider)
170        .with_custom_routers(custom_routers);
171
172    // Define the bind address
173    let bind_address: SocketAddr = "127.0.0.1:8080".parse()?;
174
175    // Print available endpoints
176    println!("šŸš€ Starting microkernel server with custom routers...");
177    println!("šŸ“ Server listening on: http://{}", bind_address);
178    println!("\nšŸ“‹ Available endpoints:");
179    println!("  OAuth:");
180    println!("    GET  /oauth/login");
181    println!("    GET  /oauth/callback");
182    println!("    POST /oauth/token");
183    println!("  Custom Endpoints:");
184    println!("    GET  /health                  - Health check");
185    println!("    POST /webhooks                - Webhook handler");
186    println!("    GET  /monitoring/metrics      - System metrics");
187    println!("    GET  /api/v1/status           - API status");
188    println!("    GET  /api/{{version}}/status   - Versioned API status");
189    println!("    GET  /admin                   - Admin dashboard");
190    println!("\nšŸ”§ Try these commands:");
191    println!("  curl http://localhost:8080/health");
192    println!("  curl http://localhost:8080/monitoring/metrics");
193    println!("  curl http://localhost:8080/api/v1/status");
194    println!("  open http://localhost:8080/admin");
195
196    // Start the server
197    microkernel.serve(bind_address).await?;
198
199    Ok(())
200}