Skip to content

Commit

Permalink
backend: Abstract global preference storage with a factory
Browse files Browse the repository at this point in the history
Refactored global preferences service adding a factory with the aim of supporting s3 and db storage
  • Loading branch information
CSantosM committed Jan 8, 2025
1 parent 612912e commit 6e37961
Show file tree
Hide file tree
Showing 18 changed files with 305 additions and 188 deletions.
2 changes: 1 addition & 1 deletion backend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion backend/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ export const CALL_USER = process.env.CALL_USER || 'user';
export const CALL_SECRET = process.env.CALL_SECRET || 'user';
export const CALL_ADMIN_USER = process.env.CALL_ADMIN_USER || 'admin';
export const CALL_ADMIN_SECRET = process.env.CALL_ADMIN_SECRET || 'admin';
// Storage mode for global preferences.
// The default storage mode is set to 's3'
export const CALL_PREFERENCES_STORAGE_MODE = process.env.CALL_PREFERENCES_STORAGE_MODE || 'db';

/**
* Log levels configuration: error, warn, info, verbose, debug, silly
Expand All @@ -38,8 +41,8 @@ export const CALL_AWS_REGION = process.env.CALL_AWS_REGION || 'us-east-1';
export const CALL_S3_WITH_PATH_STYLE_ACCESS = process.env.CALL_S3_WITH_PATH_STYLE_ACCESS || 'true';

// Sequelize configuration
// Database configuration applies only if CALL_PREFERENCES_STORAGE_MODE='s3'
export const DB_NAME = process.env.DB_NAME || 'openvidu';

// 'mysql' | 'postgres' | 'sqlite' | 'mariadb' | 'mssql' | 'db2' | 'snowflake' | 'oracle';
export const DB_DIALECT = process.env.DB_DIALECT || 'mysql';
export const DB_USER = process.env.DB_USER || 'admin';
Expand Down
4 changes: 1 addition & 3 deletions backend/src/config/sequelize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ import { Sequelize, SequelizeOptions } from 'sequelize-typescript';
import { DB_DIALECT, DB_HOST, DB_NAME, DB_PASSWORD, DB_USER } from '../config.js';

import { LoggerService } from '../services/logger.service.js';
import { GlobalPreferencesModel } from '../models/global-preferences.model.js';
import { GlobalPreferencesService } from '../services/global-preferences.service.js';
import { GlobalPreferencesService, GlobalPreferencesModel } from '../services/preferences/index.js';

const models = [GlobalPreferencesModel];
const options: SequelizeOptions = {
Expand All @@ -22,7 +21,6 @@ sequelize.addModels(models);
const sequelizeSync = async (gpService: GlobalPreferencesService) => {
const logger = LoggerService.getInstance();


try {
await sequelize.sync();
await gpService.initializeDefaultPreferences();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// src/controllers/roomPreferences.controller.ts
import { Request, Response } from 'express';
import { LoggerService } from '../../services/logger.service.js';
import { GlobalPreferencesService } from '../../services/global-preferences.service.js';
import { GlobalPreferencesService } from '../../services/preferences/index.js';
import { OpenViduCallError } from '../../models/error.model.js';

const logger = LoggerService.getInstance();
Expand All @@ -25,7 +24,7 @@ export const updateRoomPreferences = async (req: Request, res: Response) => {
return res.status(error.statusCode).json({ name: error.name, message: error.message });
}

console.error('Error saving room preferences:', error);
logger.error('Error saving room preferences:' + error);
return res.status(500).json({ message: 'Error saving room preferences', error });
}
};
Expand All @@ -38,12 +37,14 @@ export const getRoomPreferences = async (req: Request, res: Response) => {
return res.status(404).json({ message: 'Room preferences not found' });
}

return res.status(200).json(preferences.value);
} catch (error: any) {
console.error('Error fetching room preferences:', error);
//TODO: Implement error handling
return res
.status(500)
.json({ message: `${error.parent.code}. Error fetching room preferences from database`, error });
return res.status(200).json(preferences);
} catch (error) {
if (error instanceof OpenViduCallError) {
logger.error(`Error getting room preferences: ${error.message}`);
return res.status(error.statusCode).json({ name: error.name, message: error.message });
}

logger.error('Error getting room preferences:' + error);
return res.status(500).json({ message: 'Error fetching room preferences from database', error });
}
};
6 changes: 3 additions & 3 deletions backend/src/middlewares/broadcasting.middleware.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { Request, Response, NextFunction } from 'express';
import { GlobalPreferencesService } from '../services/global-preferences.service.js';
import { GlobalPreferencesService } from '../services/preferences/index.js';
import { RoomPreferences } from '@openvidu/call-common-types';
import { LoggerService } from '../services/logger.service.js';

export const withBroadcastingEnabled = async (req: Request, res: Response, next: NextFunction) => {
try {
const preferences = await GlobalPreferencesService.getInstance().getRoomPreferences();
const preferences: RoomPreferences | null = await GlobalPreferencesService.getInstance().getRoomPreferences();

if (preferences) {
const { broadcastingPreferences } = preferences.value as RoomPreferences;
const { broadcastingPreferences } = preferences;

if (!broadcastingPreferences.enabled) {
return res.status(403).json({ message: 'Broadcasting is disabled in this room.' });
Expand Down
6 changes: 3 additions & 3 deletions backend/src/middlewares/recording.middleware.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { Request, Response, NextFunction } from 'express';
import { GlobalPreferencesService } from '../services/global-preferences.service.js';
import { GlobalPreferencesService } from '../services/preferences/index.js';
import { RoomPreferences } from '@openvidu/call-common-types';
import { LoggerService } from '../services/logger.service.js';

export const withRecordingEnabled = async (req: Request, res: Response, next: NextFunction) => {
try {
const preferences = await GlobalPreferencesService.getInstance().getRoomPreferences();
const preferences: RoomPreferences | null = await GlobalPreferencesService.getInstance().getRoomPreferences();

if (preferences) {
const { recordingPreferences } = preferences.value as RoomPreferences;
const { recordingPreferences } = preferences;

if (!recordingPreferences.enabled) {
return res.status(403).json({ message: 'Recording is disabled in this room.' });
Expand Down
26 changes: 0 additions & 26 deletions backend/src/models/global-preferences.model.ts

This file was deleted.

1 change: 0 additions & 1 deletion backend/src/models/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,3 @@ export * from './recording.model.js';
export * from './room.model.js';
export * from './error.model.js';
export * from './signal.model.js';
export * from './global-preferences.model.js';
56 changes: 32 additions & 24 deletions backend/src/server.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import express, { Request, Response } from 'express';
import cors from 'cors';
import chalk from 'chalk';
import { sequelize, sequelizeSync } from './config/sequelize.js';
import { sequelizeSync } from './config/sequelize.js';
import { indexHtmlPath, publicFilesPath } from './utils/path-utils.js';
import { apiRouter, livekitRouter } from './routes/index.js';
import {
Expand All @@ -27,10 +27,11 @@ import {
DB_DIALECT,
DB_NAME,
DB_USER,
DB_PASSWORD
DB_PASSWORD,
CALL_PREFERENCES_STORAGE_MODE
} from './config.js';
import { embeddedRouter } from './routes/embedded.routes.js';
import { GlobalPreferencesService } from './services/global-preferences.service.js';
import { GlobalPreferencesService } from './services/preferences/index.js';

const createApp = () => {
const app = express();
Expand All @@ -43,9 +44,6 @@ const createApp = () => {
app.use(express.static(publicFilesPath));
app.use(express.json());

// Initialize Sequelize
sequelizeSync(GlobalPreferencesService.getInstance());

// Setup routes
app.use('/call/api', apiRouter);
app.use('/embedded/api', embeddedRouter);
Expand All @@ -54,6 +52,11 @@ const createApp = () => {
res.sendFile(indexHtmlPath);
});

if (CALL_PREFERENCES_STORAGE_MODE === 'db') {
// Initialize Sequelize
sequelizeSync(GlobalPreferencesService.getInstance());
}

return app;
};

Expand Down Expand Up @@ -82,6 +85,8 @@ const logEnvVars = () => {

console.log('CALL ADMIN USER: ', credential('****' + CALL_ADMIN_USER.slice(-3)));
console.log('CALL ADMIN PASSWORD: ', credential('****' + CALL_ADMIN_SECRET.slice(-3)));
console.log('CALL PREFERENCES STORAGE:', text(CALL_PREFERENCES_STORAGE_MODE));

console.log('---------------------------------------------------------');
console.log('LIVEKIT Configuration');
console.log('---------------------------------------------------------');
Expand All @@ -98,14 +103,17 @@ const logEnvVars = () => {
console.log('CALL S3 SECRET KEY:', credential('****' + CALL_S3_SECRET_KEY.slice(-3)));
console.log('CALL AWS REGION:', text(CALL_AWS_REGION));
console.log('---------------------------------------------------------');
console.log('Sequelize Configuration');
console.log('---------------------------------------------------------');
console.log('DB NAME:', text(DB_NAME));
console.log('BD DIALECT:', text(DB_DIALECT));
console.log('DB HOST:', text(DB_HOST));
console.log('DB USER:', credential('****' + DB_USER.slice(-3)));
console.log('DB PASSWORD:', credential('****' + DB_PASSWORD.slice(-3)));
console.log('---------------------------------------------------------');

if (CALL_PREFERENCES_STORAGE_MODE === 'db') {
console.log('Sequelize Configuration');
console.log('---------------------------------------------------------');
console.log('DB NAME:', text(DB_NAME));
console.log('BD DIALECT:', text(DB_DIALECT));
console.log('DB HOST:', text(DB_HOST));
console.log('DB USER:', credential('****' + DB_USER.slice(-3)));
console.log('DB PASSWORD:', credential('****' + DB_PASSWORD.slice(-3)));
console.log('---------------------------------------------------------');
}
};

const startServer = (app: express.Application) => {
Expand All @@ -123,17 +131,17 @@ const startServer = (app: express.Application) => {
* @returns {boolean} True if this module is the main entry point, false otherwise.
*/
const isMainModule = (): boolean => {
const importMetaUrl = import.meta.url;
let processArgv1 = process.argv[1];

if (process.platform === "win32") {
processArgv1 = processArgv1.replace(/\\/g, "/");
processArgv1 = `file:///${processArgv1}`;
} else {
processArgv1 = `file://${processArgv1}`;
}
const importMetaUrl = import.meta.url;
let processArgv1 = process.argv[1];

if (process.platform === 'win32') {
processArgv1 = processArgv1.replace(/\\/g, '/');
processArgv1 = `file:///${processArgv1}`;
} else {
processArgv1 = `file://${processArgv1}`;
}

return importMetaUrl === processArgv1;
return importMetaUrl === processArgv1;
};

if (isMainModule()) {
Expand Down
115 changes: 0 additions & 115 deletions backend/src/services/global-preferences.service.ts

This file was deleted.

2 changes: 1 addition & 1 deletion backend/src/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ export * from './recording.service.js';
export * from './room.service.js';
export * from './s3.service.js';
export * from './webhook.service.js';
export * from './global-preferences.service.js';
export * from './preferences/index.js';
Loading

0 comments on commit 6e37961

Please sign in to comment.