@codai/cbd
Version:
Codai Better Database - High-Performance Vector Memory System with HPKV-inspired architecture and MCP server
266 lines (229 loc) โข 9.45 kB
JavaScript
/**
* CBD Service Mesh Gateway
* A lightweight service discovery and routing gateway for the CBD ecosystem
*
* Features:
* - Service discovery for all CBD services
* - Health checking and status monitoring
* - Request routing and load balancing
* - API gateway functionality
*/
const express = require('express');
const cors = require('cors');
const http = require('http');
class CBDServiceMeshGateway {
constructor() {
this.app = express();
this.server = null;
this.port = process.env.PORT || 4000;
this.services = new Map();
this.isShuttingDown = false;
this.setupMiddleware();
this.setupRoutes();
this.registerKnownServices();
}
setupMiddleware() {
// CORS configuration
this.app.use(cors({
origin: ['http://localhost:3000', 'http://localhost:4001', 'http://localhost:4200'],
credentials: true
}));
this.app.use(express.json({ limit: '10mb' }));
this.app.use(express.urlencoded({ extended: true }));
// Request logging
this.app.use((req, res, next) => {
console.log(`${new Date().toISOString()} - ${req.method} ${req.path}`);
next();
});
}
setupRoutes() {
// Health check endpoint
this.app.get('/health', (req, res) => {
const healthStatus = {
status: 'healthy',
service: 'CBD Service Mesh Gateway',
version: '1.0.0',
timestamp: new Date().toLocaleString('ro-RO'),
uptime: process.uptime(),
services: this.getServiceStatuses(),
features: {
service_discovery: true,
health_monitoring: true,
request_routing: true,
load_balancing: false,
api_gateway: true
}
};
res.json(healthStatus);
});
// Service discovery endpoint
this.app.get('/services', (req, res) => {
const serviceList = Array.from(this.services.entries()).map(([name, config]) => ({
name,
url: config.url,
port: config.port,
status: config.status || 'unknown',
lastChecked: config.lastChecked
}));
res.json({
totalServices: serviceList.length,
services: serviceList,
mesh: 'CBD Universal Database Ecosystem'
});
});
// Service registration endpoint
this.app.post('/register', (req, res) => {
const { name, url, port } = req.body;
if (!name || !url || !port) {
return res.status(400).json({
error: 'Missing required fields: name, url, port'
});
}
this.services.set(name, {
url,
port,
status: 'registered',
lastChecked: new Date().toISOString()
});
res.json({
message: `Service ${name} registered successfully`,
service: { name, url, port }
});
});
// Route proxy endpoint (basic implementation)
this.app.all('/proxy/:service/*', (req, res) => {
const serviceName = req.params.service;
const service = this.services.get(serviceName);
if (!service) {
return res.status(404).json({
error: `Service ${serviceName} not found in service mesh`
});
}
// Simple proxy implementation (could be enhanced with actual proxying)
res.json({
message: `Proxying to ${serviceName}`,
targetUrl: service.url,
originalPath: req.path,
method: req.method
});
});
// Statistics endpoint
this.app.get('/stats', (req, res) => {
res.json({
totalServices: this.services.size,
activeServices: Array.from(this.services.values()).filter(s => s.status === 'healthy').length,
meshUptime: process.uptime(),
requestCount: 0, // Could implement request counting
version: '1.0.0'
});
});
}
registerKnownServices() {
// Register known CBD services
const knownServices = [
{ name: 'CBD Core Database', url: 'http://localhost:4180', port: 4180 },
{ name: 'Real-time Collaboration', url: 'http://localhost:4600', port: 4600 },
{ name: 'AI Analytics Engine', url: 'http://localhost:4700', port: 4700 },
{ name: 'GraphQL API Gateway', url: 'http://localhost:4800', port: 4800 }
];
knownServices.forEach(service => {
this.services.set(service.name, {
url: service.url,
port: service.port,
status: 'known',
lastChecked: new Date().toISOString()
});
});
}
getServiceStatuses() {
const statuses = {};
for (const [name, config] of this.services) {
statuses[name] = {
url: config.url,
status: config.status,
port: config.port
};
}
return statuses;
}
async start() {
return new Promise((resolve, reject) => {
try {
console.log('๐ Starting CBD Service Mesh Gateway...');
console.log('๐ Environment:', process.env.NODE_ENV || 'development');
console.log('๐ง Node.js version:', process.version);
this.server = this.app.listen(this.port, () => {
console.log('โ
CBD Service Mesh Gateway is running');
console.log(`๐ Server: http://localhost:${this.port}`);
console.log('๐ Registered Services:', this.services.size);
console.log('');
console.log('๐ Key Endpoints:');
console.log(` Health Check: http://localhost:${this.port}/health`);
console.log(` Service Discovery: http://localhost:${this.port}/services`);
console.log(` Service Registration: http://localhost:${this.port}/register`);
console.log(` Statistics: http://localhost:${this.port}/stats`);
console.log(` Proxy: http://localhost:${this.port}/proxy/{service}/*`);
console.log('');
console.log('๐ก Service Mesh Gateway ready. Press Ctrl+C to stop.');
resolve();
});
this.server.timeout = 30000;
this.setupGracefulShutdown();
} catch (error) {
console.error('โ Failed to start Service Mesh Gateway:', error);
reject(error);
}
});
}
setupGracefulShutdown() {
const shutdown = async (signal) => {
if (this.isShuttingDown) {
console.log('๐ Shutdown already in progress...');
return;
}
this.isShuttingDown = true;
console.log(`\n๐ก Received ${signal}. Starting graceful shutdown...`);
try {
if (this.server) {
console.log('๐ Closing HTTP server...');
await new Promise((resolve, reject) => {
this.server.close((err) => {
if (err) reject(err);
else resolve();
});
});
}
console.log('๐งน Cleaning up service mesh resources...');
this.services.clear();
console.log('โ
Graceful shutdown completed');
process.exit(0);
} catch (error) {
console.error('โ Error during shutdown:', error);
process.exit(1);
}
};
// Register signal handlers
process.on('SIGINT', () => shutdown('SIGINT'));
process.on('SIGTERM', () => shutdown('SIGTERM'));
// Handle uncaught exceptions
process.on('uncaughtException', (error) => {
console.error('๐ฅ Uncaught Exception:', error);
shutdown('UNCAUGHT_EXCEPTION');
});
// Handle unhandled promise rejections
process.on('unhandledRejection', (reason, promise) => {
console.error('๐จ Unhandled Rejection at:', promise, 'reason:', reason);
shutdown('UNHANDLED_REJECTION');
});
}
}
// Start the service if this file is run directly
if (require.main === module) {
const gateway = new CBDServiceMeshGateway();
gateway.start().catch((error) => {
console.error('๐ฅ Fatal startup error:', error);
process.exit(1);
});
}
module.exports = CBDServiceMeshGateway;