131 lines
4.0 KiB
JavaScript
131 lines
4.0 KiB
JavaScript
const { logger } = require('../config/logs');
|
|
const fs = require('fs').promises;
|
|
const path = require('path');
|
|
|
|
class BaseService {
|
|
constructor(name, defaultConfig = {}) {
|
|
this.name = name;
|
|
this.defaultConfig = defaultConfig;
|
|
this.config = {};
|
|
this.isRunning = false;
|
|
this.status = 'stopped';
|
|
this.logger = logger;
|
|
this.setupPath = path.join(process.cwd(), 'data', 'setup.json');
|
|
}
|
|
|
|
async loadConfig() {
|
|
try {
|
|
const setupContent = await fs.readFile(this.setupPath, 'utf8');
|
|
const setup = JSON.parse(setupContent);
|
|
|
|
// Retrieve the service configuration from setup.json
|
|
const serviceConfig = setup[0]?.services?.[this.name] || {};
|
|
|
|
// Merge with the default configuration
|
|
this.config = {
|
|
...this.defaultConfig,
|
|
...serviceConfig
|
|
};
|
|
|
|
return this.config;
|
|
} catch (error) {
|
|
this.logger.error(`Error loading configuration for ${this.name}:`, error);
|
|
this.config = this.defaultConfig;
|
|
return this.config;
|
|
}
|
|
}
|
|
|
|
async start() {
|
|
if (this.isRunning) {
|
|
this.logger.warn(`Service ${this.name} is already running`);
|
|
return;
|
|
}
|
|
|
|
try {
|
|
// Load the configuration before starting
|
|
await this.loadConfig();
|
|
|
|
// Check if the service is enabled
|
|
if (this.config.enabled !== 'on') {
|
|
this.logger.info(`Service ${this.name} is not enabled in the configuration`);
|
|
return;
|
|
}
|
|
|
|
await this._startImplementation();
|
|
this.isRunning = true;
|
|
this.status = 'running';
|
|
this.logger.info(`Service ${this.name} started successfully`);
|
|
} catch (error) {
|
|
this.logger.error(`Error starting service ${this.name}:`, error);
|
|
this.status = 'error';
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async stop() {
|
|
if (!this.isRunning) {
|
|
this.logger.warn(`Service ${this.name} is not running`);
|
|
return;
|
|
}
|
|
|
|
try {
|
|
await this._stopImplementation();
|
|
this.isRunning = false;
|
|
this.status = 'stopped';
|
|
this.logger.info(`Service ${this.name} stopped successfully`);
|
|
} catch (error) {
|
|
this.logger.error(`Error stopping service ${this.name}:`, error);
|
|
this.status = 'error';
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
getStatus() {
|
|
return {
|
|
name: this.name,
|
|
status: this.status,
|
|
isRunning: this.isRunning,
|
|
config: this.config
|
|
};
|
|
}
|
|
|
|
async updateConfig(newConfig) {
|
|
// Load the current configuration from setup.json
|
|
let setup;
|
|
try {
|
|
const setupContent = await fs.readFile(this.setupPath, 'utf8');
|
|
setup = JSON.parse(setupContent);
|
|
} catch (error) {
|
|
throw new Error(`Error reading setup.json: ${error.message}`);
|
|
}
|
|
|
|
// Update the service configuration
|
|
if (!setup[0].services) {
|
|
setup[0].services = {};
|
|
}
|
|
setup[0].services[this.name] = {
|
|
...this.config,
|
|
...newConfig
|
|
};
|
|
|
|
// Save to setup.json
|
|
try {
|
|
await fs.writeFile(this.setupPath, JSON.stringify(setup, null, 2));
|
|
this.config = setup[0].services[this.name];
|
|
this.logger.info(`Configuration for service ${this.name} updated:`, this.config);
|
|
} catch (error) {
|
|
throw new Error(`Error saving configuration: ${error.message}`);
|
|
}
|
|
}
|
|
|
|
// These methods must be implemented by subclasses
|
|
async _startImplementation() {
|
|
throw new Error('_startImplementation must be implemented by the subclass');
|
|
}
|
|
|
|
async _stopImplementation() {
|
|
throw new Error('_stopImplementation must be implemented by the subclass');
|
|
}
|
|
}
|
|
|
|
module.exports = BaseService; |