forked from CITKParus/P8-ExchangeService
Compare commits
1 Commits
master
...
dependabot
Author | SHA1 | Date | |
---|---|---|---|
|
7380eb9066 |
69
config.js
69
config.js
@ -9,12 +9,10 @@
|
|||||||
|
|
||||||
//Общие параметры
|
//Общие параметры
|
||||||
let common = {
|
let common = {
|
||||||
//Наименование сервера приложений
|
|
||||||
sServerName: "",
|
|
||||||
//Версия сервера приложений
|
//Версия сервера приложений
|
||||||
sVersion: "8.5.6.1",
|
sVersion: "8.5.6.1",
|
||||||
//Релиз сервера приложений
|
//Релиз сервера приложений
|
||||||
sRelease: "2025.04.29",
|
sRelease: "2024.02.28",
|
||||||
//Таймаут останова сервера (мс)
|
//Таймаут останова сервера (мс)
|
||||||
nTerminateTimeout: 60000,
|
nTerminateTimeout: 60000,
|
||||||
//Контролировать версию Системы
|
//Контролировать версию Системы
|
||||||
@ -30,7 +28,7 @@ let dbConnect = {
|
|||||||
//Схема размещения используемых объектов БД
|
//Схема размещения используемых объектов БД
|
||||||
sSchema: "PARUS",
|
sSchema: "PARUS",
|
||||||
//Строка подключения к БД
|
//Строка подключения к БД
|
||||||
sConnectString: "",
|
sConnectString: "DEMOP_CITKSERV_WAN",
|
||||||
//Наименование сервера приложений в сессии БД
|
//Наименование сервера приложений в сессии БД
|
||||||
sSessionAppName: "PARUS$ExchangeServer",
|
sSessionAppName: "PARUS$ExchangeServer",
|
||||||
//Подключаемый модуль обслуживания БД (низкоуровневые функции работы с СУБД)
|
//Подключаемый модуль обслуживания БД (низкоуровневые функции работы с СУБД)
|
||||||
@ -42,9 +40,9 @@ let outGoing = {
|
|||||||
//Проверять SSL-сертификаты адресов отправки сообщений (самоподписанные сертификаты будут отвергнуты)
|
//Проверять SSL-сертификаты адресов отправки сообщений (самоподписанные сертификаты будут отвергнуты)
|
||||||
bValidateSSL: true,
|
bValidateSSL: true,
|
||||||
//Количество одновременно обрабатываемых исходящих сообщений
|
//Количество одновременно обрабатываемых исходящих сообщений
|
||||||
nMaxWorkers: 1,
|
nMaxWorkers: 3,
|
||||||
//Интервал проверки наличия исходящих сообщений (мс)
|
//Интервал проверки наличия исходящих сообщений (мс)
|
||||||
nCheckTimeout: 500,
|
nCheckTimeout: 1000,
|
||||||
//Минимальный размер пула подключений к БД для обработчика исходящих сообщений
|
//Минимальный размер пула подключений к БД для обработчика исходящих сообщений
|
||||||
nPoolMin: 4,
|
nPoolMin: 4,
|
||||||
//Максимальный размер пула подключений к БД для обработчика исходящих сообщений
|
//Максимальный размер пула подключений к БД для обработчика исходящих сообщений
|
||||||
@ -73,73 +71,22 @@ let inComing = {
|
|||||||
nPoolIncrement: 0
|
nPoolIncrement: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
//Параметры подключения к Kafka
|
|
||||||
const kafka = [
|
|
||||||
{
|
|
||||||
//Мнемокод сервиса обмена (пусто - использовать по умолчанию)
|
|
||||||
sService: "",
|
|
||||||
//ID клиента-отправителя
|
|
||||||
sClientIdSender: "Parus",
|
|
||||||
//ID клиента-получателя
|
|
||||||
sClientIdRecipient: "Parus",
|
|
||||||
//Группа получателя
|
|
||||||
sGroupId: "Parus",
|
|
||||||
//Время ожидания успешного подключения (мс)
|
|
||||||
nConnectionTimeout: 5000,
|
|
||||||
//Необходимость попытки переподключения при потере соединения
|
|
||||||
bRestartOnFailure: true,
|
|
||||||
//Время максимального ожидания между попытками переподключения (мс)
|
|
||||||
nMaxRetryTime: 20000,
|
|
||||||
//Время ожидания между попытками переподключения (мс)
|
|
||||||
nInitialRetryTime: 10000,
|
|
||||||
//Использовать аутентификацию по SSL-сертификату
|
|
||||||
bAuthSSL: false,
|
|
||||||
//Параметры аутентификации по SSL-сертификату
|
|
||||||
ssl: {
|
|
||||||
//Запрещать использование самоподписанных сертификатов (true - запретить, false - разрешить)
|
|
||||||
bRejectUnauthorized: true,
|
|
||||||
//Путь к корневому сертификату с информацией об удостоверяющем центре
|
|
||||||
sPathCa: "",
|
|
||||||
//Путь к закрытому ключу
|
|
||||||
sPathKey: "",
|
|
||||||
//Путь к сертификату
|
|
||||||
sPathCert: ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
//Параметры подключения к MQTT
|
|
||||||
const mqtt = [
|
|
||||||
{
|
|
||||||
//Мнемокод сервиса обмена (пусто - использовать по умолчанию)
|
|
||||||
sService: "",
|
|
||||||
//ID клиента-отправителя
|
|
||||||
sClientIdSender: "Parus",
|
|
||||||
//ID клиента-получателя (если равен sClientIdSender, то отправленные сообщения будут игнорироваться)
|
|
||||||
sClientIdRecipient: "ParusRecipient",
|
|
||||||
//Время ожидания успешного подключения (мс)
|
|
||||||
nConnectTimeout: 5000,
|
|
||||||
//Время ожидания между попытками переподключения (мс)
|
|
||||||
nReconnectPeriod: 10000
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
//Параметры отправки E-Mail уведомлений
|
//Параметры отправки E-Mail уведомлений
|
||||||
let mail = {
|
let mail = {
|
||||||
//Адреc сервера SMTP
|
//Адреc сервера SMTP
|
||||||
sHost: "",
|
sHost: "smtp.mail.ru",
|
||||||
//Порт сервера SMTP
|
//Порт сервера SMTP
|
||||||
nPort: 465,
|
nPort: 465,
|
||||||
//Использовать безопасное соединение SMTP (true - использование TLS/SSL, false - использование только в случае наличия STARTTLS)
|
//Использовать безопасное соединение SMTP (true - использование TLS/SSL, false - использование только в случае наличия STARTTLS)
|
||||||
bSecure: true,
|
bSecure: true,
|
||||||
//Имя пользователя SMTP-сервера
|
//Имя пользователя SMTP-сервера
|
||||||
sUser: "",
|
sUser: "appserver@citk-parus.ru",
|
||||||
//Пароль пользователя SMTP-сервера
|
//Пароль пользователя SMTP-сервера
|
||||||
sPass: "",
|
sPass: "",
|
||||||
//Запрещать использование самоподписанных сертификатов (true - запретить, false - разрешить)
|
//Запрещать использование самоподписанных сертификатов (true - запретить, false - разрешить)
|
||||||
bRejectUnauthorized: true,
|
bRejectUnauthorized: true,
|
||||||
//Наименование отправителя для исходящих сообщений
|
//Наименование отправителя для исходящих сообщений
|
||||||
sFrom: ""
|
sFrom: "'Сервис интеграции с WEB-API' <appserver@citk-parus.ru>"
|
||||||
};
|
};
|
||||||
|
|
||||||
//-----------------
|
//-----------------
|
||||||
@ -151,7 +98,5 @@ module.exports = {
|
|||||||
dbConnect,
|
dbConnect,
|
||||||
outGoing,
|
outGoing,
|
||||||
inComing,
|
inComing,
|
||||||
kafka,
|
|
||||||
mqtt,
|
|
||||||
mail
|
mail
|
||||||
};
|
};
|
||||||
|
102
config_default.js
Normal file
102
config_default.js
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
/*
|
||||||
|
Сервис интеграции ПП Парус 8 с WEB API
|
||||||
|
Конфигурация сервера приложений
|
||||||
|
*/
|
||||||
|
|
||||||
|
//------------
|
||||||
|
// Тело модуля
|
||||||
|
//------------
|
||||||
|
|
||||||
|
//Общие параметры
|
||||||
|
let common = {
|
||||||
|
//Версия сервера приложений
|
||||||
|
sVersion: "8.5.6.1",
|
||||||
|
//Релиз сервера приложений
|
||||||
|
sRelease: "2024.02.28",
|
||||||
|
//Таймаут останова сервера (мс)
|
||||||
|
nTerminateTimeout: 60000,
|
||||||
|
//Контролировать версию Системы
|
||||||
|
bControlSystemVersion: true
|
||||||
|
};
|
||||||
|
|
||||||
|
//Параметры подключения к БД
|
||||||
|
let dbConnect = {
|
||||||
|
//Пользователь БД
|
||||||
|
sUser: "exs",
|
||||||
|
//Пароль пользователя БД
|
||||||
|
sPassword: "exs",
|
||||||
|
//Схема размещения используемых объектов БД
|
||||||
|
sSchema: "PARUS",
|
||||||
|
//Строка подключения к БД
|
||||||
|
sConnectString: "",
|
||||||
|
//Наименование сервера приложений в сессии БД
|
||||||
|
sSessionAppName: "PARUS$ExchangeServer",
|
||||||
|
//Подключаемый модуль обслуживания БД (низкоуровневые функции работы с СУБД)
|
||||||
|
sConnectorModule: "parus_oracle_db.js"
|
||||||
|
};
|
||||||
|
|
||||||
|
//Параметры обработки очереди исходящих сообщений
|
||||||
|
let outGoing = {
|
||||||
|
//Проверять SSL-сертификаты адресов отправки сообщений (самоподписанные сертификаты будут отвергнуты)
|
||||||
|
bValidateSSL: true,
|
||||||
|
//Количество одновременно обрабатываемых исходящих сообщений
|
||||||
|
nMaxWorkers: 1,
|
||||||
|
//Интервал проверки наличия исходящих сообщений (мс)
|
||||||
|
nCheckTimeout: 500,
|
||||||
|
//Минимальный размер пула подключений к БД для обработчика исходящих сообщений
|
||||||
|
nPoolMin: 4,
|
||||||
|
//Максимальный размер пула подключений к БД для обработчика исходящих сообщений
|
||||||
|
nPoolMax: 4,
|
||||||
|
//Шаг инкремента подключений к БД в пуле обработчика исходящих сообщений
|
||||||
|
nPoolIncrement: 0,
|
||||||
|
//Глобальный адрес прокси-сервера
|
||||||
|
sProxy: null
|
||||||
|
};
|
||||||
|
|
||||||
|
//Параметры обработки очереди входящих сообщений
|
||||||
|
let inComing = {
|
||||||
|
//Порт сервера входящих сообщений
|
||||||
|
nPort: 8080,
|
||||||
|
//IP-адрес сервера приложений (0.0.0.0 - все доступные)
|
||||||
|
sHost: "0.0.0.0",
|
||||||
|
//Максимальный размер входящего сообщения (мб)
|
||||||
|
nMsgMaxSize: 10,
|
||||||
|
//Каталог размещения статических ресурсов
|
||||||
|
sStaticDir: "static",
|
||||||
|
//Минимальный размер пула подключений к БД для обработчика входящих сообщений
|
||||||
|
nPoolMin: 10,
|
||||||
|
//Максимальный размер пула подключений к БД для обработчика входящих сообщений
|
||||||
|
nPoolMax: 10,
|
||||||
|
//Шаг инкремента подключений к БД в пуле обработчика входящих сообщений
|
||||||
|
nPoolIncrement: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
//Параметры отправки E-Mail уведомлений
|
||||||
|
let mail = {
|
||||||
|
//Адреc сервера SMTP
|
||||||
|
sHost: "",
|
||||||
|
//Порт сервера SMTP
|
||||||
|
nPort: 465,
|
||||||
|
//Использовать безопасное соединение SMTP (true - использование TLS/SSL, false - использование только в случае наличия STARTTLS)
|
||||||
|
bSecure: true,
|
||||||
|
//Имя пользователя SMTP-сервера
|
||||||
|
sUser: "",
|
||||||
|
//Пароль пользователя SMTP-сервера
|
||||||
|
sPass: "",
|
||||||
|
//Запрещать использование самоподписанных сертификатов (true - запретить, false - разрешить)
|
||||||
|
bRejectUnauthorized: true,
|
||||||
|
//Наименование отправителя для исходящих сообщений
|
||||||
|
sFrom: ""
|
||||||
|
};
|
||||||
|
|
||||||
|
//-----------------
|
||||||
|
// Интерфейс модуля
|
||||||
|
//-----------------
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
common,
|
||||||
|
dbConnect,
|
||||||
|
outGoing,
|
||||||
|
inComing,
|
||||||
|
mail
|
||||||
|
};
|
23
core/app.js
23
core/app.js
@ -96,7 +96,7 @@ class ParusAppServer {
|
|||||||
//Запускаем обслуживание очереди входящих
|
//Запускаем обслуживание очереди входящих
|
||||||
await this.logger.info("Запуск обработчика очереди входящих сообщений...");
|
await this.logger.info("Запуск обработчика очереди входящих сообщений...");
|
||||||
try {
|
try {
|
||||||
await this.inQ.startProcessing({ services: this.services });
|
this.inQ.startProcessing({ services: this.services });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
await this.logger.error(`Ошибка запуска обработчика очереди входящих сообщений: ${makeErrorText(e)}`);
|
await this.logger.error(`Ошибка запуска обработчика очереди входящих сообщений: ${makeErrorText(e)}`);
|
||||||
await this.stop();
|
await this.stop();
|
||||||
@ -196,25 +196,20 @@ class ParusAppServer {
|
|||||||
//Если настройки верны - будем стартовать
|
//Если настройки верны - будем стартовать
|
||||||
if (!sCheckResult) {
|
if (!sCheckResult) {
|
||||||
//Протоколируем версию и релиз
|
//Протоколируем версию и релиз
|
||||||
await this.logger.info(`Версия сервера приложений: ${prms.config.common.sVersion}, релиз: ${prms.config.common.sRelease}`);
|
await this.logger.info(
|
||||||
|
`Версия сервера приложений: ${prms.config.common.sVersion}, релиз: ${prms.config.common.sRelease}`
|
||||||
|
);
|
||||||
//Создаём подключение к БД
|
//Создаём подключение к БД
|
||||||
this.dbConn = new db.DBConnector({
|
this.dbConn = new db.DBConnector({
|
||||||
connectSettings: {
|
connectSettings: {
|
||||||
...prms.config.dbConnect,
|
...prms.config.dbConnect,
|
||||||
exsSrv: {
|
|
||||||
sServerName: prms.config.common.sServerName,
|
|
||||||
sServerIP: `${prms.config.inComing.nPort};${
|
|
||||||
prms.config.inComing.sHost === "0.0.0.0" ? getIPs().join(";") : prms.config.inComing.sHost
|
|
||||||
}`
|
|
||||||
},
|
|
||||||
sRelease: prms.config.common.sRelease,
|
sRelease: prms.config.common.sRelease,
|
||||||
bControlSystemVersion: prms.config.common.bControlSystemVersion,
|
bControlSystemVersion: prms.config.common.bControlSystemVersion,
|
||||||
nPoolMin: prms.config.inComing.nPoolMin,
|
nPoolMin: prms.config.inComing.nPoolMin,
|
||||||
nPoolMax: prms.config.inComing.nPoolMax,
|
nPoolMax: prms.config.inComing.nPoolMax,
|
||||||
nPoolIncrement: prms.config.inComing.nPoolIncrement,
|
nPoolIncrement: prms.config.inComing.nPoolIncrement,
|
||||||
nMaxWorkers: prms.config.outGoing.nMaxWorkers
|
nMaxWorkers: prms.config.outGoing.nMaxWorkers
|
||||||
},
|
}
|
||||||
bServer: true
|
|
||||||
});
|
});
|
||||||
//Создаём модуль рассылки уведомлений
|
//Создаём модуль рассылки уведомлений
|
||||||
this.notifier = new ntf.Notifier({ logger: this.logger, mail: prms.config.mail });
|
this.notifier = new ntf.Notifier({ logger: this.logger, mail: prms.config.mail });
|
||||||
@ -224,9 +219,7 @@ class ParusAppServer {
|
|||||||
dbConn: this.dbConn,
|
dbConn: this.dbConn,
|
||||||
logger: this.logger,
|
logger: this.logger,
|
||||||
notifier: this.notifier,
|
notifier: this.notifier,
|
||||||
sProxy: prms.config.outGoing.sProxy,
|
sProxy: prms.config.outGoing.sProxy
|
||||||
kafka: prms.config.kafka,
|
|
||||||
mqtt: prms.config.mqtt
|
|
||||||
});
|
});
|
||||||
//Создаём обработчик очереди входящих
|
//Создаём обработчик очереди входящих
|
||||||
this.inQ = new iq.InQueue({
|
this.inQ = new iq.InQueue({
|
||||||
@ -234,9 +227,7 @@ class ParusAppServer {
|
|||||||
inComing: prms.config.inComing,
|
inComing: prms.config.inComing,
|
||||||
dbConn: this.dbConn,
|
dbConn: this.dbConn,
|
||||||
logger: this.logger,
|
logger: this.logger,
|
||||||
notifier: this.notifier,
|
notifier: this.notifier
|
||||||
kafka: prms.config.kafka,
|
|
||||||
mqtt: prms.config.mqtt
|
|
||||||
});
|
});
|
||||||
//Создаём контроллер доступности удалённых сервисов
|
//Создаём контроллер доступности удалённых сервисов
|
||||||
this.srvAvlCtrl = new sac.ServiceAvailableController({
|
this.srvAvlCtrl = new sac.ServiceAvailableController({
|
||||||
|
@ -19,7 +19,11 @@ const objServiceFunctionsSchema = require("../models/obj_service_functions"); //
|
|||||||
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("./constants"); //Глобальные константы
|
const {
|
||||||
|
SERR_MODULES_BAD_INTERFACE,
|
||||||
|
SERR_OBJECT_BAD_INTERFACE,
|
||||||
|
SERR_MODULES_NO_MODULE_SPECIFIED
|
||||||
|
} = require("./constants"); //Глобальные константы
|
||||||
|
|
||||||
//----------
|
//----------
|
||||||
// Константы
|
// Константы
|
||||||
@ -45,7 +49,11 @@ class DBConnector extends EventEmitter {
|
|||||||
//создадим экземпляр родительского класса
|
//создадим экземпляр родительского класса
|
||||||
super();
|
super();
|
||||||
//Проверяем структуру переданного объекта для подключения
|
//Проверяем структуру переданного объекта для подключения
|
||||||
let sCheckResult = validateObject(prms, prmsDBConnectorSchema.DBConnector, "Параметры конструктора класса DBConnector");
|
let sCheckResult = validateObject(
|
||||||
|
prms,
|
||||||
|
prmsDBConnectorSchema.DBConnector,
|
||||||
|
"Параметры конструктора класса DBConnector"
|
||||||
|
);
|
||||||
//Если структура объекта в норме
|
//Если структура объекта в норме
|
||||||
if (!sCheckResult) {
|
if (!sCheckResult) {
|
||||||
//Проверяем наличие модуля для работы с БД в настройках подключения
|
//Проверяем наличие модуля для работы с БД в настройках подключения
|
||||||
@ -73,28 +81,16 @@ class DBConnector extends EventEmitter {
|
|||||||
//Инициализируем остальные свойства
|
//Инициализируем остальные свойства
|
||||||
this.connection = null;
|
this.connection = null;
|
||||||
this.bConnected = false;
|
this.bConnected = false;
|
||||||
this.nExsSrv = null;
|
|
||||||
this.bServer = prms.bServer === true ? true : false;
|
|
||||||
} else {
|
} else {
|
||||||
throw new ServerError(SERR_MODULES_NO_MODULE_SPECIFIED, "Не указано имя подключаемого модуля-коннектора!");
|
throw new ServerError(
|
||||||
|
SERR_MODULES_NO_MODULE_SPECIFIED,
|
||||||
|
"Не указано имя подключаемого модуля-коннектора!"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
|
throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Исполнение хранимого объекта БД
|
|
||||||
async executeStored(prms) {
|
|
||||||
//Работаем только при наличии подключения
|
|
||||||
if (this.bConnected) {
|
|
||||||
return await this.connector.executeStored({
|
|
||||||
connection: this.connection,
|
|
||||||
sName: prms.sName,
|
|
||||||
inPrms: prms.inPrms,
|
|
||||||
outPrms: prms.outPrms,
|
|
||||||
isFunction: prms.isFunction
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Подключиться к БД
|
//Подключиться к БД
|
||||||
async connect() {
|
async connect() {
|
||||||
//Подключаемся только если ещё не подключены
|
//Подключаемся только если ещё не подключены
|
||||||
@ -102,28 +98,6 @@ class DBConnector extends EventEmitter {
|
|||||||
try {
|
try {
|
||||||
//Подключаемся
|
//Подключаемся
|
||||||
this.connection = await this.connector.connect(this.connectSettings);
|
this.connection = await this.connector.connect(this.connectSettings);
|
||||||
//Если это запуск сервиса интеграции
|
|
||||||
if (this.bServer) {
|
|
||||||
//Проверяем общие условия запуска
|
|
||||||
await this.connector.checkAppStart({
|
|
||||||
bControlSystemVersion: this.connectSettings.bControlSystemVersion,
|
|
||||||
sRelease: this.connectSettings.sRelease,
|
|
||||||
nWorkers: this.connectSettings.nMaxWorkers,
|
|
||||||
sServerName: this.connectSettings.exsSrv.sServerName,
|
|
||||||
sSessionAppName: this.connectSettings.sSessionAppName,
|
|
||||||
connection: this.connection
|
|
||||||
});
|
|
||||||
//Если сервис интеграции разделяется на сервера
|
|
||||||
if (this.connectSettings.exsSrv.sServerName) {
|
|
||||||
//Инициализируем информацию о сервере интеграции
|
|
||||||
this.nExsSrv = await this.connector.initServer({
|
|
||||||
sServerName: this.connectSettings.exsSrv.sServerName,
|
|
||||||
sServerIP: this.connectSettings.exsSrv.sServerIP,
|
|
||||||
nMaxWorkers: this.connectSettings.nMaxWorkers,
|
|
||||||
connection: this.connection
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Выставим внутренний флаг подключения
|
//Выставим внутренний флаг подключения
|
||||||
this.bConnected = true;
|
this.bConnected = true;
|
||||||
//Расскажем всем, что подключились
|
//Расскажем всем, что подключились
|
||||||
@ -140,11 +114,6 @@ class DBConnector extends EventEmitter {
|
|||||||
//Смысл отключаться есть только когда мы подключены, в противном случае - зачем тратить время
|
//Смысл отключаться есть только когда мы подключены, в противном случае - зачем тратить время
|
||||||
if (this.bConnected) {
|
if (this.bConnected) {
|
||||||
try {
|
try {
|
||||||
//Если указана информация о сервере и это закрытие сервиса интеграции
|
|
||||||
if (this.nExsSrv && this.bServer) {
|
|
||||||
//Очищаем информацию о сервере
|
|
||||||
await this.connector.clearServer({ nExsSrv: this.nExsSrv, connection: this.connection });
|
|
||||||
}
|
|
||||||
//Отключаемся
|
//Отключаемся
|
||||||
await this.connector.disconnect({ connection: this.connection });
|
await this.connector.disconnect({ connection: this.connection });
|
||||||
//Забываем подключение и удаляем флаги подключенности
|
//Забываем подключение и удаляем флаги подключенности
|
||||||
@ -165,7 +134,7 @@ class DBConnector extends EventEmitter {
|
|||||||
if (this.bConnected) {
|
if (this.bConnected) {
|
||||||
try {
|
try {
|
||||||
//Забираем список сервисов и декорируем его заготовками под список функций
|
//Забираем список сервисов и декорируем его заготовками под список функций
|
||||||
let srvs = await this.connector.getServices({ connection: this.connection, nExsSrv: this.nExsSrv });
|
let srvs = await this.connector.getServices({ connection: this.connection });
|
||||||
srvs.forEach(s => {
|
srvs.forEach(s => {
|
||||||
s.functions = [];
|
s.functions = [];
|
||||||
});
|
});
|
||||||
@ -206,7 +175,11 @@ class DBConnector extends EventEmitter {
|
|||||||
//Работаем только при наличии подключения
|
//Работаем только при наличии подключения
|
||||||
if (this.bConnected) {
|
if (this.bConnected) {
|
||||||
//Проверяем структуру переданного объекта с параметрами для считывания функций сервиса
|
//Проверяем структуру переданного объекта с параметрами для считывания функций сервиса
|
||||||
let sCheckResult = validateObject(prms, prmsDBConnectorSchema.getServiceFunctions, "Параметры функции считывания функций сервиса");
|
let sCheckResult = validateObject(
|
||||||
|
prms,
|
||||||
|
prmsDBConnectorSchema.getServiceFunctions,
|
||||||
|
"Параметры функции считывания функций сервиса"
|
||||||
|
);
|
||||||
//Если структура объекта в норме
|
//Если структура объекта в норме
|
||||||
if (!sCheckResult) {
|
if (!sCheckResult) {
|
||||||
try {
|
try {
|
||||||
@ -216,7 +189,11 @@ class DBConnector extends EventEmitter {
|
|||||||
//И выполним считывание функций сервиса
|
//И выполним считывание функций сервиса
|
||||||
let res = await this.connector.getServiceFunctions(getServiceFunctionsData);
|
let res = await this.connector.getServiceFunctions(getServiceFunctionsData);
|
||||||
//Валидируем полученный ответ
|
//Валидируем полученный ответ
|
||||||
sCheckResult = validateObject({ functions: res }, objServiceFunctionsSchema.ServiceFunctions, "Список функций сервиса");
|
sCheckResult = validateObject(
|
||||||
|
{ functions: res },
|
||||||
|
objServiceFunctionsSchema.ServiceFunctions,
|
||||||
|
"Список функций сервиса"
|
||||||
|
);
|
||||||
if (sCheckResult) throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
|
if (sCheckResult) throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
|
||||||
//Успешно - отдаём список функций сервиса
|
//Успешно - отдаём список функций сервиса
|
||||||
return res;
|
return res;
|
||||||
@ -235,7 +212,11 @@ class DBConnector extends EventEmitter {
|
|||||||
//Работаем только при наличии подключения
|
//Работаем только при наличии подключения
|
||||||
if (this.bConnected) {
|
if (this.bConnected) {
|
||||||
//Проверяем структуру переданного объекта с параметрами для получения контекста сервиса
|
//Проверяем структуру переданного объекта с параметрами для получения контекста сервиса
|
||||||
let sCheckResult = validateObject(prms, prmsDBConnectorSchema.getServiceContext, "Параметры функции считывания контекста сервиса");
|
let sCheckResult = validateObject(
|
||||||
|
prms,
|
||||||
|
prmsDBConnectorSchema.getServiceContext,
|
||||||
|
"Параметры функции считывания контекста сервиса"
|
||||||
|
);
|
||||||
//Если структура объекта в норме
|
//Если структура объекта в норме
|
||||||
if (!sCheckResult) {
|
if (!sCheckResult) {
|
||||||
try {
|
try {
|
||||||
@ -264,7 +245,11 @@ class DBConnector extends EventEmitter {
|
|||||||
//Работаем только при наличии подключения
|
//Работаем только при наличии подключения
|
||||||
if (this.bConnected) {
|
if (this.bConnected) {
|
||||||
//Проверяем структуру переданного объекта с параметрами для установки контекста сервиса
|
//Проверяем структуру переданного объекта с параметрами для установки контекста сервиса
|
||||||
let sCheckResult = validateObject(prms, prmsDBConnectorSchema.setServiceContext, "Параметры функции установки контекста сервиса");
|
let sCheckResult = validateObject(
|
||||||
|
prms,
|
||||||
|
prmsDBConnectorSchema.setServiceContext,
|
||||||
|
"Параметры функции установки контекста сервиса"
|
||||||
|
);
|
||||||
//Если структура объекта в норме
|
//Если структура объекта в норме
|
||||||
if (!sCheckResult) {
|
if (!sCheckResult) {
|
||||||
try {
|
try {
|
||||||
@ -290,7 +275,11 @@ class DBConnector extends EventEmitter {
|
|||||||
//Работаем только при наличии подключения
|
//Работаем только при наличии подключения
|
||||||
if (this.bConnected) {
|
if (this.bConnected) {
|
||||||
//Проверяем структуру переданного объекта с параметрами для очистки контекста сервиса
|
//Проверяем структуру переданного объекта с параметрами для очистки контекста сервиса
|
||||||
let sCheckResult = validateObject(prms, prmsDBConnectorSchema.clearServiceContext, "Параметры функции очистки контекста сервиса");
|
let sCheckResult = validateObject(
|
||||||
|
prms,
|
||||||
|
prmsDBConnectorSchema.clearServiceContext,
|
||||||
|
"Параметры функции очистки контекста сервиса"
|
||||||
|
);
|
||||||
//Если структура объекта в норме
|
//Если структура объекта в норме
|
||||||
if (!sCheckResult) {
|
if (!sCheckResult) {
|
||||||
try {
|
try {
|
||||||
@ -316,7 +305,11 @@ class DBConnector extends EventEmitter {
|
|||||||
//Работаем только при наличии подключения
|
//Работаем только при наличии подключения
|
||||||
if (this.bConnected) {
|
if (this.bConnected) {
|
||||||
//Проверяем структуру переданного объекта с параметрами для проверки аутентифицированности сервиса
|
//Проверяем структуру переданного объекта с параметрами для проверки аутентифицированности сервиса
|
||||||
let sCheckResult = validateObject(prms, prmsDBConnectorSchema.isServiceAuth, "Параметры функции проверки аутентифицированности сервиса");
|
let sCheckResult = validateObject(
|
||||||
|
prms,
|
||||||
|
prmsDBConnectorSchema.isServiceAuth,
|
||||||
|
"Параметры функции проверки аутентифицированности сервиса"
|
||||||
|
);
|
||||||
//Если структура объекта в норме
|
//Если структура объекта в норме
|
||||||
if (!sCheckResult) {
|
if (!sCheckResult) {
|
||||||
try {
|
try {
|
||||||
@ -327,7 +320,10 @@ class DBConnector extends EventEmitter {
|
|||||||
let res = await this.connector.isServiceAuth(isServiceAuthData);
|
let res = await this.connector.isServiceAuth(isServiceAuthData);
|
||||||
//Валидируем результат
|
//Валидируем результат
|
||||||
if (![objServiceSchema.NIS_AUTH_NO, objServiceSchema.NIS_AUTH_YES].includes(res))
|
if (![objServiceSchema.NIS_AUTH_NO, objServiceSchema.NIS_AUTH_YES].includes(res))
|
||||||
throw new ServerError(SERR_OBJECT_BAD_INTERFACE, "Неожиданный ответ функции проверки аутентифицированности сервиса");
|
throw new ServerError(
|
||||||
|
SERR_OBJECT_BAD_INTERFACE,
|
||||||
|
"Неожиданный ответ функции проверки аутентифицированности сервиса"
|
||||||
|
);
|
||||||
//Успешно - возвращаем то, что вернула функция проверки
|
//Успешно - возвращаем то, что вернула функция проверки
|
||||||
return res;
|
return res;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -389,7 +385,11 @@ class DBConnector extends EventEmitter {
|
|||||||
//И выполним получение информации о просроченных сообщениях
|
//И выполним получение информации о просроченных сообщениях
|
||||||
let res = await this.connector.getServiceExpiredQueueInfo(getServiceExpiredQueueInfoData);
|
let res = await this.connector.getServiceExpiredQueueInfo(getServiceExpiredQueueInfoData);
|
||||||
//Валидируем полученный ответ
|
//Валидируем полученный ответ
|
||||||
sCheckResult = validateObject(res, objServiceSchema.ServiceExpiredQueueInfo, "Сведения о просроченных сообщениях обмена сервиса");
|
sCheckResult = validateObject(
|
||||||
|
res,
|
||||||
|
objServiceSchema.ServiceExpiredQueueInfo,
|
||||||
|
"Сведения о просроченных сообщениях обмена сервиса"
|
||||||
|
);
|
||||||
if (sCheckResult) throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
|
if (sCheckResult) throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
|
||||||
//Успешно - отдаём полученные сведения о просроченных сообщениях
|
//Успешно - отдаём полученные сведения о просроченных сообщениях
|
||||||
return res;
|
return res;
|
||||||
@ -408,14 +408,17 @@ class DBConnector extends EventEmitter {
|
|||||||
//Работаем только при наличии подключения
|
//Работаем только при наличии подключения
|
||||||
if (this.bConnected) {
|
if (this.bConnected) {
|
||||||
//Проверяем структуру переданного объекта с параметрами для записи в журнал
|
//Проверяем структуру переданного объекта с параметрами для записи в журнал
|
||||||
let sCheckResult = validateObject(prms, prmsDBConnectorSchema.putLog, "Параметры функции записи в журнал работы");
|
let sCheckResult = validateObject(
|
||||||
|
prms,
|
||||||
|
prmsDBConnectorSchema.putLog,
|
||||||
|
"Параметры функции записи в журнал работы"
|
||||||
|
);
|
||||||
//Если структура объекта в норме
|
//Если структура объекта в норме
|
||||||
if (!sCheckResult) {
|
if (!sCheckResult) {
|
||||||
try {
|
try {
|
||||||
//Подготовим параметры для передачи в БД
|
//Подготовим параметры для передачи в БД
|
||||||
let logData = _.cloneDeep(prms);
|
let logData = _.cloneDeep(prms);
|
||||||
logData.connection = this.connection;
|
logData.connection = this.connection;
|
||||||
logData.nExsSrv = this.nExsSrv;
|
|
||||||
//И выполним запись в журнал
|
//И выполним запись в журнал
|
||||||
let res = await this.connector.log(logData);
|
let res = await this.connector.log(logData);
|
||||||
//Валидируем полученный ответ
|
//Валидируем полученный ответ
|
||||||
@ -485,7 +488,11 @@ class DBConnector extends EventEmitter {
|
|||||||
async getQueue(prms) {
|
async getQueue(prms) {
|
||||||
if (this.bConnected) {
|
if (this.bConnected) {
|
||||||
//Проверяем структуру переданных параметров
|
//Проверяем структуру переданных параметров
|
||||||
let sCheckResult = validateObject(prms, prmsDBConnectorSchema.getQueue, "Параметры функции считывания записи очереди обмена");
|
let sCheckResult = validateObject(
|
||||||
|
prms,
|
||||||
|
prmsDBConnectorSchema.getQueue,
|
||||||
|
"Параметры функции считывания записи очереди обмена"
|
||||||
|
);
|
||||||
//Если структура объекта в норме
|
//Если структура объекта в норме
|
||||||
if (!sCheckResult) {
|
if (!sCheckResult) {
|
||||||
//Подготовим параметры
|
//Подготовим параметры
|
||||||
@ -514,7 +521,11 @@ class DBConnector extends EventEmitter {
|
|||||||
async putQueue(prms) {
|
async putQueue(prms) {
|
||||||
if (this.bConnected) {
|
if (this.bConnected) {
|
||||||
//Проверяем структуру переданных параметров
|
//Проверяем структуру переданных параметров
|
||||||
let sCheckResult = validateObject(prms, prmsDBConnectorSchema.putQueue, "Параметры функции добавления позиции очереди");
|
let sCheckResult = validateObject(
|
||||||
|
prms,
|
||||||
|
prmsDBConnectorSchema.putQueue,
|
||||||
|
"Параметры функции добавления позиции очереди"
|
||||||
|
);
|
||||||
//Если структура объекта в норме
|
//Если структура объекта в норме
|
||||||
if (!sCheckResult) {
|
if (!sCheckResult) {
|
||||||
//Подготовим параметры
|
//Подготовим параметры
|
||||||
@ -544,18 +555,25 @@ class DBConnector extends EventEmitter {
|
|||||||
async getOutgoing(prms) {
|
async getOutgoing(prms) {
|
||||||
if (this.bConnected) {
|
if (this.bConnected) {
|
||||||
//Проверяем структуру переданного объекта с параметрами считывания очереди
|
//Проверяем структуру переданного объекта с параметрами считывания очереди
|
||||||
let sCheckResult = validateObject(prms, prmsDBConnectorSchema.getOutgoing, "Параметры функции считывания очереди");
|
let sCheckResult = validateObject(
|
||||||
|
prms,
|
||||||
|
prmsDBConnectorSchema.getOutgoing,
|
||||||
|
"Параметры функции считывания очереди"
|
||||||
|
);
|
||||||
//Если структура объекта в норме
|
//Если структура объекта в норме
|
||||||
if (!sCheckResult) {
|
if (!sCheckResult) {
|
||||||
try {
|
try {
|
||||||
//Подготовим параметры для передачи в БД
|
//Подготовим параметры для передачи в БД
|
||||||
let getQueueOutgoingData = _.cloneDeep(prms);
|
let getQueueOutgoingData = _.cloneDeep(prms);
|
||||||
getQueueOutgoingData.connection = this.connection;
|
getQueueOutgoingData.connection = this.connection;
|
||||||
getQueueOutgoingData.nExsSrv = this.nExsSrv;
|
|
||||||
//Выполняем считывание из БД
|
//Выполняем считывание из БД
|
||||||
let res = await this.connector.getQueueOutgoing(getQueueOutgoingData);
|
let res = await this.connector.getQueueOutgoing(getQueueOutgoingData);
|
||||||
//Валидируем полученный ответ
|
//Валидируем полученный ответ
|
||||||
sCheckResult = validateObject({ queues: res }, objQueuesSchema.Queues, "Список сообщений очереди обмена");
|
sCheckResult = validateObject(
|
||||||
|
{ queues: res },
|
||||||
|
objQueuesSchema.Queues,
|
||||||
|
"Список сообщений очереди обмена"
|
||||||
|
);
|
||||||
if (sCheckResult) throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
|
if (sCheckResult) throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
|
||||||
//Вернём сообщения очереди обмена
|
//Вернём сообщения очереди обмена
|
||||||
return res;
|
return res;
|
||||||
@ -573,7 +591,11 @@ class DBConnector extends EventEmitter {
|
|||||||
async setQueueState(prms) {
|
async setQueueState(prms) {
|
||||||
if (this.bConnected) {
|
if (this.bConnected) {
|
||||||
//Проверяем структуру переданных параметров
|
//Проверяем структуру переданных параметров
|
||||||
let sCheckResult = validateObject(prms, prmsDBConnectorSchema.setQueueState, "Параметры функции установки состояния позиции очереди");
|
let sCheckResult = validateObject(
|
||||||
|
prms,
|
||||||
|
prmsDBConnectorSchema.setQueueState,
|
||||||
|
"Параметры функции установки состояния позиции очереди"
|
||||||
|
);
|
||||||
//Если структура объекта в норме
|
//Если структура объекта в норме
|
||||||
if (!sCheckResult) {
|
if (!sCheckResult) {
|
||||||
//Подготовим параметры
|
//Подготовим параметры
|
||||||
@ -716,7 +738,11 @@ class DBConnector extends EventEmitter {
|
|||||||
try {
|
try {
|
||||||
let res = await this.connector.getQueueResp(getQueueRespData);
|
let res = await this.connector.getQueueResp(getQueueRespData);
|
||||||
//Валидируем полученный ответ
|
//Валидируем полученный ответ
|
||||||
sCheckResult = validateObject(res, objQueueSchema.QueueResp, "Данные ответа сообщения очереди обмена");
|
sCheckResult = validateObject(
|
||||||
|
res,
|
||||||
|
objQueueSchema.QueueResp,
|
||||||
|
"Данные ответа сообщения очереди обмена"
|
||||||
|
);
|
||||||
if (sCheckResult) throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
|
if (sCheckResult) throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
|
||||||
//Вернём данные ответа на сообщение
|
//Вернём данные ответа на сообщение
|
||||||
return res;
|
return res;
|
||||||
@ -840,7 +866,11 @@ class DBConnector extends EventEmitter {
|
|||||||
//И выполним обработчик со стороны БД
|
//И выполним обработчик со стороны БД
|
||||||
let res = await this.connector.execQueuePrc(execQueuePrcData);
|
let res = await this.connector.execQueuePrc(execQueuePrcData);
|
||||||
//Валидируем полученный ответ
|
//Валидируем полученный ответ
|
||||||
sCheckResult = validateObject(res, objQueueSchema.QueuePrcResult, "Результат обработки очереди обмена");
|
sCheckResult = validateObject(
|
||||||
|
res,
|
||||||
|
objQueueSchema.QueuePrcResult,
|
||||||
|
"Результат обработки очереди обмена"
|
||||||
|
);
|
||||||
if (sCheckResult) throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
|
if (sCheckResult) throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
|
||||||
//Вернём результат обработки
|
//Вернём результат обработки
|
||||||
return res;
|
return res;
|
||||||
|
283
core/in_queue.js
283
core/in_queue.js
@ -13,20 +13,7 @@ const express = require("express"); //WEB-сервер Express
|
|||||||
const cors = require("cors"); //Управление заголовками безопасности для WEB-сервера Express
|
const cors = require("cors"); //Управление заголовками безопасности для WEB-сервера Express
|
||||||
const bodyParser = require("body-parser"); //Модуль для Express (разбор тела входящего запроса)
|
const bodyParser = require("body-parser"); //Модуль для Express (разбор тела входящего запроса)
|
||||||
const { ServerError } = require("./server_errors"); //Типовая ошибка
|
const { ServerError } = require("./server_errors"); //Типовая ошибка
|
||||||
const {
|
const { makeErrorText, validateObject, buildURL, getAppSrvFunction, buildOptionsXML, parseOptionsXML, deepMerge } = require("./utils"); //Вспомогательные функции
|
||||||
makeErrorText,
|
|
||||||
validateObject,
|
|
||||||
buildURL,
|
|
||||||
getAppSrvFunction,
|
|
||||||
buildOptionsXML,
|
|
||||||
parseOptionsXML,
|
|
||||||
deepMerge,
|
|
||||||
deepCopyObject,
|
|
||||||
isUndefined,
|
|
||||||
getKafkaConnectionSettings,
|
|
||||||
getMQTTConnectionSettings,
|
|
||||||
getURLProtocol
|
|
||||||
} = require("./utils"); //Вспомогательные функции
|
|
||||||
const { NINC_EXEC_CNT_YES, NIS_ORIGINAL_NO, NIS_ORIGINAL_YES } = require("../models/prms_db_connector"); //Схемы валидации параметров функций модуля взаимодействия с БД
|
const { NINC_EXEC_CNT_YES, NIS_ORIGINAL_NO, NIS_ORIGINAL_YES } = require("../models/prms_db_connector"); //Схемы валидации параметров функций модуля взаимодействия с БД
|
||||||
const objInQueueSchema = require("../models/obj_in_queue"); //Схема валидации сообщений обмена с бработчиком очереди входящих сообщений
|
const objInQueueSchema = require("../models/obj_in_queue"); //Схема валидации сообщений обмена с бработчиком очереди входящих сообщений
|
||||||
const objServiceSchema = require("../models/obj_service"); //Схемы валидации сервиса
|
const objServiceSchema = require("../models/obj_service"); //Схемы валидации сервиса
|
||||||
@ -41,8 +28,6 @@ const {
|
|||||||
SERR_DB_SERVER,
|
SERR_DB_SERVER,
|
||||||
SERR_UNAUTH
|
SERR_UNAUTH
|
||||||
} = require("./constants"); //Общесистемные константы
|
} = require("./constants"); //Общесистемные константы
|
||||||
const { subscribeMQTT } = require("./mqtt_connector"); //Модуль для работы с MQTT
|
|
||||||
const { subscribeKafka } = require("./kafka_connector"); //Модуль для работы с Kafka
|
|
||||||
|
|
||||||
//--------------------------
|
//--------------------------
|
||||||
// Глобальные идентификаторы
|
// Глобальные идентификаторы
|
||||||
@ -86,13 +71,6 @@ class InQueue extends EventEmitter {
|
|||||||
this.webApp.options("*", cors());
|
this.webApp.options("*", cors());
|
||||||
//WEB-сервер
|
//WEB-сервер
|
||||||
this.srv = null;
|
this.srv = null;
|
||||||
//Параметры подключения к Kafka
|
|
||||||
this.kafka = prms.kafka;
|
|
||||||
//Параметры подключения к MQTT
|
|
||||||
this.mqtt = prms.mqtt;
|
|
||||||
//Внешние подключения
|
|
||||||
this.kafkaConnections = [];
|
|
||||||
this.mqttConnections = [];
|
|
||||||
} else {
|
} else {
|
||||||
throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
|
throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
|
||||||
}
|
}
|
||||||
@ -107,7 +85,7 @@ class InQueue extends EventEmitter {
|
|||||||
//Оповестим подписчиков об останове
|
//Оповестим подписчиков об останове
|
||||||
this.emit(SEVT_IN_QUEUE_STOPPED);
|
this.emit(SEVT_IN_QUEUE_STOPPED);
|
||||||
}
|
}
|
||||||
//Обработка сообщения HTTP/HTTPS
|
//Обработка сообщения
|
||||||
async processMessage(prms) {
|
async processMessage(prms) {
|
||||||
//Проверяем структуру переданного объекта для обработки
|
//Проверяем структуру переданного объекта для обработки
|
||||||
let sCheckResult = validateObject(prms, prmsInQueueSchema.processMessage, "Параметры функции обработки входящего сообщения");
|
let sCheckResult = validateObject(prms, prmsInQueueSchema.processMessage, "Параметры функции обработки входящего сообщения");
|
||||||
@ -382,153 +360,8 @@ class InQueue extends EventEmitter {
|
|||||||
throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
|
throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Обработка MQ сообщения
|
|
||||||
async processMQMessage({ message, service, fn, sProtocol }) {
|
|
||||||
//Буфер для сообщения очереди
|
|
||||||
let q = null;
|
|
||||||
try {
|
|
||||||
//Префикс протокола
|
|
||||||
let sProtocolPrefix = sProtocol === objServiceSchema.SPROTOCOL_KAFKA ? "Kafka" : "MQTT";
|
|
||||||
//Тело сообщения
|
|
||||||
let blMsg = null;
|
|
||||||
//Параметры сообщения
|
|
||||||
let options = {};
|
|
||||||
//Флаг прекращения обработки сообщения
|
|
||||||
let bStopPropagation = false;
|
|
||||||
//Получим тело сообщения
|
|
||||||
blMsg = message.value ? message.value : null;
|
|
||||||
//Определимся с параметрами сообщения полученными от внешней системы
|
|
||||||
options = {
|
|
||||||
method: fn.sFnPrmsType,
|
|
||||||
headers: message.headers
|
|
||||||
};
|
|
||||||
//Кладём сообщение в очередь
|
|
||||||
q = await this.dbConn.putQueue({
|
|
||||||
nServiceFnId: fn.nId,
|
|
||||||
sOptions: buildOptionsXML({ options }),
|
|
||||||
blMsg
|
|
||||||
});
|
|
||||||
//Скажем что пришло новое входящее сообщение
|
|
||||||
await this.logger.info(
|
|
||||||
`Новое входящее ${sProtocolPrefix}-сообщение для функции ${fn.sCode} (${buildURL({
|
|
||||||
sSrvRoot: service.sSrvRoot,
|
|
||||||
sFnURL: fn.sFnURL
|
|
||||||
})})`,
|
|
||||||
{ nQueueId: q.nId }
|
|
||||||
);
|
|
||||||
//Выполняем обработчик "До" (если он есть)
|
|
||||||
if (fn.sAppSrvBefore) {
|
|
||||||
//Выставим статус сообщению очереди - исполняется сервером приложений
|
|
||||||
q = await this.dbConn.setQueueState({
|
|
||||||
nQueueId: q.nId,
|
|
||||||
nExecState: objQueueSchema.NQUEUE_EXEC_STATE_APP
|
|
||||||
});
|
|
||||||
//Выполняем
|
|
||||||
const fnBefore = getAppSrvFunction(fn.sAppSrvBefore);
|
|
||||||
let resBefore = null;
|
|
||||||
try {
|
|
||||||
let resBeforePrms = { service: service, function: fn };
|
|
||||||
resBeforePrms.queue = deepCopyObject(q);
|
|
||||||
resBeforePrms.queue.blMsg = blMsg;
|
|
||||||
resBeforePrms.options = deepCopyObject(options);
|
|
||||||
resBeforePrms.dbConn = this.dbConn;
|
|
||||||
resBeforePrms.notifier = this.notifier;
|
|
||||||
resBefore = await fnBefore(resBeforePrms);
|
|
||||||
} catch (e) {
|
|
||||||
throw new ServerError(SERR_APP_SERVER_BEFORE, e.message);
|
|
||||||
}
|
|
||||||
//Проверяем структуру ответа функции предобработки
|
|
||||||
if (resBefore) {
|
|
||||||
let sCheckResult = validateObject(
|
|
||||||
resBefore,
|
|
||||||
objInQueueSchema.InQueueProcessorFnBefore,
|
|
||||||
"Результат функции предобработки входящего сообщения"
|
|
||||||
);
|
|
||||||
//Если структура ответа в норме
|
|
||||||
if (!sCheckResult) {
|
|
||||||
//Выставим статус сообщению очереди - исполнено сервером приложений
|
|
||||||
q = await this.dbConn.setQueueState({
|
|
||||||
nQueueId: q.nId,
|
|
||||||
nExecState: objQueueSchema.NQUEUE_EXEC_STATE_APP_OK
|
|
||||||
});
|
|
||||||
//Фиксируем результат исполнения "До" - обработанный запрос внешней системы
|
|
||||||
if (!isUndefined(resBefore.blMsg)) {
|
|
||||||
blMsg = resBefore.blMsg;
|
|
||||||
q = await this.dbConn.setQueueMsg({
|
|
||||||
nQueueId: q.nId,
|
|
||||||
blMsg
|
|
||||||
});
|
|
||||||
}
|
|
||||||
//Фиксируем результат исполнения "До" - флаг прекращения дальнейшей обработки сообщения - если он поднят, то дальше обработку сообщения прекращаем
|
|
||||||
if (!isUndefined(resBefore.bStopPropagation) && resBefore.bStopPropagation === true) bStopPropagation = true;
|
|
||||||
} else {
|
|
||||||
//Или расскажем об ошибке
|
|
||||||
throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Вызываем обработчик со стороны БД (если он есть)
|
|
||||||
if (bStopPropagation === false && fn.sPrcResp) {
|
|
||||||
//Фиксируем начало исполнения сервером БД - в статусе сообщения
|
|
||||||
q = await this.dbConn.setQueueState({
|
|
||||||
nQueueId: q.nId,
|
|
||||||
nExecState: objQueueSchema.NQUEUE_EXEC_STATE_DB
|
|
||||||
});
|
|
||||||
//Вызов обработчика БД
|
|
||||||
let prcRes = await this.dbConn.execQueueDBPrc({ nQueueId: q.nId });
|
|
||||||
//Если результат - ошибка пробрасываем её
|
|
||||||
if (prcRes.sResult == objQueueSchema.SPRC_RESP_RESULT_ERR) throw new ServerError(SERR_DB_SERVER, prcRes.sMsg);
|
|
||||||
//Выставим статус сообщению очереди - исполнено обработчиком БД
|
|
||||||
q = await this.dbConn.setQueueState({
|
|
||||||
nQueueId: q.nId,
|
|
||||||
nExecState: objQueueSchema.NQUEUE_EXEC_STATE_DB_OK
|
|
||||||
});
|
|
||||||
}
|
|
||||||
//Фиксируем успех обработки - в протоколе работы сервиса
|
|
||||||
await this.logger.info(`Входящее сообщение ${q.nId} успешно отработано`, { nQueueId: q.nId });
|
|
||||||
//Фиксируем успех обработки - в статусе сообщения
|
|
||||||
q = await this.dbConn.setQueueState({
|
|
||||||
nQueueId: q.nId,
|
|
||||||
nIncExecCnt: NINC_EXEC_CNT_YES,
|
|
||||||
nExecState: objQueueSchema.NQUEUE_EXEC_STATE_OK
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
//Тема и текст уведомления об ошибке
|
|
||||||
let sSubject = `Ошибка обработки входящего сообщения сервером приложений для функции "${fn.sCode}" сервиса "${service.sCode}"`;
|
|
||||||
let sMessage = makeErrorText(e);
|
|
||||||
//Если сообщение очереди успели создать
|
|
||||||
if (q) {
|
|
||||||
//Фиксируем ошибку обработки сервером приложений - в статусе сообщения
|
|
||||||
q = await this.dbConn.setQueueState({
|
|
||||||
nQueueId: q.nId,
|
|
||||||
sExecMsg: sMessage,
|
|
||||||
nIncExecCnt: NINC_EXEC_CNT_YES,
|
|
||||||
nExecState: objQueueSchema.NQUEUE_EXEC_STATE_ERR
|
|
||||||
});
|
|
||||||
//Фиксируем ошибку обработки сервером приложений - в протоколе работы сервиса
|
|
||||||
await this.logger.error(`Ошибка обработки входящего сообщения ${q.nId} сервером приложений: ${sMessage}`, { nQueueId: q.nId });
|
|
||||||
//Добавим чуть больше информации в тему сообщения
|
|
||||||
sSubject = `Ошибка обработки входящего сообщения ${q.nId} сервером приложений для функции "${fn.sCode}" сервиса "${service.sCode}"`;
|
|
||||||
} else {
|
|
||||||
//Ограничимся общей ошибкой
|
|
||||||
await this.logger.error(sMessage, {
|
|
||||||
nServiceId: service.nId,
|
|
||||||
nServiceFnId: fn.nId
|
|
||||||
});
|
|
||||||
}
|
|
||||||
//Если для функции-обработчика указан признак необходимости оповещения об ошибках
|
|
||||||
if (fn.nErrNtfSign == objServiceFnSchema.NERR_NTF_SIGN_YES) {
|
|
||||||
//Отправим уведомление об ошибке отработки в почту
|
|
||||||
await this.notifier.addMessage({
|
|
||||||
sTo: fn.sErrNtfMail,
|
|
||||||
sSubject,
|
|
||||||
sMessage
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Запуск обработки очереди входящих сообщений
|
//Запуск обработки очереди входящих сообщений
|
||||||
async startProcessing(prms) {
|
startProcessing(prms) {
|
||||||
//Проверяем структуру переданного объекта для старта
|
//Проверяем структуру переданного объекта для старта
|
||||||
let sCheckResult = validateObject(prms, prmsInQueueSchema.startProcessing, "Параметры функции запуска обработки очереди входящих сообщений");
|
let sCheckResult = validateObject(prms, prmsInQueueSchema.startProcessing, "Параметры функции запуска обработки очереди входящих сообщений");
|
||||||
//Если структура объекта в норме
|
//Если структура объекта в норме
|
||||||
@ -546,14 +379,7 @@ class InQueue extends EventEmitter {
|
|||||||
//Конфигурируем сервер - обработка тела сообщения
|
//Конфигурируем сервер - обработка тела сообщения
|
||||||
this.webApp.use(bodyParser.raw({ limit: `${this.inComing.nMsgMaxSize}mb`, type: "*/*" }));
|
this.webApp.use(bodyParser.raw({ limit: `${this.inComing.nMsgMaxSize}mb`, type: "*/*" }));
|
||||||
//Конфигурируем сервер - обходим все сервисы, работающие на приём сообщений
|
//Конфигурируем сервер - обходим все сервисы, работающие на приём сообщений
|
||||||
_.forEach(
|
_.forEach(_.filter(this.services, { nSrvType: objServiceSchema.NSRV_TYPE_RECIVE }), srvs => {
|
||||||
_.filter(this.services, srv => {
|
|
||||||
return (
|
|
||||||
srv.nSrvType === objServiceSchema.NSRV_TYPE_RECIVE &&
|
|
||||||
[objServiceSchema.SPROTOCOL_HTTP, objServiceSchema.SPROTOCOL_HTTPS].includes(getURLProtocol(srv.sSrvRoot))
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
srvs => {
|
|
||||||
//Для любых запросов к корневому адресу сервиса - ответ о том, что это за сервис, и что он работает
|
//Для любых запросов к корневому адресу сервиса - ответ о том, что это за сервис, и что он работает
|
||||||
this.webApp.all(srvs.sSrvRoot, (req, res) => {
|
this.webApp.all(srvs.sSrvRoot, (req, res) => {
|
||||||
res.status(200).send(
|
res.status(200).send(
|
||||||
@ -601,81 +427,7 @@ class InQueue extends EventEmitter {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
|
||||||
);
|
|
||||||
//Инициализируем настройки подключения
|
|
||||||
let connectionSettings = null;
|
|
||||||
//Считываем прием сообщений по Kafka
|
|
||||||
let kafkaSrvs = this.services.filter(srv => {
|
|
||||||
return srv.nSrvType === objServiceSchema.NSRV_TYPE_RECIVE && getURLProtocol(srv.sSrvRoot) === objServiceSchema.SPROTOCOL_KAFKA;
|
|
||||||
});
|
});
|
||||||
//Если есть сервисы с приемом сообщений по Kafka
|
|
||||||
if (kafkaSrvs.length !== 0) {
|
|
||||||
//Обходим данные сервисы
|
|
||||||
for (let srv of kafkaSrvs) {
|
|
||||||
//Если у сервиса обмена есть функции
|
|
||||||
if (srv.functions.length !== 0) {
|
|
||||||
//Считываем настройки подключения к Kafka
|
|
||||||
connectionSettings = getKafkaConnectionSettings(srv.sCode, this.kafka);
|
|
||||||
//Если настройки подключения считаны
|
|
||||||
if (connectionSettings) {
|
|
||||||
//Подключаемся и подписываемся на соответствующий брокер
|
|
||||||
let connectionKafka = await subscribeKafka({
|
|
||||||
settings: connectionSettings,
|
|
||||||
service: srv,
|
|
||||||
processMessage: prms => this.processMQMessage({ ...prms, sProtocol: objServiceSchema.SPROTOCOL_KAFKA }),
|
|
||||||
logger: this.logger
|
|
||||||
});
|
|
||||||
//Если подключение было создано
|
|
||||||
if (connectionKafka) {
|
|
||||||
//Добавляем в общий список подключений kafka
|
|
||||||
this.kafkaConnections.push(connectionKafka);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
await this.logger.error(
|
|
||||||
`Ошибка получения настроек подключения к Kafka для сервиса "${srv.sCode}". Необходимо проверить соответствующий параметр ("kafka") файла конфигурации сервиса приложений ("config.js").`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Считываем прием сообщений по MQTT
|
|
||||||
let mqttSrvs = this.services.filter(srv => {
|
|
||||||
return (
|
|
||||||
srv.nSrvType === objServiceSchema.NSRV_TYPE_RECIVE &&
|
|
||||||
[objServiceSchema.SPROTOCOL_MQTT, objServiceSchema.SPROTOCOL_MQTTS].includes(getURLProtocol(srv.sSrvRoot))
|
|
||||||
);
|
|
||||||
});
|
|
||||||
//Если есть сервисы с приемом сообщений по MQTT
|
|
||||||
if (mqttSrvs.length !== 0) {
|
|
||||||
//Обходим данные сервисы
|
|
||||||
for (let srv of mqttSrvs) {
|
|
||||||
//Если у сервиса обмена есть функции
|
|
||||||
if (srv.functions.length !== 0) {
|
|
||||||
//Считываем настройки подключения к MQTT
|
|
||||||
connectionSettings = getMQTTConnectionSettings(srv.sCode, this.mqtt);
|
|
||||||
//Если настройки подключения считаны
|
|
||||||
if (connectionSettings) {
|
|
||||||
//Подключаемся и подписываемся на соответствующий брокер
|
|
||||||
let connectionMQTT = await subscribeMQTT({
|
|
||||||
settings: connectionSettings,
|
|
||||||
service: srv,
|
|
||||||
processMessage: prms => this.processMQMessage({ ...prms, sProtocol: objServiceSchema.SPROTOCOL_MQTT }),
|
|
||||||
logger: this.logger
|
|
||||||
});
|
|
||||||
//Если подключение было создано
|
|
||||||
if (connectionMQTT) {
|
|
||||||
//Добавляем в общий список подключений kafka
|
|
||||||
this.mqttConnections.push(connectionMQTT);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
await this.logger.error(
|
|
||||||
`Ошибка получения настроек подключения к MQTT для сервиса "${srv.sCode}". Необходимо проверить соответствующий параметр ("mqtt") файла конфигурации сервиса приложений ("config.js").`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Запросы на адреса, не входящие в состав объявленных сервисов - 404 NOT FOUND
|
//Запросы на адреса, не входящие в состав объявленных сервисов - 404 NOT FOUND
|
||||||
this.webApp.use("*", (req, res) => {
|
this.webApp.use("*", (req, res) => {
|
||||||
res.status(404).send(
|
res.status(404).send(
|
||||||
@ -701,37 +453,10 @@ class InQueue extends EventEmitter {
|
|||||||
throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
|
throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Закрытие подключений
|
|
||||||
stopConnections() {
|
|
||||||
//Если у нас есть соединения с MQTT
|
|
||||||
if (this.mqttConnections.length !== 0) {
|
|
||||||
//Закрываем их
|
|
||||||
for (let connection of this.mqttConnections) {
|
|
||||||
try {
|
|
||||||
connection.end();
|
|
||||||
} catch (e) {
|
|
||||||
this.logger.error(`Ошибка завершения MQTT подключения: ${makeErrorText(e)}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Если у нас есть соединения с Kafka
|
|
||||||
if (this.kafkaConnections.length !== 0) {
|
|
||||||
//Закрываем их
|
|
||||||
for (let connection of this.kafkaConnections) {
|
|
||||||
try {
|
|
||||||
connection.disconnect();
|
|
||||||
} catch (e) {
|
|
||||||
this.logger.error(`Ошибка завершения Kafka подключения: ${makeErrorText(e)}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Остановка обработки очереди исходящих сообщений
|
//Остановка обработки очереди исходящих сообщений
|
||||||
stopProcessing() {
|
stopProcessing() {
|
||||||
//Выставляем флаг неработы
|
//Выставляем флаг неработы
|
||||||
this.bWorking = false;
|
this.bWorking = false;
|
||||||
//Закрываем подключения, если они есть
|
|
||||||
this.stopConnections();
|
|
||||||
//Останавливаем WEB-сервер (если создавался)
|
//Останавливаем WEB-сервер (если создавался)
|
||||||
if (this.srv) {
|
if (this.srv) {
|
||||||
this.srv.close(() => {
|
this.srv.close(() => {
|
||||||
|
@ -1,119 +0,0 @@
|
|||||||
/*
|
|
||||||
Сервис интеграции ПП Парус 8 с WEB API
|
|
||||||
Модуль ядра: обработчик kafka сообщений
|
|
||||||
*/
|
|
||||||
|
|
||||||
//----------------------
|
|
||||||
// Подключение библиотек
|
|
||||||
//----------------------
|
|
||||||
|
|
||||||
const { makeErrorText, getKafkaBroker, getKafkaAuth } = require("./utils"); //Вспомогательные функции
|
|
||||||
const { Kafka, Partitioners, logLevel } = require("kafkajs"); //Работа с Kafka
|
|
||||||
|
|
||||||
//------------
|
|
||||||
// Тело модуля
|
|
||||||
//------------
|
|
||||||
|
|
||||||
//Отправка сообщения Kafka
|
|
||||||
const publishKafka = async ({ settings, url, auth, topic, message }) => {
|
|
||||||
//Иницализируем подключение к Kafka
|
|
||||||
let kafka = new Kafka({
|
|
||||||
clientId: settings.sClientIdSender,
|
|
||||||
brokers: [url],
|
|
||||||
connectionTimeout: settings.nConnectionTimeout,
|
|
||||||
logLevel: logLevel.NOTHING,
|
|
||||||
...auth
|
|
||||||
});
|
|
||||||
//Инициализируем продюсера
|
|
||||||
let producer = kafka.producer({ createPartitioner: Partitioners.LegacyPartitioner });
|
|
||||||
//Подключаемся к Kafka
|
|
||||||
await producer.connect();
|
|
||||||
//Отправляем сообщение
|
|
||||||
await producer.send({ topic: topic, messages: [{ value: message }] });
|
|
||||||
//Отключаемся
|
|
||||||
await producer.disconnect();
|
|
||||||
//Возвращаем статус успешной отправки
|
|
||||||
return { statusCode: 200 };
|
|
||||||
};
|
|
||||||
|
|
||||||
//Получение Kafka сообщений
|
|
||||||
const subscribeKafka = async ({ settings, service, processMessage, logger }) => {
|
|
||||||
try {
|
|
||||||
//Признак необходимости вывода сообщения о потере соединения
|
|
||||||
let bLogLostConnection = true;
|
|
||||||
//Получаем брокера по URL сервиса
|
|
||||||
let sBroker = getKafkaBroker(service.sSrvRoot);
|
|
||||||
//Иницализируем подключение к Kafka
|
|
||||||
let client = new Kafka({
|
|
||||||
clientId: settings.sClientIdRecipient,
|
|
||||||
brokers: [sBroker],
|
|
||||||
connectionTimeout: settings.nConnectionTimeout,
|
|
||||||
...getKafkaAuth(service.sSrvUser, service.sSrvPass, settings),
|
|
||||||
logLevel: logLevel.NOTHING,
|
|
||||||
retry: {
|
|
||||||
retries: 0,
|
|
||||||
maxRetryTime: settings.nMaxRetryTime,
|
|
||||||
initialRetryTime: settings.nInitialRetryTime,
|
|
||||||
restartOnFailure: error => {
|
|
||||||
return new Promise(resolve => {
|
|
||||||
//Если требуется вывести ошибку
|
|
||||||
if (bLogLostConnection) {
|
|
||||||
//Выводим ошибку
|
|
||||||
logger.error(`Соединение с Kafka потеряно (${sBroker}): ${makeErrorText(error)}`);
|
|
||||||
//Сбрасываем признак необходимости вывода ошибки
|
|
||||||
bLogLostConnection = false;
|
|
||||||
}
|
|
||||||
resolve(settings.bRestartOnFailure);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
//Инициализируем получателя
|
|
||||||
let consumer = client.consumer({ groupId: settings.sGroupId });
|
|
||||||
//Устанавливаем прослушивание
|
|
||||||
await consumer.connect();
|
|
||||||
consumer.subscribe({
|
|
||||||
topics: service.functions.map(fn => {
|
|
||||||
return fn.sFnURL;
|
|
||||||
})
|
|
||||||
});
|
|
||||||
//Запускаем прослушивание необходимых топиков
|
|
||||||
consumer.run({
|
|
||||||
eachMessage: async ({ topic, message }) => {
|
|
||||||
try {
|
|
||||||
//Вызываем обработчик
|
|
||||||
processMessage({
|
|
||||||
message,
|
|
||||||
service,
|
|
||||||
fn: service.functions.find(fn => {
|
|
||||||
return fn.sFnURL === topic;
|
|
||||||
})
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
await logger.error(`Ошибка обработки исходящего сообщения Kafka: ${makeErrorText(e)}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
//Отслеживаем соединение
|
|
||||||
consumer.on(consumer.events.CONNECT, () => {
|
|
||||||
//Если сообщение о потере соединения уже выводилось
|
|
||||||
if (!bLogLostConnection) {
|
|
||||||
//Сообщим о восстановлении соединения
|
|
||||||
logger.info(`Соединение с Kafka восстановлено (${sBroker})`);
|
|
||||||
//Устанавливаем признак сообщения о потере соединения
|
|
||||||
bLogLostConnection = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
//Возвращаем соединение
|
|
||||||
return consumer;
|
|
||||||
} catch (e) {
|
|
||||||
await logger.error(`Ошибка запуска обработчика очереди исходящих сообщений Kafka: ${makeErrorText(e)}`);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//-----------------
|
|
||||||
// Интерфейс модуля
|
|
||||||
//-----------------
|
|
||||||
|
|
||||||
exports.publishKafka = publishKafka;
|
|
||||||
exports.subscribeKafka = subscribeKafka;
|
|
@ -1,87 +0,0 @@
|
|||||||
/*
|
|
||||||
Сервис интеграции ПП Парус 8 с WEB API
|
|
||||||
Модуль ядра: обработчик mqtt сообщений
|
|
||||||
*/
|
|
||||||
|
|
||||||
//----------------------
|
|
||||||
// Подключение библиотек
|
|
||||||
//----------------------
|
|
||||||
|
|
||||||
const { makeErrorText } = require("./utils"); //Вспомогательные функции
|
|
||||||
const mqtt = require("mqtt"); //Работа с MQTT
|
|
||||||
|
|
||||||
//------------
|
|
||||||
// Тело модуля
|
|
||||||
//------------
|
|
||||||
|
|
||||||
//Отправка MQTT сообщения
|
|
||||||
const publishMQTT = async ({ settings, url, auth, topic, message }) => {
|
|
||||||
//Инициализируем подключение
|
|
||||||
const client = await mqtt.connectAsync(url, {
|
|
||||||
clientId: settings.sClientIdSender,
|
|
||||||
clean: true,
|
|
||||||
connectTimeout: settings.nConnectTimeout,
|
|
||||||
username: auth.user,
|
|
||||||
password: auth.pass,
|
|
||||||
reconnectPeriod: settings.nReconnectPeriod
|
|
||||||
});
|
|
||||||
//Отправляем сообщение
|
|
||||||
await client.publishAsync(topic, message);
|
|
||||||
//Закрываем подключение
|
|
||||||
await client.endAsync();
|
|
||||||
//Возвращаем статус успешной отправки
|
|
||||||
return { statusCode: 200 };
|
|
||||||
};
|
|
||||||
|
|
||||||
//Получение MQTT сообщений
|
|
||||||
const subscribeMQTT = async ({ settings, service, processMessage, logger }) => {
|
|
||||||
try {
|
|
||||||
//Инициализируем строку подключения
|
|
||||||
let sBroker = service.sSrvRoot;
|
|
||||||
//Инициализируем подключение
|
|
||||||
const client = await mqtt.connectAsync(sBroker, {
|
|
||||||
clientId: settings.sClientIdRecipient,
|
|
||||||
clean: true,
|
|
||||||
connectTimeout: settings.nConnectTimeout,
|
|
||||||
username: service.sSrvUser,
|
|
||||||
password: service.sSrvPass,
|
|
||||||
reconnectPeriod: settings.nReconnectPeriod
|
|
||||||
});
|
|
||||||
//Обходим функции сервиса
|
|
||||||
service.functions.forEach(fn => {
|
|
||||||
client.subscribe(fn.sFnURL);
|
|
||||||
});
|
|
||||||
//Прослушиваем сообщения
|
|
||||||
client.on("message", (topic, message) => {
|
|
||||||
//Обрабатываем сообщение
|
|
||||||
processMessage({
|
|
||||||
message: { value: message, headers: {} },
|
|
||||||
service,
|
|
||||||
fn: service.functions.find(fn => {
|
|
||||||
return fn.sFnURL === topic;
|
|
||||||
})
|
|
||||||
});
|
|
||||||
});
|
|
||||||
//Прослушиваем отключение от сервера
|
|
||||||
client.on("offline", () => {
|
|
||||||
//Выводим ошибку
|
|
||||||
logger.error(`Соединение с MQTT потеряно (${sBroker})`);
|
|
||||||
});
|
|
||||||
//Прослушиваем восстановление соединения
|
|
||||||
client.on("connect", () => {
|
|
||||||
//Сообщим о восстановлении соединения
|
|
||||||
logger.info(`Соединение с MQTT восстановлено (${sBroker})`);
|
|
||||||
});
|
|
||||||
//Возвращаем подключение
|
|
||||||
return client;
|
|
||||||
} catch (e) {
|
|
||||||
logger.error(`Ошибка запуска обработчика очереди исходящих сообщений MQTT: ${makeErrorText(e)}`);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//-----------------
|
|
||||||
// Интерфейс модуля
|
|
||||||
//-----------------
|
|
||||||
|
|
||||||
exports.publishMQTT = publishMQTT;
|
|
||||||
exports.subscribeMQTT = subscribeMQTT;
|
|
@ -70,10 +70,6 @@ class OutQueue extends EventEmitter {
|
|||||||
this.inProgress = [];
|
this.inProgress = [];
|
||||||
//Привяжем методы к указателю на себя для использования в обработчиках событий
|
//Привяжем методы к указателю на себя для использования в обработчиках событий
|
||||||
this.outDetectingLoop = this.outDetectingLoop.bind(this);
|
this.outDetectingLoop = this.outDetectingLoop.bind(this);
|
||||||
//Параметры подключения к Kafka
|
|
||||||
this.kafka = prms.kafka;
|
|
||||||
//Параметры подключения к MQTT
|
|
||||||
this.mqtt = prms.mqtt;
|
|
||||||
} else {
|
} else {
|
||||||
throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
|
throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
|
||||||
}
|
}
|
||||||
@ -145,7 +141,11 @@ class OutQueue extends EventEmitter {
|
|||||||
//Старт обработчика
|
//Старт обработчика
|
||||||
startQueueProcessor(prms) {
|
startQueueProcessor(prms) {
|
||||||
//Проверяем структуру переданного объекта для старта обработчика
|
//Проверяем структуру переданного объекта для старта обработчика
|
||||||
let sCheckResult = validateObject(prms, prmsOutQueueSchema.startQueueProcessor, "Параметры функции запуска обработчика сообщения очереди");
|
let sCheckResult = validateObject(
|
||||||
|
prms,
|
||||||
|
prmsOutQueueSchema.startQueueProcessor,
|
||||||
|
"Параметры функции запуска обработчика сообщения очереди"
|
||||||
|
);
|
||||||
//Если структура объекта в норме
|
//Если структура объекта в норме
|
||||||
if (!sCheckResult) {
|
if (!sCheckResult) {
|
||||||
//Добавляем идентификатор позиции очереди в список обрабатываемых
|
//Добавляем идентификатор позиции очереди в список обрабатываемых
|
||||||
@ -163,9 +163,7 @@ class OutQueue extends EventEmitter {
|
|||||||
function: _.find(_.find(this.services, { nId: prms.queue.nServiceId }).functions, {
|
function: _.find(_.find(this.services, { nId: prms.queue.nServiceId }).functions, {
|
||||||
nId: prms.queue.nServiceFnId
|
nId: prms.queue.nServiceFnId
|
||||||
}),
|
}),
|
||||||
sProxy: this.sProxy,
|
sProxy: this.sProxy
|
||||||
kafka: this.kafka,
|
|
||||||
mqtt: this.mqtt
|
|
||||||
});
|
});
|
||||||
//Уменьшаем количество доступных обработчиков
|
//Уменьшаем количество доступных обработчиков
|
||||||
this.nWorkersLeft--;
|
this.nWorkersLeft--;
|
||||||
@ -176,7 +174,11 @@ class OutQueue extends EventEmitter {
|
|||||||
//Останов обработчика
|
//Останов обработчика
|
||||||
stopQueueProcessor(prms) {
|
stopQueueProcessor(prms) {
|
||||||
//Проверяем структуру переданного объекта для останова обработчика
|
//Проверяем структуру переданного объекта для останова обработчика
|
||||||
let sCheckResult = validateObject(prms, prmsOutQueueSchema.stopQueueProcessor, "Параметры функции останова обработчика сообщения очереди");
|
let sCheckResult = validateObject(
|
||||||
|
prms,
|
||||||
|
prmsOutQueueSchema.stopQueueProcessor,
|
||||||
|
"Параметры функции останова обработчика сообщения очереди"
|
||||||
|
);
|
||||||
//Если структура объекта в норме
|
//Если структура объекта в норме
|
||||||
if (!sCheckResult) {
|
if (!sCheckResult) {
|
||||||
//Удаляем идентификатор позиции очереди из списка обрабатываемых
|
//Удаляем идентификатор позиции очереди из списка обрабатываемых
|
||||||
@ -217,13 +219,19 @@ class OutQueue extends EventEmitter {
|
|||||||
throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
|
throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
await this.logger.error(`При отправке уведомления об ошибке обработки исходящего сообщения: ${makeErrorText(e)}`);
|
await this.logger.error(
|
||||||
|
`При отправке уведомления об ошибке обработки исходящего сообщения: ${makeErrorText(e)}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Запуск обработки очередного сообщения
|
//Запуск обработки очередного сообщения
|
||||||
processMessage(prms) {
|
processMessage(prms) {
|
||||||
//Проверяем структуру переданного объекта
|
//Проверяем структуру переданного объекта
|
||||||
let sCheckResult = validateObject(prms, prmsOutQueueSchema.processMessage, "Параметры функции запуска обработки очередного сообщения");
|
let sCheckResult = validateObject(
|
||||||
|
prms,
|
||||||
|
prmsOutQueueSchema.processMessage,
|
||||||
|
"Параметры функции запуска обработки очередного сообщения"
|
||||||
|
);
|
||||||
//Если структура объекта в норме
|
//Если структура объекта в норме
|
||||||
if (!sCheckResult) {
|
if (!sCheckResult) {
|
||||||
//Проверим, что есть доступные обработчики
|
//Проверим, что есть доступные обработчики
|
||||||
@ -268,9 +276,10 @@ class OutQueue extends EventEmitter {
|
|||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
//Отразим в протоколе ошибку постановки задачи на аутентификацию сервиса
|
//Отразим в протоколе ошибку постановки задачи на аутентификацию сервиса
|
||||||
await self.logger.error(`Ошибка постановки задачи на аутентификацию сервиса: ${makeErrorText(e)}`, {
|
await self.logger.error(
|
||||||
nQueueId: prms.queue.nId
|
`Ошибка постановки задачи на аутентификацию сервиса: ${makeErrorText(e)}`,
|
||||||
});
|
{ nQueueId: prms.queue.nId }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -289,21 +298,25 @@ class OutQueue extends EventEmitter {
|
|||||||
sExecMsg: sError,
|
sExecMsg: sError,
|
||||||
nIncExecCnt: nQueueOldExecCnt == prms.queue.nExecCnt ? NINC_EXEC_CNT_YES : NINC_EXEC_CNT_NO,
|
nIncExecCnt: nQueueOldExecCnt == prms.queue.nExecCnt ? NINC_EXEC_CNT_YES : NINC_EXEC_CNT_NO,
|
||||||
nExecState:
|
nExecState:
|
||||||
(nQueueOldExecCnt == prms.queue.nExecCnt ? prms.queue.nExecCnt + 1 : prms.queue.nExecCnt) < prms.queue.nRetryAttempts
|
(nQueueOldExecCnt == prms.queue.nExecCnt
|
||||||
|
? prms.queue.nExecCnt + 1
|
||||||
|
: prms.queue.nExecCnt) < prms.queue.nRetryAttempts
|
||||||
? prms.queue.nExecState
|
? prms.queue.nExecState
|
||||||
: objQueueSchema.NQUEUE_EXEC_STATE_ERR
|
: objQueueSchema.NQUEUE_EXEC_STATE_ERR
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
//Если исполнение завершилось полностью и с ошибкой - расскажем об этом
|
//Если исполнение завершилось полностью и с ошибкой - расскажем об этом
|
||||||
if (prms.queue.nExecState == objQueueSchema.NQUEUE_EXEC_STATE_ERR) await this.notifyMessageProcessError(prms);
|
if (prms.queue.nExecState == objQueueSchema.NQUEUE_EXEC_STATE_ERR)
|
||||||
|
await this.notifyMessageProcessError(prms);
|
||||||
//Останавливаем обработчик и инкрементируем флаг их доступного количества
|
//Останавливаем обработчик и инкрементируем флаг их доступного количества
|
||||||
try {
|
try {
|
||||||
this.stopQueueProcessor({ nQueueId: prms.queue.nId, proc });
|
this.stopQueueProcessor({ nQueueId: prms.queue.nId, proc });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
//Отразим в протоколе ошибку останова
|
//Отразим в протоколе ошибку останова
|
||||||
await self.logger.error(`Ошибка останова обработчика исходящего сообщения: ${makeErrorText(e)}`, {
|
await self.logger.error(
|
||||||
nQueueId: prms.queue.nId
|
`Ошибка останова обработчика исходящего сообщения: ${makeErrorText(e)}`,
|
||||||
});
|
{ nQueueId: prms.queue.nId }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
//Перехват ошибок обработчика
|
//Перехват ошибок обработчика
|
||||||
@ -320,20 +333,23 @@ class OutQueue extends EventEmitter {
|
|||||||
sExecMsg: makeErrorText(e),
|
sExecMsg: makeErrorText(e),
|
||||||
nIncExecCnt: nQueueOldExecCnt == prms.queue.nExecCnt ? NINC_EXEC_CNT_YES : NINC_EXEC_CNT_NO,
|
nIncExecCnt: nQueueOldExecCnt == prms.queue.nExecCnt ? NINC_EXEC_CNT_YES : NINC_EXEC_CNT_NO,
|
||||||
nExecState:
|
nExecState:
|
||||||
(nQueueOldExecCnt == prms.queue.nExecCnt ? prms.queue.nExecCnt + 1 : prms.queue.nExecCnt) < prms.queue.nRetryAttempts
|
(nQueueOldExecCnt == prms.queue.nExecCnt ? prms.queue.nExecCnt + 1 : prms.queue.nExecCnt) <
|
||||||
|
prms.queue.nRetryAttempts
|
||||||
? prms.queue.nExecState
|
? prms.queue.nExecState
|
||||||
: objQueueSchema.NQUEUE_EXEC_STATE_ERR
|
: objQueueSchema.NQUEUE_EXEC_STATE_ERR
|
||||||
});
|
});
|
||||||
//Если исполнение завершилось полностью и с ошибкой - расскажем об этом
|
//Если исполнение завершилось полностью и с ошибкой - расскажем об этом
|
||||||
if (prms.queue.nExecState == objQueueSchema.NQUEUE_EXEC_STATE_ERR) await this.notifyMessageProcessError(prms);
|
if (prms.queue.nExecState == objQueueSchema.NQUEUE_EXEC_STATE_ERR)
|
||||||
|
await this.notifyMessageProcessError(prms);
|
||||||
//Останавливаем обработчик и инкрементируем флаг их доступного количества
|
//Останавливаем обработчик и инкрементируем флаг их доступного количества
|
||||||
try {
|
try {
|
||||||
this.stopQueueProcessor({ nQueueId: prms.queue.nId, proc });
|
this.stopQueueProcessor({ nQueueId: prms.queue.nId, proc });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
//Отразим в протоколе ошибку останова
|
//Отразим в протоколе ошибку останова
|
||||||
await self.logger.error(`Ошибка останова обработчика исходящего сообщения: ${makeErrorText(e)}`, {
|
await self.logger.error(
|
||||||
nQueueId: prms.queue.nId
|
`Ошибка останова обработчика исходящего сообщения: ${makeErrorText(e)}`,
|
||||||
});
|
{ nQueueId: prms.queue.nId }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
//Перехват останова обработчика
|
//Перехват останова обработчика
|
||||||
@ -376,12 +392,16 @@ class OutQueue extends EventEmitter {
|
|||||||
nQueueId: outMsg.nId,
|
nQueueId: outMsg.nId,
|
||||||
sExecMsg: makeErrorText(e),
|
sExecMsg: makeErrorText(e),
|
||||||
nIncExecCnt: NINC_EXEC_CNT_YES,
|
nIncExecCnt: NINC_EXEC_CNT_YES,
|
||||||
nExecState: outMsg.nExecCnt + 1 < outMsg.nRetryAttempts ? outMsg.nExecState : objQueueSchema.NQUEUE_EXEC_STATE_ERR
|
nExecState:
|
||||||
|
outMsg.nExecCnt + 1 < outMsg.nRetryAttempts
|
||||||
|
? outMsg.nExecState
|
||||||
|
: objQueueSchema.NQUEUE_EXEC_STATE_ERR
|
||||||
});
|
});
|
||||||
//Фиксируем ошибку обработки сервером приложений - запись в протокол работы сервера приложений
|
//Фиксируем ошибку обработки сервером приложений - запись в протокол работы сервера приложений
|
||||||
await this.logger.error(makeErrorText(e), { nQueueId: outMsg.nId });
|
await this.logger.error(makeErrorText(e), { nQueueId: outMsg.nId });
|
||||||
//Если исполнение завершилось полностью и с ошибкой - расскажем об этом
|
//Если исполнение завершилось полностью и с ошибкой - расскажем об этом
|
||||||
if (queue.nExecState == objQueueSchema.NQUEUE_EXEC_STATE_ERR) await this.notifyMessageProcessError({ queue });
|
if (queue.nExecState == objQueueSchema.NQUEUE_EXEC_STATE_ERR)
|
||||||
|
await this.notifyMessageProcessError({ queue });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,21 +12,7 @@ const _ = require("lodash"); //Работа с массивами и объек
|
|||||||
const rqp = require("request-promise"); //Работа с HTTP/HTTPS запросами
|
const rqp = require("request-promise"); //Работа с HTTP/HTTPS запросами
|
||||||
const lg = require("./logger"); //Протоколирование работы
|
const lg = require("./logger"); //Протоколирование работы
|
||||||
const db = require("./db_connector"); //Взаимодействие с БД
|
const db = require("./db_connector"); //Взаимодействие с БД
|
||||||
const {
|
const { makeErrorText, validateObject, getAppSrvFunction, buildURL, parseOptionsXML, buildOptionsXML, deepMerge } = require("./utils"); //Вспомогательные функции
|
||||||
makeErrorText,
|
|
||||||
validateObject,
|
|
||||||
getAppSrvFunction,
|
|
||||||
buildURL,
|
|
||||||
parseOptionsXML,
|
|
||||||
buildOptionsXML,
|
|
||||||
deepMerge,
|
|
||||||
getKafkaConnectionSettings,
|
|
||||||
getMQTTConnectionSettings,
|
|
||||||
getKafkaBroker,
|
|
||||||
getKafkaAuth,
|
|
||||||
getURLProtocol,
|
|
||||||
wrapPromiseTimeout
|
|
||||||
} = require("./utils"); //Вспомогательные функции
|
|
||||||
const { ServerError } = require("./server_errors"); //Типовая ошибка
|
const { ServerError } = require("./server_errors"); //Типовая ошибка
|
||||||
const objOutQueueProcessorSchema = require("../models/obj_out_queue_processor"); //Схема валидации сообщений обмена с бработчиком очереди исходящих сообщений
|
const objOutQueueProcessorSchema = require("../models/obj_out_queue_processor"); //Схема валидации сообщений обмена с бработчиком очереди исходящих сообщений
|
||||||
const prmsOutQueueProcessorSchema = require("../models/prms_out_queue_processor"); //Схема валидации параметров функций модуля
|
const prmsOutQueueProcessorSchema = require("../models/prms_out_queue_processor"); //Схема валидации параметров функций модуля
|
||||||
@ -34,7 +20,6 @@ const objQueueSchema = require("../models/obj_queue"); //Схемы валида
|
|||||||
const objServiceSchema = require("../models/obj_service"); //Схемы валидации сервиса
|
const objServiceSchema = require("../models/obj_service"); //Схемы валидации сервиса
|
||||||
const objServiceFnSchema = require("../models/obj_service_function"); //Схемы валидации функции сервиса
|
const objServiceFnSchema = require("../models/obj_service_function"); //Схемы валидации функции сервиса
|
||||||
const {
|
const {
|
||||||
SERR_UNEXPECTED,
|
|
||||||
SERR_OBJECT_BAD_INTERFACE,
|
SERR_OBJECT_BAD_INTERFACE,
|
||||||
SERR_APP_SERVER_BEFORE,
|
SERR_APP_SERVER_BEFORE,
|
||||||
SERR_APP_SERVER_AFTER,
|
SERR_APP_SERVER_AFTER,
|
||||||
@ -43,8 +28,6 @@ const {
|
|||||||
SERR_UNAUTH
|
SERR_UNAUTH
|
||||||
} = require("./constants"); //Глобальные константы
|
} = require("./constants"); //Глобальные константы
|
||||||
const { NINC_EXEC_CNT_YES, NINC_EXEC_CNT_NO, NIS_ORIGINAL_NO, NIS_ORIGINAL_YES } = require("../models/prms_db_connector"); //Схемы валидации параметров функций модуля взаимодействия с БД
|
const { NINC_EXEC_CNT_YES, NINC_EXEC_CNT_NO, NIS_ORIGINAL_NO, NIS_ORIGINAL_YES } = require("../models/prms_db_connector"); //Схемы валидации параметров функций модуля взаимодействия с БД
|
||||||
const { publishMQTT } = require("./mqtt_connector"); //Работа с MQTT/MQTTS запросами
|
|
||||||
const { publishKafka } = require("./kafka_connector"); //Работа с Kafka запросами
|
|
||||||
|
|
||||||
//--------------------------
|
//--------------------------
|
||||||
// Глобальные идентификаторы
|
// Глобальные идентификаторы
|
||||||
@ -146,59 +129,11 @@ const appProcess = async prms => {
|
|||||||
let optionsResp = {};
|
let optionsResp = {};
|
||||||
//Флаг прекращения обработки сообщения
|
//Флаг прекращения обработки сообщения
|
||||||
let bStopPropagation = false;
|
let bStopPropagation = false;
|
||||||
//Флаг выполнения обработчика "До"
|
|
||||||
let bExecuteBefore = true;
|
|
||||||
//Флаг выполнения обработчика "После"
|
|
||||||
let bExecuteAfter = true;
|
|
||||||
//Считываем протокол работы
|
|
||||||
let sProtocol = getURLProtocol(prms.service.sSrvRoot);
|
|
||||||
//Исходя из протокола собираем параметры
|
|
||||||
switch (true) {
|
|
||||||
//Kafka
|
|
||||||
case sProtocol === objServiceSchema.SPROTOCOL_KAFKA:
|
|
||||||
options.url = getKafkaBroker(prms.service.sSrvRoot);
|
|
||||||
options.body = prms.queue.blMsg;
|
|
||||||
options.topic = prms.function.sFnURL;
|
|
||||||
options.settings = getKafkaConnectionSettings(prms.service.sCode, prms.kafka);
|
|
||||||
options.auth = getKafkaAuth(prms.service.sSrvUser, prms.service.sSrvPass, options.settings);
|
|
||||||
//Если параметры подключения не считаны
|
|
||||||
if (!options.settings) {
|
|
||||||
//Расскажем об ошибке считывания
|
|
||||||
throw new ServerError(
|
|
||||||
SERR_UNEXPECTED,
|
|
||||||
`Ошибка получения настроек подключения к Kafka для сервиса "${prms.service.sCode}". Необходимо проверить соответствующий параметр ("kafka") файла конфигурации сервиса приложений ("config.js").`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
//Указываем, что выполнение обработчика "После" невозможно
|
|
||||||
bExecuteAfter = false;
|
|
||||||
break;
|
|
||||||
//MQTT/MQTTS
|
|
||||||
case [objServiceSchema.SPROTOCOL_MQTT, objServiceSchema.SPROTOCOL_MQTTS].includes(sProtocol):
|
|
||||||
options.url = prms.service.sSrvRoot;
|
|
||||||
options.body = prms.queue.blMsg;
|
|
||||||
options.topic = prms.function.sFnURL;
|
|
||||||
options.auth = { user: prms.service.sSrvUser, pass: prms.service.sSrvPass };
|
|
||||||
options.settings = getMQTTConnectionSettings(prms.service.sCode, prms.mqtt);
|
|
||||||
//Если параметры подключения не считаны
|
|
||||||
if (!options.settings) {
|
|
||||||
//Расскажем об ошибке считывания
|
|
||||||
throw new ServerError(
|
|
||||||
SERR_UNEXPECTED,
|
|
||||||
`Ошибка получения настроек подключения к MQTT для сервиса "${prms.service.sCode}". Необходимо проверить соответствующий параметр ("mqtt") файла конфигурации сервиса приложений ("config.js").`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
//Указываем, что выполнение обработчика "После" невозможно
|
|
||||||
bExecuteAfter = false;
|
|
||||||
break;
|
|
||||||
//HTTP/HTTPS
|
|
||||||
default:
|
|
||||||
//Определимся с URL и телом сообщения в зависимости от способа передачи параметров (для POST, PATCH и PUT - данные в теле, для остальных - в URI)
|
//Определимся с URL и телом сообщения в зависимости от способа передачи параметров (для POST, PATCH и PUT - данные в теле, для остальных - в URI)
|
||||||
if (
|
if (
|
||||||
[
|
[objServiceFnSchema.NFN_PRMS_TYPE_POST, objServiceFnSchema.NFN_PRMS_TYPE_PATCH, objServiceFnSchema.NFN_PRMS_TYPE_PUT].includes(
|
||||||
objServiceFnSchema.NFN_PRMS_TYPE_POST,
|
prms.function.nFnPrmsType
|
||||||
objServiceFnSchema.NFN_PRMS_TYPE_PATCH,
|
)
|
||||||
objServiceFnSchema.NFN_PRMS_TYPE_PUT
|
|
||||||
].includes(prms.function.nFnPrmsType)
|
|
||||||
) {
|
) {
|
||||||
options.url = buildURL({ sSrvRoot: prms.service.sSrvRoot, sFnURL: prms.function.sFnURL });
|
options.url = buildURL({ sSrvRoot: prms.service.sSrvRoot, sFnURL: prms.function.sFnURL });
|
||||||
options.body = prms.queue.blMsg;
|
options.body = prms.queue.blMsg;
|
||||||
@ -210,8 +145,6 @@ const appProcess = async prms => {
|
|||||||
sQuery: prms.queue.blMsg === null ? "" : prms.queue.blMsg.toString()
|
sQuery: prms.queue.blMsg === null ? "" : prms.queue.blMsg.toString()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
// Если у сервиса указан прокси, либо у приложения установлен глобальный прокси
|
// Если у сервиса указан прокси, либо у приложения установлен глобальный прокси
|
||||||
if (prms.service.sProxyURL || prms.sProxy) {
|
if (prms.service.sProxyURL || prms.sProxy) {
|
||||||
// Добавляем прокси с приоритетом сервиса
|
// Добавляем прокси с приоритетом сервиса
|
||||||
@ -234,7 +167,7 @@ const appProcess = async prms => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Выполняем обработчик "До" (если он есть)
|
//Выполняем обработчик "До" (если он есть)
|
||||||
if (prms.function.sAppSrvBefore && bExecuteBefore) {
|
if (prms.function.sAppSrvBefore) {
|
||||||
const fnBefore = getAppSrvFunction(prms.function.sAppSrvBefore);
|
const fnBefore = getAppSrvFunction(prms.function.sAppSrvBefore);
|
||||||
let resBefore = null;
|
let resBefore = null;
|
||||||
try {
|
try {
|
||||||
@ -266,10 +199,7 @@ const appProcess = async prms => {
|
|||||||
objServiceFnSchema.NFN_PRMS_TYPE_POST,
|
objServiceFnSchema.NFN_PRMS_TYPE_POST,
|
||||||
objServiceFnSchema.NFN_PRMS_TYPE_PATCH,
|
objServiceFnSchema.NFN_PRMS_TYPE_PATCH,
|
||||||
objServiceFnSchema.NFN_PRMS_TYPE_PUT
|
objServiceFnSchema.NFN_PRMS_TYPE_PUT
|
||||||
].includes(prms.function.nFnPrmsType) ||
|
].includes(prms.function.nFnPrmsType)
|
||||||
[objServiceSchema.SPROTOCOL_KAFKA, objServiceSchema.SPROTOCOL_MQTT, objServiceSchema.SPROTOCOL_MQTTS].includes(
|
|
||||||
sProtocol
|
|
||||||
)
|
|
||||||
) {
|
) {
|
||||||
options.body = prms.queue.blMsg;
|
options.body = prms.queue.blMsg;
|
||||||
} else {
|
} else {
|
||||||
@ -322,7 +252,6 @@ const appProcess = async prms => {
|
|||||||
delete tmpOptions.body;
|
delete tmpOptions.body;
|
||||||
delete tmpOptions.cert;
|
delete tmpOptions.cert;
|
||||||
delete tmpOptions.key;
|
delete tmpOptions.key;
|
||||||
delete tmpOptions.auth;
|
|
||||||
//Конвертируем в XML
|
//Конвертируем в XML
|
||||||
let sOptions = buildOptionsXML({ options: tmpOptions });
|
let sOptions = buildOptionsXML({ options: tmpOptions });
|
||||||
//Сохраняемв БД
|
//Сохраняемв БД
|
||||||
@ -332,42 +261,9 @@ const appProcess = async prms => {
|
|||||||
nQueueId: prms.queue.nId
|
nQueueId: prms.queue.nId
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
//Инициализируем ответ от сервера
|
//Ждем ответ от удалённого сервера
|
||||||
let serverResp = null;
|
|
||||||
//Выполняем отправку исходя из протокола
|
|
||||||
switch (true) {
|
|
||||||
//Kafka
|
|
||||||
case sProtocol === objServiceSchema.SPROTOCOL_KAFKA:
|
|
||||||
serverResp = await publishKafka({
|
|
||||||
settings: options.settings,
|
|
||||||
url: options.url,
|
|
||||||
auth: options.auth,
|
|
||||||
topic: options.topic,
|
|
||||||
message: options.body
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
//MQTT/MQTTS
|
|
||||||
case [objServiceSchema.SPROTOCOL_MQTT, objServiceSchema.SPROTOCOL_MQTTS].includes(sProtocol):
|
|
||||||
serverResp = await publishMQTT({
|
|
||||||
settings: options.settings,
|
|
||||||
url: options.url,
|
|
||||||
auth: options.auth,
|
|
||||||
topic: options.topic,
|
|
||||||
message: options.body
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
//HTTP/HTTPS
|
|
||||||
default:
|
|
||||||
//Установим флаг возврата полного ответа (и тела и заголовков)
|
|
||||||
options.resolveWithFullResponse = true;
|
options.resolveWithFullResponse = true;
|
||||||
//Установим таймаут подключения (если задан в настройках функции и ещё не задан в параметрах сообщения)
|
let serverResp = await rqp(options);
|
||||||
if (prms.function.nTimeoutConn && !options.timeout) options.timeout = prms.function.nTimeoutConn;
|
|
||||||
//Отправляем запрос
|
|
||||||
serverResp = prms.function.nTimeoutAsynch
|
|
||||||
? await wrapPromiseTimeout(prms.function.nTimeoutAsynch, rqp(options))
|
|
||||||
: await rqp(options);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
//Сохраняем полученный ответ
|
//Сохраняем полученный ответ
|
||||||
prms.queue.blResp = Buffer.from(serverResp.body || "");
|
prms.queue.blResp = Buffer.from(serverResp.body || "");
|
||||||
await dbConn.setQueueResp({
|
await dbConn.setQueueResp({
|
||||||
@ -397,7 +293,7 @@ const appProcess = async prms => {
|
|||||||
throw new ServerError(SERR_WEB_SERVER, sError);
|
throw new ServerError(SERR_WEB_SERVER, sError);
|
||||||
}
|
}
|
||||||
//Выполняем обработчик "После" (если он есть)
|
//Выполняем обработчик "После" (если он есть)
|
||||||
if (prms.function.sAppSrvAfter && bExecuteAfter) {
|
if (prms.function.sAppSrvAfter) {
|
||||||
const fnAfter = getAppSrvFunction(prms.function.sAppSrvAfter);
|
const fnAfter = getAppSrvFunction(prms.function.sAppSrvAfter);
|
||||||
let resAfter = null;
|
let resAfter = null;
|
||||||
try {
|
try {
|
||||||
@ -619,34 +515,17 @@ const processTask = async prms => {
|
|||||||
queue: q,
|
queue: q,
|
||||||
service: prms.task.service,
|
service: prms.task.service,
|
||||||
function: prms.task.function,
|
function: prms.task.function,
|
||||||
sProxy: prms.task.sProxy,
|
sProxy: prms.task.sProxy
|
||||||
kafka: prms.task.kafka,
|
|
||||||
mqtt: prms.task.mqtt
|
|
||||||
});
|
});
|
||||||
//Если результат обработки ошибка - пробрасываем её дальше
|
//Если результат обработки ошибка - пробрасываем её дальше
|
||||||
if (res instanceof ServerError) {
|
if (res instanceof ServerError) {
|
||||||
throw res;
|
throw res;
|
||||||
} else {
|
} else {
|
||||||
//Нет ошибки, посмотрим что прилетело сообщение в успешном статусе и тогда по необходимости запустим обработку сервером БД
|
//Нет ошибки, посмотрим что прилетело сообщение в успешном статусе и тогда запустим обработку сервером БД
|
||||||
if (res.nExecState == objQueueSchema.NQUEUE_EXEC_STATE_APP_OK) {
|
if (res.nExecState == objQueueSchema.NQUEUE_EXEC_STATE_APP_OK) {
|
||||||
//Если это не MQTT/MQTTS/Kafka - запустим обработку сервером БД, иначе установим статус успешного выполнения
|
|
||||||
if (
|
|
||||||
![objServiceSchema.SPROTOCOL_KAFKA, objServiceSchema.SPROTOCOL_MQTT, objServiceSchema.SPROTOCOL_MQTTS].includes(
|
|
||||||
getURLProtocol(prms.task.service.sSrvRoot)
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
res = await dbProcess({ queue: res, function: prms.task.function });
|
res = await dbProcess({ queue: res, function: prms.task.function });
|
||||||
//Если результат обработки ошибка - пробрасываем её дальше
|
//Если результат обработки ошибка - пробрасываем её дальше
|
||||||
if (res instanceof ServerError) throw res;
|
if (res instanceof ServerError) throw res;
|
||||||
} else {
|
|
||||||
//Финализируем обработку
|
|
||||||
await dbConn.setQueueState({
|
|
||||||
nQueueId: q.nId,
|
|
||||||
sExecMsg: null,
|
|
||||||
nIncExecCnt: q.nExecCnt == 0 ? NINC_EXEC_CNT_YES : NINC_EXEC_CNT_NO,
|
|
||||||
nExecState: objQueueSchema.NQUEUE_EXEC_STATE_OK
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
137
core/utils.js
137
core/utils.js
@ -7,7 +7,6 @@
|
|||||||
// Подключение библиотек
|
// Подключение библиотек
|
||||||
//----------------------
|
//----------------------
|
||||||
|
|
||||||
const fs = require("fs"); //Работа с файлами
|
|
||||||
const _ = require("lodash"); //Работа с массивами и объектами
|
const _ = require("lodash"); //Работа с массивами и объектами
|
||||||
const os = require("os"); //Средства операционной системы
|
const os = require("os"); //Средства операционной системы
|
||||||
const xml2js = require("xml2js"); //Конвертация XML в JSON
|
const xml2js = require("xml2js"); //Конвертация XML в JSON
|
||||||
@ -23,7 +22,6 @@ const {
|
|||||||
} = require("./constants"); //Глобавльные константы системы
|
} = require("./constants"); //Глобавльные константы системы
|
||||||
const { ServerError } = require("./server_errors"); //Ошибка сервера
|
const { ServerError } = require("./server_errors"); //Ошибка сервера
|
||||||
const prmsUtilsSchema = require("../models/prms_utils"); //Схемы валидации параметров функций
|
const prmsUtilsSchema = require("../models/prms_utils"); //Схемы валидации параметров функций
|
||||||
const { SPROTOCOL_HTTP, SPROTOCOL_KAFKA } = require("../models/obj_service"); //Схемы валидации сервиса
|
|
||||||
|
|
||||||
//------------
|
//------------
|
||||||
// Тело модуля
|
// Тело модуля
|
||||||
@ -47,7 +45,9 @@ const validateObject = (obj, schema, sObjName) => {
|
|||||||
let a = errors.map(e => {
|
let a = errors.map(e => {
|
||||||
return e.message;
|
return e.message;
|
||||||
});
|
});
|
||||||
sRes = `Объект${sObjName ? ` "${sObjName}" ` : " "}имеет некорректный формат: ${_.uniq(a).join("; ")}`;
|
sRes = `Объект${sObjName ? ` "${sObjName}" ` : " "}имеет некорректный формат: ${_.uniq(a).join(
|
||||||
|
"; "
|
||||||
|
)}`;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//Валидатор вернул не то, что мы ожидали
|
//Валидатор вернул не то, что мы ожидали
|
||||||
@ -142,7 +142,8 @@ const getAppSrvFunction = sAppSrv => {
|
|||||||
//Объявим формат (для сообщений об ошибках)
|
//Объявим формат (для сообщений об ошибках)
|
||||||
const sFormat = "(ожидаемый формат: <МОДУЛЬ>/<ФУНКЦИЯ>)";
|
const sFormat = "(ожидаемый формат: <МОДУЛЬ>/<ФУНКЦИЯ>)";
|
||||||
//Проверим, что есть что разбирать
|
//Проверим, что есть что разбирать
|
||||||
if (!sAppSrv) throw new ServerError(SERR_MODULES_NO_MODULE_SPECIFIED, `Не указаны модуль и функция обработчика ${sFormat}`);
|
if (!sAppSrv)
|
||||||
|
throw new ServerError(SERR_MODULES_NO_MODULE_SPECIFIED, `Не указаны модуль и функция обработчика ${sFormat}`);
|
||||||
//Разбираем
|
//Разбираем
|
||||||
try {
|
try {
|
||||||
//Разбираем на модуль и функцию
|
//Разбираем на модуль и функцию
|
||||||
@ -174,7 +175,11 @@ const getAppSrvFunction = sAppSrv => {
|
|||||||
const sendMail = prms => {
|
const sendMail = prms => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
//Проверяем структуру переданного объекта для отправки E-Mail уведомления
|
//Проверяем структуру переданного объекта для отправки E-Mail уведомления
|
||||||
let sCheckResult = validateObject(prms, prmsUtilsSchema.sendMail, "Параметры функции отправки E-Mail уведомления");
|
let sCheckResult = validateObject(
|
||||||
|
prms,
|
||||||
|
prmsUtilsSchema.sendMail,
|
||||||
|
"Параметры функции отправки E-Mail уведомления"
|
||||||
|
);
|
||||||
//Если структура объекта в норме
|
//Если структура объекта в норме
|
||||||
if (!sCheckResult) {
|
if (!sCheckResult) {
|
||||||
//Формируем параметры для подключения к SMTP
|
//Формируем параметры для подключения к SMTP
|
||||||
@ -191,7 +196,7 @@ const sendMail = prms => {
|
|||||||
transpOptions.auth = {
|
transpOptions.auth = {
|
||||||
user: prms.mail.sUser,
|
user: prms.mail.sUser,
|
||||||
pass: prms.mail.sPass
|
pass: prms.mail.sPass
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
//Настраиваем подключение к SMTP-серверу
|
//Настраиваем подключение к SMTP-серверу
|
||||||
let transporter = nodemailer.createTransport(transpOptions);
|
let transporter = nodemailer.createTransport(transpOptions);
|
||||||
@ -210,7 +215,12 @@ const sendMail = prms => {
|
|||||||
reject(new ServerError(SERR_MAIL_FAILED, `${error.code}: ${error}`));
|
reject(new ServerError(SERR_MAIL_FAILED, `${error.code}: ${error}`));
|
||||||
} else {
|
} else {
|
||||||
if (info.rejected && Array.isArray(info.rejected) && info.rejected.length > 0) {
|
if (info.rejected && Array.isArray(info.rejected) && info.rejected.length > 0) {
|
||||||
reject(new ServerError(SERR_MAIL_FAILED, `Сообщение не доствлено адресатам: ${info.rejected.join(", ")}`));
|
reject(
|
||||||
|
new ServerError(
|
||||||
|
SERR_MAIL_FAILED,
|
||||||
|
`Сообщение не доствлено адресатам: ${info.rejected.join(", ")}`
|
||||||
|
)
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
resolve(info);
|
resolve(info);
|
||||||
}
|
}
|
||||||
@ -229,7 +239,7 @@ const buildURL = prms => {
|
|||||||
//Если структура объекта в норме
|
//Если структура объекта в норме
|
||||||
if (!sCheckResult) {
|
if (!sCheckResult) {
|
||||||
//Формируем URL с учетом лишних "/"
|
//Формируем URL с учетом лишних "/"
|
||||||
return `${prms.sSrvRoot.replace(/\/+$/, "")}/${prms.sFnURL.replace(/^\/+/, "")}${prms.sQuery ? `?${prms.sQuery}` : ""}`;
|
return `${prms.sSrvRoot.replace(/\/+$/, '')}/${prms.sFnURL.replace(/^\/+/, '')}${prms.sQuery ? `?${prms.sQuery}` : ""}`;
|
||||||
} else {
|
} else {
|
||||||
throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
|
throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
|
||||||
}
|
}
|
||||||
@ -273,7 +283,11 @@ const parseXML = prms => {
|
|||||||
//Разбор параметров сообщения/ответа (XML > JSON)
|
//Разбор параметров сообщения/ответа (XML > JSON)
|
||||||
const parseOptionsXML = async prms => {
|
const parseOptionsXML = async prms => {
|
||||||
//Проверяем структуру переданных параметров
|
//Проверяем структуру переданных параметров
|
||||||
let sCheckResult = validateObject(prms, prmsUtilsSchema.parseOptionsXML, "Параметры функции разбора XML параметров сообщения/ответа");
|
let sCheckResult = validateObject(
|
||||||
|
prms,
|
||||||
|
prmsUtilsSchema.parseOptionsXML,
|
||||||
|
"Параметры функции разбора XML параметров сообщения/ответа"
|
||||||
|
);
|
||||||
//Если структура объекта в норме
|
//Если структура объекта в норме
|
||||||
if (!sCheckResult) {
|
if (!sCheckResult) {
|
||||||
try {
|
try {
|
||||||
@ -297,7 +311,11 @@ const parseOptionsXML = async prms => {
|
|||||||
//Сборка параметров сообщения/ответа (JSON > XML)
|
//Сборка параметров сообщения/ответа (JSON > XML)
|
||||||
const buildOptionsXML = prms => {
|
const buildOptionsXML = prms => {
|
||||||
//Проверяем структуру переданных параметров
|
//Проверяем структуру переданных параметров
|
||||||
let sCheckResult = validateObject(prms, prmsUtilsSchema.buildOptionsXML, "Параметры функции сборки XML параметров сообщения/ответа");
|
let sCheckResult = validateObject(
|
||||||
|
prms,
|
||||||
|
prmsUtilsSchema.buildOptionsXML,
|
||||||
|
"Параметры функции сборки XML параметров сообщения/ответа"
|
||||||
|
);
|
||||||
//Если структура объекта в норме
|
//Если структура объекта в норме
|
||||||
if (!sCheckResult) {
|
if (!sCheckResult) {
|
||||||
try {
|
try {
|
||||||
@ -328,97 +346,6 @@ const deepMerge = (...args) => {
|
|||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
//Глубокое копирование объекта
|
|
||||||
const deepCopyObject = obj => JSON.parse(JSON.stringify(obj));
|
|
||||||
|
|
||||||
//Проверка на undefined
|
|
||||||
const isUndefined = value => value === undefined;
|
|
||||||
|
|
||||||
//Считывание параметров подключения для сервиса обмена (при service === "" считывание подключения "По умолчанию", settingsArray - массив объектов [{sService: "", ...},...])
|
|
||||||
const getConnectionSettings = (service, settingsArray) => {
|
|
||||||
//Считываем параметры и возвращаем
|
|
||||||
return settingsArray.find(connection => {
|
|
||||||
return connection.sService === service;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
//Считывание параметров подключения к Kafka для сервиса обмена (kafka - массив объектов [{sService: "", ...},...])
|
|
||||||
const getKafkaConnectionSettings = (service, kafka) => {
|
|
||||||
//Считываем подключение с указанным сервисом обмена
|
|
||||||
let kafkaConnection = getConnectionSettings(service, kafka);
|
|
||||||
//Если нет подключения с указанным сервисом обмена
|
|
||||||
if (!kafkaConnection) {
|
|
||||||
//Считываем "По умолчанию"
|
|
||||||
kafkaConnection = getConnectionSettings("", kafka);
|
|
||||||
}
|
|
||||||
//Вернем результат
|
|
||||||
return kafkaConnection;
|
|
||||||
};
|
|
||||||
|
|
||||||
//Считывание параметров подключения к MQTT для сервиса обмена (mqtt - массив объектов [{sService: "", ...},...])
|
|
||||||
const getMQTTConnectionSettings = (service, mqtt) => {
|
|
||||||
//Считываем подключение с указанным сервисом обмена
|
|
||||||
let mqttConnection = getConnectionSettings(service, mqtt);
|
|
||||||
//Если нет подключения с указанным сервисом обмена
|
|
||||||
if (!mqttConnection) {
|
|
||||||
//Считываем "По умолчанию"
|
|
||||||
mqttConnection = getConnectionSettings("", mqtt);
|
|
||||||
}
|
|
||||||
//Вернем результат
|
|
||||||
return mqttConnection;
|
|
||||||
};
|
|
||||||
|
|
||||||
//Получение брокера Kafka по адресу сервиса обмена (прим. kafka://server.ru -> server.ru, https://server.ru => undefined)
|
|
||||||
const getKafkaBroker = sURL => {
|
|
||||||
//Если протокол URL - Kafka
|
|
||||||
if (getURLProtocol(sURL) === SPROTOCOL_KAFKA) {
|
|
||||||
//Возвращаем брокера
|
|
||||||
return sURL.slice(8);
|
|
||||||
}
|
|
||||||
//Возвращаем undefined
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
//Получение авторизации для Kafka
|
|
||||||
const getKafkaAuth = (sUser, sPass, kafka) => {
|
|
||||||
//Если аутентификация по SSL-сертификату
|
|
||||||
if (kafka.bAuthSSL) {
|
|
||||||
//Возвращаем авторизацию в формате SSL
|
|
||||||
return {
|
|
||||||
ssl: {
|
|
||||||
rejectUnauthorized: kafka.ssl.bRejectUnauthorized,
|
|
||||||
ca: kafka.ssl.sPathCa ? [fs.readFileSync(kafka.ssl.sPathCa, "utf-8")] : [],
|
|
||||||
key: kafka.ssl.sPathKey ? fs.readFileSync(kafka.ssl.sPathKey, "utf-8") : "",
|
|
||||||
cert: kafka.ssl.sPathCert ? fs.readFileSync(kafka.ssl.sPathCert, "utf-8") : ""
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
//Возвращаем авторизацию по пользователю, если необходимо
|
|
||||||
return sUser ? { ssl: true, sasl: { mechanism: "plain", username: sUser, password: sPass } } : null;
|
|
||||||
};
|
|
||||||
|
|
||||||
//Получение протокола адреса (прим. mqtt://server.ru -> mqtt, https://server.ru => https, ...)
|
|
||||||
const getURLProtocol = sURL => {
|
|
||||||
//Если начинается с "/" - HTTP, иначе получаем из URL
|
|
||||||
return sURL.substring(0, 1) === "/" ? SPROTOCOL_HTTP : new URL(sURL).protocol.slice(0, -1);
|
|
||||||
};
|
|
||||||
|
|
||||||
//Обёртывание промиса в таймаут исполнения
|
|
||||||
const wrapPromiseTimeout = (timeout, promise) => {
|
|
||||||
if (!timeout) return promise;
|
|
||||||
let timeoutPid;
|
|
||||||
const timeoutPromise = new Promise((resolve, reject) => {
|
|
||||||
const sMessage = `Истёк интервал ожидания (${timeout} мс) завершения асинхронного процесса.`;
|
|
||||||
let e = new Error(sMessage);
|
|
||||||
e.error = sMessage;
|
|
||||||
timeoutPid = setTimeout(() => reject(e), timeout);
|
|
||||||
});
|
|
||||||
return Promise.race([promise, timeoutPromise]).finally(() => {
|
|
||||||
if (promise.promise().isPending()) promise.cancel();
|
|
||||||
if (timeoutPid) clearTimeout(timeoutPid);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
//-----------------
|
//-----------------
|
||||||
// Интерфейс модуля
|
// Интерфейс модуля
|
||||||
//-----------------
|
//-----------------
|
||||||
@ -437,11 +364,3 @@ exports.parseOptionsXML = parseOptionsXML;
|
|||||||
exports.buildOptionsXML = buildOptionsXML;
|
exports.buildOptionsXML = buildOptionsXML;
|
||||||
exports.getNowString = getNowString;
|
exports.getNowString = getNowString;
|
||||||
exports.deepMerge = deepMerge;
|
exports.deepMerge = deepMerge;
|
||||||
exports.deepCopyObject = deepCopyObject;
|
|
||||||
exports.isUndefined = isUndefined;
|
|
||||||
exports.getKafkaConnectionSettings = getKafkaConnectionSettings;
|
|
||||||
exports.getMQTTConnectionSettings = getMQTTConnectionSettings;
|
|
||||||
exports.getKafkaBroker = getKafkaBroker;
|
|
||||||
exports.getKafkaAuth = getKafkaAuth;
|
|
||||||
exports.getURLProtocol = getURLProtocol;
|
|
||||||
exports.wrapPromiseTimeout = wrapPromiseTimeout;
|
|
||||||
|
@ -24,63 +24,13 @@ const validateAsyncFunctionType = val => {
|
|||||||
|
|
||||||
//Схема валидации подключаемого модуля взаимодействия с БД
|
//Схема валидации подключаемого модуля взаимодействия с БД
|
||||||
exports.dbConnectorModule = new Schema({
|
exports.dbConnectorModule = new Schema({
|
||||||
//Тип данных - строка БД
|
|
||||||
DT_VARCHAR: {
|
|
||||||
required: true,
|
|
||||||
message: {
|
|
||||||
required: path => `Не реализована константа для типа данных "Строка" БД (${path})`
|
|
||||||
}
|
|
||||||
},
|
|
||||||
//Тип данных - число БД
|
|
||||||
DT_NUMBER: {
|
|
||||||
required: true,
|
|
||||||
message: {
|
|
||||||
required: path => `Не реализована константа для типа данных "Число" БД (${path})`
|
|
||||||
}
|
|
||||||
},
|
|
||||||
//Тип данных - дата БД
|
|
||||||
DT_DATE: {
|
|
||||||
required: true,
|
|
||||||
message: {
|
|
||||||
required: path => `Не реализована константа для типа данных "Дата" БД (${path})`
|
|
||||||
}
|
|
||||||
},
|
|
||||||
//Тип данных - текстовые данные БД
|
|
||||||
DT_CLOB: {
|
|
||||||
required: true,
|
|
||||||
message: {
|
|
||||||
required: path => `Не реализована константа для типа данных "Текстовые данные" БД (${path})`
|
|
||||||
}
|
|
||||||
},
|
|
||||||
//Тип данных - двоичные данные БД
|
|
||||||
DT_BLOB: {
|
|
||||||
required: true,
|
|
||||||
message: {
|
|
||||||
required: path => `Не реализована константа для типа данных "Двоичные данные" БД (${path})`
|
|
||||||
}
|
|
||||||
},
|
|
||||||
//Тип данных - курсор БД
|
|
||||||
DT_CURSOR: {
|
|
||||||
required: true,
|
|
||||||
message: {
|
|
||||||
required: path => `Не реализована константа для типа данных "Курсор" БД (${path})`
|
|
||||||
}
|
|
||||||
},
|
|
||||||
//Исполнение хранимого объекта БД
|
|
||||||
executeStored: {
|
|
||||||
use: { validateAsyncFunctionType },
|
|
||||||
required: true,
|
|
||||||
message: {
|
|
||||||
validateAsyncFunctionType: path => `Функция исполнения хранимого объекта БД (${path}) имеет неверный формат (ожидалось - AsyncFunction)`,
|
|
||||||
required: path => `Не реализована функция исполнения хранимого объекта БД (${path})`
|
|
||||||
}
|
|
||||||
},
|
|
||||||
//Подключение к БД
|
//Подключение к БД
|
||||||
connect: {
|
connect: {
|
||||||
use: { validateAsyncFunctionType },
|
use: { validateAsyncFunctionType },
|
||||||
required: true,
|
required: true,
|
||||||
message: {
|
message: {
|
||||||
validateAsyncFunctionType: path => `Функция подключения к БД (${path}) имеет неверный формат (ожидалось - AsyncFunction)`,
|
validateAsyncFunctionType: path =>
|
||||||
|
`Функция подключения к БД (${path}) имеет неверный формат (ожидалось - AsyncFunction)`,
|
||||||
required: path => `Не реализована функция подключения к БД (${path})`
|
required: path => `Не реализована функция подключения к БД (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -89,7 +39,8 @@ exports.dbConnectorModule = new Schema({
|
|||||||
use: { validateAsyncFunctionType },
|
use: { validateAsyncFunctionType },
|
||||||
required: true,
|
required: true,
|
||||||
message: {
|
message: {
|
||||||
validateAsyncFunctionType: path => `Функция отключения от БД (${path}) имеет неверный формат (ожидалось - AsyncFunction)`,
|
validateAsyncFunctionType: path =>
|
||||||
|
`Функция отключения от БД (${path}) имеет неверный формат (ожидалось - AsyncFunction)`,
|
||||||
required: path => `Не реализована функция отключения от БД (${path})`
|
required: path => `Не реализована функция отключения от БД (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -98,7 +49,8 @@ exports.dbConnectorModule = new Schema({
|
|||||||
use: { validateAsyncFunctionType },
|
use: { validateAsyncFunctionType },
|
||||||
required: true,
|
required: true,
|
||||||
message: {
|
message: {
|
||||||
validateAsyncFunctionType: path => `Функция получения списка сервисов (${path}) имеет неверный формат (ожидалось - AsyncFunction)`,
|
validateAsyncFunctionType: path =>
|
||||||
|
`Функция получения списка сервисов (${path}) имеет неверный формат (ожидалось - AsyncFunction)`,
|
||||||
required: path => `Не реализована функция получения списка сервисов (${path})`
|
required: path => `Не реализована функция получения списка сервисов (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -107,7 +59,8 @@ exports.dbConnectorModule = new Schema({
|
|||||||
use: { validateAsyncFunctionType },
|
use: { validateAsyncFunctionType },
|
||||||
required: true,
|
required: true,
|
||||||
message: {
|
message: {
|
||||||
validateAsyncFunctionType: path => `Функция получения списка функций сервиса (${path}) имеет неверный формат (ожидалось - AsyncFunction)`,
|
validateAsyncFunctionType: path =>
|
||||||
|
`Функция получения списка функций сервиса (${path}) имеет неверный формат (ожидалось - AsyncFunction)`,
|
||||||
required: path => `Не реализована функция получения списка функций сервиса (${path})`
|
required: path => `Не реализована функция получения списка функций сервиса (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -116,7 +69,8 @@ exports.dbConnectorModule = new Schema({
|
|||||||
use: { validateAsyncFunctionType },
|
use: { validateAsyncFunctionType },
|
||||||
required: true,
|
required: true,
|
||||||
message: {
|
message: {
|
||||||
validateAsyncFunctionType: path => `Функция получения контекста сервиса (${path}) имеет неверный формат (ожидалось - AsyncFunction)`,
|
validateAsyncFunctionType: path =>
|
||||||
|
`Функция получения контекста сервиса (${path}) имеет неверный формат (ожидалось - AsyncFunction)`,
|
||||||
required: path => `Не реализована функция получения контекста сервиса (${path})`
|
required: path => `Не реализована функция получения контекста сервиса (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -125,7 +79,8 @@ exports.dbConnectorModule = new Schema({
|
|||||||
use: { validateAsyncFunctionType },
|
use: { validateAsyncFunctionType },
|
||||||
required: true,
|
required: true,
|
||||||
message: {
|
message: {
|
||||||
validateAsyncFunctionType: path => `Функция установки контекста сервиса (${path}) имеет неверный формат (ожидалось - AsyncFunction)`,
|
validateAsyncFunctionType: path =>
|
||||||
|
`Функция установки контекста сервиса (${path}) имеет неверный формат (ожидалось - AsyncFunction)`,
|
||||||
required: path => `Не реализована функция установки контекста сервиса (${path})`
|
required: path => `Не реализована функция установки контекста сервиса (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -134,7 +89,8 @@ exports.dbConnectorModule = new Schema({
|
|||||||
use: { validateAsyncFunctionType },
|
use: { validateAsyncFunctionType },
|
||||||
required: true,
|
required: true,
|
||||||
message: {
|
message: {
|
||||||
validateAsyncFunctionType: path => `Функция очистки контекста сервиса (${path}) имеет неверный формат (ожидалось - AsyncFunction)`,
|
validateAsyncFunctionType: path =>
|
||||||
|
`Функция очистки контекста сервиса (${path}) имеет неверный формат (ожидалось - AsyncFunction)`,
|
||||||
required: path => `Не реализована функция очистки контекста сервиса (${path})`
|
required: path => `Не реализована функция очистки контекста сервиса (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -165,7 +121,8 @@ exports.dbConnectorModule = new Schema({
|
|||||||
message: {
|
message: {
|
||||||
validateAsyncFunctionType: path =>
|
validateAsyncFunctionType: path =>
|
||||||
`Функция получения информации о просроченных сообщениях обмена сервиса (${path}) имеет неверный формат (ожидалось - AsyncFunction)`,
|
`Функция получения информации о просроченных сообщениях обмена сервиса (${path}) имеет неверный формат (ожидалось - AsyncFunction)`,
|
||||||
required: path => `Не реализована функция получения информации о просроченных сообщениях обмена сервиса (${path})`
|
required: path =>
|
||||||
|
`Не реализована функция получения информации о просроченных сообщениях обмена сервиса (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
//Протоколирование работы сервиса
|
//Протоколирование работы сервиса
|
||||||
@ -173,7 +130,8 @@ exports.dbConnectorModule = new Schema({
|
|||||||
use: { validateAsyncFunctionType },
|
use: { validateAsyncFunctionType },
|
||||||
required: true,
|
required: true,
|
||||||
message: {
|
message: {
|
||||||
validateAsyncFunctionType: path => `Функция протоколирования работы сервиса (${path}) имеет неверный формат (ожидалось - AsyncFunction)`,
|
validateAsyncFunctionType: path =>
|
||||||
|
`Функция протоколирования работы сервиса (${path}) имеет неверный формат (ожидалось - AsyncFunction)`,
|
||||||
required: path => `Не реализована функция протоколирования работы сервиса (${path})`
|
required: path => `Не реализована функция протоколирования работы сервиса (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -182,7 +140,8 @@ exports.dbConnectorModule = new Schema({
|
|||||||
use: { validateAsyncFunctionType },
|
use: { validateAsyncFunctionType },
|
||||||
required: true,
|
required: true,
|
||||||
message: {
|
message: {
|
||||||
validateAsyncFunctionType: path => `Функция считывания записи очереди обмена (${path}) имеет неверный формат (ожидалось - AsyncFunction)`,
|
validateAsyncFunctionType: path =>
|
||||||
|
`Функция считывания записи очереди обмена (${path}) имеет неверный формат (ожидалось - AsyncFunction)`,
|
||||||
required: path => `Не реализована функция считывания записи очереди обмена (${path})`
|
required: path => `Не реализована функция считывания записи очереди обмена (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -191,7 +150,8 @@ exports.dbConnectorModule = new Schema({
|
|||||||
use: { validateAsyncFunctionType },
|
use: { validateAsyncFunctionType },
|
||||||
required: true,
|
required: true,
|
||||||
message: {
|
message: {
|
||||||
validateAsyncFunctionType: path => `Функция добавления сообщения очереди (${path}) имеет неверный формат (ожидалось - AsyncFunction)`,
|
validateAsyncFunctionType: path =>
|
||||||
|
`Функция добавления сообщения очереди (${path}) имеет неверный формат (ожидалось - AsyncFunction)`,
|
||||||
required: path => `Не реализована функция добавления сообщения очереди (${path})`
|
required: path => `Не реализована функция добавления сообщения очереди (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -272,7 +232,8 @@ exports.dbConnectorModule = new Schema({
|
|||||||
message: {
|
message: {
|
||||||
validateAsyncFunctionType: path =>
|
validateAsyncFunctionType: path =>
|
||||||
`Функция установки параметров результата обработки сообщения очереди (${path}) имеет неверный формат (ожидалось - AsyncFunction)`,
|
`Функция установки параметров результата обработки сообщения очереди (${path}) имеет неверный формат (ожидалось - AsyncFunction)`,
|
||||||
required: path => `Не реализована функция установки параметров результата обработки сообщения очереди (${path})`
|
required: path =>
|
||||||
|
`Не реализована функция установки параметров результата обработки сообщения очереди (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
//Исполнение обработчика со стороны БД для сообщения очереди
|
//Исполнение обработчика со стороны БД для сообщения очереди
|
||||||
@ -282,7 +243,8 @@ exports.dbConnectorModule = new Schema({
|
|||||||
message: {
|
message: {
|
||||||
validateAsyncFunctionType: path =>
|
validateAsyncFunctionType: path =>
|
||||||
`Функция исполнения обработчика со стороны БД для сообщения очереди (${path}) имеет неверный формат (ожидалось - AsyncFunction)`,
|
`Функция исполнения обработчика со стороны БД для сообщения очереди (${path}) имеет неверный формат (ожидалось - AsyncFunction)`,
|
||||||
required: path => `Не реализована функция исполнения обработчика со стороны БД для сообщения очереди (${path})`
|
required: path =>
|
||||||
|
`Не реализована функция исполнения обработчика со стороны БД для сообщения очереди (${path})`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -13,9 +13,6 @@ const Schema = require("validate"); //Схемы валидации
|
|||||||
// Тело модуля
|
// Тело модуля
|
||||||
//-------------
|
//-------------
|
||||||
|
|
||||||
//Функция проверки длины значения наименование сервера приложений
|
|
||||||
const validateServerName = val => val.length <= 40;
|
|
||||||
|
|
||||||
//Функция проверки значения таймаута останова сервера
|
//Функция проверки значения таймаута останова сервера
|
||||||
const validateTerminateTimeout = val => val >= 1000 && val <= 120000 && Number.isInteger(val);
|
const validateTerminateTimeout = val => val >= 1000 && val <= 120000 && Number.isInteger(val);
|
||||||
|
|
||||||
@ -51,16 +48,6 @@ const validatePoolIncrementInComing = val => val >= 0 && val <= 1000;
|
|||||||
|
|
||||||
//Схема валидации общих параметров сервера приложений
|
//Схема валидации общих параметров сервера приложений
|
||||||
const common = new Schema({
|
const common = new Schema({
|
||||||
//Наименование сервера приложений
|
|
||||||
sServerName: {
|
|
||||||
type: String,
|
|
||||||
required: false,
|
|
||||||
use: { validateServerName },
|
|
||||||
message: {
|
|
||||||
type: path => `Наименование сервера приложений (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
|
||||||
validateServerName: path => `Длина наименования сервера приложений (${path}) не может превышать 40 символов`
|
|
||||||
}
|
|
||||||
},
|
|
||||||
//Версия сервера приложений
|
//Версия сервера приложений
|
||||||
sVersion: {
|
sVersion: {
|
||||||
type: String,
|
type: String,
|
||||||
|
@ -33,13 +33,6 @@ const NIS_AUTH_NO = 0; //Неаутентифицирован
|
|||||||
const SIS_AUTH_YES = "IS_AUTH_YES"; //Аутентифицирован (строковый код)
|
const SIS_AUTH_YES = "IS_AUTH_YES"; //Аутентифицирован (строковый код)
|
||||||
const SIS_AUTH_NO = "IS_AUTH_NO"; //Неаутентифицирован (строковый код)
|
const SIS_AUTH_NO = "IS_AUTH_NO"; //Неаутентифицирован (строковый код)
|
||||||
|
|
||||||
//Протоколы работы сервиса
|
|
||||||
const SPROTOCOL_HTTP = "http"; //Протокол HTTP
|
|
||||||
const SPROTOCOL_HTTPS = "https"; //Протокол HTTPS
|
|
||||||
const SPROTOCOL_MQTT = "mqtt"; //Протокол MQTT
|
|
||||||
const SPROTOCOL_MQTTS = "mqtts"; //Протокол MQTTS
|
|
||||||
const SPROTOCOL_KAFKA = "kafka"; //Протокол для работы с KAFKA
|
|
||||||
|
|
||||||
//-------------
|
//-------------
|
||||||
// Тело модуля
|
// Тело модуля
|
||||||
//-------------
|
//-------------
|
||||||
@ -66,11 +59,6 @@ exports.NIS_AUTH_YES = NIS_AUTH_YES;
|
|||||||
exports.NIS_AUTH_NO = NIS_AUTH_NO;
|
exports.NIS_AUTH_NO = NIS_AUTH_NO;
|
||||||
exports.SIS_AUTH_YES = SIS_AUTH_YES;
|
exports.SIS_AUTH_YES = SIS_AUTH_YES;
|
||||||
exports.SIS_AUTH_NO = SIS_AUTH_NO;
|
exports.SIS_AUTH_NO = SIS_AUTH_NO;
|
||||||
exports.SPROTOCOL_HTTP = SPROTOCOL_HTTP;
|
|
||||||
exports.SPROTOCOL_HTTPS = SPROTOCOL_HTTPS;
|
|
||||||
exports.SPROTOCOL_MQTT = SPROTOCOL_MQTT;
|
|
||||||
exports.SPROTOCOL_MQTTS = SPROTOCOL_MQTTS;
|
|
||||||
exports.SPROTOCOL_KAFKA = SPROTOCOL_KAFKA;
|
|
||||||
|
|
||||||
//Схема валидации сервиса
|
//Схема валидации сервиса
|
||||||
exports.Service = new Schema({
|
exports.Service = new Schema({
|
||||||
@ -156,8 +144,10 @@ exports.Service = new Schema({
|
|||||||
enum: [NUNAVLBL_NTF_SIGN_NO, NUNAVLBL_NTF_SIGN_YES],
|
enum: [NUNAVLBL_NTF_SIGN_NO, NUNAVLBL_NTF_SIGN_YES],
|
||||||
required: true,
|
required: true,
|
||||||
message: {
|
message: {
|
||||||
type: path => `Признак необходимости оповещения о простое внешнего сервиса (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
type: path =>
|
||||||
enum: path => `Значение признака необходимости оповещения о простое внешнего сервиса (${path}) не поддерживается`,
|
`Признак необходимости оповещения о простое внешнего сервиса (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
||||||
|
enum: path =>
|
||||||
|
`Значение признака необходимости оповещения о простое внешнего сервиса (${path}) не поддерживается`,
|
||||||
required: path => `Не указан признак необходимости оповещения о простое внешнего сервиса (${path})`
|
required: path => `Не указан признак необходимости оповещения о простое внешнего сервиса (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -169,8 +159,10 @@ exports.Service = new Schema({
|
|||||||
message: {
|
message: {
|
||||||
type: path =>
|
type: path =>
|
||||||
`Строковый код признака необходимости оповещения о простое внешнего сервиса (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
`Строковый код признака необходимости оповещения о простое внешнего сервиса (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
||||||
enum: path => `Значение строкового кода признака необходимости оповещения о простое внешнего сервиса (${path}) не поддерживается`,
|
enum: path =>
|
||||||
required: path => `Не указан строковый код признака необходимости оповещения о простое внешнего сервиса (${path})`
|
`Значение строкового кода признака необходимости оповещения о простое внешнего сервиса (${path}) не поддерживается`,
|
||||||
|
required: path =>
|
||||||
|
`Не указан строковый код признака необходимости оповещения о простое внешнего сервиса (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
//Максимальное время простоя (мин) удалённого сервиса для генерации оповещения
|
//Максимальное время простоя (мин) удалённого сервиса для генерации оповещения
|
||||||
@ -180,7 +172,8 @@ exports.Service = new Schema({
|
|||||||
message: {
|
message: {
|
||||||
type: path =>
|
type: path =>
|
||||||
`Максимальное время простоя (мин) удалённого сервиса для генерации оповещения (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
`Максимальное время простоя (мин) удалённого сервиса для генерации оповещения (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
||||||
required: path => `Не указано максимальное время простоя (мин) удалённого сервиса для генерации оповещения (${path})`
|
required: path =>
|
||||||
|
`Не указано максимальное время простоя (мин) удалённого сервиса для генерации оповещения (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
//Список адресов E-Mail для оповещения о простое внешнего сервиса
|
//Список адресов E-Mail для оповещения о простое внешнего сервиса
|
||||||
@ -201,7 +194,8 @@ exports.Service = new Schema({
|
|||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false,
|
||||||
message: {
|
message: {
|
||||||
type: path => `Адрес прокси-сервера в очереди обмена (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
type: path =>
|
||||||
|
`Адрес прокси-сервера в очереди обмена (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
||||||
required: path => `Не указан адрес прокси-сервера в очереди обмена (${path})`
|
required: path => `Не указан адрес прокси-сервера в очереди обмена (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -243,7 +237,8 @@ exports.ServiceCtx = new Schema({
|
|||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false,
|
||||||
message: {
|
message: {
|
||||||
type: path => `Строковое представление даты истечения контекста (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
type: path =>
|
||||||
|
`Строковое представление даты истечения контекста (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
||||||
required: path => `Не указано строковое представление даты истечения контекста (${path})`
|
required: path => `Не указано строковое представление даты истечения контекста (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -253,7 +248,8 @@ exports.ServiceCtx = new Schema({
|
|||||||
enum: [NIS_AUTH_YES, NIS_AUTH_NO],
|
enum: [NIS_AUTH_YES, NIS_AUTH_NO],
|
||||||
required: true,
|
required: true,
|
||||||
message: {
|
message: {
|
||||||
type: path => `Признака аутентицированности сервиса (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
type: path =>
|
||||||
|
`Признака аутентицированности сервиса (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
||||||
enum: path => `Значение признака аутентицированности сервиса (${path}) не поддерживается`,
|
enum: path => `Значение признака аутентицированности сервиса (${path}) не поддерживается`,
|
||||||
required: path => `Не указан признак аутентицированности сервиса (${path})`
|
required: path => `Не указан признак аутентицированности сервиса (${path})`
|
||||||
}
|
}
|
||||||
@ -264,7 +260,8 @@ exports.ServiceCtx = new Schema({
|
|||||||
enum: [SIS_AUTH_YES, SIS_AUTH_NO],
|
enum: [SIS_AUTH_YES, SIS_AUTH_NO],
|
||||||
required: true,
|
required: true,
|
||||||
message: {
|
message: {
|
||||||
type: path => `Строковый код признака аутентицированности сервиса (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
type: path =>
|
||||||
|
`Строковый код признака аутентицированности сервиса (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
||||||
enum: path => `Значение строкового кода признака аутентицированности сервиса (${path}) не поддерживается`,
|
enum: path => `Значение строкового кода признака аутентицированности сервиса (${path}) не поддерживается`,
|
||||||
required: path => `Не указан строковый код признака аутентицированности сервиса (${path})`
|
required: path => `Не указан строковый код признака аутентицированности сервиса (${path})`
|
||||||
}
|
}
|
||||||
@ -287,7 +284,8 @@ exports.ServiceExpiredQueueInfo = new Schema({
|
|||||||
type: Number,
|
type: Number,
|
||||||
required: true,
|
required: true,
|
||||||
message: {
|
message: {
|
||||||
type: path => `Количество просроченных сообщений обмена (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
type: path =>
|
||||||
|
`Количество просроченных сообщений обмена (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
||||||
required: path => `Не указано количество просроченных сообщений обмена (${path})`
|
required: path => `Не указано количество просроченных сообщений обмена (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -296,7 +294,8 @@ exports.ServiceExpiredQueueInfo = new Schema({
|
|||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
message: {
|
message: {
|
||||||
type: path => `Информация о просроченных сообщениях обмена (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
type: path =>
|
||||||
|
`Информация о просроченных сообщениях обмена (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
||||||
required: path => `Не указана информация о просроченных сообщениях обмена (${path})`
|
required: path => `Не указана информация о просроченных сообщениях обмена (${path})`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,7 +156,8 @@ exports.ServiceFunction = new Schema({
|
|||||||
type: Number,
|
type: Number,
|
||||||
required: true,
|
required: true,
|
||||||
message: {
|
message: {
|
||||||
type: path => `Идентификатор родительского сервиса функции (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
type: path =>
|
||||||
|
`Идентификатор родительского сервиса функции (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
||||||
required: path => `Не указан идентификатор родительского сервиса функции (${path})`
|
required: path => `Не указан идентификатор родительского сервиса функции (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -186,7 +187,8 @@ exports.ServiceFunction = new Schema({
|
|||||||
enum: [SFN_TYPE_DATA, SFN_TYPE_LOGIN, SFN_TYPE_LOGOUT],
|
enum: [SFN_TYPE_DATA, SFN_TYPE_LOGIN, SFN_TYPE_LOGOUT],
|
||||||
required: true,
|
required: true,
|
||||||
message: {
|
message: {
|
||||||
type: path => `Строковый код типа функции сервиса (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
type: path =>
|
||||||
|
`Строковый код типа функции сервиса (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
||||||
enum: path => `Значение строкового кода типа функции сервиса (${path}) не поддерживается`,
|
enum: path => `Значение строкового кода типа функции сервиса (${path}) не поддерживается`,
|
||||||
required: path => `Не указан строковый код типа функции сервиса (${path})`
|
required: path => `Не указан строковый код типа функции сервиса (${path})`
|
||||||
}
|
}
|
||||||
@ -216,7 +218,8 @@ exports.ServiceFunction = new Schema({
|
|||||||
],
|
],
|
||||||
required: true,
|
required: true,
|
||||||
message: {
|
message: {
|
||||||
type: path => `Способ передачи параметров функции сервиса (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
type: path =>
|
||||||
|
`Способ передачи параметров функции сервиса (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
||||||
enum: path => `Значение способа передачи параметров функции сервиса (${path}) не поддерживается`,
|
enum: path => `Значение способа передачи параметров функции сервиса (${path}) не поддерживается`,
|
||||||
required: path => `Не указан способ передачи параметров функции сервиса (${path})`
|
required: path => `Не указан способ передачи параметров функции сервиса (${path})`
|
||||||
}
|
}
|
||||||
@ -237,8 +240,10 @@ exports.ServiceFunction = new Schema({
|
|||||||
],
|
],
|
||||||
required: true,
|
required: true,
|
||||||
message: {
|
message: {
|
||||||
type: path => `Строковый код способа передачи параметров функции сервиса (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
type: path =>
|
||||||
enum: path => `Значение строкового кода способа передачи параметров функции сервиса (${path}) не поддерживается`,
|
`Строковый код способа передачи параметров функции сервиса (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
||||||
|
enum: path =>
|
||||||
|
`Значение строкового кода способа передачи параметров функции сервиса (${path}) не поддерживается`,
|
||||||
required: path => `Не указан строковый код способа передачи параметров функции сервиса (${path})`
|
required: path => `Не указан строковый код способа передачи параметров функции сервиса (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -256,7 +261,8 @@ exports.ServiceFunction = new Schema({
|
|||||||
],
|
],
|
||||||
required: true,
|
required: true,
|
||||||
message: {
|
message: {
|
||||||
type: path => `График повторной отправки запроса функции сервиса (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
type: path =>
|
||||||
|
`График повторной отправки запроса функции сервиса (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
||||||
enum: path => `Значение графика повторной отправки запроса функции сервиса (${path}) не поддерживается`,
|
enum: path => `Значение графика повторной отправки запроса функции сервиса (${path}) не поддерживается`,
|
||||||
required: path => `Не указан график повторной отправки запроса функции сервиса (${path})`
|
required: path => `Не указан график повторной отправки запроса функции сервиса (${path})`
|
||||||
}
|
}
|
||||||
@ -277,7 +283,8 @@ exports.ServiceFunction = new Schema({
|
|||||||
message: {
|
message: {
|
||||||
type: path =>
|
type: path =>
|
||||||
`Строковый код графика повторной отправки запроса функции сервиса (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
`Строковый код графика повторной отправки запроса функции сервиса (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
||||||
enum: path => `Значение строкового кода графика повторной отправки запроса функции сервиса (${path}) не поддерживается`,
|
enum: path =>
|
||||||
|
`Значение строкового кода графика повторной отправки запроса функции сервиса (${path}) не поддерживается`,
|
||||||
required: path => `Не указан строковый код графика повторной отправки запроса функции сервиса (${path})`
|
required: path => `Не указан строковый код графика повторной отправки запроса функции сервиса (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -288,7 +295,8 @@ exports.ServiceFunction = new Schema({
|
|||||||
message: {
|
message: {
|
||||||
type: path =>
|
type: path =>
|
||||||
`Идентификатор типового сообщения обмена, обрабатываемого функцией сервиса (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
`Идентификатор типового сообщения обмена, обрабатываемого функцией сервиса (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
||||||
required: path => `Не указан идентификатор типового сообщения обмена, обрабатываемого функцией сервиса (${path})`
|
required: path =>
|
||||||
|
`Не указан идентификатор типового сообщения обмена, обрабатываемого функцией сервиса (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
//Код типового сообщения обмена, обрабатываемого функцией сервиса
|
//Код типового сообщения обмена, обрабатываемого функцией сервиса
|
||||||
@ -306,7 +314,8 @@ exports.ServiceFunction = new Schema({
|
|||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false,
|
||||||
message: {
|
message: {
|
||||||
type: path => `Обработчик сообщения со стороны БД для функции сервиса (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
type: path =>
|
||||||
|
`Обработчик сообщения со стороны БД для функции сервиса (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
||||||
required: path => `Не указан обработчик сообщения со стороны БД для функции сервиса (${path})`
|
required: path => `Не указан обработчик сообщения со стороны БД для функции сервиса (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -318,7 +327,8 @@ exports.ServiceFunction = new Schema({
|
|||||||
message: {
|
message: {
|
||||||
type: path =>
|
type: path =>
|
||||||
`Обработчик сообщения 'до' на строне сервера приложений для функции сервиса (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
`Обработчик сообщения 'до' на строне сервера приложений для функции сервиса (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
||||||
required: path => `Не указан обработчик сообщения 'до' на строне сервера приложений для функции сервиса (${path})`,
|
required: path =>
|
||||||
|
`Не указан обработчик сообщения 'до' на строне сервера приложений для функции сервиса (${path})`,
|
||||||
validateAppSrvFn: path =>
|
validateAppSrvFn: path =>
|
||||||
`Обработчик сообщения 'до' на строне сервера приложений для функции сервиса (${path}) имеет некорректный формат, ожидалось: <МОДУЛЬ>.js/<ФУНКЦИЯ>`
|
`Обработчик сообщения 'до' на строне сервера приложений для функции сервиса (${path}) имеет некорректный формат, ожидалось: <МОДУЛЬ>.js/<ФУНКЦИЯ>`
|
||||||
}
|
}
|
||||||
@ -331,7 +341,8 @@ exports.ServiceFunction = new Schema({
|
|||||||
message: {
|
message: {
|
||||||
type: path =>
|
type: path =>
|
||||||
`Обработчик сообщения 'после' на строне сервера приложений для функции сервиса (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
`Обработчик сообщения 'после' на строне сервера приложений для функции сервиса (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
||||||
required: path => `Не указан обработчик сообщения 'после' на строне сервера приложений для функции сервиса (${path})`,
|
required: path =>
|
||||||
|
`Не указан обработчик сообщения 'после' на строне сервера приложений для функции сервиса (${path})`,
|
||||||
validateAppSrvFn: path =>
|
validateAppSrvFn: path =>
|
||||||
`Обработчик сообщения 'после' на строне сервера приложений для функции сервиса (${path}) имеет некорректный формат, ожидалось: <МОДУЛЬ>.js/<ФУНКЦИЯ>`
|
`Обработчик сообщения 'после' на строне сервера приложений для функции сервиса (${path}) имеет некорректный формат, ожидалось: <МОДУЛЬ>.js/<ФУНКЦИЯ>`
|
||||||
}
|
}
|
||||||
@ -344,8 +355,10 @@ exports.ServiceFunction = new Schema({
|
|||||||
message: {
|
message: {
|
||||||
type: path =>
|
type: path =>
|
||||||
`Признак необходимости аутентификации для исполнения функции сервсиа обмена (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
`Признак необходимости аутентификации для исполнения функции сервсиа обмена (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
||||||
enum: path => `Значение признака необходимости аутентификации для исполнения функции сервсиа обмена (${path}) не поддерживается`,
|
enum: path =>
|
||||||
required: path => `Не указан признак необходимости аутентификации для исполнения функции сервсиа обмена (${path})`
|
`Значение признака необходимости аутентификации для исполнения функции сервсиа обмена (${path}) не поддерживается`,
|
||||||
|
required: path =>
|
||||||
|
`Не указан признак необходимости аутентификации для исполнения функции сервсиа обмена (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
//Признак необходимости аутентификации для исполнения функции сервсиа обмена (строковый код)
|
//Признак необходимости аутентификации для исполнения функции сервсиа обмена (строковый код)
|
||||||
@ -358,7 +371,8 @@ exports.ServiceFunction = new Schema({
|
|||||||
`Строковый код признака необходимости аутентификации для исполнения функции сервсиа обмена (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
`Строковый код признака необходимости аутентификации для исполнения функции сервсиа обмена (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
||||||
enum: path =>
|
enum: path =>
|
||||||
`Значение строкового кода признака необходимости аутентификации для исполнения функции сервсиа обмена (${path}) не поддерживается`,
|
`Значение строкового кода признака необходимости аутентификации для исполнения функции сервсиа обмена (${path}) не поддерживается`,
|
||||||
required: path => `Не указан строковый код признака необходимости аутентификации для исполнения функции сервсиа обмена (${path})`
|
required: path =>
|
||||||
|
`Не указан строковый код признака необходимости аутентификации для исполнения функции сервсиа обмена (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
//Признак оповещения об ошибке исполнения сообщения очереди для функции обработки
|
//Признак оповещения об ошибке исполнения сообщения очереди для функции обработки
|
||||||
@ -369,8 +383,10 @@ exports.ServiceFunction = new Schema({
|
|||||||
message: {
|
message: {
|
||||||
type: path =>
|
type: path =>
|
||||||
`Признак оповещения об ошибке исполнения сообщения очереди для функции обработки (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
`Признак оповещения об ошибке исполнения сообщения очереди для функции обработки (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
||||||
enum: path => `Значение признака оповещения об ошибке исполнения сообщения очереди для функции обработки (${path}) не поддерживается`,
|
enum: path =>
|
||||||
required: path => `Не указан признак оповещения об ошибке исполнения сообщения очереди для функции обработки (${path})`
|
`Значение признака оповещения об ошибке исполнения сообщения очереди для функции обработки (${path}) не поддерживается`,
|
||||||
|
required: path =>
|
||||||
|
`Не указан признак оповещения об ошибке исполнения сообщения очереди для функции обработки (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
//Признак оповещения об ошибке исполнения сообщения очереди для функции обработки (строковый код)
|
//Признак оповещения об ошибке исполнения сообщения очереди для функции обработки (строковый код)
|
||||||
@ -383,7 +399,8 @@ exports.ServiceFunction = new Schema({
|
|||||||
`Строковый код признака оповещения об ошибке исполнения сообщения очереди для функции обработки (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
`Строковый код признака оповещения об ошибке исполнения сообщения очереди для функции обработки (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
||||||
enum: path =>
|
enum: path =>
|
||||||
`Значение строкового кода признака оповещения об ошибке исполнения сообщения очереди для функции обработки (${path}) не поддерживается`,
|
`Значение строкового кода признака оповещения об ошибке исполнения сообщения очереди для функции обработки (${path}) не поддерживается`,
|
||||||
required: path => `Не указан строковый код признака оповещения об ошибке исполнения сообщения очереди для функции обработки (${path})`
|
required: path =>
|
||||||
|
`Не указан строковый код признака оповещения об ошибке исполнения сообщения очереди для функции обработки (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
//Список адресов E-Mail для оповещения об ошибке исполнения сообщения очереди для функции обработки
|
//Список адресов E-Mail для оповещения об ошибке исполнения сообщения очереди для функции обработки
|
||||||
@ -394,25 +411,10 @@ exports.ServiceFunction = new Schema({
|
|||||||
message: {
|
message: {
|
||||||
type: path =>
|
type: path =>
|
||||||
`Список адресов E-Mail для оповещения об ошибке исполнения сообщения очереди для функции обработки (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
`Список адресов E-Mail для оповещения об ошибке исполнения сообщения очереди для функции обработки (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
||||||
required: path => `Не указан список адресов E-Mail для оповещения об ошибке исполнения сообщения очереди для функции обработки (${path})`,
|
required: path =>
|
||||||
|
`Не указан список адресов E-Mail для оповещения об ошибке исполнения сообщения очереди для функции обработки (${path})`,
|
||||||
validateErrNtfMail: path =>
|
validateErrNtfMail: path =>
|
||||||
`Неверный формат списка адресов E-Mail для оповещения об ошибке исполнения сообщения очереди для функции обработки (${path}), для указания нескольких адресов следует использовать запятую в качестве разделителя (без пробелов)`
|
`Неверный формат списка адресов E-Mail для оповещения об ошибке исполнения сообщения очереди для функции обработки (${path}), для указания нескольких адресов следует использовать запятую в качестве разделителя (без пробелов)`
|
||||||
}
|
}
|
||||||
},
|
|
||||||
//Таймаут сетевого подключения (мс)
|
|
||||||
nTimeoutConn: {
|
|
||||||
type: Number,
|
|
||||||
required: false,
|
|
||||||
message: {
|
|
||||||
type: path => `Таймаут сетевого подключения функции сервиса (${path}) имеет некорректный тип данных (ожидалось - Number)`
|
|
||||||
}
|
|
||||||
},
|
|
||||||
//Таймаут асинхронной отправки (мс)
|
|
||||||
nTimeoutAsynch: {
|
|
||||||
type: Number,
|
|
||||||
required: false,
|
|
||||||
message: {
|
|
||||||
type: path => `Таймаут асинхронной отправки функции сервиса (${path}) имеет некорректный тип данных (ожидалось - Number)`
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -174,7 +174,8 @@ exports.putServiceAuthInQueue = new Schema({
|
|||||||
required: false,
|
required: false,
|
||||||
enum: [NFORCE_YES, NFORCE_NO],
|
enum: [NFORCE_YES, NFORCE_NO],
|
||||||
message: {
|
message: {
|
||||||
type: path => `Признак принудительного завершения сессии (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
type: path =>
|
||||||
|
`Признак принудительного завершения сессии (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
||||||
enum: path => `Значение признака принудительного завершения сессии (${path}) не поддерживается`,
|
enum: path => `Значение признака принудительного завершения сессии (${path}) не поддерживается`,
|
||||||
required: path => `Не указан признак принудительного завершения сессии (${path})`
|
required: path => `Не указан признак принудительного завершения сессии (${path})`
|
||||||
}
|
}
|
||||||
@ -202,7 +203,8 @@ exports.putLog = new Schema({
|
|||||||
enum: [NLOG_STATE_INF, NLOG_STATE_WRN, NLOG_STATE_ERR],
|
enum: [NLOG_STATE_INF, NLOG_STATE_WRN, NLOG_STATE_ERR],
|
||||||
required: true,
|
required: true,
|
||||||
message: {
|
message: {
|
||||||
type: path => `Тип сообщения журнала работы сервиса (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
type: path =>
|
||||||
|
`Тип сообщения журнала работы сервиса (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
||||||
enum: path => `Значение типа сообщения журнала работы сервиса (${path}) не поддерживается`,
|
enum: path => `Значение типа сообщения журнала работы сервиса (${path}) не поддерживается`,
|
||||||
required: path => `Не указан тип сообщения журнала работы сервиса (${path})`
|
required: path => `Не указан тип сообщения журнала работы сервиса (${path})`
|
||||||
}
|
}
|
||||||
@ -212,7 +214,8 @@ exports.putLog = new Schema({
|
|||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false,
|
||||||
message: {
|
message: {
|
||||||
type: path => `Сообщение журнала работы сервиса (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
type: path =>
|
||||||
|
`Сообщение журнала работы сервиса (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
||||||
required: path => `Не указано сообщение журнала работы сервиса (${path})`
|
required: path => `Не указано сообщение журнала работы сервиса (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -233,7 +236,8 @@ exports.putLog = new Schema({
|
|||||||
message: {
|
message: {
|
||||||
type: path =>
|
type: path =>
|
||||||
`Идентификатор связанной функции-обработчика сообщения журнала работы сервиса (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
`Идентификатор связанной функции-обработчика сообщения журнала работы сервиса (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
||||||
required: path => `Не указан идентификатор связанной функции-обработчика сообщения журнала работы сервиса (${path})`
|
required: path =>
|
||||||
|
`Не указан идентификатор связанной функции-обработчика сообщения журнала работы сервиса (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
//Идентификатор связанной позиции очереди обмена
|
//Идентификатор связанной позиции очереди обмена
|
||||||
@ -243,7 +247,8 @@ exports.putLog = new Schema({
|
|||||||
message: {
|
message: {
|
||||||
type: path =>
|
type: path =>
|
||||||
`Идентификатор связанной позиции очереди обмена сообщения журнала работы сервиса (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
`Идентификатор связанной позиции очереди обмена сообщения журнала работы сервиса (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
||||||
required: path => `Не указан идентификатор связанной позиции очереди обмена сообщения журнала работы сервиса (${path})`
|
required: path =>
|
||||||
|
`Не указан идентификатор связанной позиции очереди обмена сообщения журнала работы сервиса (${path})`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -255,7 +260,8 @@ exports.getQueue = new Schema({
|
|||||||
type: Number,
|
type: Number,
|
||||||
required: true,
|
required: true,
|
||||||
message: {
|
message: {
|
||||||
type: path => `Идентификатор позиции очереди обмена (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
type: path =>
|
||||||
|
`Идентификатор позиции очереди обмена (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
||||||
required: path => `Не указан идентификатор позиции очереди обмена (${path})`
|
required: path => `Не указан идентификатор позиции очереди обмена (${path})`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -268,7 +274,8 @@ exports.putQueue = new Schema({
|
|||||||
type: Number,
|
type: Number,
|
||||||
required: true,
|
required: true,
|
||||||
message: {
|
message: {
|
||||||
type: path => `Идентификатор функции сервиса обработчика позиции очереди (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
type: path =>
|
||||||
|
`Идентификатор функции сервиса обработчика позиции очереди (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
||||||
required: path => `Не указан идентификатор функции сервиса обработчика позиции очереди (${path})`
|
required: path => `Не указан идентификатор функции сервиса обработчика позиции очереди (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -277,7 +284,8 @@ exports.putQueue = new Schema({
|
|||||||
use: { validateBuffer },
|
use: { validateBuffer },
|
||||||
required: false,
|
required: false,
|
||||||
message: {
|
message: {
|
||||||
validateBuffer: path => `Данные сообщения очереди обмена (${path}) имеют некорректный тип данных (ожидалось - null или Buffer)`,
|
validateBuffer: path =>
|
||||||
|
`Данные сообщения очереди обмена (${path}) имеют некорректный тип данных (ожидалось - null или Buffer)`,
|
||||||
required: path => `Не указаны данные сообщения очереди обмена (${path})`
|
required: path => `Не указаны данные сообщения очереди обмена (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -286,7 +294,8 @@ exports.putQueue = new Schema({
|
|||||||
type: Number,
|
type: Number,
|
||||||
required: false,
|
required: false,
|
||||||
message: {
|
message: {
|
||||||
type: path => `Идентификатор связанной позиции очереди обмена (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
type: path =>
|
||||||
|
`Идентификатор связанной позиции очереди обмена (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
||||||
required: path => `Не указан идентификатор связанной позиции очереди обмена (${path})`
|
required: path => `Не указан идентификатор связанной позиции очереди обмена (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -295,7 +304,8 @@ exports.putQueue = new Schema({
|
|||||||
type: Number,
|
type: Number,
|
||||||
required: false,
|
required: false,
|
||||||
message: {
|
message: {
|
||||||
type: path => `Идентификатор связанной организации (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
type: path =>
|
||||||
|
`Идентификатор связанной организации (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
||||||
required: path => `Не указан идентификатор связанной организации (${path})`
|
required: path => `Не указан идентификатор связанной организации (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -304,7 +314,8 @@ exports.putQueue = new Schema({
|
|||||||
type: Number,
|
type: Number,
|
||||||
required: false,
|
required: false,
|
||||||
message: {
|
message: {
|
||||||
type: path => `Идентификатор связанного документа (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
type: path =>
|
||||||
|
`Идентификатор связанного документа (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
||||||
required: path => `Не указан идентификатор связанного документа (${path})`
|
required: path => `Не указан идентификатор связанного документа (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -335,7 +346,8 @@ exports.getOutgoing = new Schema({
|
|||||||
type: Number,
|
type: Number,
|
||||||
required: true,
|
required: true,
|
||||||
message: {
|
message: {
|
||||||
type: path => `Количество считываемых сообщений очереди (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
type: path =>
|
||||||
|
`Количество считываемых сообщений очереди (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
||||||
required: path => `Не указано количество считываемых сообщений очереди (${path})`
|
required: path => `Не указано количество считываемых сообщений очереди (${path})`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -388,7 +400,8 @@ exports.setQueueState = new Schema({
|
|||||||
enum: [NINC_EXEC_CNT_NO, NINC_EXEC_CNT_YES],
|
enum: [NINC_EXEC_CNT_NO, NINC_EXEC_CNT_YES],
|
||||||
required: false,
|
required: false,
|
||||||
message: {
|
message: {
|
||||||
type: path => `Флаг инкремента количества исполнений (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
type: path =>
|
||||||
|
`Флаг инкремента количества исполнений (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
||||||
enum: path => `Значение флага инкремента количества исполнений (${path}) не поддерживается`,
|
enum: path => `Значение флага инкремента количества исполнений (${path}) не поддерживается`,
|
||||||
required: path => `Не указан флаг икремента количества исполнений (${path})`
|
required: path => `Не указан флаг икремента количества исполнений (${path})`
|
||||||
}
|
}
|
||||||
@ -435,7 +448,8 @@ exports.setQueueMsg = new Schema({
|
|||||||
use: { validateBuffer },
|
use: { validateBuffer },
|
||||||
required: true,
|
required: true,
|
||||||
message: {
|
message: {
|
||||||
validateBuffer: path => `Данные сообщения очереди обмена (${path}) имеют некорректный тип данных (ожидалось - null или Buffer)`,
|
validateBuffer: path =>
|
||||||
|
`Данные сообщения очереди обмена (${path}) имеют некорректный тип данных (ожидалось - null или Buffer)`,
|
||||||
required: path => `Не указаны данные сообщения очереди обмена (${path})`
|
required: path => `Не указаны данные сообщения очереди обмена (${path})`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -457,7 +471,8 @@ exports.setQueueOptions = new Schema({
|
|||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
message: {
|
message: {
|
||||||
validateBuffer: path => `Парамметры сообщения очереди обмена (${path}) имеют некорректный тип данных (ожидалось - String)`,
|
validateBuffer: path =>
|
||||||
|
`Парамметры сообщения очереди обмена (${path}) имеют некорректный тип данных (ожидалось - String)`,
|
||||||
required: path => `Не указаны параметры сообщения очереди обмена (${path})`
|
required: path => `Не указаны параметры сообщения очереди обмена (${path})`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -492,7 +507,8 @@ exports.setQueueResp = new Schema({
|
|||||||
use: { validateBuffer },
|
use: { validateBuffer },
|
||||||
required: true,
|
required: true,
|
||||||
message: {
|
message: {
|
||||||
validateBuffer: path => `Данные ответа сообщения очереди обмена (${path}) имеют некорректный тип данных (ожидалось - null или Buffer)`,
|
validateBuffer: path =>
|
||||||
|
`Данные ответа сообщения очереди обмена (${path}) имеют некорректный тип данных (ожидалось - null или Buffer)`,
|
||||||
required: path => `Не указаны данные ответа сообщения очереди обмена (${path})`
|
required: path => `Не указаны данные ответа сообщения очереди обмена (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -502,7 +518,8 @@ exports.setQueueResp = new Schema({
|
|||||||
enum: [NIS_ORIGINAL_NO, NIS_ORIGINAL_YES],
|
enum: [NIS_ORIGINAL_NO, NIS_ORIGINAL_YES],
|
||||||
required: true,
|
required: true,
|
||||||
message: {
|
message: {
|
||||||
type: path => `Признак передачи оригинала ответа (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
type: path =>
|
||||||
|
`Признак передачи оригинала ответа (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
||||||
enum: path => `Значение признака передачи оригинала ответа (${path}) не поддерживается`,
|
enum: path => `Значение признака передачи оригинала ответа (${path}) не поддерживается`,
|
||||||
required: path => `Не указан признак передачи оригинала ответа (${path})`
|
required: path => `Не указан признак передачи оригинала ответа (${path})`
|
||||||
}
|
}
|
||||||
@ -525,7 +542,8 @@ exports.setQueueOptionsResp = new Schema({
|
|||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
message: {
|
message: {
|
||||||
validateBuffer: path => `Парамметры ответа на сообщение очереди обмена (${path}) имеют некорректный тип данных (ожидалось - String)`,
|
validateBuffer: path =>
|
||||||
|
`Парамметры ответа на сообщение очереди обмена (${path}) имеют некорректный тип данных (ожидалось - String)`,
|
||||||
required: path => `Не указаны параметры ответа на сообщение очереди обмена (${path})`
|
required: path => `Не указаны параметры ответа на сообщение очереди обмена (${path})`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -547,7 +565,8 @@ exports.setQueueAppSrvResult = new Schema({
|
|||||||
use: { validateBuffer },
|
use: { validateBuffer },
|
||||||
required: true,
|
required: true,
|
||||||
message: {
|
message: {
|
||||||
validateBuffer: path => `Данные сообщения очереди обмена (${path}) имеют некорректный тип данных (ожидалось - null или Buffer)`,
|
validateBuffer: path =>
|
||||||
|
`Данные сообщения очереди обмена (${path}) имеют некорректный тип данных (ожидалось - null или Buffer)`,
|
||||||
required: path => `Не указаны данные сообщения очереди обмена (${path})`
|
required: path => `Не указаны данные сообщения очереди обмена (${path})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -556,7 +575,8 @@ exports.setQueueAppSrvResult = new Schema({
|
|||||||
use: { validateBuffer },
|
use: { validateBuffer },
|
||||||
required: true,
|
required: true,
|
||||||
message: {
|
message: {
|
||||||
validateBuffer: path => `Данные ответа сообщения очереди обмена (${path}) имеют некорректный тип данных (ожидалось - null или Buffer)`,
|
validateBuffer: path =>
|
||||||
|
`Данные ответа сообщения очереди обмена (${path}) имеют некорректный тип данных (ожидалось - null или Buffer)`,
|
||||||
required: path => `Не указаны данные ответа сообщения очереди обмена (${path})`
|
required: path => `Не указаны данные ответа сообщения очереди обмена (${path})`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
const xml2js = require("xml2js"); //Конвертация XML в JSON и JSON в XML
|
const xml2js = require("xml2js"); //Конвертация XML в JSON и JSON в XML
|
||||||
const _ = require("lodash"); //Работа с коллекциями и объектами
|
const _ = require("lodash"); //Работа с коллекциями и объектами
|
||||||
const rqp = require("request-promise"); //Работа с HTTP/HTTPS запросами
|
const rqp = require("request-promise"); //Работа с HTTP/HTTPS запросами
|
||||||
const config = require("../config"); //Параметры сервера
|
|
||||||
const { SDDAUTH_API_CLIENT_ID, SDEPARTMENT_NAME, SDEPARTMENT_ID } = require("./diadoc_config"); //Ключ разработчика
|
const { SDDAUTH_API_CLIENT_ID, SDEPARTMENT_NAME, SDEPARTMENT_ID } = require("./diadoc_config"); //Ключ разработчика
|
||||||
|
|
||||||
//---------------------
|
//---------------------
|
||||||
@ -20,7 +19,6 @@ const { SDDAUTH_API_CLIENT_ID, SDEPARTMENT_NAME, SDEPARTMENT_ID } = require("./d
|
|||||||
// Список тегов которые должны содержать массив
|
// Список тегов которые должны содержать массив
|
||||||
const tag = [
|
const tag = [
|
||||||
"DocumentAttachments",
|
"DocumentAttachments",
|
||||||
"Metadata",
|
|
||||||
"Signatures",
|
"Signatures",
|
||||||
"CorrectionRequests",
|
"CorrectionRequests",
|
||||||
"Receipts",
|
"Receipts",
|
||||||
@ -35,18 +33,8 @@ const tag = [
|
|||||||
//------------
|
//------------
|
||||||
|
|
||||||
//формирования адреса запроса для получения данных о текущей организации пользователя
|
//формирования адреса запроса для получения данных о текущей организации пользователя
|
||||||
const buildMyOrganizationURL = srvRoot => {
|
|
||||||
return `${srvRoot.replace(/\/+$/, "")}/GetMyOrganizations`;
|
|
||||||
};
|
|
||||||
|
|
||||||
//формирования адреса запроса для получения данных о организации по идентификатору ящика
|
|
||||||
const buildOrganizationBoxIdURL = srvRoot => {
|
|
||||||
return `${srvRoot.replace(/\/+$/, "")}/GetBox`;
|
|
||||||
};
|
|
||||||
|
|
||||||
//формирования адреса запроса для получения данных о организации по ИНН/КПП
|
|
||||||
const buildOrganizationURL = srvRoot => {
|
const buildOrganizationURL = srvRoot => {
|
||||||
return `${srvRoot.replace(/\/+$/, "")}/GetOrganization`;
|
return `${srvRoot.replace(/\/+$/, "")}/GetMyOrganizations`;
|
||||||
};
|
};
|
||||||
|
|
||||||
//формирования адреса запроса для получения данных о организации по ИНН/КПП
|
//формирования адреса запроса для получения данных о организации по ИНН/КПП
|
||||||
@ -57,13 +45,13 @@ const buildOrganizationsByInnKppURL = srvRoot => {
|
|||||||
//Обернуть содержимое тега в массив
|
//Обернуть содержимое тега в массив
|
||||||
const toArray = (obj, tags) => {
|
const toArray = (obj, tags) => {
|
||||||
for (const prop in obj) {
|
for (const prop in obj) {
|
||||||
let value = obj[prop];
|
const value = obj[prop];
|
||||||
if (typeof value === "object") {
|
|
||||||
obj[prop] = toArray(value, tag);
|
|
||||||
}
|
|
||||||
if (tags.indexOf(prop) != -1 && !_.isArray(obj[prop])) {
|
if (tags.indexOf(prop) != -1 && !_.isArray(obj[prop])) {
|
||||||
obj[prop] = JSON.parse("[" + JSON.stringify(value) + "]");
|
obj[prop] = JSON.parse("[" + JSON.stringify(value) + "]");
|
||||||
}
|
}
|
||||||
|
if (typeof value === "object") {
|
||||||
|
toArray(value, tag);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
};
|
};
|
||||||
@ -128,113 +116,34 @@ const checkAPIClientId = sAPIClientId => {
|
|||||||
|
|
||||||
//Формиорвание заголовка сообщения
|
//Формиорвание заголовка сообщения
|
||||||
const buildHeaders = (sAPIClientId, sToken = null) => ({
|
const buildHeaders = (sAPIClientId, sToken = null) => ({
|
||||||
"Content-type": "application/json",
|
"Content-type": "application/json; charset=utf-8",
|
||||||
"X-Solution-Info": `PARUS_${config.common.sRelease}`,
|
|
||||||
Authorization: `DiadocAuth ddauth_api_client_id=${sAPIClientId}${sToken ? `,ddauth_token=${sToken}` : ""}`,
|
Authorization: `DiadocAuth ddauth_api_client_id=${sAPIClientId}${sToken ? `,ddauth_token=${sToken}` : ""}`,
|
||||||
Accept: "application/json"
|
Accept: "application/json; charset=utf-8"
|
||||||
});
|
});
|
||||||
|
|
||||||
//Отбор организций
|
//Отбор организций
|
||||||
const getOrganizations = organizations => {
|
const GetOrganizations = Organizations => {
|
||||||
//Параметры отбора
|
//Параметры отбора
|
||||||
let isRoaming = false;
|
let isRoaming = false;
|
||||||
let isActive = true;
|
|
||||||
//Итоговая выборка
|
//Итоговая выборка
|
||||||
let organization = { Organizations: [] };
|
let Organization = { Organizations: [] };
|
||||||
//Найдем активную организацию не в роуминге
|
//Найдем организацию не в роуминге
|
||||||
organization.Organizations[0] = organizations.Organizations.find(org => (org.IsRoaming === isRoaming) && (org.IsActive === isActive));
|
Organization.Organizations[0] = Organizations.Organizations.find(Org => Org.IsRoaming === isRoaming);
|
||||||
//Если не удалось получить организацию не в роуминге
|
//Если не удалось получить организацию не в роуминге
|
||||||
if (!organization.Organizations[0]) {
|
if (!Organization.Organizations[0]) {
|
||||||
//Если нет организации не в роуминге и найдено более одной организации
|
//Если нет организации не в роуминге и найдено более одной организации
|
||||||
if (organizations.Organizations.length > 1) {
|
if (Organizations.Organizations.length > 1) {
|
||||||
throw Error(`Найдено несколько организаций в роуминге.`);
|
throw Error(`Найдено несколько организаций в роуминге.`);
|
||||||
} else {
|
} else {
|
||||||
//Вернем единственную найденую организацию
|
//Вернем единственную найденую организацию
|
||||||
return organizations[0];
|
return Organizations;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//Вернем найденую организацию
|
//Вернем найденую организацию
|
||||||
return organization;
|
return Organization;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//Получение организации по ИНН/КПП контрагента
|
|
||||||
const getOrganization = async (sSrvRoot, headers, nInn, nKpp) => {
|
|
||||||
//Параметры запроса
|
|
||||||
let rqpOptions;
|
|
||||||
let serverResp;
|
|
||||||
//Формируем запрос для получения BoxId
|
|
||||||
rqpOptions = {
|
|
||||||
uri: buildOrganizationURL(sSrvRoot),
|
|
||||||
qs: {
|
|
||||||
inn: nInn,
|
|
||||||
kpp: nKpp
|
|
||||||
},
|
|
||||||
headers: headers,
|
|
||||||
json: true
|
|
||||||
};
|
|
||||||
//Выполним запрос
|
|
||||||
serverResp = { Organizations: [await rqp(rqpOptions)] };
|
|
||||||
return serverResp;
|
|
||||||
};
|
|
||||||
|
|
||||||
//Получение ящика организации по ИНН/КПП контрагента
|
|
||||||
const getOrganizationBoxId = async (sSrvRoot, headers, nInn, nKpp) => {
|
|
||||||
//Параметры запроса
|
|
||||||
let rqpOptions;
|
|
||||||
let serverResp;
|
|
||||||
let organization = {};
|
|
||||||
//Формируем запрос для получения BoxId по ИНН/КПП
|
|
||||||
rqpOptions = {
|
|
||||||
uri: buildOrganizationsByInnKppURL(sSrvRoot),
|
|
||||||
qs: {
|
|
||||||
inn: nInn,
|
|
||||||
kpp: nKpp
|
|
||||||
},
|
|
||||||
headers: headers,
|
|
||||||
json: true
|
|
||||||
};
|
|
||||||
try {
|
|
||||||
//Выполним запрос
|
|
||||||
serverResp = await rqp(rqpOptions);
|
|
||||||
try {
|
|
||||||
//Получим организацию не в роуминге (или единственную организацию в роуминге)
|
|
||||||
serverResp = getOrganizations(serverResp);
|
|
||||||
if (!serverResp?.Organizations[0]) {
|
|
||||||
throw Error(`Не удалось получить ящик получателя для контрагента с ИНН: ${nInn} и КПП: ${nKpp}`);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
//Получим головную организацию по ИНН/КПП
|
|
||||||
serverResp = await getOrganization(sSrvRoot, headers, nInn, nKpp);
|
|
||||||
};
|
|
||||||
//Проверим соответствие КПП организации
|
|
||||||
if ((serverResp?.Organizations[0]?.Kpp != nKpp) && (serverResp?.Organizations[0])) {
|
|
||||||
//Если КПП не соответстует заданному - проверим, что в полученной организации есть департамент с заданным КПП
|
|
||||||
for (let i in serverResp.Organizations[0].Departments) {
|
|
||||||
//Если найден подходящий департамент - запомним идентификатор и выходим из цикла
|
|
||||||
if (serverResp.Organizations[0].Departments[i]?.Kpp == nKpp) {
|
|
||||||
//Сохраняем полученный ответ
|
|
||||||
organization.DepartmentId = serverResp.Organizations[0].Departments[i].DepartmentId;
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
//Не удалось получить ящик получателя или полученая организация не соответствует заданному ИНН
|
|
||||||
if ((!serverResp?.Organizations[0]?.Boxes[0]?.BoxId) || (serverResp?.Organizations[0]?.Inn != nInn)) {
|
|
||||||
throw new Error(`Не удалось получить ящик получателя для контрагента с ИНН: ${nInn} и КПП: ${nKpp}`);
|
|
||||||
}
|
|
||||||
//Не удалось получить департаментом с соответствующим КПП
|
|
||||||
if ((serverResp?.Organizations[0]?.Kpp != nKpp) && (!organization?.DepartmentId)) {
|
|
||||||
throw new Error(`Не удалось получить ящик получателя для контрагента с ИНН: ${nInn} и КПП: ${nKpp}, у головной организации отсутствует подразделение с КПП: ${nKpp}`);
|
|
||||||
}
|
|
||||||
//Сохраняем полученный ответ
|
|
||||||
organization.BoxId = serverResp.Organizations[0].Boxes[0].BoxId;
|
|
||||||
return organization;
|
|
||||||
} catch (e) {
|
|
||||||
throw Error(`Ошибка при получении ящика получателя: ${e.message}`);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
//Обработчик "До" подключения к сервису
|
//Обработчик "До" подключения к сервису
|
||||||
const beforeConnect = async prms => {
|
const beforeConnect = async prms => {
|
||||||
//Подготовим параметры аутентификации
|
//Подготовим параметры аутентификации
|
||||||
@ -293,17 +202,15 @@ const beforeMessagePost = async prms => {
|
|||||||
//Конвертируем XML из "Парус 8" в JSON
|
//Конвертируем XML из "Парус 8" в JSON
|
||||||
let obj = await toJSON(prms.queue.blMsg.toString());
|
let obj = await toJSON(prms.queue.blMsg.toString());
|
||||||
//Формируем запрос для получения FromBoxId
|
//Формируем запрос для получения FromBoxId
|
||||||
let rqpOptions = {
|
let rqpoptions = {
|
||||||
uri: buildMyOrganizationURL(prms.service.sSrvRoot),
|
uri: buildOrganizationURL(prms.service.sSrvRoot),
|
||||||
headers: buildHeaders(sAPIClientId, sToken),
|
headers: buildHeaders(sAPIClientId, sToken),
|
||||||
json: true
|
json: true
|
||||||
};
|
};
|
||||||
//Переменные для запросов
|
|
||||||
let serverResp;
|
let serverResp;
|
||||||
let organization;
|
|
||||||
try {
|
try {
|
||||||
//Выполним запрос
|
//Выполним запрос
|
||||||
serverResp = await rqp(rqpOptions);
|
serverResp = await rqp(rqpoptions);
|
||||||
//Получим идентификатор организации по ИНН/КПП поставщика документа
|
//Получим идентификатор организации по ИНН/КПП поставщика документа
|
||||||
for (let i in serverResp.Organizations) {
|
for (let i in serverResp.Organizations) {
|
||||||
//Если найдена подходящая организация - запомним идентификатор и выходим из цикла
|
//Если найдена подходящая организация - запомним идентификатор и выходим из цикла
|
||||||
@ -320,13 +227,33 @@ const beforeMessagePost = async prms => {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw Error(`Ошибка при получении ящика текущей организации: ${e.message}`);
|
throw Error(`Ошибка при получении ящика текущей организации: ${e.message}`);
|
||||||
}
|
}
|
||||||
//Получим ящик получателя
|
//Очистим предыдущий запрос
|
||||||
organization = await getOrganizationBoxId(prms.service.sSrvRoot, buildHeaders(sAPIClientId, sToken), prms.options.inn_cs, prms.options.kpp_cs);
|
rqpoptions = null;
|
||||||
obj.ToBoxId = organization.BoxId;
|
serverResp = null;
|
||||||
//Если не заполнен идентификатор подразделения и при получении ящика удалось его подобрать
|
//Формируем запрос для получения ToBoxId
|
||||||
if ((!obj.ToDepartmentId) && (organization.DepartmentId)) {
|
rqpoptions = {
|
||||||
obj.ToDepartmentId = organization.DepartmentId;
|
uri: buildOrganizationsByInnKppURL(prms.service.sSrvRoot),
|
||||||
|
qs: {
|
||||||
|
inn: prms.options.inn_cs,
|
||||||
|
kpp: prms.options.kpp_cs
|
||||||
|
},
|
||||||
|
headers: buildHeaders(sAPIClientId, sToken),
|
||||||
|
json: true
|
||||||
};
|
};
|
||||||
|
try {
|
||||||
|
//Выполним запрос
|
||||||
|
serverResp = await rqp(rqpoptions);
|
||||||
|
//Получим организацию не в роуминге (или единственную организацию в роуминге)
|
||||||
|
serverResp = GetOrganizations(serverResp);
|
||||||
|
//Не удалось получить ящик получателя
|
||||||
|
if (!serverResp.Organizations[0].Boxes[0].BoxId) {
|
||||||
|
throw new Error(`Не удалось получить ящик получателя для контрагента с ИНН: ${prms.options.inn_cs} и КПП: ${prms.options.kpp_cs}`);
|
||||||
|
}
|
||||||
|
//Сохраняем полученный ответ
|
||||||
|
obj.ToBoxId = serverResp.Organizations[0].Boxes[0].BoxId;
|
||||||
|
} catch (e) {
|
||||||
|
throw Error(`Ошибка при получении ящика получателя: ${e.message}`);
|
||||||
|
}
|
||||||
//Если пришел ответ
|
//Если пришел ответ
|
||||||
if (prms.queue.blResp && serverResp.statusCode == 200) {
|
if (prms.queue.blResp && serverResp.statusCode == 200) {
|
||||||
//Вернем загруженный документ
|
//Вернем загруженный документ
|
||||||
@ -449,14 +376,14 @@ const beforeEvent = async prms => {
|
|||||||
//Если не достали из контекста токен доступа - значит нет аутентификации на сервере
|
//Если не достали из контекста токен доступа - значит нет аутентификации на сервере
|
||||||
if (!sToken) return { bUnAuth: true };
|
if (!sToken) return { bUnAuth: true };
|
||||||
//Формируем запрос для получения BoxId
|
//Формируем запрос для получения BoxId
|
||||||
let rqpOptions = {
|
let rqpoptions = {
|
||||||
uri: buildMyOrganizationURL(prms.service.sSrvRoot),
|
uri: buildOrganizationURL(prms.service.sSrvRoot),
|
||||||
headers: buildHeaders(sAPIClientId, sToken),
|
headers: buildHeaders(sAPIClientId, sToken),
|
||||||
json: true
|
json: true
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
//Выполним запрос
|
//Выполним запрос
|
||||||
serverResp = await rqp(rqpOptions);
|
serverResp = await rqp(rqpoptions);
|
||||||
//Получим идентификатор организации по ИНН/КПП контрагента организации
|
//Получим идентификатор организации по ИНН/КПП контрагента организации
|
||||||
for (let i in serverResp.Organizations) {
|
for (let i in serverResp.Organizations) {
|
||||||
//Если найдена подходящая организация - запомним идентификатор и выходим из цикла
|
//Если найдена подходящая организация - запомним идентификатор и выходим из цикла
|
||||||
@ -530,97 +457,12 @@ const beforeEvent = async prms => {
|
|||||||
|
|
||||||
//Обработчик "После" запроса на получение новых событий к сервису "ДИАДОК"
|
//Обработчик "После" запроса на получение новых событий к сервису "ДИАДОК"
|
||||||
const afterEvent = async prms => {
|
const afterEvent = async prms => {
|
||||||
let sAPIClientId = null; //Ключ разработчика
|
let resu = null;
|
||||||
let sToken = null; //Токен доступа
|
|
||||||
let resu = null; //Ответ сервера
|
|
||||||
let rqpOptions = null; //Параметры для запроса информации по ящику
|
|
||||||
let serverResp; //Результат запроса информации по организации
|
|
||||||
let resp = null; //Ответ сервера
|
|
||||||
let box = null; //Информация ящика
|
|
||||||
let boxIds = { boxIds: [] }; //Список уникальных ящиков контрагентов
|
|
||||||
//Действие выполнено успешно
|
//Действие выполнено успешно
|
||||||
if (prms.optionsResp.statusCode == 200) {
|
if (prms.optionsResp.statusCode == 200) {
|
||||||
//Получим ключ разработчика
|
|
||||||
sAPIClientId = getAPIClientId(prms.options.nCompany, prms.options.nJurPers);
|
|
||||||
//Проверим ключ разработчика
|
|
||||||
checkAPIClientId(sAPIClientId);
|
|
||||||
//Разберем ответ сервера
|
|
||||||
resp = JSON.parse(prms.queue.blResp.toString());
|
|
||||||
//Получим список уникальных ящиков
|
|
||||||
for (let i in resp.Events) {
|
|
||||||
if (resp.Events[i]?.Message) {
|
|
||||||
if ((!boxIds.boxIds.find(box => box.boxId === resp.Events[i]?.Message.FromBoxId)) && (resp.Events[i]?.Message.FromBoxId)) {
|
|
||||||
boxIds.boxIds.push({ boxId: resp.Events[i]?.Message.FromBoxId });
|
|
||||||
}
|
|
||||||
if ((!boxIds.boxIds.find(box => box.boxId === resp.Events[i]?.Message.ToBoxId)) && (resp.Events[i]?.Message.ToBoxId)) {
|
|
||||||
boxIds.boxIds.push({ boxId: resp.Events[i]?.Message.ToBoxId });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Если требуется выполнить запросы доп. информации по ящикам организации
|
|
||||||
if (boxIds.boxIds.length) {
|
|
||||||
//Считаем токен доступа из контекста сервиса
|
|
||||||
if (prms.service.sCtx) {
|
|
||||||
sToken = prms.service.sCtx;
|
|
||||||
}
|
|
||||||
//Если не достали из контекста токен доступа - значит нет аутентификации на сервере
|
|
||||||
if (!sToken) return { bUnAuth: true };
|
|
||||||
for (let i in boxIds.boxIds) {
|
|
||||||
rqpOptions = null;
|
|
||||||
//Формируем запрос для получения BoxId
|
|
||||||
rqpOptions = {
|
|
||||||
uri: buildOrganizationBoxIdURL(prms.service.sSrvRoot),
|
|
||||||
headers: buildHeaders(sAPIClientId, sToken),
|
|
||||||
qs: {
|
|
||||||
boxId: boxIds.boxIds[i].boxId
|
|
||||||
},
|
|
||||||
json: true
|
|
||||||
};
|
|
||||||
try {
|
|
||||||
//Выполним запрос
|
|
||||||
serverResp = await rqp(rqpOptions);
|
|
||||||
if (serverResp?.Organization) {
|
|
||||||
//Запишем полученную информацию о контрагенте
|
|
||||||
boxIds.boxIds[i].Inn = serverResp?.Organization?.Inn;
|
|
||||||
boxIds.boxIds[i].Kpp = serverResp?.Organization?.Kpp;
|
|
||||||
boxIds.boxIds[i].FullName = serverResp?.Organization?.FullName;
|
|
||||||
boxIds.boxIds[i].ShortName = serverResp?.Organization?.ShortName;
|
|
||||||
boxIds.boxIds[i].FnsParticipantId = serverResp?.Organization?.FnsParticipantId;
|
|
||||||
} else {
|
|
||||||
//Не удалось получить информацию о контрагенте по ящику организации
|
|
||||||
throw new Error(`Не удалось получить информацию о контрагенте по ящику организации ${boxIds.boxIds[i].boxId}`);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
throw Error(`Ошибка при получении информации о контрагенте по ящику организации: ${e.message}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Добавим к ответу информацию о контрагентах ящика
|
|
||||||
for (let i in resp.Events) {
|
|
||||||
if (resp.Events[i]?.Message) {
|
|
||||||
//Если надо добавить информацию по ящику-отправителю
|
|
||||||
box = boxIds.boxIds.find(box => box.boxId === resp.Events[i]?.Message.FromBoxId);
|
|
||||||
if (box) {
|
|
||||||
resp.Events[i].Message.FromInn = box.Inn;
|
|
||||||
resp.Events[i].Message.FromKpp = box.Kpp;
|
|
||||||
resp.Events[i].Message.FromFullName = box.FullName;
|
|
||||||
resp.Events[i].Message.FromShortName = box.ShortName;
|
|
||||||
resp.Events[i].Message.FromFnsParticipantId = box.FnsParticipantId;
|
|
||||||
}
|
|
||||||
//Если надо добавить информацию по ящику-получателю
|
|
||||||
box = boxIds.boxIds.find(box => box.boxId === resp.Events[i]?.Message.ToBoxId);
|
|
||||||
if (box) {
|
|
||||||
resp.Events[i].Message.ToInn = box.Inn;
|
|
||||||
resp.Events[i].Message.ToKpp = box.Kpp;
|
|
||||||
resp.Events[i].Message.ToFullName = box.FullName;
|
|
||||||
resp.Events[i].Message.ToShortName = box.ShortName;
|
|
||||||
resp.Events[i].Message.ToFnsParticipantId = box.FnsParticipantId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
//Преобразуем JSON ответ сервиса "ДИАДОК" в XML, понятный "Парус 8"
|
//Преобразуем JSON ответ сервиса "ДИАДОК" в XML, понятный "Парус 8"
|
||||||
resu = toXML({ root: resp });
|
resu = toXML({ root: JSON.parse(prms.queue.blResp.toString()) });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new Error(`Неожиданный ответ сервера ЭДО "ДИАДОК". Ошибка интерпретации: ${e.message}`);
|
throw new Error(`Неожиданный ответ сервера ЭДО "ДИАДОК". Ошибка интерпретации: ${e.message}`);
|
||||||
}
|
}
|
||||||
@ -822,80 +664,14 @@ const beforeDepartmentIdGet = async prms => {
|
|||||||
//Обработчик "После" отправки запроса на получение списка подразделений контрагента к сервису "ДИАДОК"
|
//Обработчик "После" отправки запроса на получение списка подразделений контрагента к сервису "ДИАДОК"
|
||||||
const afterDepartmentIdGet = async prms => {
|
const afterDepartmentIdGet = async prms => {
|
||||||
let resu = null;
|
let resu = null;
|
||||||
let organization = {};
|
let Organization = {};
|
||||||
//Действие выполнено успешно
|
//Действие выполнено успешно
|
||||||
if (prms.optionsResp.statusCode == 200) {
|
if (prms.optionsResp.statusCode == 200) {
|
||||||
try {
|
|
||||||
try {
|
try {
|
||||||
//Получим организацию не в роуминге (или единственную организацию в роуминге)
|
//Получим организацию не в роуминге (или единственную организацию в роуминге)
|
||||||
organization = getOrganizations(JSON.parse(prms.queue.blResp.toString()));
|
Organization = GetOrganizations(JSON.parse(prms.queue.blResp.toString()));
|
||||||
if (!organization) {
|
|
||||||
throw Error(`Не удалось получить ящик для контрагента с ИНН: ${prms.options.nINN} и КПП: ${prms.options.nKPP}`);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
//Получим ключ разработчика
|
|
||||||
let sAPIClientId = getAPIClientId(prms.options.nCompany, prms.options.nJurPers);
|
|
||||||
//Считаем токен доступа из контекста сервиса
|
|
||||||
let sToken = prms.service.sCtx;
|
|
||||||
//Получим головную организацию по ИНН/КПП
|
|
||||||
organization = await getOrganization(prms.service.sSrvRoot, buildHeaders(sAPIClientId, sToken), prms.options.nINN, prms.options.nKPP);
|
|
||||||
};
|
|
||||||
//Преобразуем JSON ответ сервиса "ДИАДОК" в XML, понятный "Парус 8"
|
//Преобразуем JSON ответ сервиса "ДИАДОК" в XML, понятный "Парус 8"
|
||||||
resu = toXML({ root: organization });
|
resu = toXML({ root: Organization });
|
||||||
} catch (e) {
|
|
||||||
throw new Error(`Неожиданный ответ сервера ЭДО "ДИАДОК". Ошибка интерпретации: ${e.message}`);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//Если пришел текст ошибки
|
|
||||||
if (prms.queue.blResp) {
|
|
||||||
throw new Error(`Неожиданный ответ сервера ЭДО "ДИАДОК": ${prms.queue.blResp.toString()}`);
|
|
||||||
} else {
|
|
||||||
throw new Error('Сервер ЭДО "ДИАДОК" не вернул ответ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Возврат результата
|
|
||||||
return {
|
|
||||||
blResp: Buffer.from(resu)
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
//Обработчик "До" отправки запроса на получение списка документов в сообщении к сервису "ДИАДОК"
|
|
||||||
const beforeDocumentsByMessageIdGet = async prms => {
|
|
||||||
//Получим ключ разработчика
|
|
||||||
let sAPIClientId = getAPIClientId(prms.options.nCompany, prms.options.nJurPers);
|
|
||||||
//Проверим ключ разработчика
|
|
||||||
checkAPIClientId(sAPIClientId);
|
|
||||||
//Формируем запрос
|
|
||||||
try {
|
|
||||||
//Считаем токен доступа из контекста сервиса
|
|
||||||
let sToken = null;
|
|
||||||
if (prms.service.sCtx) {
|
|
||||||
sToken = prms.service.sCtx;
|
|
||||||
}
|
|
||||||
//Если не достали из контекста токен доступа - значит нет аутентификации на сервере
|
|
||||||
if (!sToken) return { bUnAuth: true };
|
|
||||||
//Собираем и отдаём общий результат работы
|
|
||||||
return {
|
|
||||||
options: {
|
|
||||||
headers: buildHeaders(sAPIClientId, sToken),
|
|
||||||
simple: false
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} catch (e) {
|
|
||||||
throw Error(e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//Обработчик "После" отправки запроса на получение списка документов в сообщении к сервису "ДИАДОК"
|
|
||||||
const afterDocumentsByMessageIdGet = async prms => {
|
|
||||||
let resu = null;
|
|
||||||
//Действие выполнено успешно
|
|
||||||
if (prms.optionsResp.statusCode == 200) {
|
|
||||||
try {
|
|
||||||
//Разберем ответ сервера
|
|
||||||
resp = JSON.parse(prms.queue.blResp.toString());
|
|
||||||
//Преобразуем JSON ответ сервиса "ДИАДОК" в XML, понятный "Парус 8"
|
|
||||||
resu = toXML({ root: resp });
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new Error(`Неожиданный ответ сервера ЭДО "ДИАДОК". Ошибка интерпретации: ${e.message}`);
|
throw new Error(`Неожиданный ответ сервера ЭДО "ДИАДОК". Ошибка интерпретации: ${e.message}`);
|
||||||
}
|
}
|
||||||
@ -930,5 +706,3 @@ exports.afterDocLoad = afterDocLoad;
|
|||||||
exports.beforeDocDelete = beforeDocDelete;
|
exports.beforeDocDelete = beforeDocDelete;
|
||||||
exports.beforeDepartmentIdGet = beforeDepartmentIdGet;
|
exports.beforeDepartmentIdGet = beforeDepartmentIdGet;
|
||||||
exports.afterDepartmentIdGet = afterDepartmentIdGet;
|
exports.afterDepartmentIdGet = afterDepartmentIdGet;
|
||||||
exports.beforeDocumentsByMessageIdGet = beforeDocumentsByMessageIdGet;
|
|
||||||
exports.afterDocumentsByMessageIdGet = afterDocumentsByMessageIdGet;
|
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
const { ServerError } = require("./../core/server_errors"); //Типовая ошибка
|
const { ServerError } = require("./../core/server_errors"); //Типовая ошибка
|
||||||
const { SERR_APP_SERVER_BEFORE, SERR_DB_SERVER } = require("./../core/constants"); //Общесистемные константы
|
const { SERR_APP_SERVER_BEFORE, SERR_DB_SERVER } = require("./../core/constants"); //Общесистемные константы
|
||||||
|
const oracledb = require("oracledb"); //Работа с СУБД Oracle
|
||||||
|
|
||||||
//------------
|
//------------
|
||||||
// Тело модуля
|
// Тело модуля
|
||||||
@ -20,37 +21,52 @@ const before = async prms => {
|
|||||||
if (prms.options.qs && prms.options.qs.STOKEN && prms.options.qs.NPREVIEW && prms.options.qs.NACTUAL_CHECK) {
|
if (prms.options.qs && prms.options.qs.STOKEN && prms.options.qs.NPREVIEW && prms.options.qs.NACTUAL_CHECK) {
|
||||||
//И есть подключение к БД
|
//И есть подключение к БД
|
||||||
if (prms.dbConn.bConnected) {
|
if (prms.dbConn.bConnected) {
|
||||||
let olappExtractData = await prms.dbConn.executeStored({
|
let pooledConnection;
|
||||||
sName: "PKG_EXS_EXT_OLAPP_RUN.EXTRACT",
|
try {
|
||||||
inPrms: {
|
//Считаем курсор с данными публикации
|
||||||
|
pooledConnection = await prms.dbConn.connection.getConnection();
|
||||||
|
let res = await pooledConnection.execute(
|
||||||
|
"BEGIN PKG_EXS_EXT_OLAPP_RUN.EXTRACT(STOKEN => :STOKEN, NPREVIEW => :NPREVIEW, NACTUAL_CHECK => :NACTUAL_CHECK, RCDATA => :RCDATA); END;",
|
||||||
|
{
|
||||||
STOKEN: prms.options.qs.STOKEN,
|
STOKEN: prms.options.qs.STOKEN,
|
||||||
NPREVIEW: prms.options.qs.NPREVIEW,
|
NPREVIEW: prms.options.qs.NPREVIEW,
|
||||||
NACTUAL_CHECK: prms.options.qs.NACTUAL_CHECK
|
NACTUAL_CHECK: prms.options.qs.NACTUAL_CHECK,
|
||||||
|
RCDATA: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||||
},
|
},
|
||||||
outPrms: {
|
{ outFormat: oracledb.OBJECT }
|
||||||
RCDATA: prms.dbConn.connector.DT_CURSOR
|
);
|
||||||
}
|
|
||||||
});
|
|
||||||
//Установим заголовок ответа и начнём выдачу данных
|
//Установим заголовок ответа и начнём выдачу данных
|
||||||
prms.res.set({
|
prms.res.set({
|
||||||
"content-type": "application/json;charset=utf-8"
|
"content-type": "application/json;charset=utf-8"
|
||||||
});
|
});
|
||||||
prms.res.write("[");
|
prms.res.write("[");
|
||||||
if (olappExtractData)
|
//Обходим курсор и выдаём порционно ответ
|
||||||
if (olappExtractData.RCDATA) {
|
const rs = res.outBinds.RCDATA;
|
||||||
let cnt = 1;
|
let cnt = 1;
|
||||||
olappExtractData.RCDATA.map(row => {
|
let row;
|
||||||
|
while ((row = await rs.getRow())) {
|
||||||
prms.res.write(Buffer.from(`${cnt > 1 ? "," : ""}${JSON.stringify(row)}`));
|
prms.res.write(Buffer.from(`${cnt > 1 ? "," : ""}${JSON.stringify(row)}`));
|
||||||
cnt++;
|
cnt++;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
//Завершаем передачу
|
//Завершаем передачу
|
||||||
prms.res.write("]");
|
prms.res.write("]");
|
||||||
prms.res.end();
|
prms.res.end();
|
||||||
|
await rs.close();
|
||||||
//Дальше обрабатывать не надо
|
//Дальше обрабатывать не надо
|
||||||
return {
|
return {
|
||||||
bStopPropagation: true
|
bStopPropagation: true
|
||||||
};
|
};
|
||||||
|
} catch (e) {
|
||||||
|
throw new ServerError(SERR_DB_SERVER, e.message);
|
||||||
|
} finally {
|
||||||
|
if (pooledConnection) {
|
||||||
|
try {
|
||||||
|
await pooledConnection.close();
|
||||||
|
} catch (e) {
|
||||||
|
throw new ServerError(SERR_DB_SERVER, e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new ServerError(SERR_DB_SERVER, "Нет подключения к БД");
|
throw new ServerError(SERR_DB_SERVER, "Нет подключения к БД");
|
||||||
}
|
}
|
||||||
|
@ -14,70 +14,12 @@ const oracledb = require("oracledb"); //Работа с СУБД Oracle
|
|||||||
//--------------------------
|
//--------------------------
|
||||||
|
|
||||||
const NPOOL_DRAIN_TIME = 30; //Таймаут ожидания завершения подключений при отключении пула от БД (сек)
|
const NPOOL_DRAIN_TIME = 30; //Таймаут ожидания завершения подключений при отключении пула от БД (сек)
|
||||||
const DT_VARCHAR = oracledb.DB_TYPE_VARCHAR; //Тип данных "Строка" БД
|
|
||||||
const DT_NUMBER = oracledb.DB_TYPE_NUMBER; //Тип данных "Число" БД
|
|
||||||
const DT_DATE = oracledb.DB_TYPE_DATE; //Тип данных "Дата" БД
|
|
||||||
const DT_CLOB = oracledb.DB_TYPE_CLOB; //Тип данных "Текстовые данные" БД
|
|
||||||
const DT_BLOB = oracledb.DB_TYPE_BLOB; //Тип данных "Двоичные данные" БД
|
|
||||||
const DT_CURSOR = oracledb.CURSOR; //Тип данных "Курсор" БД
|
|
||||||
const DT_VARCHAR_LENGTH = 32767; //Длина типа "Строка"
|
|
||||||
|
|
||||||
//------------
|
//------------
|
||||||
// Тело модуля
|
// Тело модуля
|
||||||
//------------
|
//------------
|
||||||
|
|
||||||
//Формирование имени хранимого объекта БД (с параметрами)
|
//Чтение данных из курсора
|
||||||
const makeStoredName = (sName, inPrms, outPrms, isFunction = false) => {
|
|
||||||
let prms = "";
|
|
||||||
let resultVar = "";
|
|
||||||
for (i in inPrms) prms += `${prms ? ", " : ""}${i} => :${i}`;
|
|
||||||
for (i in outPrms) {
|
|
||||||
if (isFunction) resultVar = `:${i} := `;
|
|
||||||
else prms += `${prms ? ", " : ""}${i} => :${i}`;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return `${resultVar ? resultVar : ""}${sName.replace(/\$[0-9]{1,9}$/, "").replace("$", ".")}(${prms})`;
|
|
||||||
};
|
|
||||||
|
|
||||||
//Формирование параметров хранимого объекта БД
|
|
||||||
const makeStoredPrms = (inPrms, outPrms) => {
|
|
||||||
let prms = inPrms ? inPrms : {};
|
|
||||||
for (i in outPrms) {
|
|
||||||
prms[i] = {
|
|
||||||
type: outPrms[i],
|
|
||||||
dir: oracledb.BIND_OUT,
|
|
||||||
...(outPrms[i] === DT_VARCHAR ? { maxSize: DT_VARCHAR_LENGTH } : {})
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return prms;
|
|
||||||
};
|
|
||||||
|
|
||||||
//Исполнение хранимого объекта БД
|
|
||||||
const executeStored = async prms => {
|
|
||||||
let pooledConnection;
|
|
||||||
let outResult = {};
|
|
||||||
try {
|
|
||||||
pooledConnection = await prms.connection.getConnection();
|
|
||||||
let outPrmName = "";
|
|
||||||
let outPrmIsCursor = false;
|
|
||||||
for (i in prms.outPrms) {
|
|
||||||
outPrmName = i;
|
|
||||||
outPrmIsCursor = prms.outPrms[i] == DT_CURSOR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
let res = await pooledConnection.execute(
|
|
||||||
`begin ${makeStoredName(prms.sName, prms.inPrms, prms.outPrms, prms.isFunction)}; end;`,
|
|
||||||
makeStoredPrms(prms.inPrms, prms.outPrms),
|
|
||||||
{
|
|
||||||
...(outPrmIsCursor ? { outFormat: oracledb.OBJECT } : {}),
|
|
||||||
...{ autoCommit: true }
|
|
||||||
}
|
|
||||||
);
|
|
||||||
if (res)
|
|
||||||
if (res.outBinds) {
|
|
||||||
const outBind = res.outBinds[outPrmName];
|
|
||||||
if (outPrmIsCursor) {
|
|
||||||
const readCursorData = cursor => {
|
const readCursorData = cursor => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let queryStream = cursor.toQueryStream();
|
let queryStream = cursor.toQueryStream();
|
||||||
@ -95,20 +37,25 @@ const executeStored = async prms => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
let rows = await readCursorData(outBind);
|
|
||||||
let rowsRes = [];
|
//Проверка допустимого количества воркеров
|
||||||
await Promise.all(
|
const checkWorkers = async prms => {
|
||||||
rows.map(async row => {
|
let pooledConnection;
|
||||||
let rowRes = {};
|
try {
|
||||||
for (i in row) {
|
pooledConnection = await prms.connection.getConnection();
|
||||||
let isLob = row[i] ? (row[i].type ? row[i].type == oracledb.BLOB || row[i].type == oracledb.CLOB : false) : false;
|
let res = await pooledConnection.execute("BEGIN :LIC_CNT := PKG_EXS.UTL_LIC_CLNT_COUNT_GET(); END;", {
|
||||||
rowRes[i] = isLob ? await row[i].getData() : row[i];
|
LIC_CNT: { dir: oracledb.BIND_OUT, type: oracledb.NUMBER }
|
||||||
|
});
|
||||||
|
let nMaxLic = res.outBinds.LIC_CNT;
|
||||||
|
if (nMaxLic === 0) {
|
||||||
|
throw new Error(`Не определено количество лицензий для приложения "ExchangeServer".`);
|
||||||
}
|
}
|
||||||
rowsRes.push(rowRes);
|
if (prms.nMaxWorkers > nMaxLic - 1) {
|
||||||
})
|
throw new Error(
|
||||||
|
`Недопустимое значение параметра "Количество одновременно обрабатываемых исходящих сообщений" ("outGoing.nMaxWorkers") файла конфигурации сервиса приложений ("config.js"). Максимальное количество одновременно обрабатываемых исходящих сообщений - ${
|
||||||
|
nMaxLic - 1
|
||||||
|
}.`
|
||||||
);
|
);
|
||||||
outResult[outPrmName] = rowsRes;
|
|
||||||
} else outResult[outPrmName] = outBind;
|
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new Error(e.message);
|
throw new Error(e.message);
|
||||||
@ -121,71 +68,36 @@ const executeStored = async prms => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (outResult) return outResult;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//Проверка условий при запуске сервиса интеграции
|
//Проверка соответствия релизов сервера приложений и системы
|
||||||
const checkAppStart = async prms => {
|
const checkRelease = async prms => {
|
||||||
let res = await executeStored({
|
let pooledConnection;
|
||||||
connection: prms.connection,
|
try {
|
||||||
sName: "PKG_EXS.UTL_APPSRV_START_CHECK",
|
pooledConnection = await prms.connection.getConnection();
|
||||||
inPrms: {
|
let res = await pooledConnection.execute("BEGIN :DB_RELEASE := PKG_EXS.UTL_PRODUCT_RELEASE_GET(); END;", {
|
||||||
NCONTROL_VERSION: prms.bControlSystemVersion ? 1 : 0,
|
DB_RELEASE: { dir: oracledb.BIND_OUT, type: oracledb.DB_TYPE_VARCHAR }
|
||||||
SEXS_RELEASE_DATE: prms.sRelease,
|
|
||||||
NWORKERS: prms.nWorkers,
|
|
||||||
SEXSSRV: prms.sServerName,
|
|
||||||
SSESSION_APP_NAME: prms.sSessionAppName
|
|
||||||
},
|
|
||||||
outPrms: {
|
|
||||||
SERR_TEXT: DT_VARCHAR
|
|
||||||
},
|
|
||||||
isFunction: false
|
|
||||||
});
|
});
|
||||||
//Если есть ошибки запуска
|
let sDB_RELEASE = res.outBinds.DB_RELEASE;
|
||||||
if (res.SERR_TEXT) {
|
if (sDB_RELEASE !== prms.sRelease) {
|
||||||
throw new Error(res.SERR_TEXT);
|
throw new Error(`Версия сервера приложений (${prms.sRelease}) не соответствует версии системы (${sDB_RELEASE}).`);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
} finally {
|
||||||
|
if (pooledConnection) {
|
||||||
|
try {
|
||||||
|
await pooledConnection.close();
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
//Инициализация сервера интеграции
|
|
||||||
const initServer = async prms => {
|
|
||||||
let res = await executeStored({
|
|
||||||
connection: prms.connection,
|
|
||||||
sName: "PKG_EXS.EXSSRV_INIT",
|
|
||||||
inPrms: {
|
|
||||||
SEXSSRV: prms.sServerName,
|
|
||||||
SIP: prms.sServerIP,
|
|
||||||
NWORKERS: prms.nMaxWorkers
|
|
||||||
},
|
|
||||||
outPrms: {
|
|
||||||
NEXSSRV: DT_NUMBER
|
|
||||||
},
|
|
||||||
isFunction: false
|
|
||||||
});
|
|
||||||
//Если рег. номер сервера интеграции не определен
|
|
||||||
if (!res.NEXSSRV) {
|
|
||||||
throw new Error(`Ошибка считывания сервера интеграции с мнемокодом "${prms.sServerName}".`);
|
|
||||||
}
|
}
|
||||||
//Возвращаем рег. номер сервера интеграции
|
|
||||||
return res.NEXSSRV;
|
|
||||||
};
|
|
||||||
|
|
||||||
//Очистка информации о сервере при закрытии сервиса
|
|
||||||
const clearServer = async prms => {
|
|
||||||
await executeStored({
|
|
||||||
connection: prms.connection,
|
|
||||||
sName: "PKG_EXS.EXSSRV_CLEAR",
|
|
||||||
inPrms: {
|
|
||||||
NEXSSRV: prms.nExsSrv
|
|
||||||
},
|
|
||||||
isFunction: false
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
//Подключение к БД
|
//Подключение к БД
|
||||||
const connect = async prms => {
|
const connect = async prms => {
|
||||||
try {
|
try {
|
||||||
//Создаем пул подключения
|
|
||||||
let pool = await oracledb.createPool({
|
let pool = await oracledb.createPool({
|
||||||
user: prms.sUser,
|
user: prms.sUser,
|
||||||
password: prms.sPassword,
|
password: prms.sPassword,
|
||||||
@ -195,21 +107,21 @@ const connect = async prms => {
|
|||||||
poolMax: prms.nPoolMax ? prms.nPoolMax : 4,
|
poolMax: prms.nPoolMax ? prms.nPoolMax : 4,
|
||||||
poolIncrement: prms.nPoolIncrement ? prms.nPoolIncrement : 0,
|
poolIncrement: prms.nPoolIncrement ? prms.nPoolIncrement : 0,
|
||||||
sessionCallback: (connection, requestedTag, callback) => {
|
sessionCallback: (connection, requestedTag, callback) => {
|
||||||
//Устанавливаем схему
|
if (prms.sSessionAppName) connection.module = prms.sSessionAppName;
|
||||||
connection
|
connection.execute(`ALTER SESSION SET CURRENT_SCHEMA=${prms.sSchema}`).then(
|
||||||
.execute(`ALTER SESSION SET CURRENT_SCHEMA=${prms.sSchema}`)
|
r => {
|
||||||
.then(r => {
|
|
||||||
//Устанавливаем модуль сессии
|
|
||||||
connection.execute(`begin PKG_EXS.UTL_MODULE_SET(SEXSSRV => '${prms.exsSrv.sServerName}'); end;`);
|
|
||||||
})
|
|
||||||
.then(r => {
|
|
||||||
callback(null, connection);
|
callback(null, connection);
|
||||||
})
|
},
|
||||||
.catch(e => {
|
e => {
|
||||||
callback(e, null);
|
callback(e, null);
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (prms.bControlSystemVersion) {
|
||||||
|
await checkRelease({ sRelease: prms.sRelease, connection: pool });
|
||||||
|
}
|
||||||
|
await checkWorkers({ nMaxWorkers: prms.nMaxWorkers, connection: pool });
|
||||||
return pool;
|
return pool;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new Error(e.message);
|
throw new Error(e.message);
|
||||||
@ -219,7 +131,6 @@ const connect = async prms => {
|
|||||||
//Отключение от БД
|
//Отключение от БД
|
||||||
const disconnect = async prms => {
|
const disconnect = async prms => {
|
||||||
try {
|
try {
|
||||||
//Отключаем от базы данных
|
|
||||||
await prms.connection.close(NPOOL_DRAIN_TIME);
|
await prms.connection.close(NPOOL_DRAIN_TIME);
|
||||||
return;
|
return;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -229,302 +140,566 @@ const disconnect = async prms => {
|
|||||||
|
|
||||||
//Получение списка сервисов
|
//Получение списка сервисов
|
||||||
const getServices = async prms => {
|
const getServices = async prms => {
|
||||||
let servicesData = await executeStored({
|
let pooledConnection;
|
||||||
connection: prms.connection,
|
try {
|
||||||
sName: "PKG_EXS.SERVICES_GET",
|
pooledConnection = await prms.connection.getConnection();
|
||||||
inPrms: {
|
let res = await pooledConnection.execute(
|
||||||
NEXSSRV: prms.nExsSrv
|
"BEGIN PKG_EXS.SERVICES_GET(RCSERVICES => :RCSERVICES); END;",
|
||||||
},
|
{ RCSERVICES: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT } },
|
||||||
outPrms: {
|
{ outFormat: oracledb.OBJECT }
|
||||||
RCSERVICES: DT_CURSOR
|
);
|
||||||
|
let rows = await readCursorData(res.outBinds.RCSERVICES);
|
||||||
|
return rows;
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
} finally {
|
||||||
|
if (pooledConnection) {
|
||||||
|
try {
|
||||||
|
await pooledConnection.close();
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
return servicesData.RCSERVICES;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//Получение списка функций сервиса
|
//Получение списка функций сервиса
|
||||||
const getServiceFunctions = async prms => {
|
const getServiceFunctions = async prms => {
|
||||||
let serviceFunctionsData = await executeStored({
|
let pooledConnection;
|
||||||
connection: prms.connection,
|
try {
|
||||||
sName: "PKG_EXS.SERVICEFNS_GET",
|
pooledConnection = await prms.connection.getConnection();
|
||||||
inPrms: {
|
let res = await pooledConnection.execute(
|
||||||
NEXSSERVICE: prms.nServiceId
|
"BEGIN PKG_EXS.SERVICEFNS_GET(NEXSSERVICE => :NEXSSERVICE, RCSERVICEFNS => :RCSERVICEFNS); END;",
|
||||||
},
|
{ NEXSSERVICE: prms.nServiceId, RCSERVICEFNS: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT } },
|
||||||
outPrms: {
|
{ outFormat: oracledb.OBJECT }
|
||||||
RCSERVICEFNS: DT_CURSOR
|
);
|
||||||
|
let rows = await readCursorData(res.outBinds.RCSERVICEFNS);
|
||||||
|
return rows;
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
} finally {
|
||||||
|
if (pooledConnection) {
|
||||||
|
try {
|
||||||
|
await pooledConnection.close();
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
return serviceFunctionsData.RCSERVICEFNS;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//Получение контекста сервиса
|
//Получение контекста сервиса
|
||||||
const getServiceContext = async prms => {
|
const getServiceContext = async prms => {
|
||||||
let serviceContextData = await executeStored({
|
let pooledConnection;
|
||||||
connection: prms.connection,
|
try {
|
||||||
sName: "PKG_EXS.SERVICE_CTX_GET",
|
pooledConnection = await prms.connection.getConnection();
|
||||||
inPrms: {
|
let res = await pooledConnection.execute(
|
||||||
NFLAG_SMART: 0,
|
"BEGIN PKG_EXS.SERVICE_CTX_GET(NFLAG_SMART => 0, NEXSSERVICE => :NEXSSERVICE, RCSERVICE_CTX => :RCSERVICE_CTX); END;",
|
||||||
NEXSSERVICE: prms.nServiceId
|
{ NEXSSERVICE: prms.nServiceId, RCSERVICE_CTX: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT } },
|
||||||
},
|
{ outFormat: oracledb.OBJECT }
|
||||||
outPrms: {
|
);
|
||||||
RCSERVICE_CTX: DT_CURSOR
|
let rows = await readCursorData(res.outBinds.RCSERVICE_CTX);
|
||||||
|
return rows[0];
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
} finally {
|
||||||
|
if (pooledConnection) {
|
||||||
|
try {
|
||||||
|
await pooledConnection.close();
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
return serviceContextData.RCSERVICE_CTX[0];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//Установка контекста сервиса
|
//Установка контекста сервиса
|
||||||
const setServiceContext = async prms => {
|
const setServiceContext = async prms => {
|
||||||
await executeStored({
|
let pooledConnection;
|
||||||
connection: prms.connection,
|
try {
|
||||||
sName: "PKG_EXS.SERVICE_CTX_SET",
|
pooledConnection = await prms.connection.getConnection();
|
||||||
inPrms: {
|
await pooledConnection.execute(
|
||||||
NEXSSERVICE: prms.nServiceId,
|
"BEGIN PKG_EXS.SERVICE_CTX_SET(NEXSSERVICE => :NEXSSERVICE, SCTX => :SCTX, DCTX_EXP => :DCTX_EXP); END;",
|
||||||
SCTX: prms.sCtx,
|
{ NEXSSERVICE: prms.nServiceId, SCTX: prms.sCtx, DCTX_EXP: prms.dCtxExp },
|
||||||
DCTX_EXP: prms.dCtxExp
|
{ autoCommit: true }
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
} finally {
|
||||||
|
if (pooledConnection) {
|
||||||
|
try {
|
||||||
|
await pooledConnection.close();
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//Очистка контекста сервиса
|
//Очистка контекста сервиса
|
||||||
const clearServiceContext = async prms => {
|
const clearServiceContext = async prms => {
|
||||||
await executeStored({
|
let pooledConnection;
|
||||||
connection: prms.connection,
|
try {
|
||||||
sName: "PKG_EXS.SERVICE_CTX_CLEAR",
|
pooledConnection = await prms.connection.getConnection();
|
||||||
inPrms: { NEXSSERVICE: prms.nServiceId }
|
await pooledConnection.execute(
|
||||||
});
|
"BEGIN PKG_EXS.SERVICE_CTX_CLEAR(NEXSSERVICE => :NEXSSERVICE); END;",
|
||||||
|
{ NEXSSERVICE: prms.nServiceId },
|
||||||
|
{ autoCommit: true }
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
} finally {
|
||||||
|
if (pooledConnection) {
|
||||||
|
try {
|
||||||
|
await pooledConnection.close();
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//Проверка атуентифицированности сервиса
|
//Проверка атуентифицированности сервиса
|
||||||
const isServiceAuth = async prms => {
|
const isServiceAuth = async prms => {
|
||||||
let serviceAuth = await executeStored({
|
let pooledConnection;
|
||||||
connection: prms.connection,
|
try {
|
||||||
sName: "PKG_EXS.SERVICE_IS_AUTH",
|
pooledConnection = await prms.connection.getConnection();
|
||||||
inPrms: { NEXSSERVICE: prms.nServiceId },
|
let res = await pooledConnection.execute("BEGIN :RET := PKG_EXS.SERVICE_IS_AUTH(NEXSSERVICE => :NEXSSERVICE); END;", {
|
||||||
outPrms: {
|
NEXSSERVICE: prms.nServiceId,
|
||||||
RET: DT_NUMBER
|
RET: { dir: oracledb.BIND_OUT, type: oracledb.NUMBER }
|
||||||
},
|
|
||||||
isFunction: true
|
|
||||||
});
|
});
|
||||||
return serviceAuth.RET;
|
return res.outBinds.RET;
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
} finally {
|
||||||
|
if (pooledConnection) {
|
||||||
|
try {
|
||||||
|
await pooledConnection.close();
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//Постановка в очередь задания на аутентификацию сервиса
|
//Постановка в очередь задания на аутентификацию сервиса
|
||||||
const putServiceAuthInQueue = async prms => {
|
const putServiceAuthInQueue = async prms => {
|
||||||
await executeStored({
|
let pooledConnection;
|
||||||
connection: prms.connection,
|
try {
|
||||||
sName: "PKG_EXS.SERVICE_AUTH_PUT_INQUEUE_AT",
|
pooledConnection = await prms.connection.getConnection();
|
||||||
inPrms: { NEXSSERVICE: prms.nServiceId, NFORCE: prms.nForce }
|
await pooledConnection.execute(
|
||||||
});
|
"BEGIN PKG_EXS.SERVICE_AUTH_PUT_INQUEUE_AT(NEXSSERVICE => :NEXSSERVICE, NFORCE => :NFORCE); END;",
|
||||||
|
{ NEXSSERVICE: prms.nServiceId, NFORCE: prms.nForce },
|
||||||
|
{ autoCommit: true }
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
} finally {
|
||||||
|
if (pooledConnection) {
|
||||||
|
try {
|
||||||
|
await pooledConnection.close();
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//Получение информации о просроченных сообщениях обмена сервиса
|
//Получение информации о просроченных сообщениях обмена сервиса
|
||||||
const getServiceExpiredQueueInfo = async prms => {
|
const getServiceExpiredQueueInfo = async prms => {
|
||||||
let serviceExpiredQueueInfoData = await executeStored({
|
let pooledConnection;
|
||||||
connection: prms.connection,
|
try {
|
||||||
sName: "PKG_EXS.SERVICE_QUEUE_EXPIRED_INFO_GET",
|
pooledConnection = await prms.connection.getConnection();
|
||||||
inPrms: {
|
let res = await pooledConnection.execute(
|
||||||
NEXSSERVICE: prms.nServiceId
|
"BEGIN PKG_EXS.SERVICE_QUEUE_EXPIRED_INFO_GET(NEXSSERVICE => :NEXSSERVICE, RCSERVICE_QUEUE_EXPIRED_INFO => :RCSERVICE_QUEUE_EXPIRED_INFO); END;",
|
||||||
|
{
|
||||||
|
NEXSSERVICE: prms.nServiceId,
|
||||||
|
RCSERVICE_QUEUE_EXPIRED_INFO: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||||
},
|
},
|
||||||
outPrms: {
|
{ outFormat: oracledb.OBJECT }
|
||||||
RCSERVICE_QUEUE_EXPIRED_INFO: DT_CURSOR
|
);
|
||||||
|
let rows = await readCursorData(res.outBinds.RCSERVICE_QUEUE_EXPIRED_INFO);
|
||||||
|
return rows[0];
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
} finally {
|
||||||
|
if (pooledConnection) {
|
||||||
|
try {
|
||||||
|
await pooledConnection.close();
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
return serviceExpiredQueueInfoData.RCSERVICE_QUEUE_EXPIRED_INFO[0];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//Запись в протокол работы
|
//Запись в протокол работы
|
||||||
const log = async prms => {
|
const log = async prms => {
|
||||||
let logData = await executeStored({
|
let pooledConnection;
|
||||||
connection: prms.connection,
|
try {
|
||||||
sName: "PKG_EXS.LOG_PUT",
|
pooledConnection = await prms.connection.getConnection();
|
||||||
inPrms: {
|
let res = await pooledConnection.execute(
|
||||||
|
"BEGIN PKG_EXS.LOG_PUT(NLOG_STATE => :NLOG_STATE, SMSG => :SMSG, NEXSSERVICE => :NEXSSERVICE, NEXSSERVICEFN => :NEXSSERVICEFN, NEXSQUEUE => :NEXSQUEUE, RCLOG => :RCLOG); END;",
|
||||||
|
{
|
||||||
NLOG_STATE: prms.nLogState,
|
NLOG_STATE: prms.nLogState,
|
||||||
SMSG: prms.sMsg,
|
SMSG: prms.sMsg,
|
||||||
NEXSSERVICE: prms.nServiceId,
|
NEXSSERVICE: prms.nServiceId,
|
||||||
NEXSSERVICEFN: prms.nServiceFnId,
|
NEXSSERVICEFN: prms.nServiceFnId,
|
||||||
NEXSQUEUE: prms.nQueueId,
|
NEXSQUEUE: prms.nQueueId,
|
||||||
NEXSSRV: prms.nExsSrv
|
RCLOG: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||||
},
|
},
|
||||||
outPrms: { RCLOG: DT_CURSOR }
|
{ outFormat: oracledb.OBJECT, autoCommit: true }
|
||||||
});
|
);
|
||||||
return logData.RCLOG[0];
|
let rows = await readCursorData(res.outBinds.RCLOG);
|
||||||
|
return rows[0];
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
} finally {
|
||||||
|
if (pooledConnection) {
|
||||||
|
try {
|
||||||
|
await pooledConnection.close();
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//Считывание записи очереди обмена
|
//Считывание записи очереди обмена
|
||||||
const getQueue = async prms => {
|
const getQueue = async prms => {
|
||||||
let queueData = await executeStored({
|
let pooledConnection;
|
||||||
connection: prms.connection,
|
try {
|
||||||
sName: "PKG_EXS.QUEUE_GET",
|
pooledConnection = await prms.connection.getConnection();
|
||||||
inPrms: {
|
let res = await pooledConnection.execute(
|
||||||
NFLAG_SMART: 0,
|
"BEGIN PKG_EXS.QUEUE_GET(NFLAG_SMART => 0, NEXSQUEUE => :NEXSQUEUE, RCQUEUE => :RCQUEUE); END;",
|
||||||
NEXSQUEUE: prms.nQueueId
|
{
|
||||||
|
NEXSQUEUE: prms.nQueueId,
|
||||||
|
RCQUEUE: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||||
},
|
},
|
||||||
outPrms: { RCQUEUE: DT_CURSOR }
|
{ outFormat: oracledb.OBJECT, autoCommit: true }
|
||||||
});
|
);
|
||||||
return queueData.RCQUEUE[0];
|
let rows = await readCursorData(res.outBinds.RCQUEUE);
|
||||||
|
return rows[0];
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
} finally {
|
||||||
|
if (pooledConnection) {
|
||||||
|
try {
|
||||||
|
await pooledConnection.close();
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//Помещение сообщения в очередь
|
//Помещение сообщения в очередь
|
||||||
const putQueue = async prms => {
|
const putQueue = async prms => {
|
||||||
let queueData = await executeStored({
|
let pooledConnection;
|
||||||
connection: prms.connection,
|
try {
|
||||||
sName: "PKG_EXS.QUEUE_PUT",
|
pooledConnection = await prms.connection.getConnection();
|
||||||
inPrms: {
|
let res = await pooledConnection.execute(
|
||||||
|
"BEGIN PKG_EXS.QUEUE_PUT(NEXSSERVICEFN => :NEXSSERVICEFN, BMSG => :BMSG, NEXSQUEUE => :NEXSQUEUE, NLNK_COMPANY => :NLNK_COMPANY, NLNK_DOCUMENT => :NLNK_DOCUMENT, SLNK_UNITCODE => :SLNK_UNITCODE, SOPTIONS => :SOPTIONS, RCQUEUE => :RCQUEUE); END;",
|
||||||
|
{
|
||||||
NEXSSERVICEFN: prms.nServiceFnId,
|
NEXSSERVICEFN: prms.nServiceFnId,
|
||||||
BMSG: prms.blMsg,
|
BMSG: prms.blMsg,
|
||||||
NEXSQUEUE: prms.nQueueId,
|
NEXSQUEUE: prms.nQueueId,
|
||||||
NLNK_COMPANY: prms.nLnkCompanyId,
|
NLNK_COMPANY: prms.nLnkCompanyId,
|
||||||
NLNK_DOCUMENT: prms.nLnkDocumentId,
|
NLNK_DOCUMENT: prms.nLnkDocumentId,
|
||||||
SLNK_UNITCODE: prms.sLnkUnitcode,
|
SLNK_UNITCODE: prms.sLnkUnitcode,
|
||||||
SOPTIONS: prms.sOptions
|
SOPTIONS: prms.sOptions,
|
||||||
|
RCQUEUE: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||||
},
|
},
|
||||||
outPrms: { RCQUEUE: DT_CURSOR }
|
{ outFormat: oracledb.OBJECT, autoCommit: true }
|
||||||
});
|
);
|
||||||
return queueData.RCQUEUE[0];
|
let rows = await readCursorData(res.outBinds.RCQUEUE);
|
||||||
|
return rows[0];
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
} finally {
|
||||||
|
if (pooledConnection) {
|
||||||
|
try {
|
||||||
|
await pooledConnection.close();
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//Считывание очередной порции исходящих сообщений из очереди
|
//Считывание очередной порции исходящих сообщений из очереди
|
||||||
const getQueueOutgoing = async prms => {
|
const getQueueOutgoing = async prms => {
|
||||||
let queueOutgoingData = await executeStored({
|
let pooledConnection;
|
||||||
connection: prms.connection,
|
try {
|
||||||
sName: "PKG_EXS.QUEUE_SRV_TYPE_SEND_GET",
|
pooledConnection = await prms.connection.getConnection();
|
||||||
inPrms: {
|
let res = await pooledConnection.execute(
|
||||||
|
"BEGIN PKG_EXS.QUEUE_SRV_TYPE_SEND_GET(NPORTION_SIZE => :NPORTION_SIZE, RCQUEUES => :RCQUEUES); END;",
|
||||||
|
{
|
||||||
NPORTION_SIZE: prms.nPortionSize,
|
NPORTION_SIZE: prms.nPortionSize,
|
||||||
NEXSSRV: prms.nExsSrv
|
RCQUEUES: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||||
},
|
},
|
||||||
outPrms: { RCQUEUES: DT_CURSOR }
|
{ outFormat: oracledb.OBJECT }
|
||||||
});
|
);
|
||||||
return queueOutgoingData.RCQUEUES;
|
let rows = await readCursorData(res.outBinds.RCQUEUES);
|
||||||
|
return rows;
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
} finally {
|
||||||
|
if (pooledConnection) {
|
||||||
|
try {
|
||||||
|
await pooledConnection.close();
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//Установка значения состояния в сообщении очереди
|
//Установка значения состояния в сообщении очереди
|
||||||
const setQueueState = async prms => {
|
const setQueueState = async prms => {
|
||||||
let queueStateData = await executeStored({
|
let pooledConnection;
|
||||||
connection: prms.connection,
|
try {
|
||||||
sName: "PKG_EXS.QUEUE_EXEC_STATE_SET",
|
pooledConnection = await prms.connection.getConnection();
|
||||||
inPrms: {
|
let res = await pooledConnection.execute(
|
||||||
|
"BEGIN PKG_EXS.QUEUE_EXEC_STATE_SET(NEXSQUEUE => :NEXSQUEUE, NEXEC_STATE => :NEXEC_STATE, SEXEC_MSG => :SEXEC_MSG, NINC_EXEC_CNT => :NINC_EXEC_CNT, NRESET_DATA => :NRESET_DATA, RCQUEUE => :RCQUEUE); END;",
|
||||||
|
{
|
||||||
NEXSQUEUE: prms.nQueueId,
|
NEXSQUEUE: prms.nQueueId,
|
||||||
NEXEC_STATE: prms.nExecState,
|
NEXEC_STATE: prms.nExecState,
|
||||||
SEXEC_MSG: prms.sExecMsg,
|
SEXEC_MSG: prms.sExecMsg,
|
||||||
NINC_EXEC_CNT: prms.nIncExecCnt,
|
NINC_EXEC_CNT: prms.nIncExecCnt,
|
||||||
NRESET_DATA: prms.nResetData
|
NRESET_DATA: prms.nResetData,
|
||||||
|
RCQUEUE: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||||
},
|
},
|
||||||
outPrms: { RCQUEUE: DT_CURSOR }
|
{ outFormat: oracledb.OBJECT, autoCommit: true }
|
||||||
});
|
);
|
||||||
return queueStateData.RCQUEUE[0];
|
let rows = await readCursorData(res.outBinds.RCQUEUE);
|
||||||
|
return rows[0];
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
} finally {
|
||||||
|
if (pooledConnection) {
|
||||||
|
try {
|
||||||
|
await pooledConnection.close();
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//Считывание данных сообщения очереди
|
//Считывание данных сообщения очереди
|
||||||
const getQueueMsg = async prms => {
|
const getQueueMsg = async prms => {
|
||||||
let queueMsgData = await executeStored({
|
let pooledConnection;
|
||||||
connection: prms.connection,
|
try {
|
||||||
sName: "PKG_EXS.QUEUE_MSG_GET",
|
pooledConnection = await prms.connection.getConnection();
|
||||||
inPrms: {
|
let res = await pooledConnection.execute(
|
||||||
NEXSQUEUE: prms.nQueueId
|
"BEGIN PKG_EXS.QUEUE_MSG_GET(NEXSQUEUE => :NEXSQUEUE, RCQUEUE_MSG => :RCQUEUE_MSG); END;",
|
||||||
|
{
|
||||||
|
NEXSQUEUE: prms.nQueueId,
|
||||||
|
RCQUEUE_MSG: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||||
},
|
},
|
||||||
outPrms: { RCQUEUE_MSG: DT_CURSOR }
|
{
|
||||||
});
|
outFormat: oracledb.OBJECT,
|
||||||
return queueMsgData.RCQUEUE_MSG[0];
|
autoCommit: true,
|
||||||
|
fetchInfo: { blMsg: { type: oracledb.BUFFER } }
|
||||||
|
}
|
||||||
|
);
|
||||||
|
let rows = await readCursorData(res.outBinds.RCQUEUE_MSG);
|
||||||
|
return rows[0];
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
} finally {
|
||||||
|
if (pooledConnection) {
|
||||||
|
try {
|
||||||
|
await pooledConnection.close();
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//Установка данных сообщения очереди
|
//Установка данных сообщения очереди
|
||||||
const setQueueMsg = async prms => {
|
const setQueueMsg = async prms => {
|
||||||
let queueMsgData = await executeStored({
|
let pooledConnection;
|
||||||
connection: prms.connection,
|
try {
|
||||||
sName: "PKG_EXS.QUEUE_MSG_SET",
|
pooledConnection = await prms.connection.getConnection();
|
||||||
inPrms: {
|
let res = await pooledConnection.execute(
|
||||||
|
"BEGIN PKG_EXS.QUEUE_MSG_SET(NEXSQUEUE => :NEXSQUEUE, BMSG => :BMSG, RCQUEUE => :RCQUEUE); END;",
|
||||||
|
{
|
||||||
NEXSQUEUE: prms.nQueueId,
|
NEXSQUEUE: prms.nQueueId,
|
||||||
BMSG: prms.blMsg
|
BMSG: prms.blMsg,
|
||||||
|
RCQUEUE: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||||
},
|
},
|
||||||
outPrms: { RCQUEUE: DT_CURSOR }
|
{ outFormat: oracledb.OBJECT, autoCommit: true }
|
||||||
});
|
);
|
||||||
return queueMsgData.RCQUEUE[0];
|
let rows = await readCursorData(res.outBinds.RCQUEUE);
|
||||||
|
return rows[0];
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
} finally {
|
||||||
|
if (pooledConnection) {
|
||||||
|
try {
|
||||||
|
await pooledConnection.close();
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//Установка параметров сообщения очереди
|
//Установка параметров сообщения очереди
|
||||||
const setQueueOptions = async prms => {
|
const setQueueOptions = async prms => {
|
||||||
let queueOptionsData = await executeStored({
|
let pooledConnection;
|
||||||
connection: prms.connection,
|
try {
|
||||||
sName: "PKG_EXS.QUEUE_OPTIONS_SET",
|
pooledConnection = await prms.connection.getConnection();
|
||||||
inPrms: {
|
let res = await pooledConnection.execute(
|
||||||
|
"BEGIN PKG_EXS.QUEUE_OPTIONS_SET(NEXSQUEUE => :NEXSQUEUE, SOPTIONS => :SOPTIONS, RCQUEUE => :RCQUEUE); END;",
|
||||||
|
{
|
||||||
NEXSQUEUE: prms.nQueueId,
|
NEXSQUEUE: prms.nQueueId,
|
||||||
SOPTIONS: prms.sOptions
|
SOPTIONS: prms.sOptions,
|
||||||
|
RCQUEUE: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||||
},
|
},
|
||||||
outPrms: { RCQUEUE: DT_CURSOR }
|
{ outFormat: oracledb.OBJECT, autoCommit: true }
|
||||||
});
|
);
|
||||||
return queueOptionsData.RCQUEUE[0];
|
let rows = await readCursorData(res.outBinds.RCQUEUE);
|
||||||
|
return rows[0];
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
} finally {
|
||||||
|
if (pooledConnection) {
|
||||||
|
try {
|
||||||
|
await pooledConnection.close();
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//Считывание результата обработки сообщения очереди
|
//Считывание результата обработки сообщения очереди
|
||||||
const getQueueResp = async prms => {
|
const getQueueResp = async prms => {
|
||||||
let queueRespData = await executeStored({
|
let pooledConnection;
|
||||||
connection: prms.connection,
|
try {
|
||||||
sName: "PKG_EXS.QUEUE_RESP_GET",
|
pooledConnection = await prms.connection.getConnection();
|
||||||
inPrms: {
|
let res = await pooledConnection.execute(
|
||||||
NEXSQUEUE: prms.nQueueId
|
"BEGIN PKG_EXS.QUEUE_RESP_GET(NEXSQUEUE => :NEXSQUEUE, RCQUEUE_RESP => :RCQUEUE_RESP); END;",
|
||||||
|
{
|
||||||
|
NEXSQUEUE: prms.nQueueId,
|
||||||
|
RCQUEUE_RESP: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||||
},
|
},
|
||||||
outPrms: { RCQUEUE_RESP: DT_CURSOR }
|
{
|
||||||
});
|
outFormat: oracledb.OBJECT,
|
||||||
return queueRespData.RCQUEUE_RESP[0];
|
autoCommit: true,
|
||||||
|
fetchInfo: { blResp: { type: oracledb.BUFFER } }
|
||||||
|
}
|
||||||
|
);
|
||||||
|
let rows = await readCursorData(res.outBinds.RCQUEUE_RESP);
|
||||||
|
return rows[0];
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
} finally {
|
||||||
|
if (pooledConnection) {
|
||||||
|
try {
|
||||||
|
await pooledConnection.close();
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//Установка результата обработки сообщения очереди
|
//Установка результата обработки сообщения очереди
|
||||||
const setQueueResp = async prms => {
|
const setQueueResp = async prms => {
|
||||||
let queueRespData = await executeStored({
|
let pooledConnection;
|
||||||
connection: prms.connection,
|
try {
|
||||||
sName: "PKG_EXS.QUEUE_RESP_SET",
|
pooledConnection = await prms.connection.getConnection();
|
||||||
inPrms: {
|
let res = await pooledConnection.execute(
|
||||||
|
"BEGIN PKG_EXS.QUEUE_RESP_SET(NEXSQUEUE => :NEXSQUEUE, BRESP => :BRESP, NIS_ORIGINAL => :NIS_ORIGINAL, RCQUEUE => :RCQUEUE); END;",
|
||||||
|
{
|
||||||
NEXSQUEUE: prms.nQueueId,
|
NEXSQUEUE: prms.nQueueId,
|
||||||
BRESP: prms.blResp,
|
BRESP: prms.blResp,
|
||||||
NIS_ORIGINAL: prms.nIsOriginal
|
NIS_ORIGINAL: prms.nIsOriginal,
|
||||||
|
RCQUEUE: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||||
},
|
},
|
||||||
outPrms: { RCQUEUE: DT_CURSOR }
|
{ outFormat: oracledb.OBJECT, autoCommit: true }
|
||||||
});
|
);
|
||||||
return queueRespData.RCQUEUE[0];
|
let rows = await readCursorData(res.outBinds.RCQUEUE);
|
||||||
|
return rows[0];
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
} finally {
|
||||||
|
if (pooledConnection) {
|
||||||
|
try {
|
||||||
|
await pooledConnection.close();
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//Установка параметров результата обработки сообщения очереди
|
//Установка параметров результата обработки сообщения очереди
|
||||||
const setQueueOptionsResp = async prms => {
|
const setQueueOptionsResp = async prms => {
|
||||||
let queueOptionsRespData = await executeStored({
|
let pooledConnection;
|
||||||
connection: prms.connection,
|
try {
|
||||||
sName: "PKG_EXS.QUEUE_OPTIONS_RESP_SET",
|
pooledConnection = await prms.connection.getConnection();
|
||||||
inPrms: {
|
let res = await pooledConnection.execute(
|
||||||
|
"BEGIN PKG_EXS.QUEUE_OPTIONS_RESP_SET(NEXSQUEUE => :NEXSQUEUE, SOPTIONS_RESP => :SOPTIONS_RESP, RCQUEUE => :RCQUEUE); END;",
|
||||||
|
{
|
||||||
NEXSQUEUE: prms.nQueueId,
|
NEXSQUEUE: prms.nQueueId,
|
||||||
SOPTIONS_RESP: prms.sOptionsResp
|
SOPTIONS_RESP: prms.sOptionsResp,
|
||||||
|
RCQUEUE: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||||
},
|
},
|
||||||
outPrms: { RCQUEUE: DT_CURSOR }
|
{ outFormat: oracledb.OBJECT, autoCommit: true }
|
||||||
});
|
);
|
||||||
return queueOptionsRespData.RCQUEUE[0];
|
let rows = await readCursorData(res.outBinds.RCQUEUE);
|
||||||
|
return rows[0];
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
} finally {
|
||||||
|
if (pooledConnection) {
|
||||||
|
try {
|
||||||
|
await pooledConnection.close();
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//Исполнение обработчика со стороны БД для сообщения очереди
|
//Исполнение обработчика со стороны БД для сообщения очереди
|
||||||
const execQueuePrc = async prms => {
|
const execQueuePrc = async prms => {
|
||||||
let queuePrcData = await executeStored({
|
let pooledConnection;
|
||||||
connection: prms.connection,
|
try {
|
||||||
sName: "PKG_EXS.QUEUE_PRC",
|
pooledConnection = await prms.connection.getConnection();
|
||||||
inPrms: {
|
let res = await pooledConnection.execute(
|
||||||
NEXSQUEUE: prms.nQueueId
|
"BEGIN PKG_EXS.QUEUE_PRC(NEXSQUEUE => :NEXSQUEUE, RCRESULT => :RCRESULT); END;",
|
||||||
|
{
|
||||||
|
NEXSQUEUE: prms.nQueueId,
|
||||||
|
RCRESULT: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||||
},
|
},
|
||||||
outPrms: { RCRESULT: DT_CURSOR }
|
{ outFormat: oracledb.OBJECT, autoCommit: true }
|
||||||
});
|
);
|
||||||
return queuePrcData.RCRESULT[0];
|
let rows = await readCursorData(res.outBinds.RCRESULT);
|
||||||
|
return rows[0];
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
} finally {
|
||||||
|
if (pooledConnection) {
|
||||||
|
try {
|
||||||
|
await pooledConnection.close();
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//-----------------
|
//-----------------
|
||||||
// Интерфейс модуля
|
// Интерфейс модуля
|
||||||
//-----------------
|
//-----------------
|
||||||
|
|
||||||
exports.DT_VARCHAR = DT_VARCHAR;
|
|
||||||
exports.DT_NUMBER = DT_NUMBER;
|
|
||||||
exports.DT_DATE = DT_DATE;
|
|
||||||
exports.DT_CLOB = DT_CLOB;
|
|
||||||
exports.DT_BLOB = DT_BLOB;
|
|
||||||
exports.DT_CURSOR = DT_CURSOR;
|
|
||||||
exports.executeStored = executeStored;
|
|
||||||
exports.checkAppStart = checkAppStart;
|
|
||||||
exports.initServer = initServer;
|
|
||||||
exports.clearServer = clearServer;
|
|
||||||
exports.connect = connect;
|
exports.connect = connect;
|
||||||
exports.disconnect = disconnect;
|
exports.disconnect = disconnect;
|
||||||
exports.getServices = getServices;
|
exports.getServices = getServices;
|
||||||
|
@ -1,537 +0,0 @@
|
|||||||
/*
|
|
||||||
Сервис интеграции ПП Парус 8 с WEB API
|
|
||||||
Дополнительный модуль: работа с БД ПП Парус 8 (Postgre)
|
|
||||||
*/
|
|
||||||
|
|
||||||
//----------------------
|
|
||||||
// Подключение библиотек
|
|
||||||
//----------------------
|
|
||||||
|
|
||||||
const pg = require("pg"); //Работа с СУБД Postgre
|
|
||||||
|
|
||||||
//--------------------------
|
|
||||||
// Глобальные идентификаторы
|
|
||||||
//--------------------------
|
|
||||||
|
|
||||||
const DT_VARCHAR = pg.types.builtins.VARCHAR; //Тип данных "Строка" БД
|
|
||||||
const DT_NUMBER = pg.types.builtins.NUMERIC; //Тип данных "Число" БД
|
|
||||||
const DT_DATE = pg.types.builtins.DATE; //Тип данных "Дата" БД
|
|
||||||
const DT_CLOB = pg.types.builtins.TEXT; //Тип данных "Текстовые данные" БД
|
|
||||||
const DT_BLOB = pg.types.builtins.BYTEA; //Тип данных "Двоичные данные" БД
|
|
||||||
const DT_CURSOR = pg.types.builtins.REFCURSOR; //Тип данных "Курсор" БД
|
|
||||||
|
|
||||||
//------------
|
|
||||||
// Тело модуля
|
|
||||||
//------------
|
|
||||||
|
|
||||||
//Установка парсера значений для типа данных NUMERIC БД PG
|
|
||||||
pg.types.setTypeParser(pg.types.builtins.NUMERIC, val => {
|
|
||||||
return val ? Number(val) : val;
|
|
||||||
});
|
|
||||||
|
|
||||||
//Формирование имени хранимого объекта БД (с параметрами)
|
|
||||||
const makeStoredName = (sName, inPrms) => {
|
|
||||||
let prms = "";
|
|
||||||
let prm_numb = 0;
|
|
||||||
for (i in inPrms) {
|
|
||||||
prm_numb++;
|
|
||||||
let prm_type = "";
|
|
||||||
if (inPrms[i] != null && inPrms[i] != undefined)
|
|
||||||
switch (typeof inPrms[i]) {
|
|
||||||
case "string":
|
|
||||||
if (inPrms[i].length ? inPrms[i].length > 4000 : false) prm_type = "::text";
|
|
||||||
else prm_type = "::character varying";
|
|
||||||
break;
|
|
||||||
case "number":
|
|
||||||
prm_type = "::numeric";
|
|
||||||
break;
|
|
||||||
case "bigint":
|
|
||||||
prm_type = "::numeric";
|
|
||||||
break;
|
|
||||||
case "boolean":
|
|
||||||
prm_type = "::boolean";
|
|
||||||
break;
|
|
||||||
case "object":
|
|
||||||
if (inPrms[i] instanceof Date) prm_type = "::date";
|
|
||||||
else prm_type = "::bytea";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
prms += `${prms ? ", " : ""}$${prm_numb}${prm_type}`;
|
|
||||||
}
|
|
||||||
return `${sName.replace(".", "$")}(${prms})`;
|
|
||||||
};
|
|
||||||
|
|
||||||
//Формирование параметров хранимого объекта БД
|
|
||||||
const makeStoredPrms = inPrms => {
|
|
||||||
let prms = [];
|
|
||||||
for (i in inPrms) prms.push(inPrms[i]);
|
|
||||||
return prms;
|
|
||||||
};
|
|
||||||
|
|
||||||
//Исполнение хранимого объекта БД
|
|
||||||
const executeStored = async prms => {
|
|
||||||
let client;
|
|
||||||
let outResult = {};
|
|
||||||
try {
|
|
||||||
client = await prms.connection.connect();
|
|
||||||
let outPrmName = "";
|
|
||||||
let outPrmIsCursor = false;
|
|
||||||
for (i in prms.outPrms) {
|
|
||||||
outPrmName = i;
|
|
||||||
outPrmIsCursor = prms.outPrms[i] == DT_CURSOR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
await client.query(`begin;`);
|
|
||||||
let res = await client.query({
|
|
||||||
text: `select ${makeStoredName(prms.sName, prms.inPrms)}${outPrmName ? ` as "${outPrmName}"` : ""};`,
|
|
||||||
values: makeStoredPrms(prms.inPrms)
|
|
||||||
});
|
|
||||||
if (res)
|
|
||||||
if (res.rows)
|
|
||||||
if (res.rows[0]) {
|
|
||||||
const outBind = res.rows[0][outPrmName];
|
|
||||||
if (outPrmIsCursor) {
|
|
||||||
let rowsRes = [];
|
|
||||||
let doExit = false;
|
|
||||||
while (!doExit) {
|
|
||||||
doExit = true;
|
|
||||||
res = await client.query(`fetch next from "${outBind}";`);
|
|
||||||
if (res)
|
|
||||||
if (res.rows)
|
|
||||||
if (res.rowCount > 0 && res.rows.length > 0) {
|
|
||||||
doExit = false;
|
|
||||||
res.rows.map(r => rowsRes.push(r));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
outResult[outPrmName] = rowsRes;
|
|
||||||
} else outResult[outPrmName] = outBind;
|
|
||||||
}
|
|
||||||
await client.query(`commit;`);
|
|
||||||
} catch (e) {
|
|
||||||
if (client) {
|
|
||||||
try {
|
|
||||||
await client.query(`rollback;`);
|
|
||||||
} catch (err) {
|
|
||||||
throw new Error(err.message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new Error(e.message);
|
|
||||||
} finally {
|
|
||||||
if (client) {
|
|
||||||
try {
|
|
||||||
await client.release();
|
|
||||||
} catch (err) {
|
|
||||||
throw new Error(err.message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (outResult) return outResult;
|
|
||||||
};
|
|
||||||
|
|
||||||
//Проверка условий при запуске сервиса интеграции
|
|
||||||
const checkAppStart = async prms => {
|
|
||||||
let res = await executeStored({
|
|
||||||
connection: prms.connection,
|
|
||||||
sName: "PKG_EXS$UTL_APPSRV_START_CHECK",
|
|
||||||
inPrms: {
|
|
||||||
NCONTROL_VERSION: prms.bControlSystemVersion ? 1 : 0,
|
|
||||||
SEXS_RELEASE_DATE: prms.sRelease,
|
|
||||||
NWORKERS: prms.nWorkers,
|
|
||||||
SEXSSRV: prms.sServerName !== "" ? prms.sServerName : null,
|
|
||||||
SSESSION_APP_NAME: prms.sSessionAppName
|
|
||||||
},
|
|
||||||
outPrms: {
|
|
||||||
SERR_TEXT: DT_VARCHAR
|
|
||||||
}
|
|
||||||
});
|
|
||||||
//Если есть ошибки запуска
|
|
||||||
if (res.SERR_TEXT) {
|
|
||||||
throw new Error(res.SERR_TEXT);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//Инициализация сервера интеграции
|
|
||||||
const initServer = async prms => {
|
|
||||||
let res = await executeStored({
|
|
||||||
connection: prms.connection,
|
|
||||||
sName: "PKG_EXS$EXSSRV_INIT",
|
|
||||||
inPrms: {
|
|
||||||
SEXSSRV: prms.sServerName,
|
|
||||||
SIP: prms.sServerIP,
|
|
||||||
NWORKERS: prms.nMaxWorkers
|
|
||||||
},
|
|
||||||
outPrms: {
|
|
||||||
NEXSSRV: DT_NUMBER
|
|
||||||
}
|
|
||||||
});
|
|
||||||
//Если рег. номер сервера интеграции потерялся
|
|
||||||
if (!res.NEXSSRV) {
|
|
||||||
throw new Error(`Ошибка считывания сервера интеграции с мнемокодом "${prms.sServerName}".`);
|
|
||||||
}
|
|
||||||
//Возвращаем рег. номер сервера интеграции
|
|
||||||
return res.NEXSSRV;
|
|
||||||
};
|
|
||||||
|
|
||||||
//Очистка информации о сервере при закрытии сервиса
|
|
||||||
const clearServer = async prms => {
|
|
||||||
await executeStored({
|
|
||||||
connection: prms.connection,
|
|
||||||
sName: "PKG_EXS$EXSSRV_CLEAR",
|
|
||||||
inPrms: {
|
|
||||||
NEXSSRV: prms.nExsSrv
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
//Подключение к БД
|
|
||||||
const connect = async prms => {
|
|
||||||
try {
|
|
||||||
//Создаем пул подключения
|
|
||||||
let pool = new pg.Pool({
|
|
||||||
connectionString: `postgres://${prms.sUser}:${prms.sPassword}@${prms.sConnectString}`,
|
|
||||||
connectionTimeoutMillis: 600000,
|
|
||||||
min: prms.nPoolMin ? prms.nPoolMin : 4,
|
|
||||||
max: prms.nPoolMax ? prms.nPoolMax : 4
|
|
||||||
});
|
|
||||||
pool.on("acquire", async client => {
|
|
||||||
//Устанавливаем схему
|
|
||||||
await client.query(`select ALTER_SESSION_SET_SCHEMA($1);`, [prms.sSchema]);
|
|
||||||
//Устанавливаем модуль сессии
|
|
||||||
await client.query(`select PKG_EXS$UTL_MODULE_SET($1);`, [prms.exsSrv.sServerName]);
|
|
||||||
});
|
|
||||||
return pool;
|
|
||||||
} catch (e) {
|
|
||||||
throw new Error(e.message);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//Отключение от БД
|
|
||||||
const disconnect = async prms => {
|
|
||||||
try {
|
|
||||||
await prms.connection.end();
|
|
||||||
} catch (e) {
|
|
||||||
throw new Error(e.message);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//Получение списка сервисов
|
|
||||||
const getServices = async prms => {
|
|
||||||
let servicesData = await executeStored({
|
|
||||||
connection: prms.connection,
|
|
||||||
sName: "PKG_EXS$SERVICES_GET",
|
|
||||||
inPrms: {
|
|
||||||
NEXSSRV: prms.nExsSrv
|
|
||||||
},
|
|
||||||
outPrms: {
|
|
||||||
RCSERVICES: DT_CURSOR
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return servicesData.RCSERVICES;
|
|
||||||
};
|
|
||||||
|
|
||||||
//Получение списка функций сервиса
|
|
||||||
const getServiceFunctions = async prms => {
|
|
||||||
let serviceFunctionsData = await executeStored({
|
|
||||||
connection: prms.connection,
|
|
||||||
sName: "PKG_EXS$SERVICEFNS_GET",
|
|
||||||
inPrms: {
|
|
||||||
NEXSSERVICE: prms.nServiceId
|
|
||||||
},
|
|
||||||
outPrms: {
|
|
||||||
RCSERVICEFNS: DT_CURSOR
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return serviceFunctionsData.RCSERVICEFNS;
|
|
||||||
};
|
|
||||||
|
|
||||||
//Получение контекста сервиса
|
|
||||||
const getServiceContext = async prms => {
|
|
||||||
let serviceContextData = await executeStored({
|
|
||||||
connection: prms.connection,
|
|
||||||
sName: "PKG_EXS$SERVICE_CTX_GET",
|
|
||||||
inPrms: {
|
|
||||||
NFLAG_SMART: 0,
|
|
||||||
NEXSSERVICE: prms.nServiceId
|
|
||||||
},
|
|
||||||
outPrms: {
|
|
||||||
RCSERVICE_CTX: DT_CURSOR
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return serviceContextData.RCSERVICE_CTX[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
//Установка контекста сервиса
|
|
||||||
const setServiceContext = async prms => {
|
|
||||||
await executeStored({
|
|
||||||
connection: prms.connection,
|
|
||||||
sName: "PKG_EXS$SERVICE_CTX_SET",
|
|
||||||
inPrms: {
|
|
||||||
NEXSSERVICE: prms.nServiceId,
|
|
||||||
SCTX: prms.sCtx,
|
|
||||||
DCTX_EXP: prms.dCtxExp
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
//Очистка контекста сервиса
|
|
||||||
const clearServiceContext = async prms => {
|
|
||||||
await executeStored({
|
|
||||||
connection: prms.connection,
|
|
||||||
sName: "PKG_EXS$SERVICE_CTX_CLEAR",
|
|
||||||
inPrms: { NEXSSERVICE: prms.nServiceId }
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
//Проверка атуентифицированности сервиса
|
|
||||||
const isServiceAuth = async prms => {
|
|
||||||
let serviceAuth = await executeStored({
|
|
||||||
connection: prms.connection,
|
|
||||||
sName: "PKG_EXS$SERVICE_IS_AUTH",
|
|
||||||
inPrms: { NEXSSERVICE: prms.nServiceId },
|
|
||||||
outPrms: {
|
|
||||||
RET: DT_NUMBER
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return serviceAuth.RET;
|
|
||||||
};
|
|
||||||
|
|
||||||
//Постановка в очередь задания на аутентификацию сервиса
|
|
||||||
const putServiceAuthInQueue = async prms => {
|
|
||||||
await executeStored({
|
|
||||||
connection: prms.connection,
|
|
||||||
sName: "PKG_EXS$SERVICE_AUTH_PUT_INQUEUE_AT",
|
|
||||||
inPrms: { NEXSSERVICE: prms.nServiceId, NFORCE: prms.nForce }
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
//Получение информации о просроченных сообщениях обмена сервиса
|
|
||||||
const getServiceExpiredQueueInfo = async prms => {
|
|
||||||
let serviceExpiredQueueInfoData = await executeStored({
|
|
||||||
connection: prms.connection,
|
|
||||||
sName: "PKG_EXS$SERVICE_QUEUE_EXPIRED_INFO_GET",
|
|
||||||
inPrms: {
|
|
||||||
NEXSSERVICE: prms.nServiceId
|
|
||||||
},
|
|
||||||
outPrms: {
|
|
||||||
RCSERVICE_QUEUE_EXPIRED_INFO: DT_CURSOR
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return serviceExpiredQueueInfoData.RCSERVICE_QUEUE_EXPIRED_INFO[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
//Запись в протокол работы
|
|
||||||
const log = async prms => {
|
|
||||||
let logData = await executeStored({
|
|
||||||
connection: prms.connection,
|
|
||||||
sName: "PKG_EXS$LOG_PUT",
|
|
||||||
inPrms: {
|
|
||||||
NLOG_STATE: prms.nLogState,
|
|
||||||
SMSG: prms.sMsg,
|
|
||||||
NEXSSERVICE: prms.nServiceId,
|
|
||||||
NEXSSERVICEFN: prms.nServiceFnId,
|
|
||||||
NEXSQUEUE: prms.nQueueId,
|
|
||||||
NEXSSRV: prms.nExsSrv
|
|
||||||
},
|
|
||||||
outPrms: { RCLOG: DT_CURSOR }
|
|
||||||
});
|
|
||||||
return logData.RCLOG[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
//Считывание записи очереди обмена
|
|
||||||
const getQueue = async prms => {
|
|
||||||
let queueData = await executeStored({
|
|
||||||
connection: prms.connection,
|
|
||||||
sName: "PKG_EXS$QUEUE_GET",
|
|
||||||
inPrms: {
|
|
||||||
NFLAG_SMART: 0,
|
|
||||||
NEXSQUEUE: prms.nQueueId
|
|
||||||
},
|
|
||||||
outPrms: { RCQUEUE: DT_CURSOR }
|
|
||||||
});
|
|
||||||
return queueData.RCQUEUE[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
//Помещение сообщения в очередь
|
|
||||||
const putQueue = async prms => {
|
|
||||||
let queueData = await executeStored({
|
|
||||||
connection: prms.connection,
|
|
||||||
sName: "PKG_EXS$QUEUE_PUT$2",
|
|
||||||
inPrms: {
|
|
||||||
NEXSSERVICEFN: prms.nServiceFnId,
|
|
||||||
BMSG: prms.blMsg,
|
|
||||||
NEXSQUEUE: prms.nQueueId,
|
|
||||||
NLNK_COMPANY: prms.nLnkCompanyId,
|
|
||||||
NLNK_DOCUMENT: prms.nLnkDocumentId,
|
|
||||||
SLNK_UNITCODE: prms.sLnkUnitcode,
|
|
||||||
SOPTIONS: prms.sOptions
|
|
||||||
},
|
|
||||||
outPrms: { RCQUEUE: DT_CURSOR }
|
|
||||||
});
|
|
||||||
return queueData.RCQUEUE[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
//Считывание очередной порции исходящих сообщений из очереди
|
|
||||||
const getQueueOutgoing = async prms => {
|
|
||||||
let queueOutgoingData = await executeStored({
|
|
||||||
connection: prms.connection,
|
|
||||||
sName: "PKG_EXS$QUEUE_SRV_TYPE_SEND_GET",
|
|
||||||
inPrms: {
|
|
||||||
NPORTION_SIZE: prms.nPortionSize,
|
|
||||||
NEXSSRV: prms.nExsSrv
|
|
||||||
},
|
|
||||||
outPrms: { RCQUEUES: DT_CURSOR }
|
|
||||||
});
|
|
||||||
return queueOutgoingData.RCQUEUES;
|
|
||||||
};
|
|
||||||
|
|
||||||
//Установка значения состояния в сообщении очереди
|
|
||||||
const setQueueState = async prms => {
|
|
||||||
let queueStateData = await executeStored({
|
|
||||||
connection: prms.connection,
|
|
||||||
sName: "PKG_EXS$QUEUE_EXEC_STATE_SET",
|
|
||||||
inPrms: {
|
|
||||||
NEXSQUEUE: prms.nQueueId,
|
|
||||||
NEXEC_STATE: prms.nExecState,
|
|
||||||
SEXEC_MSG: prms.sExecMsg,
|
|
||||||
NINC_EXEC_CNT: prms.nIncExecCnt,
|
|
||||||
NRESET_DATA: prms.nResetData
|
|
||||||
},
|
|
||||||
outPrms: { RCQUEUE: DT_CURSOR }
|
|
||||||
});
|
|
||||||
return queueStateData.RCQUEUE[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
//Считывание данных сообщения очереди
|
|
||||||
const getQueueMsg = async prms => {
|
|
||||||
let queueMsgData = await executeStored({
|
|
||||||
connection: prms.connection,
|
|
||||||
sName: "PKG_EXS$QUEUE_MSG_GET",
|
|
||||||
inPrms: {
|
|
||||||
NEXSQUEUE: prms.nQueueId
|
|
||||||
},
|
|
||||||
outPrms: { RCQUEUE_MSG: DT_CURSOR }
|
|
||||||
});
|
|
||||||
return queueMsgData.RCQUEUE_MSG[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
//Установка данных сообщения очереди
|
|
||||||
const setQueueMsg = async prms => {
|
|
||||||
let queueMsgData = await executeStored({
|
|
||||||
connection: prms.connection,
|
|
||||||
sName: "PKG_EXS$QUEUE_MSG_SET$2",
|
|
||||||
inPrms: {
|
|
||||||
NEXSQUEUE: prms.nQueueId,
|
|
||||||
BMSG: prms.blMsg
|
|
||||||
},
|
|
||||||
outPrms: { RCQUEUE: DT_CURSOR }
|
|
||||||
});
|
|
||||||
return queueMsgData.RCQUEUE[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
//Установка параметров сообщения очереди
|
|
||||||
const setQueueOptions = async prms => {
|
|
||||||
let queueOptionsData = await executeStored({
|
|
||||||
connection: prms.connection,
|
|
||||||
sName: "PKG_EXS$QUEUE_OPTIONS_SET$2",
|
|
||||||
inPrms: {
|
|
||||||
NEXSQUEUE: prms.nQueueId,
|
|
||||||
SOPTIONS: prms.sOptions
|
|
||||||
},
|
|
||||||
outPrms: { RCQUEUE: DT_CURSOR }
|
|
||||||
});
|
|
||||||
return queueOptionsData.RCQUEUE[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
//Считывание результата обработки сообщения очереди
|
|
||||||
const getQueueResp = async prms => {
|
|
||||||
let queueRespData = await executeStored({
|
|
||||||
connection: prms.connection,
|
|
||||||
sName: "PKG_EXS$QUEUE_RESP_GET",
|
|
||||||
inPrms: {
|
|
||||||
NEXSQUEUE: prms.nQueueId
|
|
||||||
},
|
|
||||||
outPrms: { RCQUEUE_RESP: DT_CURSOR }
|
|
||||||
});
|
|
||||||
return queueRespData.RCQUEUE_RESP[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
//Установка результата обработки сообщения очереди
|
|
||||||
const setQueueResp = async prms => {
|
|
||||||
let queueRespData = await executeStored({
|
|
||||||
connection: prms.connection,
|
|
||||||
sName: "PKG_EXS$QUEUE_RESP_SET$2",
|
|
||||||
inPrms: {
|
|
||||||
NEXSQUEUE: prms.nQueueId,
|
|
||||||
BRESP: prms.blResp,
|
|
||||||
NIS_ORIGINAL: prms.nIsOriginal
|
|
||||||
},
|
|
||||||
outPrms: { RCQUEUE: DT_CURSOR }
|
|
||||||
});
|
|
||||||
return queueRespData.RCQUEUE[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
//Установка параметров результата обработки сообщения очереди
|
|
||||||
const setQueueOptionsResp = async prms => {
|
|
||||||
let queueOptionsRespData = await executeStored({
|
|
||||||
connection: prms.connection,
|
|
||||||
sName: "PKG_EXS$QUEUE_OPTIONS_RESP_SET$2",
|
|
||||||
inPrms: {
|
|
||||||
NEXSQUEUE: prms.nQueueId,
|
|
||||||
SOPTIONS_RESP: prms.sOptionsResp
|
|
||||||
},
|
|
||||||
outPrms: { RCQUEUE: DT_CURSOR }
|
|
||||||
});
|
|
||||||
return queueOptionsRespData.RCQUEUE[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
//Исполнение обработчика со стороны БД для сообщения очереди
|
|
||||||
const execQueuePrc = async prms => {
|
|
||||||
let queuePrcData = await executeStored({
|
|
||||||
connection: prms.connection,
|
|
||||||
sName: "PKG_EXS$QUEUE_PRC",
|
|
||||||
inPrms: {
|
|
||||||
NEXSQUEUE: prms.nQueueId
|
|
||||||
},
|
|
||||||
outPrms: { RCRESULT: DT_CURSOR }
|
|
||||||
});
|
|
||||||
return queuePrcData.RCRESULT[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
//-----------------
|
|
||||||
// Интерфейс модуля
|
|
||||||
//-----------------
|
|
||||||
|
|
||||||
exports.DT_VARCHAR = DT_VARCHAR;
|
|
||||||
exports.DT_NUMBER = DT_NUMBER;
|
|
||||||
exports.DT_DATE = DT_DATE;
|
|
||||||
exports.DT_CLOB = DT_CLOB;
|
|
||||||
exports.DT_BLOB = DT_BLOB;
|
|
||||||
exports.DT_CURSOR = DT_CURSOR;
|
|
||||||
exports.executeStored = executeStored;
|
|
||||||
exports.checkAppStart = checkAppStart;
|
|
||||||
exports.initServer = initServer;
|
|
||||||
exports.clearServer = clearServer;
|
|
||||||
exports.connect = connect;
|
|
||||||
exports.disconnect = disconnect;
|
|
||||||
exports.getServices = getServices;
|
|
||||||
exports.getServiceFunctions = getServiceFunctions;
|
|
||||||
exports.getServiceContext = getServiceContext;
|
|
||||||
exports.setServiceContext = setServiceContext;
|
|
||||||
exports.clearServiceContext = clearServiceContext;
|
|
||||||
exports.isServiceAuth = isServiceAuth;
|
|
||||||
exports.putServiceAuthInQueue = putServiceAuthInQueue;
|
|
||||||
exports.getServiceExpiredQueueInfo = getServiceExpiredQueueInfo;
|
|
||||||
exports.log = log;
|
|
||||||
exports.getQueue = getQueue;
|
|
||||||
exports.putQueue = putQueue;
|
|
||||||
exports.getQueueOutgoing = getQueueOutgoing;
|
|
||||||
exports.setQueueState = setQueueState;
|
|
||||||
exports.getQueueMsg = getQueueMsg;
|
|
||||||
exports.setQueueMsg = setQueueMsg;
|
|
||||||
exports.setQueueOptions = setQueueOptions;
|
|
||||||
exports.getQueueResp = getQueueResp;
|
|
||||||
exports.setQueueResp = setQueueResp;
|
|
||||||
exports.setQueueOptionsResp = setQueueOptionsResp;
|
|
||||||
exports.execQueuePrc = execQueuePrc;
|
|
@ -30,24 +30,10 @@ const tag = [
|
|||||||
"Доверенность"
|
"Доверенность"
|
||||||
];
|
];
|
||||||
|
|
||||||
// Список имен тегов для замены ([Старое значение], [Новое значение])
|
|
||||||
const replaceTags = [
|
|
||||||
['"Иные получатели":', '"ИныеПолучатели":'],
|
|
||||||
['"Создатель документа":', '"СоздательДокумента":'],
|
|
||||||
];
|
|
||||||
|
|
||||||
//------------
|
//------------
|
||||||
// Тело модуля
|
// Тело модуля
|
||||||
//------------
|
//------------
|
||||||
|
|
||||||
//Замена наименований тегов (для корректной работы toXML)
|
|
||||||
const replaceTag = (obj) => {
|
|
||||||
for (let value of replaceTags) {
|
|
||||||
obj = obj.replace(new RegExp(value[0], 'g'), value[1]);
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
};
|
|
||||||
|
|
||||||
//Обернуть содержимое тега в массив
|
//Обернуть содержимое тега в массив
|
||||||
const toArray = (obj, tags) => {
|
const toArray = (obj, tags) => {
|
||||||
for (const prop in obj) {
|
for (const prop in obj) {
|
||||||
@ -163,7 +149,7 @@ const beforeDocParse = async prms => {
|
|||||||
//Подготовка действия
|
//Подготовка действия
|
||||||
case "СБИС.ПодготовитьДействие":
|
case "СБИС.ПодготовитьДействие":
|
||||||
//Если требуется использовать МЧД
|
//Если требуется использовать МЧД
|
||||||
if (obj.params?.Документ?.Этап[0]?.Действие?.Сертификат?.Доверенность) {
|
if (obj.params?.Документ?.Этап[0]?.Действие?.Сертификат?.Доверенность !== "undefined") {
|
||||||
obj.params.Документ.Этап[0].Действие.Сертификат.Доверенность.СистемаХраненияМЧД = SMCHD_STORAGE_SYSTEM;
|
obj.params.Документ.Этап[0].Действие.Сертификат.Доверенность.СистемаХраненияМЧД = SMCHD_STORAGE_SYSTEM;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -172,7 +158,7 @@ const beforeDocParse = async prms => {
|
|||||||
//Если требуется использовать МЧД
|
//Если требуется использовать МЧД
|
||||||
if (obj.params?.Документ?.Этап[0]?.Вложение?.Подпись?.Сертификат?.Доверенность) {
|
if (obj.params?.Документ?.Этап[0]?.Вложение?.Подпись?.Сертификат?.Доверенность) {
|
||||||
obj.params.Документ.Этап[0].Вложение.Подпись.Сертификат.Доверенность.СистемаХраненияМЧД = SMCHD_STORAGE_SYSTEM;
|
obj.params.Документ.Этап[0].Вложение.Подпись.Сертификат.Доверенность.СистемаХраненияМЧД = SMCHD_STORAGE_SYSTEM;
|
||||||
} else if (obj.params?.Документ?.Этап[0]?.Вложение[0]?.Подпись?.Сертификат?.Доверенность) {
|
} else if (obj.params?.Документ?.Этап[0]?.Вложение[0]?.Подпись?.Сертификат?.Доверенность !== "undefined") {
|
||||||
for (i = 0; i < obj.params.Документ.Этап[0].Вложение.length; i++) {
|
for (i = 0; i < obj.params.Документ.Этап[0].Вложение.length; i++) {
|
||||||
obj.params.Документ.Этап[0].Вложение[i].Подпись.Сертификат.Доверенность.СистемаХраненияМЧД = SMCHD_STORAGE_SYSTEM;
|
obj.params.Документ.Этап[0].Вложение[i].Подпись.Сертификат.Доверенность.СистемаХраненияМЧД = SMCHD_STORAGE_SYSTEM;
|
||||||
}
|
}
|
||||||
@ -204,7 +190,7 @@ const afterDocParse = async prms => {
|
|||||||
let resu = null;
|
let resu = null;
|
||||||
if (prms.queue.blResp) {
|
if (prms.queue.blResp) {
|
||||||
try {
|
try {
|
||||||
resu = toXML(JSON.parse(replaceTag(prms.queue.blResp.toString())));
|
resu = toXML(JSON.parse(prms.queue.blResp.toString()));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new Error(`Неожиданный ответ сервера ЭДО "СБИС". Ошибка интерпретации: ${e.message}`);
|
throw new Error(`Неожиданный ответ сервера ЭДО "СБИС". Ошибка интерпретации: ${e.message}`);
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
const xml2js = require("xml2js"); //Конвертация XML в JSON и JSON в XML
|
const xml2js = require("xml2js"); //Конвертация XML в JSON и JSON в XML
|
||||||
const cfg = require("./../config"); //Настройки сервера приложений
|
const cfg = require("./../config"); //Настройки сервера приложений
|
||||||
const { makeErrorText, sendMail } = require("./../core/utils"); //Вспомогательные функции
|
const { makeErrorText, sendMail } = require("./../core/utils"); //Вспомогательные функции
|
||||||
|
const oracledb = require("oracledb"); //Работа с СУБД Oracle
|
||||||
|
|
||||||
//---------------------
|
//---------------------
|
||||||
// Глобальные константы
|
// Глобальные константы
|
||||||
@ -23,37 +24,84 @@ const NSTATUS_DONE = 3;
|
|||||||
// Тело модуля
|
// Тело модуля
|
||||||
//------------
|
//------------
|
||||||
|
|
||||||
|
//Чтение данных из курсора
|
||||||
|
const readCursorData = cursor => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let queryStream = cursor.toQueryStream();
|
||||||
|
let rows = [];
|
||||||
|
queryStream.on("data", row => {
|
||||||
|
rows.push(row);
|
||||||
|
});
|
||||||
|
queryStream.on("error", err => {
|
||||||
|
reject(new Error(err.message));
|
||||||
|
});
|
||||||
|
queryStream.on("close", () => {
|
||||||
|
resolve(rows);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
//Установка статуса отправки
|
//Установка статуса отправки
|
||||||
const setSendMsg = async prms => {
|
const setSendMsg = async prms => {
|
||||||
await prms.dbConn.executeStored({
|
let pooledConnection;
|
||||||
connection: prms.dbConn.connection,
|
try {
|
||||||
sName: "PKG_EXS_EXT_MAIL.EXSEXTMAIL_SET_STATUS",
|
pooledConnection = await prms.connection.getConnection();
|
||||||
inPrms: {
|
await pooledConnection.execute(
|
||||||
NRN: prms.nRn,
|
"begin PKG_EXS_EXT_MAIL.EXSEXTMAIL_SET_STATUS(NRN => :NRN, SERR_TEXT => :SERR_TEXT, NSTATUS => :NSTATUS); end;",
|
||||||
SERR_TEXT: prms.sErrMsg,
|
{ NRN: prms.nRn, SERR_TEXT: prms.sErrMsg, NSTATUS: prms.nStatus },
|
||||||
NSTATUS: prms.nStatus
|
{ autoCommit: true }
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
} finally {
|
||||||
|
if (pooledConnection) {
|
||||||
|
try {
|
||||||
|
await pooledConnection.close();
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//Считывание записей прикладываемых документов
|
//Считывание записей прикладываемых документов
|
||||||
const getMailAttach = async prms => {
|
const getMailAttach = async prms => {
|
||||||
let attachData = await prms.dbConn.executeStored({
|
let pooledConnection;
|
||||||
connection: prms.dbConn.connection,
|
try {
|
||||||
sName: "PKG_EXS_EXT_MAIL.GET_ATTACH",
|
pooledConnection = await prms.connection.getConnection();
|
||||||
inPrms: { NIDENT: prms.nIdent },
|
let res = await pooledConnection.execute(
|
||||||
outPrms: { RCDOCUMENTS: prms.dbConn.connector.DT_CURSOR }
|
"begin PKG_EXS_EXT_MAIL.GET_ATTACH(NIDENT => :NIDENT, RCDOCUMENTS => :RCDOCUMENTS); end;",
|
||||||
});
|
{
|
||||||
|
NIDENT: prms.nIdent,
|
||||||
|
RCDOCUMENTS: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||||
|
},
|
||||||
|
{ outFormat: oracledb.OBJECT, autoCommit: true }
|
||||||
|
);
|
||||||
|
let rows = await readCursorData(res.outBinds.RCDOCUMENTS);
|
||||||
let rowsRes = [];
|
let rowsRes = [];
|
||||||
if (attachData)
|
//Если результат запроса не пустой
|
||||||
if (attachData.RCDOCUMENTS)
|
if (rows.length !== 0) {
|
||||||
attachData.RCDOCUMENTS.map(data => {
|
//Переводим BLOB в BUFFER и формируем формат аттача
|
||||||
|
for (let i = 0; i < rows.length; i++) {
|
||||||
|
let rowContent = await rows[i].BDATA.getData();
|
||||||
rowsRes.push({
|
rowsRes.push({
|
||||||
filename: data.filename,
|
filename: rows[i].FILENAME,
|
||||||
content: data.bdata
|
content: rowContent
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
return rowsRes;
|
return rowsRes;
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
} finally {
|
||||||
|
if (pooledConnection) {
|
||||||
|
try {
|
||||||
|
await pooledConnection.close();
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//Разбор XML
|
//Разбор XML
|
||||||
@ -77,7 +125,7 @@ const before = async prms => {
|
|||||||
parseRes = await parseXML(prms.queue.blMsg.toString());
|
parseRes = await parseXML(prms.queue.blMsg.toString());
|
||||||
//Если есть присоединенные файлы - добавляем их
|
//Если есть присоединенные файлы - добавляем их
|
||||||
if (parseRes.mail.ident) {
|
if (parseRes.mail.ident) {
|
||||||
parseRes.mail.attachments = await getMailAttach({ dbConn: prms.dbConn, nIdent: parseRes.mail.ident });
|
parseRes.mail.attachments = await getMailAttach({ connection: prms.dbConn.connection, nIdent: parseRes.mail.ident });
|
||||||
}
|
}
|
||||||
//Если указан текст в обычном формате
|
//Если указан текст в обычном формате
|
||||||
if (parseRes.mail.text) {
|
if (parseRes.mail.text) {
|
||||||
@ -110,7 +158,7 @@ const before = async prms => {
|
|||||||
//Если имеется рег. номер записи очереди отправки E-mail - обновляем информацию о текущем сообщении
|
//Если имеется рег. номер записи очереди отправки E-mail - обновляем информацию о текущем сообщении
|
||||||
if (parseRes.mail.nExsextmailId) {
|
if (parseRes.mail.nExsextmailId) {
|
||||||
await setSendMsg({
|
await setSendMsg({
|
||||||
dbConn: prms.dbConn,
|
connection: prms.dbConn.connection,
|
||||||
nRn: parseRes.mail.nExsextmailId,
|
nRn: parseRes.mail.nExsextmailId,
|
||||||
sErrMsg: "",
|
sErrMsg: "",
|
||||||
nStatus: NSTATUS_DONE
|
nStatus: NSTATUS_DONE
|
||||||
@ -122,7 +170,7 @@ const before = async prms => {
|
|||||||
//Если имеется рег. номер записи очереди отправки E-mail - обновляем информацию о текущем сообщении
|
//Если имеется рег. номер записи очереди отправки E-mail - обновляем информацию о текущем сообщении
|
||||||
if (parseRes.mail.nExsextmailId) {
|
if (parseRes.mail.nExsextmailId) {
|
||||||
await setSendMsg({
|
await setSendMsg({
|
||||||
dbConn: prms.dbConn,
|
connection: prms.dbConn.connection,
|
||||||
nRn: parseRes.mail.nExsextmailId,
|
nRn: parseRes.mail.nExsextmailId,
|
||||||
sErrMsg: res,
|
sErrMsg: res,
|
||||||
nStatus: NSTATUS_ERR
|
nStatus: NSTATUS_ERR
|
||||||
|
1905
package-lock.json
generated
1905
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -20,14 +20,11 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"body-parser": "^1.19.0",
|
"body-parser": "^1.19.0",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"express": "^4.17.1",
|
"express": "^4.19.2",
|
||||||
"kafkajs": "^2.2.4",
|
|
||||||
"lodash": "^4.17.19",
|
"lodash": "^4.17.19",
|
||||||
"module-alias": "^2.2.2",
|
"module-alias": "^2.2.2",
|
||||||
"mqtt": "^5.10.1",
|
|
||||||
"nodemailer": "^6.4.11",
|
"nodemailer": "^6.4.11",
|
||||||
"oracledb": "^4.2.0",
|
"oracledb": "^4.2.0",
|
||||||
"pg": "^8.13.1",
|
|
||||||
"request": "^2.88.2",
|
"request": "^2.88.2",
|
||||||
"request-promise": "^4.2.6",
|
"request-promise": "^4.2.6",
|
||||||
"validate": "^5.1.0",
|
"validate": "^5.1.0",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user