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    Router,
14    extract::Path,
15    response::{Html, Json},
16    routing::{get, post},
17};
18use oauth_provider_rs::{GitHubOAuthProvider, OAuthProvider, provider_trait::OAuthProviderConfig};
19use remote_mcp_kernel::microkernel::{
20    GitHubMicrokernelServer, MicrokernelServer, core::CustomRouterConfig,
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(
62        r#"
63        <!DOCTYPE html>
64        <html>
65        <head>
66            <title>Admin Dashboard</title>
67            <style>
68                body { font-family: Arial, sans-serif; margin: 40px; }
69                .card { border: 1px solid #ddd; padding: 20px; margin: 10px 0; border-radius: 5px; }
70                .header { color: #333; }
71            </style>
72        </head>
73        <body>
74            <h1 class="header">Microkernel Admin Dashboard</h1>
75            <div class="card">
76                <h3>Server Status</h3>
77                <p>āœ… Microkernel Server: Running</p>
78                <p>āœ… OAuth Provider: Connected</p>
79                <p>āœ… Custom Routers: 3 attached</p>
80            </div>
81            <div class="card">
82                <h3>Available Endpoints</h3>
83                <ul>
84                    <li><a href="/health">Health Check</a></li>
85                    <li><a href="/monitoring/metrics">Metrics</a></li>
86                    <li><a href="/api/v1/status">API Status</a></li>
87                    <li><a href="/admin">Admin Dashboard</a></li>
88                </ul>
89            </div>
90        </body>
91        </html>
92    "#,
93    )
94}
95
96/// Custom webhook endpoint
97async fn webhook_handler() -> Json<serde_json::Value> {
98    Json(json!({
99        "message": "Webhook received",
100        "processed": true,
101        "timestamp": std::time::SystemTime::now()
102            .duration_since(std::time::UNIX_EPOCH)
103            .unwrap()
104            .as_secs()
105    }))
106}
107
108#[tokio::main]
109async fn main() -> Result<(), Box<dyn std::error::Error>> {
110    // Initialize tracing for logging
111    tracing_subscriber::fmt::init();
112
113    // Create GitHub OAuth provider
114    let github_config = OAuthProviderConfig::with_oauth_config(
115        std::env::var("GITHUB_CLIENT_ID").unwrap_or_else(|_| "demo_client_id".to_string()),
116        std::env::var("GITHUB_CLIENT_SECRET").unwrap_or_else(|_| "demo_client_secret".to_string()),
117        "http://localhost:8080/oauth/callback".to_string(),
118        "read:user".to_string(),
119        "github".to_string(),
120    );
121
122    let github_oauth_provider = GitHubOAuthProvider::new_github(github_config);
123    let oauth_provider = OAuthProvider::new(
124        github_oauth_provider,
125        oauth_provider_rs::http_integration::config::OAuthProviderConfig::default(),
126    );
127
128    // Create custom routers
129
130    // 1. Health and basic endpoints router
131    let health_router = Router::new()
132        .route("/health", get(health_check))
133        .route("/webhooks", post(webhook_handler));
134
135    // 2. Monitoring router with path prefix
136    let monitoring_router = Router::new().route("/metrics", get(metrics));
137
138    // 3. API router with versioned endpoints
139    let api_router = Router::new()
140        .route("/v1/status", get(api_status))
141        .route("/{version}/status", get(api_status));
142
143    // 4. Admin router with HTML interface
144    let admin_router = Router::new().route("/", get(admin_dashboard));
145
146    // Configure custom routers with different configurations
147    let custom_routers = vec![
148        // Health router without prefix (attached to root)
149        (health_router, CustomRouterConfig::default()),
150        // Monitoring router with prefix and name
151        (
152            monitoring_router,
153            CustomRouterConfig::with_name_and_prefix("Monitoring", "/monitoring"),
154        ),
155        // API router with prefix
156        (
157            api_router,
158            CustomRouterConfig::with_name_and_prefix("API", "/api"),
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}