@codai/cbd
Version:
Codai Better Database - High-Performance Vector Memory System with HPKV-inspired architecture and MCP server
629 lines • 20.5 kB
JavaScript
/**
* Ecosystem Integration Framework
* Service mesh, cross-service synchronization, authentication, and monitoring
*/
import { EventEmitter } from 'events';
import axios from 'axios';
import WebSocket from 'ws';
/**
* CODAI Ecosystem Integration Manager
* Manages connections and communication between all CODAI services
*/
export class EcosystemIntegrationManager extends EventEmitter {
services = new Map();
meshConfig;
syncManager;
authManager;
monitoringManager;
discoveryInterval;
constructor(config) {
super();
this.meshConfig = config;
this.syncManager = new DataSynchronizationManager(this);
this.authManager = new UnifiedAuthenticationManager(config.security);
this.monitoringManager = new ServiceMonitoringManager(this);
}
/**
* Initialize ecosystem integration
*/
async initialize() {
console.log('🌐 Initializing CODAI Ecosystem Integration...');
try {
// Initialize authentication
await this.authManager.initialize();
// Start service discovery
if (this.meshConfig.discovery.enabled) {
await this.startServiceDiscovery();
}
// Initialize monitoring
await this.monitoringManager.initialize();
// Initialize data synchronization
await this.syncManager.initialize();
// Connect to configured services
await this.connectToServices();
this.emit('ecosystem-ready');
console.log('✅ Ecosystem integration initialized successfully');
}
catch (error) {
console.error('❌ Failed to initialize ecosystem integration:', error);
throw error;
}
}
/**
* Connect to all configured services
*/
async connectToServices() {
const connectionPromises = Object.entries(this.meshConfig.services).map(([name, config]) => this.connectToService(name, config));
const results = await Promise.allSettled(connectionPromises);
results.forEach((result, index) => {
const serviceName = Object.keys(this.meshConfig.services)[index];
if (result.status === 'rejected') {
console.warn(`⚠️ Failed to connect to ${serviceName}:`, result.reason);
}
});
}
/**
* Connect to individual service
*/
async connectToService(name, config) {
try {
const connection = new ServiceConnection(name, config, this.authManager);
await connection.connect();
this.services.set(name, connection);
this.emit('service-connected', { name, config });
console.log(`🔗 Connected to ${name} service`);
}
catch (error) {
console.error(`❌ Failed to connect to ${name}:`, error);
throw error;
}
}
/**
* Start service discovery process
*/
async startServiceDiscovery() {
const discoveryProcess = async () => {
try {
await this.discoverServices();
}
catch (error) {
console.error('Service discovery error:', error);
}
};
// Initial discovery
await discoveryProcess();
// Periodic discovery
this.discoveryInterval = setInterval(discoveryProcess, this.meshConfig.discovery.refresh_interval);
}
/**
* Discover available services
*/
async discoverServices() {
// Implementation would check for new services
// For now, use configured services
console.log('🔍 Discovering services...');
for (const [name, config] of Object.entries(this.meshConfig.services)) {
if (!this.services.has(name)) {
try {
await this.connectToService(name, config);
}
catch (error) {
// Service not available yet
}
}
}
}
/**
* Get service by name
*/
getService(name) {
return this.services.get(name);
}
/**
* Get all connected services
*/
getAllServices() {
return Array.from(this.services.values());
}
/**
* Execute cross-service operation
*/
async executeDistributedOperation(operation) {
console.log(`🔄 Executing distributed operation: ${operation.name}`);
const results = new Map();
const errors = [];
for (const step of operation.steps) {
try {
const service = this.getService(step.service);
if (!service) {
throw new Error(`Service ${step.service} not available`);
}
const result = await service.execute(step.endpoint, step.method, step.data);
results.set(step.service, result);
// Handle step dependencies
if (step.onSuccess) {
await step.onSuccess(result);
}
}
catch (error) {
errors.push(`${step.service}: ${error}`);
if (step.onError) {
await step.onError(error);
}
if (step.required) {
throw new Error(`Required step failed: ${step.service}`);
}
}
}
return {
success: errors.length === 0,
results: Object.fromEntries(results),
errors
};
}
/**
* Shutdown ecosystem integration
*/
async shutdown() {
console.log('🔽 Shutting down ecosystem integration...');
// Stop discovery
if (this.discoveryInterval) {
clearInterval(this.discoveryInterval);
}
// Disconnect from services
for (const connection of this.services.values()) {
await connection.disconnect();
}
// Shutdown managers
await this.syncManager.shutdown();
await this.monitoringManager.shutdown();
this.emit('ecosystem-shutdown');
console.log('✅ Ecosystem integration shutdown complete');
}
}
/**
* Individual service connection manager
*/
class ServiceConnection extends EventEmitter {
name;
config;
authManager;
httpClient;
wsConnection;
healthCheckInterval;
isConnected = false;
constructor(name, config, authManager) {
super();
this.name = name;
this.config = config;
this.authManager = authManager;
this.httpClient = axios.create({
baseURL: config.url,
timeout: 5000,
headers: {
'Content-Type': 'application/json',
'User-Agent': 'CODAI-Ecosystem-Client/1.0'
}
});
// Add authentication interceptor
this.httpClient.interceptors.request.use((config) => this.authManager.attachAuth(config));
}
/**
* Connect to service
*/
async connect() {
try {
// Test HTTP connection
const healthResponse = await this.httpClient.get(this.config.health_endpoint);
if (healthResponse.status !== 200) {
throw new Error(`Health check failed: ${healthResponse.status}`);
}
// Establish WebSocket connection for real-time communication
if (this.config.capabilities.includes('websocket')) {
await this.connectWebSocket();
}
this.isConnected = true;
this.startHealthChecks();
this.emit('connected');
console.log(`✅ ${this.name} service connected`);
}
catch (error) {
console.error(`❌ Failed to connect to ${this.name}:`, error);
throw error;
}
}
/**
* Connect WebSocket for real-time communication
*/
async connectWebSocket() {
return new Promise((resolve, reject) => {
const wsUrl = this.config.url.replace('http', 'ws') + '/ws';
this.wsConnection = new WebSocket(wsUrl);
this.wsConnection.on('open', () => {
console.log(`🔌 WebSocket connected to ${this.name}`);
resolve();
});
this.wsConnection.on('error', (error) => {
console.error(`WebSocket error for ${this.name}:`, error);
reject(error);
});
this.wsConnection.on('message', (data) => {
try {
const message = JSON.parse(data.toString());
this.emit('message', message);
}
catch (error) {
console.error('Failed to parse WebSocket message:', error);
}
});
this.wsConnection.on('close', () => {
console.log(`🔌 WebSocket disconnected from ${this.name}`);
this.emit('websocket-disconnected');
});
});
}
/**
* Start periodic health checks
*/
startHealthChecks() {
this.healthCheckInterval = setInterval(async () => {
try {
const response = await this.httpClient.get(this.config.health_endpoint);
if (response.status !== 200) {
this.handleHealthCheckFailure();
}
}
catch (error) {
this.handleHealthCheckFailure();
}
}, 30000); // Check every 30 seconds
}
/**
* Handle health check failure
*/
handleHealthCheckFailure() {
if (this.isConnected) {
this.isConnected = false;
this.emit('disconnected');
console.warn(`⚠️ ${this.name} service became unavailable`);
}
}
/**
* Execute API call
*/
async execute(endpoint, method = 'GET', data) {
if (!this.isConnected) {
throw new Error(`Service ${this.name} is not connected`);
}
try {
let response;
switch (method) {
case 'GET':
response = await this.httpClient.get(endpoint);
break;
case 'POST':
response = await this.httpClient.post(endpoint, data);
break;
case 'PUT':
response = await this.httpClient.put(endpoint, data);
break;
case 'DELETE':
response = await this.httpClient.delete(endpoint);
break;
}
return response.data;
}
catch (error) {
console.error(`API call failed for ${this.name}:`, error);
throw error;
}
}
/**
* Send WebSocket message
*/
sendMessage(message) {
if (this.wsConnection && this.wsConnection.readyState === WebSocket.OPEN) {
this.wsConnection.send(JSON.stringify(message));
}
else {
throw new Error(`WebSocket not available for ${this.name}`);
}
}
/**
* Disconnect from service
*/
async disconnect() {
if (this.healthCheckInterval) {
clearInterval(this.healthCheckInterval);
}
if (this.wsConnection) {
this.wsConnection.close();
}
this.isConnected = false;
this.emit('disconnected');
console.log(`🔌 Disconnected from ${this.name}`);
}
}
/**
* Data Synchronization Manager
* Handles cross-service data synchronization
*/
class DataSynchronizationManager extends EventEmitter {
ecosystem;
syncOperations = new Map();
syncInterval;
constructor(ecosystem) {
super();
this.ecosystem = ecosystem;
}
async initialize() {
console.log('🔄 Initializing data synchronization...');
// Start periodic sync
this.syncInterval = setInterval(() => {
this.performPeriodicSync();
}, 60000); // Sync every minute
console.log('✅ Data synchronization initialized');
}
/**
* Register sync operation
*/
registerSyncOperation(operation) {
this.syncOperations.set(operation.name, operation);
console.log(`📝 Registered sync operation: ${operation.name}`);
}
/**
* Perform periodic synchronization
*/
async performPeriodicSync() {
for (const [name, operation] of this.syncOperations) {
try {
await this.executeSyncOperation(operation);
}
catch (error) {
console.error(`Sync operation ${name} failed:`, error);
}
}
}
/**
* Execute sync operation
*/
async executeSyncOperation(operation) {
const sourceService = this.ecosystem.getService(operation.source);
const targetService = this.ecosystem.getService(operation.target);
if (!sourceService || !targetService) {
return; // Services not available
}
// Get data from source
const sourceData = await sourceService.execute(operation.sourceEndpoint);
// Transform data if needed
const transformedData = operation.transform ?
operation.transform(sourceData) : sourceData;
// Send to target
await targetService.execute(operation.targetEndpoint, 'POST', transformedData);
this.emit('sync-completed', { operation: operation.name, data: transformedData });
}
async shutdown() {
if (this.syncInterval) {
clearInterval(this.syncInterval);
}
console.log('🔄 Data synchronization shutdown');
}
}
/**
* Unified Authentication Manager
* Handles authentication across all services
*/
class UnifiedAuthenticationManager {
securityConfig;
tokens = new Map();
refreshInterval;
constructor(securityConfig) {
this.securityConfig = securityConfig;
}
async initialize() {
if (!this.securityConfig.authentication) {
return;
}
console.log('🔐 Initializing unified authentication...');
// Initialize API keys or tokens
await this.loadAuthTokens();
// Start token refresh process
this.refreshInterval = setInterval(() => {
this.refreshTokens();
}, 3600000); // Refresh every hour
console.log('✅ Unified authentication initialized');
}
/**
* Load authentication tokens
*/
async loadAuthTokens() {
// Load from environment or secure storage
const apiKey = process.env.CODAI_API_KEY;
if (apiKey) {
this.tokens.set('api_key', apiKey);
}
// Additional token loading logic
}
/**
* Attach authentication to request
*/
attachAuth(config) {
if (this.securityConfig.api_key_required) {
const apiKey = this.tokens.get('api_key');
if (apiKey) {
config.headers['X-API-Key'] = apiKey;
}
}
return config;
}
/**
* Refresh authentication tokens
*/
async refreshTokens() {
// Token refresh logic
console.log('🔄 Refreshing authentication tokens...');
}
async shutdown() {
if (this.refreshInterval) {
clearInterval(this.refreshInterval);
}
console.log('🔐 Authentication manager shutdown');
}
}
/**
* Service Monitoring Manager
* Monitors health and performance of all services
*/
class ServiceMonitoringManager extends EventEmitter {
ecosystem;
metrics = new Map();
monitoringInterval;
constructor(ecosystem) {
super();
this.ecosystem = ecosystem;
}
async initialize() {
console.log('📊 Initializing service monitoring...');
// Start monitoring
this.monitoringInterval = setInterval(() => {
this.collectMetrics();
}, 30000); // Collect metrics every 30 seconds
console.log('✅ Service monitoring initialized');
}
/**
* Collect metrics from all services
*/
async collectMetrics() {
const services = this.ecosystem.getAllServices();
for (const service of services) {
try {
const startTime = Date.now();
await service.execute('/health');
const responseTime = Date.now() - startTime;
const metrics = {
name: service.name,
status: 'healthy',
responseTime,
timestamp: new Date(),
uptime: this.calculateUptime(service.name)
};
this.metrics.set(service.name, metrics);
this.emit('metrics-collected', metrics);
}
catch (error) {
const metrics = {
name: service.name,
status: 'unhealthy',
responseTime: -1,
timestamp: new Date(),
uptime: 0,
error: error.message
};
this.metrics.set(service.name, metrics);
this.emit('service-unhealthy', metrics);
}
}
}
/**
* Calculate service uptime
*/
calculateUptime(serviceName) {
// Simplified uptime calculation
const previousMetrics = this.metrics.get(serviceName);
return previousMetrics ? Date.now() - previousMetrics.timestamp.getTime() : 0;
}
/**
* Get current metrics
*/
getMetrics() {
return Array.from(this.metrics.values());
}
/**
* Get service health status
*/
getServiceHealth(serviceName) {
return this.metrics.get(serviceName);
}
async shutdown() {
if (this.monitoringInterval) {
clearInterval(this.monitoringInterval);
}
console.log('📊 Service monitoring shutdown');
}
}
// Default CODAI ecosystem configuration
export const DEFAULT_ECOSYSTEM_CONFIG = {
services: {
gateway: {
name: 'Gateway Service',
url: 'http://localhost:3001',
port: 3001,
health_endpoint: '/health',
version: '1.0.0',
capabilities: ['routing', 'load-balancing', 'websocket']
},
codai: {
name: 'CODAI Service',
url: 'http://localhost:3002',
port: 3002,
health_endpoint: '/health',
version: '1.0.0',
capabilities: ['ai-assistance', 'code-generation', 'websocket']
},
admin: {
name: 'Admin Service',
url: 'http://localhost:3003',
port: 3003,
health_endpoint: '/health',
version: '1.0.0',
capabilities: ['administration', 'user-management']
},
hub: {
name: 'Hub Service',
url: 'http://localhost:3004',
port: 3004,
health_endpoint: '/health',
version: '1.0.0',
capabilities: ['integration', 'orchestration', 'websocket']
},
bancai: {
name: 'BancAI Service',
url: 'http://localhost:3005',
port: 3005,
health_endpoint: '/health',
version: '1.0.0',
capabilities: ['banking', 'financial-ai', 'compliance']
},
memorai: {
name: 'MemorAI Service',
url: 'http://localhost:3006',
port: 3006,
health_endpoint: '/health',
version: '1.0.0',
capabilities: ['memory-management', 'context-retention', 'ai-memory']
},
cbd: {
name: 'CBD Database Service',
url: 'http://localhost:4180',
port: 4180,
health_endpoint: '/health',
version: '1.0.0',
capabilities: ['database', 'vector-search', 'multi-paradigm']
}
},
discovery: {
enabled: true,
refresh_interval: 60000,
timeout: 5000
},
load_balancing: {
strategy: 'round-robin',
health_check_interval: 30000
},
security: {
authentication: true,
encryption: false,
api_key_required: true
}
};
//# sourceMappingURL=ecosystem-integration.js.map