pms-analysis-reports-mcp-server
Version:
PMS analysis reports server handling maintenance reports, equipment analysis, compliance tracking, and performance metrics with ERP access for data extraction
224 lines • 7.81 kB
JavaScript
// Service layer exports
export { BaseService } from './base-service.js';
export { CacheService } from './cache-service.js';
export { ExternalApiService } from './external-api-service.js';
export { DatabaseService } from './database-service.js';
// Service factory and manager
import { logger } from "../utils/logger.js";
import { CacheService } from './cache-service.js';
import { ExternalApiService } from './external-api-service.js';
import { DatabaseService } from './database-service.js';
export class ServiceManager {
constructor() {
this.services = new Map();
}
static getInstance() {
if (!ServiceManager.instance) {
ServiceManager.instance = new ServiceManager();
}
return ServiceManager.instance;
}
/**
* Initialize services with configuration
*/
async initialize(config) {
logger.info('Initializing service manager');
try {
// Initialize cache service
if (config.cache) {
const cacheService = new CacheService(config.cache);
this.services.set('cache', cacheService);
logger.info('Cache service initialized');
}
// Initialize database service
if (config.database) {
const databaseService = new DatabaseService(config.database);
await databaseService.connect();
this.services.set('database', databaseService);
logger.info('Database service initialized');
}
// Initialize external API services
if (config.externalApis) {
for (const [name, apiConfig] of Object.entries(config.externalApis)) {
if (apiConfig) {
const apiService = new ExternalApiService(apiConfig);
this.services.set(`api_${name}`, apiService);
logger.info(`External API service initialized: ${name}`);
}
}
}
// Start health monitoring
this.startHealthMonitoring();
logger.info('Service manager initialization completed', {
serviceCount: this.services.size,
services: Array.from(this.services.keys())
});
}
catch (error) {
logger.error('Service manager initialization failed', { error: error.message });
throw error;
}
}
/**
* Get service by name
*/
getService(name) {
return this.services.get(name);
}
/**
* Get cache service
*/
getCache() {
return this.getService('cache');
}
/**
* Get database service
*/
getDatabase() {
return this.getService('database');
}
/**
* Get external API service
*/
getExternalApi(name) {
return this.getService(`api_${name}`);
}
/**
* Get all service health statuses
*/
async getHealthStatus() {
const healthStatus = {};
for (const [name, service] of this.services.entries()) {
try {
if (typeof service.getHealth === 'function') {
healthStatus[name] = service.getHealth();
}
else if (typeof service.healthCheck === 'function') {
const isHealthy = await service.healthCheck();
healthStatus[name] = {
status: isHealthy ? 'healthy' : 'unhealthy',
lastCheck: new Date()
};
}
else {
healthStatus[name] = {
status: 'unknown',
message: 'No health check available'
};
}
}
catch (error) {
healthStatus[name] = {
status: 'error',
error: error.message,
lastCheck: new Date()
};
}
}
return healthStatus;
}
/**
* Start health monitoring for all services
*/
startHealthMonitoring() {
// Run health checks every 5 minutes
this.healthCheckInterval = setInterval(async () => {
try {
const healthStatus = await this.getHealthStatus();
const unhealthyServices = Object.entries(healthStatus)
.filter(([_, status]) => status.status === 'unhealthy' || status.status === 'error')
.map(([name]) => name);
if (unhealthyServices.length > 0) {
logger.warn('Unhealthy services detected', {
unhealthyServices,
healthStatus
});
}
else {
logger.debug('All services healthy');
}
}
catch (error) {
logger.error('Health monitoring error', { error: error.message });
}
}, 300000); // 5 minutes
// Don't keep the process alive for health monitoring
this.healthCheckInterval.unref();
}
/**
* Shutdown all services gracefully
*/
async shutdown() {
logger.info('Shutting down service manager');
// Stop health monitoring
if (this.healthCheckInterval) {
clearInterval(this.healthCheckInterval);
this.healthCheckInterval = undefined;
}
// Shutdown services in reverse order
const serviceEntries = Array.from(this.services.entries()).reverse();
for (const [name, service] of serviceEntries) {
try {
if (typeof service.shutdown === 'function') {
await service.shutdown();
}
else if (typeof service.disconnect === 'function') {
await service.disconnect();
}
logger.info(`Service shut down: ${name}`);
}
catch (error) {
logger.error(`Error shutting down service ${name}:`, { error: error.message });
}
}
this.services.clear();
logger.info('Service manager shutdown completed');
}
/**
* Reset service manager (useful for testing)
*/
reset() {
if (this.healthCheckInterval) {
clearInterval(this.healthCheckInterval);
this.healthCheckInterval = undefined;
}
this.services.clear();
}
/**
* Get service metrics
*/
getMetrics() {
const metrics = {};
for (const [name, service] of this.services.entries()) {
try {
if (typeof service.getHealth === 'function') {
const health = service.getHealth();
metrics[name] = {
status: health.status,
metrics: health.metrics,
uptime: health.uptime
};
}
else if (typeof service.getStats === 'function') {
metrics[name] = service.getStats();
}
else {
metrics[name] = {
status: 'unknown',
message: 'No metrics available'
};
}
}
catch (error) {
metrics[name] = {
status: 'error',
error: error.message
};
}
}
return metrics;
}
}
// Export singleton instance
export const serviceManager = ServiceManager.getInstance();
//# sourceMappingURL=index.js.map