Внедрение схем валидации параметров классов ParusAppServer, DBConnector, OutQueue

This commit is contained in:
Mikhail Chechnev 2018-11-27 21:49:40 +03:00
parent 38609f4c90
commit e9df76ac7b
4 changed files with 41 additions and 39 deletions

View File

@ -13,7 +13,7 @@ const oq = require("./out_queue"); //Прослушивание очереди
const { ServerError } = require("./server_errors"); //Типовая ошибка const { ServerError } = require("./server_errors"); //Типовая ошибка
const { validateObject } = require("./utils"); //Вспомогательные функции const { validateObject } = require("./utils"); //Вспомогательные функции
const { SERR_COMMON, SERR_OBJECT_BAD_INTERFACE } = require("./constants"); //Общесистемные константы const { SERR_COMMON, SERR_OBJECT_BAD_INTERFACE } = require("./constants"); //Общесистемные константы
const objConfigSchema = require("../models/obj_config"); //Схема валидации файла настроек const prmsAppSchema = require("../models/prms_app"); //Схема валидации параметров функций класса
//------------ //------------
// Тело модуля // Тело модуля
//------------ //------------
@ -43,16 +43,16 @@ class ParusAppServer {
await this.logger.warn("Сервер приложений отключен от БД"); await this.logger.warn("Сервер приложений отключен от БД");
} }
//Инициализация сервера //Инициализация сервера
async init(cfg) { async init(prms) {
await this.logger.info("Инициализация сервера приложений..."); await this.logger.info("Инициализация сервера приложений...");
//Проверяем структуру переданного объекта конфигурации //Проверяем структуру переданного объекта конфигурации
let sCheckResult = validateObject(cfg, objConfigSchema.config, "Настройки сервера приложений"); let sCheckResult = validateObject(prms, prmsAppSchema.init, "Параметры инициализации");
//Если настройки верны - будем стартовать //Если настройки верны - будем стартовать
if (!sCheckResult) { if (!sCheckResult) {
//Создаём подключение к БД //Создаём подключение к БД
this.dbConn = new db.DBConnector(cfg.dbConnect); this.dbConn = new db.DBConnector({ connectSettings: prms.config.dbConnect });
//Создаём обработчик очереди исходящих //Создаём обработчик очереди исходящих
this.outQ = new oq.OutQueue(cfg.outgoing, this.dbConn, this.logger); this.outQ = new oq.OutQueue({ outGoing: prms.config.outGoing, dbConn: this.dbConn, logger: this.logger });
//Скажем что инициализировали //Скажем что инициализировали
await this.logger.info("Сервер приложение инициализирован"); await this.logger.info("Сервер приложение инициализирован");
} else { } else {

View File

@ -9,7 +9,6 @@
const _ = require("lodash"); //Работа с массивами и объектами const _ = require("lodash"); //Работа с массивами и объектами
const EventEmitter = require("events"); //Обработчик пользовательских событий const EventEmitter = require("events"); //Обработчик пользовательских событий
const glConst = require("../core/constants"); //Глобальные константы
const { ServerError } = require("../core/server_errors"); //Типовая ошибка const { ServerError } = require("../core/server_errors"); //Типовая ошибка
const { makeModuleFullPath, validateObject } = require("../core/utils"); //Вспомогательные функции const { makeModuleFullPath, validateObject } = require("../core/utils"); //Вспомогательные функции
const prmsDBConnectorSchema = require("../models/prms_db_connector"); //Схемы валидации параметров функций модуля const prmsDBConnectorSchema = require("../models/prms_db_connector"); //Схемы валидации параметров функций модуля
@ -18,6 +17,11 @@ const objServicesSchema = require("../models/obj_services"); //Схема вал
const objQueueSchema = require("../models/obj_queue"); //Схема валидации сообщения очереди обмена const objQueueSchema = require("../models/obj_queue"); //Схема валидации сообщения очереди обмена
const objQueuesSchema = require("../models/obj_queues"); //Схема валидации списка сообщений очереди обмена const objQueuesSchema = require("../models/obj_queues"); //Схема валидации списка сообщений очереди обмена
const objLogSchema = require("../models/obj_log"); //Схема валидации записи журнала const objLogSchema = require("../models/obj_log"); //Схема валидации записи журнала
const {
SERR_MODULES_BAD_INTERFACE,
SERR_OBJECT_BAD_INTERFACE,
SERR_MODULES_NO_MODULE_SPECIFIED
} = require("../core/constants"); //Глобальные константы
//---------- //----------
// Константы // Константы
@ -51,31 +55,31 @@ class DBConnector extends EventEmitter {
//Если структура объекта в норме //Если структура объекта в норме
if (!sCheckResult) { if (!sCheckResult) {
//Проверяем наличие модуля для работы с БД в настройках подключения //Проверяем наличие модуля для работы с БД в настройках подключения
if (prms.sConnectorModule) { if (prms.connectSettings.sConnectorModule) {
//Подключим модуль //Подключим модуль
this.connector = require(makeModuleFullPath(prms.sConnectorModule)); this.connector = require(makeModuleFullPath(prms.connectSettings.sConnectorModule));
//Проверим его интерфейс //Проверим его интерфейс
let sCheckResult = validateObject( let sCheckResult = validateObject(
this.connector, this.connector,
intfDBConnectorModuleSchema.dbConnectorModule, intfDBConnectorModuleSchema.dbConnectorModule,
"Модуль " + prms.sConnectorModule "Модуль " + prms.connectSettings.sConnectorModule
); );
if (sCheckResult) { if (sCheckResult) {
throw new ServerError(glConst.SERR_MODULES_BAD_INTERFACE, sCheckResult); throw new ServerError(SERR_MODULES_BAD_INTERFACE, sCheckResult);
} }
//Всё успешно - сохраним настройки подключения //Всё успешно - сохраним настройки подключения
this.connectSettings = _.cloneDeep(prms); this.connectSettings = _.cloneDeep(prms.connectSettings);
//Инициализируем остальные свойства //Инициализируем остальные свойства
this.connection = null; this.connection = null;
this.bConnected = false; this.bConnected = false;
} else { } else {
throw new ServerError( throw new ServerError(
glConst.SERR_MODULES_NO_MODULE_SPECIFIED, SERR_MODULES_NO_MODULE_SPECIFIED,
"Не указано имя подключаемого модуля-коннектора!" "Не указано имя подключаемого модуля-коннектора!"
); );
} }
} else { } else {
throw new ServerError(glConst.SERR_OBJECT_BAD_INTERFACE, sCheckResult); throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
} }
} }
//Подключиться к БД //Подключиться к БД
@ -146,11 +150,11 @@ class DBConnector extends EventEmitter {
//Валидируем финальный объект //Валидируем финальный объект
sCheckResult = validateObject({ services: res }, objServicesSchema.Services, "Список сервисов"); sCheckResult = validateObject({ services: res }, objServicesSchema.Services, "Список сервисов");
//Если валидация не прошла //Если валидация не прошла
if (sCheckResult) throw new ServerError(glConst.SERR_OBJECT_BAD_INTERFACE, sCheckResult); if (sCheckResult) throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
//Успешно - отдаём список сервисов //Успешно - отдаём список сервисов
return res; return res;
} else { } else {
throw new ServerError(glConst.SERR_OBJECT_BAD_INTERFACE, sCheckResult); throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
} }
} catch (e) { } catch (e) {
if (e instanceof ServerError) throw e; if (e instanceof ServerError) throw e;
@ -180,14 +184,14 @@ class DBConnector extends EventEmitter {
let res = await this.connector.log(logData); let res = await this.connector.log(logData);
//Валидируем полученный ответ //Валидируем полученный ответ
sCheckResult = validateObject(res, objLogSchema.Log, "Добавленная запись журнала работы"); sCheckResult = validateObject(res, objLogSchema.Log, "Добавленная запись журнала работы");
if (sCheckResult) throw new ServerError(glConst.SERR_OBJECT_BAD_INTERFACE, sCheckResult); if (sCheckResult) throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
//Вернём добавленную запись //Вернём добавленную запись
return res; return res;
} catch (e) { } catch (e) {
throw new ServerError(SERR_DB_EXECUTE, e.message); throw new ServerError(SERR_DB_EXECUTE, e.message);
} }
} else { } else {
throw new ServerError(glConst.SERR_OBJECT_BAD_INTERFACE, sCheckResult); throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
} }
} else { } else {
throw new ServerError(SERR_DB_EXECUTE, "Нет подключения к БД"); throw new ServerError(SERR_DB_EXECUTE, "Нет подключения к БД");
@ -264,14 +268,14 @@ class DBConnector extends EventEmitter {
objQueuesSchema.Queues, objQueuesSchema.Queues,
"Список сообщений очереди обмена" "Список сообщений очереди обмена"
); );
if (sCheckResult) throw new ServerError(glConst.SERR_OBJECT_BAD_INTERFACE, sCheckResult); if (sCheckResult) throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
//Вернём сообщения очереди обмена //Вернём сообщения очереди обмена
return res; return res;
} catch (e) { } catch (e) {
throw new ServerError(SERR_DB_EXECUTE, e.message); throw new ServerError(SERR_DB_EXECUTE, e.message);
} }
} else { } else {
throw new ServerError(glConst.SERR_OBJECT_BAD_INTERFACE, sCheckResult); throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
} }
} else { } else {
throw new ServerError(SERR_DB_EXECUTE, "Нет подключения к БД"); throw new ServerError(SERR_DB_EXECUTE, "Нет подключения к БД");
@ -292,7 +296,7 @@ class DBConnector extends EventEmitter {
let res = await this.connector.setQueueState(setStateData); let res = await this.connector.setQueueState(setStateData);
//Валидируем полученный ответ //Валидируем полученный ответ
sCheckResult = validateObject(res, objQueueSchema.Queue, "Изменённое сообщение очереди обмена"); sCheckResult = validateObject(res, objQueueSchema.Queue, "Изменённое сообщение очереди обмена");
if (sCheckResult) throw new ServerError(glConst.SERR_OBJECT_BAD_INTERFACE, sCheckResult); if (sCheckResult) throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
//Вернём измененную запись //Вернём измененную запись
return res; return res;
} catch (e) { } catch (e) {
@ -300,7 +304,7 @@ class DBConnector extends EventEmitter {
else throw new ServerError(SERR_DB_EXECUTE, e.message); else throw new ServerError(SERR_DB_EXECUTE, e.message);
} }
} else { } else {
throw new ServerError(glConst.SERR_OBJECT_BAD_INTERFACE, sCheckResult); throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
} }
} else { } else {
throw new ServerError(SERR_DB_EXECUTE, "Нет подключения к БД"); throw new ServerError(SERR_DB_EXECUTE, "Нет подключения к БД");

View File

@ -9,7 +9,10 @@
const _ = require("lodash"); //Работа с массивами и коллекциями const _ = require("lodash"); //Работа с массивами и коллекциями
const EventEmitter = require("events"); //Обработчик пользовательских событий const EventEmitter = require("events"); //Обработчик пользовательских событий
const { checkObject } = require("../core/utils"); //Вспомогательные функции const { ServerError } = require("./server_errors"); //Типовая ошибка
const { SERR_OBJECT_BAD_INTERFACE } = require("./constants"); //Общесистемные константы
const { validateObject } = require("../core/utils"); //Вспомогательные функции
const prmsOutQueueSchema = require("../models/prms_out_queue"); //Схемы валидации параметров функций класса
//-------------------------- //--------------------------
// Глобальные идентификаторы // Глобальные идентификаторы
@ -24,14 +27,12 @@ const SEVT_OUT_QUEUE_NEW = "OUT_QUEUE_NEW"; //Новое сообщение в
//Класс очереди сообщений //Класс очереди сообщений
class OutQueue extends EventEmitter { class OutQueue extends EventEmitter {
//конструктор класса //Конструктор класса
constructor(prms, dbConn, logger) { constructor(prms) {
//Создадим экземпляр родительского класса //Создадим экземпляр родительского класса
super(); super();
//Проверяем структуру переданного объекта с параметрами очереди //Проверяем структуру переданного объекта для подключения
let sCheckResult = checkObject(prms, { let sCheckResult = validateObject(prms, prmsOutQueueSchema.OutQueue, "Параметры конструктора класса OutQueue");
fields: [{ sName: "nPortionSize", bRequired: true }, { sName: "nCheckTimeout", bRequired: true }]
});
//Если структура объекта в норме //Если структура объекта в норме
if (!sCheckResult) { if (!sCheckResult) {
//Хранилище очереди сообщений //Хранилище очереди сообщений
@ -39,18 +40,15 @@ class OutQueue extends EventEmitter {
//Признак функционирования обработчика //Признак функционирования обработчика
this.bWorking = false; this.bWorking = false;
//Параметры очереди //Параметры очереди
_.extend(this, prms); this.outGoing = _.cloneDeep(prms.outGoing);
//Запомним подключение к БД //Запомним подключение к БД
this.dbConn = dbConn; this.dbConn = prms.dbConn;
//Запомним логгер //Запомним логгер
this.logger = logger; this.logger = prms.logger;
//Привяжем методы к указателю на себя для использования в обработчиках событий //Привяжем методы к указателю на себя для использования в обработчиках событий
this.outDetectingLoop = this.outDetectingLoop.bind(this); this.outDetectingLoop = this.outDetectingLoop.bind(this);
} else { } else {
throw new ServerError( throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
glConst.SERR_OBJECT_BAD_INTERFACE,
"Объект имеет недопустимый интерфейс: " + sCheckResult
);
} }
} }
//Добавление нового исходящего сообщения в очередь для отработки //Добавление нового исходящего сообщения в очередь для отработки
@ -58,7 +56,7 @@ class OutQueue extends EventEmitter {
//Cоздадим новый элемент очереди //Cоздадим новый элемент очереди
let tmp = {}; let tmp = {};
_.extend(tmp, message); _.extend(tmp, message);
//добавим его в очередь //Добавим его в очередь
this.queue.push(tmp); this.queue.push(tmp);
} }
//Уведомление о получении нового сообщения //Уведомление о получении нового сообщения
@ -71,13 +69,13 @@ class OutQueue extends EventEmitter {
if (this.bWorking) if (this.bWorking)
setTimeout(() => { setTimeout(() => {
this.outDetectingLoop(); this.outDetectingLoop();
}, this.nCheckTimeout); }, this.outGoing.nCheckTimeout);
} }
//Опрос очереди исходящих сообщений //Опрос очереди исходящих сообщений
async outDetectingLoop() { async outDetectingLoop() {
//Сходим на сервер за очередным исходящим сообщением //Сходим на сервер за очередным исходящим сообщением
try { try {
let outMsgs = await this.dbConn.getOutgoing({ nPortionSize: this.nPortionSize }); let outMsgs = await this.dbConn.getOutgoing({ nPortionSize: this.outGoing.nPortionSize });
if (Array.isArray(outMsgs) && outMsgs.length > 0) { if (Array.isArray(outMsgs) && outMsgs.length > 0) {
let logAll = outMsgs.map(async msg => { let logAll = outMsgs.map(async msg => {
await this.logger.info( await this.logger.info(

View File

@ -41,7 +41,7 @@ process.on("SIGINT", () => {
//Старутем //Старутем
appSrv appSrv
.init(cfg) .init({ config: cfg })
.then(r => { .then(r => {
appSrv appSrv
.run() .run()