Переход к реальной схеме аутентификации (транш второй)

This commit is contained in:
Mikhail Chechnev 2019-01-06 00:36:40 +03:00
parent 01a3e88e6b
commit 1a64f7999b
13 changed files with 488 additions and 198 deletions

View File

@ -14,7 +14,7 @@ let dbConnect = {
//Пароль пользователя БД //Пароль пользователя БД
sPassword: "parus", sPassword: "parus",
//Строка подключения к БД //Строка подключения к БД
sConnectString: "DEMOP_CITKSERV", sConnectString: "DEMOP_CITKSERV_WAN",
//Наименование сервера приложений в сессии БД //Наименование сервера приложений в сессии БД
sSessionAppName: "PARUS$ExchangeServer", sSessionAppName: "PARUS$ExchangeServer",
//Подключаемый модуль обслуживания БД (низкоуровневые функции работы с СУБД) //Подключаемый модуль обслуживания БД (низкоуровневые функции работы с СУБД)
@ -24,7 +24,7 @@ let dbConnect = {
//Параметры обработки очереди исходящих сообщений //Параметры обработки очереди исходящих сообщений
let outGoing = { let outGoing = {
//Количество одновременно обрабатываемых исходящих сообщений //Количество одновременно обрабатываемых исходящих сообщений
nMaxWorkers: 1, nMaxWorkers: 3,
//Интервал проверки наличия исходящих сообщений (мс) //Интервал проверки наличия исходящих сообщений (мс)
nCheckTimeout: 1 nCheckTimeout: 1
}; };

View File

@ -33,6 +33,7 @@ exports.SERR_MAIL_FAILED = "ERR_MAIL_FAILED"; //Ошибка отправки п
//Типовые коды ошибок WEB-сервера //Типовые коды ошибок WEB-сервера
exports.SERR_WEB_SERVER = "ERR_WEB_SERVER"; //Ошибка WEB-сервера exports.SERR_WEB_SERVER = "ERR_WEB_SERVER"; //Ошибка WEB-сервера
//Типовые коди ошибок пользовательских обработчиков сервера приложений //Типовые коди ошибок пользовательских обработчиков сервера приложений и сервера БД
exports.SERR_APP_SERVER_BEFORE = "ERR_APP_SERVER_BEFORE"; //Ошибка предобработчика exports.SERR_APP_SERVER_BEFORE = "ERR_APP_SERVER_BEFORE"; //Ошибка предобработчика
exports.SERR_APP_SERVER_AFTER = "ERR_APP_SERVER_AFTER"; //Ошибка постобработчика exports.SERR_APP_SERVER_AFTER = "ERR_APP_SERVER_AFTER"; //Ошибка постобработчика
exports.SERR_DB_SERVER = "SERR_DB_SERVER"; //Ошибка обработчика сервера БД

View File

@ -139,7 +139,6 @@ class DBConnector extends EventEmitter {
let srvs = await this.connector.getServices({ connection: this.connection }); let srvs = await this.connector.getServices({ connection: this.connection });
srvs.forEach(s => { srvs.forEach(s => {
s.functions = []; s.functions = [];
s.context = {};
}); });
//Валидируем его //Валидируем его
let sCheckResult = validateObject({ services: srvs }, objServicesSchema.Services, "Список сервисов"); let sCheckResult = validateObject({ services: srvs }, objServicesSchema.Services, "Список сервисов");
@ -760,14 +759,19 @@ class DBConnector extends EventEmitter {
if (!sCheckResult) { if (!sCheckResult) {
//Исполняем действие в БД //Исполняем действие в БД
try { try {
let res = await this.connector.execQueuePrc({ //Подготовим параметры для передачи в БД
nQueueId: prms.nQueueId, let execQueuePrcData = _.cloneDeep(prms);
connection: this.connection execQueuePrcData.connection = this.connection;
}); //И выполним обработчик со стороны БД
let res = await this.connector.execQueuePrc(execQueuePrcData);
//Валидируем полученный ответ //Валидируем полученный ответ
sCheckResult = validateObject(res, objQueueSchema.Queue, "Изменённое сообщение очереди обмена"); 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;
} catch (e) { } catch (e) {
if (e instanceof ServerError) throw e; if (e instanceof ServerError) throw e;

View File

@ -23,7 +23,9 @@ const {
SERR_OBJECT_BAD_INTERFACE, SERR_OBJECT_BAD_INTERFACE,
SERR_WEB_SERVER, SERR_WEB_SERVER,
SERR_APP_SERVER_BEFORE, SERR_APP_SERVER_BEFORE,
SERR_APP_SERVER_AFTER SERR_APP_SERVER_AFTER,
SERR_DB_SERVER,
SERR_UNAUTH
} = require("./constants"); //Общесистемные константы } = require("./constants"); //Общесистемные константы
//-------------------------- //--------------------------
@ -144,7 +146,7 @@ class InQueue extends EventEmitter {
nQueueId: q.nId, nQueueId: q.nId,
nExecState: objQueueSchema.NQUEUE_EXEC_STATE_APP_OK nExecState: objQueueSchema.NQUEUE_EXEC_STATE_APP_OK
}); });
//Фиксируем успех исполнения //Фиксируем результат исполнения
if (!_.isUndefined(resBefore.blMsg)) { if (!_.isUndefined(resBefore.blMsg)) {
blMsg = resBefore.blMsg; blMsg = resBefore.blMsg;
q = await this.dbConn.setQueueMsg({ q = await this.dbConn.setQueueMsg({
@ -159,6 +161,10 @@ class InQueue extends EventEmitter {
blResp blResp
}); });
} }
//Если пришел флаг ошибочной аутентификации и он положительный - то это ошибка, дальше ничего не делаем
if (!_.isUndefined(resBefore.bUnAuth))
if (resBefore.bUnAuth === true)
throw new ServerError(SERR_UNAUTH, "Не аутентифицирован");
} else { } else {
//Или расскажем об ошибке //Или расскажем об ошибке
throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult); throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
@ -173,7 +179,13 @@ class InQueue extends EventEmitter {
nExecState: objQueueSchema.NQUEUE_EXEC_STATE_DB nExecState: objQueueSchema.NQUEUE_EXEC_STATE_DB
}); });
//Вызов обработчика БД //Вызов обработчика БД
q = await this.dbConn.execQueueDBPrc({ nQueueId: q.nId }); 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);
//Если результат - ошибка аутентификации, то и её пробрасываем, но с правильным кодом
if (prcRes.sResult == objQueueSchema.SPRC_RESP_RESULT_UNAUTH)
throw new ServerError(SERR_UNAUTH, prcRes.sMsg || "Не аутентифицирован");
//Выставим статус сообщению очереди - исполнено обработчиком БД //Выставим статус сообщению очереди - исполнено обработчиком БД
q = await this.dbConn.setQueueState({ q = await this.dbConn.setQueueState({
nQueueId: q.nId, nQueueId: q.nId,
@ -216,7 +228,7 @@ class InQueue extends EventEmitter {
nQueueId: q.nId, nQueueId: q.nId,
nExecState: objQueueSchema.NQUEUE_EXEC_STATE_APP_OK nExecState: objQueueSchema.NQUEUE_EXEC_STATE_APP_OK
}); });
//Фиксируем успех исполнения //Фиксируем результат исполнения
if (!_.isUndefined(resAfter.blResp)) { if (!_.isUndefined(resAfter.blResp)) {
blResp = resAfter.blResp; blResp = resAfter.blResp;
q = await this.dbConn.setQueueResp({ q = await this.dbConn.setQueueResp({
@ -224,6 +236,10 @@ class InQueue extends EventEmitter {
blResp blResp
}); });
} }
//Если пришел флаг ошибочной аутентификации и он положительный - то это ошибка, дальше ничего не делаем
if (!_.isUndefined(resAfter.bUnAuth))
if (resAfter.bUnAuth === true)
throw new ServerError(SERR_UNAUTH, "Не аутентифицирован");
} else { } else {
//Или расскажем об ошибке //Или расскажем об ошибке
throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult); throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);

View File

@ -220,9 +220,8 @@ class OutQueue extends EventEmitter {
} else { } else {
//Ошибки обработки нет, но может быть есть ошибка аутентификации //Ошибки обработки нет, но может быть есть ошибка аутентификации
if (result.sResult == objOutQueueProcessorSchema.STASK_RESULT_UNAUTH) { if (result.sResult == objOutQueueProcessorSchema.STASK_RESULT_UNAUTH) {
//!!!!!!!!!!!!!! //Ставим задачу на аутентификацию сервиса
//?????????????? await this.dbConn.putServiceAuthInQueue({ nServiceId: prms.queue.nServiceId });
//!!!!!!!!!!!!!!
} }
} }
} else { } else {

View File

@ -23,6 +23,7 @@ const {
SERR_OBJECT_BAD_INTERFACE, SERR_OBJECT_BAD_INTERFACE,
SERR_APP_SERVER_BEFORE, SERR_APP_SERVER_BEFORE,
SERR_APP_SERVER_AFTER, SERR_APP_SERVER_AFTER,
SERR_DB_SERVER,
SERR_UNAUTH SERR_UNAUTH
} = require("./constants"); //Глобальные константы } = require("./constants"); //Глобальные константы
const { NINC_EXEC_CNT_YES, NINC_EXEC_CNT_NO } = require("../models/prms_db_connector"); //Схемы валидации параметров функций модуля взаимодействия с БД const { NINC_EXEC_CNT_YES, NINC_EXEC_CNT_NO } = require("../models/prms_db_connector"); //Схемы валидации параметров функций модуля взаимодействия с БД
@ -114,21 +115,23 @@ const appProcess = async prms => {
let qData = await dbConn.getQueueMsg({ nQueueId: prms.queue.nId }); let qData = await dbConn.getQueueMsg({ nQueueId: prms.queue.nId });
//Считаем контекст сервиса //Считаем контекст сервиса
let serviceCtx = await dbConn.getServiceContext({ nServiceId: prms.service.nId }); let serviceCtx = await dbConn.getServiceContext({ nServiceId: prms.service.nId });
//Флаг установленности контекста для функции начала сеанса
let bCtxIsSet = false;
//Кладём данные тела в объект сообщения и инициализируем поле для ответа //Кладём данные тела в объект сообщения и инициализируем поле для ответа
_.extend(prms.queue, { blMsg: qData.blMsg, blResp: null }); _.extend(prms.queue, { blMsg: qData.blMsg, blResp: null });
//Кладём данные контекста в сервис //Кладём данные контекста в сервис
_.extend(prms.service, serviceCtx); _.extend(prms.service, serviceCtx);
//Собираем параметры для передачи серверу //Собираем параметры для передачи серверу
let options = { method: prms.service.sFnPrmsType }; let options = { method: prms.function.sFnPrmsType };
//Определимся с URL и телом сообщения в зависимости от способа передачи параметров //Определимся с URL и телом сообщения в зависимости от способа передачи параметров
if (prms.service.sFnPrmsType == objServiceFnSchema.NFN_PRMS_TYPE_POST) { if (prms.function.nFnPrmsType == objServiceFnSchema.NFN_PRMS_TYPE_POST) {
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;
} else { } else {
options.url = buildURL({ options.url = buildURL({
sSrvRoot: prms.service.sSrvRoot, sSrvRoot: prms.service.sSrvRoot,
sFnURL: prms.function.sFnURL, sFnURL: prms.function.sFnURL,
sQuery: prms.queue.blMsg.toString() sQuery: prms.queue.blMsg === null ? "" : prms.queue.blMsg.toString()
}); });
} }
//Выполняем обработчик "До" (если он есть) //Выполняем обработчик "До" (если он есть)
@ -150,26 +153,40 @@ const appProcess = async prms => {
); );
//Если структура ответа в норме //Если структура ответа в норме
if (!sCheckResult) { if (!sCheckResult) {
//Применим её //Применим ответ "До" - обработанное сообщение очереди
if (!_.isUndefined(resBefore.blMsg)) { if (!_.isUndefined(resBefore.blMsg)) {
prms.queue.blMsg = resBefore.blMsg; prms.queue.blMsg = resBefore.blMsg;
await dbConn.setQueueMsg({ await dbConn.setQueueMsg({
nQueueId: prms.queue.nId, nQueueId: prms.queue.nId,
blMsg: prms.queue.blMsg blMsg: prms.queue.blMsg
}); });
if (prms.service.sFnPrmsType == objServiceFnSchema.NFN_PRMS_TYPE_POST) { if (prms.function.nFnPrmsType == objServiceFnSchema.NFN_PRMS_TYPE_POST) {
options.body = prms.queue.blMsg; options.body = prms.queue.blMsg;
} else { } else {
options.url = buildURL({ options.url = buildURL({
sSrvRoot: prms.service.sSrvRoot, sSrvRoot: prms.service.sSrvRoot,
sFnURL: prms.function.sFnURL, sFnURL: prms.function.sFnURL,
sQuery: prms.queue.blMsg.toString() sQuery: prms.queue.blMsg === null ? "" : prms.queue.blMsg.toString()
}); });
} }
} }
if (!_.isUndefined(resBefore.options)) options = _.cloneDeep(resBefore.options); //Применим ответ "До" - параметры отправки сообщения удаленному серверу
if (!_.isUndefined(resBefore.options)) _.extend(options, resBefore.options);
//Применим ответ "До" - флаг отсуствия аутентификации
if (!_.isUndefined(resBefore.bUnAuth)) if (!_.isUndefined(resBefore.bUnAuth))
if (resBefore.bUnAuth === true) {
throw new ServerError(SERR_UNAUTH, "Не аутентифицирован"); throw new ServerError(SERR_UNAUTH, "Не аутентифицирован");
}
//Применим ответ "До" - контекст работы сервиса
if (!_.isUndefined(resBefore.sCtx))
if (prms.function.nFnType == objServiceFnSchema.NFN_TYPE_LOGIN) {
await dbConn.setServiceContext({
nServiceId: prms.service.nId,
sCtx: resBefore.sCtx,
dCtxExp: resBefore.dCtxExp
});
bCtxIsSet = true;
}
} else { } else {
//Или расскажем об ошибке в структуре ответа //Или расскажем об ошибке в структуре ответа
throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult); throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
@ -207,7 +224,7 @@ const appProcess = async prms => {
); );
//Если структура ответа в норме //Если структура ответа в норме
if (!sCheckResult) { if (!sCheckResult) {
//Применим её //Применим ответ "После" - обработанный ответ удаленного сервиса
if (!_.isUndefined(resAfter.blResp)) { if (!_.isUndefined(resAfter.blResp)) {
prms.queue.blResp = resAfter.blResp; prms.queue.blResp = resAfter.blResp;
await dbConn.setQueueResp({ await dbConn.setQueueResp({
@ -215,14 +232,38 @@ const appProcess = async prms => {
blResp: prms.queue.blResp blResp: prms.queue.blResp
}); });
} }
//Применим ответ "После" - флаг утентификации сервиса
if (!_.isUndefined(resAfter.bUnAuth)) if (!_.isUndefined(resAfter.bUnAuth))
if (resAfter.bUnAuth === true)
throw new ServerError(SERR_UNAUTH, "Не аутентифицирован"); throw new ServerError(SERR_UNAUTH, "Не аутентифицирован");
//Применим ответ "После" - контекст работы сервиса
if (!_.isUndefined(resAfter.sCtx))
if (prms.function.nFnType == objServiceFnSchema.NFN_TYPE_LOGIN) {
await dbConn.setServiceContext({
nServiceId: prms.service.nId,
sCtx: resAfter.sCtx,
dCtxExp: resAfter.dCtxExp
});
bCtxIsSet = true;
}
} else { } else {
//Или расскажем об ошибке в структуре ответа //Или расскажем об ошибке в структуре ответа
throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult); throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult);
} }
} }
} }
//Если это функция начала сеанса, и нет обработчика на стороне БД и контекст не был установлен до сих пор - то положим в него то, что нам ответил сервер
if (
prms.function.nFnType == objServiceFnSchema.NFN_TYPE_LOGIN &&
!prms.function.sPrcResp &&
!bCtxIsSet
) {
await dbConn.setServiceContext({ nServiceId: prms.service.nId, sCtx: serverResp });
}
//Если это функция окончания сеанса, и нет обработчика на стороне БД - то сбросим контекст здесь
if (prms.function.nFnType == objServiceFnSchema.NFN_TYPE_LOGOUT && !prms.function.sPrcResp) {
await dbConn.clearServiceContext({ nServiceId: prms.service.nId });
}
//Фиксируем успешное исполнение сервером приложений - в статусе сообщения //Фиксируем успешное исполнение сервером приложений - в статусе сообщения
res = await dbConn.setQueueState({ res = await dbConn.setQueueState({
nQueueId: prms.queue.nId, nQueueId: prms.queue.nId,
@ -287,8 +328,17 @@ const dbProcess = async prms => {
}, ${prms.queue.sExecState}, попытка исполнения - ${prms.queue.nExecCnt + 1}`, }, ${prms.queue.sExecState}, попытка исполнения - ${prms.queue.nExecCnt + 1}`,
{ nQueueId: prms.queue.nId } { nQueueId: prms.queue.nId }
); );
//Вызов обработчика БД //Если обработчик со стороны БД указан
res = await dbConn.execQueueDBPrc({ nQueueId: prms.queue.nId }); if (prms.function.sPrcResp) {
//Вызываем его
let prcRes = await dbConn.execQueueDBPrc({ nQueueId: prms.queue.nId });
//Если результат - ошибка пробрасываем её
if (prcRes.sResult == objQueueSchema.SPRC_RESP_RESULT_ERR)
throw new ServerError(SERR_DB_SERVER, prcRes.sMsg);
//Если результат - ошибка аутентификации, то и её пробрасываем, но с правильным кодом
if (prcRes.sResult == objQueueSchema.SPRC_RESP_RESULT_UNAUTH)
throw new ServerError(SERR_UNAUTH, prcRes.sMsg || "Не аутентифицирован");
}
//Фиксируем успешное исполнение (полное - дальше обработки нет) - в статусе сообщения //Фиксируем успешное исполнение (полное - дальше обработки нет) - в статусе сообщения
res = await dbConn.setQueueState({ res = await dbConn.setQueueState({
nQueueId: prms.queue.nId, nQueueId: prms.queue.nId,
@ -351,8 +401,6 @@ const processTask = async prms => {
await dbConn.connect(); await dbConn.connect();
//Считываем запись очереди //Считываем запись очереди
q = await dbConn.getQueue({ nQueueId: prms.task.nQueueId }); q = await dbConn.getQueue({ nQueueId: prms.task.nQueueId });
//Выставим флаг - нет ошибок аутентификации на удаленном сервере
let bUnAuthFlag = false;
//Далее работаем от статуса считанной записи //Далее работаем от статуса считанной записи
switch (q.nExecState) { switch (q.nExecState) {
//Статусы "Поставлено в очередь" или "Ошибка обработки сервером приложений" //Статусы "Поставлено в очередь" или "Ошибка обработки сервером приложений"
@ -361,61 +409,22 @@ const processTask = async prms => {
//Если ещё не обрабатывали или есть ещё попытки отработки //Если ещё не обрабатывали или есть ещё попытки отработки
if (q.nExecCnt == 0 || q.nExecCnt < q.nRetryAttempts) { if (q.nExecCnt == 0 || q.nExecCnt < q.nRetryAttempts) {
//Запускаем обработку сервером приложений //Запускаем обработку сервером приложений
try {
let res = await appProcess({ let res = await appProcess({
queue: q, queue: q,
service: prms.task.service, service: prms.task.service,
function: prms.task.function function: prms.task.function
}); });
//Если результат обработки - ошибка аутентификации //Если результат обработки ошибка - пробрасываем её дальше
if (res === objOutQueueProcessorSchema.STASK_RESULT_UNAUTH) { if (res instanceof ServerError) {
//Выставим флаг, который будет указывать на ошибку аутентификации throw res;
bUnAuthFlag = true;
} else { } else {
//Нет такой ошибки, посмотрим что прилетело сообщение в успешном статусе и тогда запустим обработку сервером БД //Нет ошибки, посмотрим что прилетело сообщение в успешном статусе и тогда запустим обработку сервером БД
if (res.nExecState == objQueueSchema.NQUEUE_EXEC_STATE_APP_OK) { if (res.nExecState == objQueueSchema.NQUEUE_EXEC_STATE_APP_OK) {
try { res = await dbProcess({ queue: res, function: prms.task.function });
await dbProcess({ queue: res }); //Если результат обработки ошибка - пробрасываем её дальше
} catch (e) { if (res instanceof ServerError) throw res;
//Фиксируем ошибку обработки сервером БД - в статусе сообщения
await dbConn.setQueueState({
nQueueId: res.nId,
sExecMsg: makeErrorText(e),
nIncExecCnt: NINC_EXEC_CNT_YES,
nExecState:
res.nExecCnt + 1 < res.nRetryAttempts
? objQueueSchema.NQUEUE_EXEC_STATE_DB_ERR
: objQueueSchema.NQUEUE_EXEC_STATE_ERR
});
//Фиксируем ошибку обработки сервером БД - в протоколе работы сервиса
await logger.error(
`Ошибка обработки исходящего сообщения ${
res.nId
} сервером БД: ${makeErrorText(e)}`,
{ nQueueId: res.nId }
);
} }
} }
}
} catch (e) {
//Фиксируем ошибку обработки сервером приложений - в статусе сообщения
newQueue = await dbConn.setQueueState({
nQueueId: q.nId,
sExecMsg: makeErrorText(e),
nIncExecCnt: NINC_EXEC_CNT_YES,
nExecState:
q.nExecCnt + 1 < q.nRetryAttempts
? objQueueSchema.NQUEUE_EXEC_STATE_APP_ERR
: objQueueSchema.NQUEUE_EXEC_STATE_ERR
});
//Фиксируем ошибку обработки сервером приложений - в протоколе работы сервиса
await logger.error(
`Ошибка обработки исходящего сообщения ${q.nId} сервером приложений: ${makeErrorText(
e
)}`,
{ nQueueId: q.nId }
);
}
} else { } else {
//Попыток нет - финализируем обработку //Попыток нет - финализируем обработку
await dbConn.setQueueState({ await dbConn.setQueueState({
@ -433,25 +442,9 @@ const processTask = async prms => {
//Если ещё есть попытки отработки //Если ещё есть попытки отработки
if (q.nExecCnt == 0 || q.nExecCnt < q.nRetryAttempts) { if (q.nExecCnt == 0 || q.nExecCnt < q.nRetryAttempts) {
//Снова запускаем обработку сервером БД //Снова запускаем обработку сервером БД
try { let res = await dbProcess({ queue: q, function: prms.task.function });
await dbProcess({ queue: q }); //Если результат обработки ошибка - пробрасываем её дальше
} catch (e) { if (res instanceof ServerError) throw res;
//Фиксируем ошибку обработки сервером БД - в статусе сообщения
await dbConn.setQueueState({
nQueueId: q.nId,
sExecMsg: makeErrorText(e),
nIncExecCnt: NINC_EXEC_CNT_YES,
nExecState:
q.nExecCnt + 1 < q.nRetryAttempts
? objQueueSchema.NQUEUE_EXEC_STATE_DB_ERR
: objQueueSchema.NQUEUE_EXEC_STATE_ERR
});
//Фиксируем ошибку обработки сервером БД - в протоколе работы сервиса
await logger.error(
`Ошибка обработки исходящего сообщения ${q.nId} сервером БД: ${makeErrorText(e)}`,
{ nQueueId: q.nId }
);
}
} else { } else {
//Попыток нет - финализируем обработку //Попыток нет - финализируем обработку
await dbConn.setQueueState({ await dbConn.setQueueState({
@ -493,14 +486,14 @@ const processTask = async prms => {
} }
//Отключаемся от БД //Отключаемся от БД
if (dbConn) await dbConn.disconnect(); if (dbConn) await dbConn.disconnect();
//Отправляем успех или ошибку аутентификации //Отправляем успех
if (bUnAuthFlag) sendUnAuthResult(); sendOKResult();
else sendOKResult();
} catch (e) { } catch (e) {
//Отключаемся от БД //Отключаемся от БД
if (dbConn) await dbConn.disconnect(); if (dbConn) await dbConn.disconnect();
//Отправляем ошибку //Отправляем ошибку
sendErrorResult({ sMessage: makeErrorText(e) }); if (e instanceof ServerError && e.sCode == SERR_UNAUTH) sendUnAuthResult();
else sendErrorResult({ sMessage: makeErrorText(e) });
} }
} else { } else {
sendErrorResult({ sMessage: sCheckResult }); sendErrorResult({ sMessage: sCheckResult });

View File

@ -9,8 +9,11 @@ create or replace package PKG_EXS as
SCONT_PRC constant PKG_STD.TSTRING := 'PRC'; -- Íàèìåíîâàíèå êîíòåéíåðà äëÿ ïàðàìåòðîâ ïðîöåññà SCONT_PRC constant PKG_STD.TSTRING := 'PRC'; -- Íàèìåíîâàíèå êîíòåéíåðà äëÿ ïàðàìåòðîâ ïðîöåññà
/* Êîíñòàíòû - ïîëÿ êîíòåéíåðîâ */ /* Êîíñòàíòû - ïîëÿ êîíòåéíåðîâ */
SCONT_FLD_SERR constant PKG_STD.TSTRING := 'SERR'; -- Íàèìåíîâàíèå ïîëÿ êîíòåéíåðà äëÿ îøèáêè SCONT_FLD_SRESULT constant PKG_STD.TSTRING := 'SRESULT'; -- Íàèìåíîâàíèå ïîëÿ êîíòåéíåðà äëÿ êîäà ðåçóëüòàòà îáðàáîòêè
SCONT_FLD_SMSG constant PKG_STD.TSTRING := 'SMSG'; -- Íàèìåíîâàíèå ïîëÿ êîíòåéíåðà äëÿ ñîîáùåíèÿ îáðàáîòêè
SCONT_FLD_BRESP constant PKG_STD.TSTRING := 'BRESP'; -- Íàèìåíîâàíèå ïîëÿ êîíòåéíåðà äëÿ ðåçóëüòàòà îáðàáîòêè SCONT_FLD_BRESP constant PKG_STD.TSTRING := 'BRESP'; -- Íàèìåíîâàíèå ïîëÿ êîíòåéíåðà äëÿ ðåçóëüòàòà îáðàáîòêè
SCONT_FLD_DCTX_EXP constant PKG_STD.TSTRING := 'DCTX_EXP'; -- Íàèìåíîâàíèå ïîëÿ êîíòåéíåðà äëÿ äàòû èñòå÷åíèÿ êîíòåêòñà ñåðâèñà
SCONT_FLD_SCTX constant PKG_STD.TSTRING := 'SCTX'; -- Íàèìåíîâàíèå ïîëÿ êîíòåéíåðà äëÿ äëÿ êîíòåêñòà ñåðâèñà
/* Êîíñòàíòû - òèïû ñåðâèñîâ */ /* Êîíñòàíòû - òèïû ñåðâèñîâ */
NSRV_TYPE_SEND constant EXSSERVICE.SRV_TYPE%type := 0; -- Îòïðàâêà ñîîáùåíèé NSRV_TYPE_SEND constant EXSSERVICE.SRV_TYPE%type := 0; -- Îòïðàâêà ñîîáùåíèé
@ -108,8 +111,13 @@ create or replace package PKG_EXS as
SAUTH_ONLY_YES constant varchar2(40) := 'AUTH_ONLY_YES'; -- Òðåáóåòñÿ àóòåíòèôèêàöèÿ (ñòðîêîâûé êîä) SAUTH_ONLY_YES constant varchar2(40) := 'AUTH_ONLY_YES'; -- Òðåáóåòñÿ àóòåíòèôèêàöèÿ (ñòðîêîâûé êîä)
SAUTH_ONLY_NO constant varchar2(40) := 'AUTH_ONLY_NO'; -- Àóòåíòèôèêàöèÿ íå òðåáóåòñÿ (ñòðîêîâûé êîä) SAUTH_ONLY_NO constant varchar2(40) := 'AUTH_ONLY_NO'; -- Àóòåíòèôèêàöèÿ íå òðåáóåòñÿ (ñòðîêîâûé êîä)
/* Êîíñòàíòû - êîäû ðåçóëüòàòîâ èñïîëíåíèÿ îáðàáîò÷èêà ñîîáùåíèÿ */
SPRC_RESP_RESULT_OK constant varchar2(40) := 'OK'; -- Îáðàáîòàíî óñïåøíî
SPRC_RESP_RESULT_ERR constant varchar2(40) := 'ERR'; -- Îøèáêà îáðàáîòêè
SPRC_RESP_RESULT_UNAUTH constant varchar2(40) := 'UNAUTH'; -- Íåàóòåíòèôèöèðîâàí
/* Êîíñòàíòû - îæèäàåìûé èíòåðôåéñ ïðîöåäóðû îáðàáîòêè ñîîáùåíèÿ î÷åðåäè íà ñòîðîíå ÁÄ */ /* Êîíñòàíòû - îæèäàåìûé èíòåðôåéñ ïðîöåäóðû îáðàáîòêè ñîîáùåíèÿ î÷åðåäè íà ñòîðîíå ÁÄ */
SPRC_RESP_ARGS constant varchar2(80) := 'NIDENT,IN,NUMBER;NSRV_TYPE,IN,NUMBER;NEXSQUEUE,IN,NUMBER;'; -- Ñïèñîê ïàðàìåòðîâ ïðîöåäóðû îáðàáîòêè SPRC_RESP_ARGS constant varchar2(80) := 'NIDENT,IN,NUMBER;NEXSQUEUE,IN,NUMBER;'; -- Ñïèñîê ïàðàìåòðîâ ïðîöåäóðû îáðàáîòêè
/* Ïðîâåðêà àêòèâíîñòè ñåðâåðà ïðèëîæåíèé */ /* Ïðîâåðêà àêòèâíîñòè ñåðâåðà ïðèëîæåíèé */
function UTL_APPSRV_IS_ACTIVE function UTL_APPSRV_IS_ACTIVE
@ -223,6 +231,28 @@ create or replace package PKG_EXS as
SARG in varchar2 -- Íàèìåíîâàíèå ïàðàìåòðà SARG in varchar2 -- Íàèìåíîâàíèå ïàðàìåòðà
) return blob; -- Çíà÷åíèå ïàðàìåòðà ) return blob; -- Çíà÷åíèå ïàðàìåòðà
/* Óñòàíîâêà ðåçóëüòàòà èñïîëíåíèÿ îáðàáîò÷èêà */
procedure PRC_RESP_RESULT_SET
(
NIDENT in number, -- Èäåíòèôèêàòîð ïðîöåññà
SRESULT in varchar2 := SPRC_RESP_RESULT_OK, -- Êîä ðåçóëüòàòà (ñì. êîíñòàíòû SPRC_RESP_RESULT_*)
BRESP in blob := null, -- Ðåçóëüòàò îáðàáîòêè
SMSG in varchar2 := null, -- Ñîîáùåíèå îáðàáîò÷èêà
SCTX in varchar2 := null, -- Êîíòåêñò
DCTX_EXP in date := null -- Äàòà èñòå÷åíèÿ êîíòåêñòà
);
/* Ñ÷èòûâàíèå ðåçóëüòàòà èñïîëíåíèÿ îáðàáîò÷èêà */
procedure PRC_RESP_RESULT_GET
(
NIDENT in number, -- Èäåíòèôèêàòîð ïðîöåññà
SRESULT out varchar2, -- Êîä ðåçóëüòàòà (ñì. êîíñòàíòû SPRC_RESP_RESULT_*)
BRESP out blob, -- Ðåçóëüòàò îáðàáîòêè
SMSG out varchar2, -- Ñîîáùåíèå îáðàáîò÷èêà
SCTX out varchar2, -- Êîíòåêñò
DCTX_EXP out date -- Äàòà èñòå÷åíèÿ êîíòåêñòà
);
/* Áàçîâîå äîáàâëåíèå â áóôåð îòáîðà äîêóìåíòîâ */ /* Áàçîâîå äîáàâëåíèå â áóôåð îòáîðà äîêóìåíòîâ */
procedure RNLIST_BASE_INSERT procedure RNLIST_BASE_INSERT
( (
@ -271,7 +301,7 @@ create or replace package PKG_EXS as
( (
NEXSSERVICE in number, -- Ðåã. íîìåð çàïèñè ñåðâèñà NEXSSERVICE in number, -- Ðåã. íîìåð çàïèñè ñåðâèñà
SCTX in varchar2, -- Êîíòåêñò SCTX in varchar2, -- Êîíòåêñò
DCTX_EXP in date -- Äàòà èñòå÷åíèÿ êîíòåêñòà DCTX_EXP in date := null -- Äàòà èñòå÷åíèÿ êîíòåêñòà
); );
/* Î÷èñòêà êîíòåêñòà ñåðâèñà */ /* Î÷èñòêà êîíòåêñòà ñåðâèñà */
@ -421,6 +451,13 @@ create or replace package PKG_EXS as
/* Óñòàíîâêà ðåçóëüòàòà îáðàáîòêè çàïèñè î÷åðåäè */ /* Óñòàíîâêà ðåçóëüòàòà îáðàáîòêè çàïèñè î÷åðåäè */
procedure QUEUE_RESP_SET procedure QUEUE_RESP_SET
(
NEXSQUEUE in number, -- Ðåã. íîìåð çàïèñè î÷åðåäè
BRESP in blob -- Ðåçóëüòàò îáðàáîòêè
);
/* Óñòàíîâêà ðåçóëüòàòà îáðàáîòêè çàïèñè î÷åðåäè (âîçâðàùàåò èçìåíåííóþ ïîçèöèþ î÷åðåäè) */
procedure QUEUE_RESP_SET
( (
NEXSQUEUE in number, -- Ðåã. íîìåð çàïèñè î÷åðåäè NEXSQUEUE in number, -- Ðåã. íîìåð çàïèñè î÷åðåäè
BRESP in blob, -- Ðåçóëüòàò îáðàáîòêè BRESP in blob, -- Ðåçóëüòàò îáðàáîòêè
@ -436,6 +473,13 @@ create or replace package PKG_EXS as
/* Óñòàíîâêà ñîîáùåíèÿ çàïèñè î÷åðåäè */ /* Óñòàíîâêà ñîîáùåíèÿ çàïèñè î÷åðåäè */
procedure QUEUE_MSG_SET procedure QUEUE_MSG_SET
(
NEXSQUEUE in number, -- Ðåã. íîìåð çàïèñè î÷åðåäè
BMSG in blob -- Ðåçóëüòàò îáðàáîòêè
);
/* Óñòàíîâêà ñîîáùåíèÿ çàïèñè î÷åðåäè (âîçâðàùàåò èçìåíåííóþ ïîçèöèþ î÷åðåäè) */
procedure QUEUE_MSG_SET
( (
NEXSQUEUE in number, -- Ðåã. íîìåð çàïèñè î÷åðåäè NEXSQUEUE in number, -- Ðåã. íîìåð çàïèñè î÷åðåäè
BMSG in blob, -- Ðåçóëüòàò îáðàáîòêè BMSG in blob, -- Ðåçóëüòàò îáðàáîòêè
@ -500,7 +544,7 @@ create or replace package PKG_EXS as
procedure QUEUE_PRC procedure QUEUE_PRC
( (
NEXSQUEUE in number, -- Ðåã. íîìåð çàïèñè î÷åðåäè NEXSQUEUE in number, -- Ðåã. íîìåð çàïèñè î÷åðåäè
RCQUEUE out sys_refcursor -- Êóðñîð ñ îáðàáîòàííîé ïîçèöèåé î÷åðåäè RCRESULT out sys_refcursor -- Êóðñîð ñ ðåçóëüòàòàìè îáðàáîòêè
); );
end; end;
@ -720,6 +764,10 @@ create or replace package body PKG_EXS as
NARGS_LIST_CUR_CORRECT := 0; NARGS_LIST_CUR_CORRECT := 0;
end if; end if;
end loop; end loop;
/* Ïðîâåðèì ñîâïàäåíèå è ïî êîëè÷åñòâó */
if (RARGS_LIST.COUNT <> RARGS_LIST_CUR.COUNT) then
NARGS_LIST_CUR_CORRECT := 0;
end if;
/* Óñòàíîâêà ðåçóëüòàòà */ /* Óñòàíîâêà ðåçóëüòàòà */
NRESULT := NARGS_LIST_CUR_CORRECT; NRESULT := NARGS_LIST_CUR_CORRECT;
/* Óñòàíîâèì ñîîáùåíèå îá îæèäàåìîì èíòåðôåéñå */ /* Óñòàíîâèì ñîîáùåíèå îá îæèäàåìîì èíòåðôåéñå */
@ -1006,6 +1054,8 @@ create or replace package body PKG_EXS as
SCONTAINER := UTL_CONTAINER_MAKE_NAME(NIDENT => NIDENT); SCONTAINER := UTL_CONTAINER_MAKE_NAME(NIDENT => NIDENT);
/* Ñ÷èòàåì çíà÷åíèå èäåíòèôèêàòîðà áóôåðà èç êîíòåéíåðà */ /* Ñ÷èòàåì çíà÷åíèå èäåíòèôèêàòîðà áóôåðà èç êîíòåéíåðà */
NFILE_IDENT := PKG_CONTVARGLB.GETN(SCONTAINER => SCONTAINER, SNAME => SARG); NFILE_IDENT := PKG_CONTVARGLB.GETN(SCONTAINER => SCONTAINER, SNAME => SARG);
/* Åñëè èäåíòèôèêàòîð áóôåðà áûë â êîíòåéíåðå */
if (NFILE_IDENT is not null) then
/* Çàáåðåì ðåçóëüòàòû îáðàáîòêè èç ôàéëîâîãî áóôåðà */ /* Çàáåðåì ðåçóëüòàòû îáðàáîòêè èç ôàéëîâîãî áóôåðà */
begin begin
select T.BDATA into BRESP from FILE_BUFFER T where T.IDENT = NFILE_IDENT; select T.BDATA into BRESP from FILE_BUFFER T where T.IDENT = NFILE_IDENT;
@ -1021,10 +1071,72 @@ create or replace package body PKG_EXS as
end; end;
/* Çà÷èñòèì ôàéëîâûé áóôåð */ /* Çà÷èñòèì ôàéëîâûé áóôåð */
P_FILE_BUFFER_CLEAR(NIDENT => NFILE_IDENT); P_FILE_BUFFER_CLEAR(NIDENT => NFILE_IDENT);
else
/* Èäåíòèôèêàòîð áóôåðà â êîíòåéíåðå îòñóòñòâîâàë - äàííûõ íåò */
BRESP := null;
end if;
/* Âåðí¸ì çíà÷åíèå */ /* Âåðí¸ì çíà÷åíèå */
return BRESP; return BRESP;
end PRC_RESP_ARG_BLOB_GET; end PRC_RESP_ARG_BLOB_GET;
/* Óñòàíîâêà ðåçóëüòàòà èñïîëíåíèÿ îáðàáîò÷èêà */
procedure PRC_RESP_RESULT_SET
(
NIDENT in number, -- Èäåíòèôèêàòîð ïðîöåññà
SRESULT in varchar2 := SPRC_RESP_RESULT_OK, -- Êîä ðåçóëüòàòà (ñì. êîíñòàíòû SPRC_RESP_RESULT_*)
BRESP in blob := null, -- Äàííûå îòâåòà
SMSG in varchar2 := null, -- Ñîîáùåíèå îáðàáîò÷èêà
SCTX in varchar2 := null, -- Êîíòåêñò
DCTX_EXP in date := null -- Äàòà èñòå÷åíèÿ êîíòåêñòà
)
is
begin
/* Ïðîâåðèì ïàðàìåòðû */
if (SRESULT is not null) then
if (SRESULT not in (SPRC_RESP_RESULT_OK, SPRC_RESP_RESULT_ERR, SPRC_RESP_RESULT_UNAUTH)) then
P_EXCEPTION(0,
'Êîä ðåçóëüòàòà èñïîëíåíèÿ îáðàáîò÷èêà "%s" íå ïîääåðæèâàåòñÿ',
SRESULT);
end if;
else
P_EXCEPTION(0, 'Íå óêàçàí êîä ðåçóëüòàòà èñïîëíåíèÿ îáðàáîò÷èêà');
end if;
/* Ñîõðàíÿåì êîä ðåçóëüòàòà */
PRC_RESP_ARG_STR_SET(NIDENT => NIDENT, SARG => SCONT_FLD_SRESULT, SVALUE => SRESULT);
/* Ñîõðàíÿåì äàííûå îòâåòà */
PRC_RESP_ARG_BLOB_SET(NIDENT => NIDENT, SARG => SCONT_FLD_BRESP, BVALUE => BRESP);
/* Ñîõðàíÿåì ñîîáùåíèå îáðàáîò÷èêà */
PRC_RESP_ARG_STR_SET(NIDENT => NIDENT, SARG => SCONT_FLD_SMSG, SVALUE => SMSG);
/* Ñîõðàíÿåì êîíòåêñò */
PRC_RESP_ARG_STR_SET(NIDENT => NIDENT, SARG => SCONT_FLD_SCTX, SVALUE => SCTX);
/* Ñîõðàíÿåì äàòó èñòå÷åíèÿ êîíòåêñòà */
PRC_RESP_ARG_DATE_SET(NIDENT => NIDENT, SARG => SCONT_FLD_DCTX_EXP, DVALUE => DCTX_EXP);
end PRC_RESP_RESULT_SET;
/* Ñ÷èòûâàíèå ðåçóëüòàòà èñïîëíåíèÿ îáðàáîò÷èêà */
procedure PRC_RESP_RESULT_GET
(
NIDENT in number, -- Èäåíòèôèêàòîð ïðîöåññà
SRESULT out varchar2, -- Êîä ðåçóëüòàòà (ñì. êîíñòàíòû SPRC_RESP_RESULT_*)
BRESP out blob, -- Äàííûå îòâåòà
SMSG out varchar2, -- Ñîîáùåíèå îáðàáîò÷èêà
SCTX out varchar2, -- Êîíòåêñò
DCTX_EXP out date -- Äàòà èñòå÷åíèÿ êîíòåêñòà
)
is
begin
/* Ñ÷èòàåì êîä ðåçóëüòàòà */
SRESULT := PRC_RESP_ARG_STR_GET(NIDENT => NIDENT, SARG => SCONT_FLD_SRESULT);
/* Ñ÷èòàåì äàííûå îòâåòà */
BRESP := PRC_RESP_ARG_BLOB_GET(NIDENT => NIDENT, SARG => SCONT_FLD_BRESP);
/* Ñ÷èòàåì ñîîáùåíèå îáðàáîò÷èêà */
SMSG := PRC_RESP_ARG_STR_GET(NIDENT => NIDENT, SARG => SCONT_FLD_SMSG);
/* Ñ÷èòàåì êîíòåêñò */
SCTX := PRC_RESP_ARG_STR_GET(NIDENT => NIDENT, SARG => SCONT_FLD_SCTX);
/* Ñ÷èòàåì äàòó èñòå÷åíèÿ êîíòåêñòà */
DCTX_EXP := PRC_RESP_ARG_DATE_GET(NIDENT => NIDENT, SARG => SCONT_FLD_DCTX_EXP);
end PRC_RESP_RESULT_GET;
/* Áàçîâîå äîáàâëåíèå â áóôåð îòáîðà äîêóìåíòîâ */ /* Áàçîâîå äîáàâëåíèå â áóôåð îòáîðà äîêóìåíòîâ */
procedure RNLIST_BASE_INSERT procedure RNLIST_BASE_INSERT
( (
@ -1149,7 +1261,7 @@ create or replace package body PKG_EXS as
( (
NEXSSERVICE in number, -- Ðåã. íîìåð çàïèñè ñåðâèñà NEXSSERVICE in number, -- Ðåã. íîìåð çàïèñè ñåðâèñà
SCTX in varchar2, -- Êîíòåêñò SCTX in varchar2, -- Êîíòåêñò
DCTX_EXP in date -- Äàòà èñòå÷åíèÿ êîíòåêñòà DCTX_EXP in date := null -- Äàòà èñòå÷åíèÿ êîíòåêñòà
) )
is is
REXSSERVICE EXSSERVICE%rowtype; -- Çàïèñü ñåðâèñà REXSSERVICE EXSSERVICE%rowtype; -- Çàïèñü ñåðâèñà
@ -1386,7 +1498,7 @@ create or replace package body PKG_EXS as
SRETRY_SCHEDULE_MONTH) "sRetrySchedule", SRETRY_SCHEDULE_MONTH) "sRetrySchedule",
T.EXSMSGTYPE "nMsgId", T.EXSMSGTYPE "nMsgId",
M.CODE "sMsgCode", M.CODE "sMsgCode",
DECODE(M.PRC_RESP, null, null, UTL_STORED_MAKE_LINK(SPROCEDURE => M.PRC_RESP, SPACKAGE => M.PKG_RESP)) "sPrcResp", DECODE(M.PRC_RESP, null, null, UTL_STORED_MAKE_LINK(M.PRC_RESP, M.PKG_RESP)) "sPrcResp",
M.APPSRV_BEFORE "sAppSrvBefore", M.APPSRV_BEFORE "sAppSrvBefore",
M.APPSRV_AFTER "sAppSrvAfter", M.APPSRV_AFTER "sAppSrvAfter",
T.AUTH_ONLY "nAuthOnly", T.AUTH_ONLY "nAuthOnly",
@ -1838,8 +1950,7 @@ create or replace package body PKG_EXS as
procedure QUEUE_RESP_SET procedure QUEUE_RESP_SET
( (
NEXSQUEUE in number, -- Ðåã. íîìåð çàïèñè î÷åðåäè NEXSQUEUE in number, -- Ðåã. íîìåð çàïèñè î÷åðåäè
BRESP in blob, -- Ðåçóëüòàò îáðàáîòêè BRESP in blob -- Ðåçóëüòàò îáðàáîòêè
RCQUEUE out sys_refcursor -- Êóðñîð ñ èçìåí¸ííîé ïîçèöèåé î÷åðåäè
) )
is is
begin begin
@ -1848,6 +1959,19 @@ create or replace package body PKG_EXS as
if (sql%rowcount = 0) then if (sql%rowcount = 0) then
PKG_MSG.RECORD_NOT_FOUND(NFLAG_SMART => 0, NDOCUMENT => NEXSQUEUE, SUNIT_TABLE => 'EXSQUEUE'); PKG_MSG.RECORD_NOT_FOUND(NFLAG_SMART => 0, NDOCUMENT => NEXSQUEUE, SUNIT_TABLE => 'EXSQUEUE');
end if; end if;
end QUEUE_RESP_SET;
/* Óñòàíîâêà ðåçóëüòàòà îáðàáîòêè çàïèñè î÷åðåäè (âîçâðàùàåò èçìåíåííóþ ïîçèöèþ î÷åðåäè) */
procedure QUEUE_RESP_SET
(
NEXSQUEUE in number, -- Ðåã. íîìåð çàïèñè î÷åðåäè
BRESP in blob, -- Ðåçóëüòàò îáðàáîòêè
RCQUEUE out sys_refcursor -- Êóðñîð ñ èçìåí¸ííîé ïîçèöèåé î÷åðåäè
)
is
begin
/* Âûñòàâèì ðåçóëüòàò */
QUEUE_RESP_SET(NEXSQUEUE => NEXSQUEUE, BRESP => BRESP);
/* Âåðíåì èçìåíåííóþ ïîçèöèþ î÷åðåäè */ /* Âåðíåì èçìåíåííóþ ïîçèöèþ î÷åðåäè */
QUEUE_GET(NFLAG_SMART => 0, NEXSQUEUE => NEXSQUEUE, RCQUEUE => RCQUEUE); QUEUE_GET(NFLAG_SMART => 0, NEXSQUEUE => NEXSQUEUE, RCQUEUE => RCQUEUE);
end QUEUE_RESP_SET; end QUEUE_RESP_SET;
@ -1872,8 +1996,7 @@ create or replace package body PKG_EXS as
procedure QUEUE_MSG_SET procedure QUEUE_MSG_SET
( (
NEXSQUEUE in number, -- Ðåã. íîìåð çàïèñè î÷åðåäè NEXSQUEUE in number, -- Ðåã. íîìåð çàïèñè î÷åðåäè
BMSG in blob, -- Ðåçóëüòàò îáðàáîòêè BMSG in blob -- Ðåçóëüòàò îáðàáîòêè
RCQUEUE out sys_refcursor -- Êóðñîð ñ èçìåí¸ííîé ïîçèöèåé î÷åðåäè
) )
is is
begin begin
@ -1882,6 +2005,19 @@ create or replace package body PKG_EXS as
if (sql%rowcount = 0) then if (sql%rowcount = 0) then
PKG_MSG.RECORD_NOT_FOUND(NFLAG_SMART => 0, NDOCUMENT => NEXSQUEUE, SUNIT_TABLE => 'EXSQUEUE'); PKG_MSG.RECORD_NOT_FOUND(NFLAG_SMART => 0, NDOCUMENT => NEXSQUEUE, SUNIT_TABLE => 'EXSQUEUE');
end if; end if;
end QUEUE_MSG_SET;
/* Óñòàíîâêà ñîîáùåíèÿ çàïèñè î÷åðåäè (âîçâðàùàåò èçìåíåííóþ ïîçèöèþ î÷åðåäè) */
procedure QUEUE_MSG_SET
(
NEXSQUEUE in number, -- Ðåã. íîìåð çàïèñè î÷åðåäè
BMSG in blob, -- Ðåçóëüòàò îáðàáîòêè
RCQUEUE out sys_refcursor -- Êóðñîð ñ èçìåí¸ííîé ïîçèöèåé î÷åðåäè
)
is
begin
/* Âûñòàâèì ñîîáùåíèå */
QUEUE_MSG_SET(NEXSQUEUE => NEXSQUEUE, BMSG => BMSG);
/* Âåðíåì èçìåíåííóþ ïîçèöèþ î÷åðåäè */ /* Âåðíåì èçìåíåííóþ ïîçèöèþ î÷åðåäè */
QUEUE_GET(NFLAG_SMART => 0, NEXSQUEUE => NEXSQUEUE, RCQUEUE => RCQUEUE); QUEUE_GET(NFLAG_SMART => 0, NEXSQUEUE => NEXSQUEUE, RCQUEUE => RCQUEUE);
end QUEUE_MSG_SET; end QUEUE_MSG_SET;
@ -2036,15 +2172,19 @@ create or replace package body PKG_EXS as
procedure QUEUE_PRC procedure QUEUE_PRC
( (
NEXSQUEUE in number, -- Ðåã. íîìåð çàïèñè î÷åðåäè NEXSQUEUE in number, -- Ðåã. íîìåð çàïèñè î÷åðåäè
RCQUEUE out sys_refcursor -- Êóðñîð ñ îáðàáîòàííîé ïîçèöèåé î÷åðåäè RCRESULT out sys_refcursor -- Êóðñîð ñ ðåçóëüòàòàìè îáðàáîòêè
) )
is is
REXSQUEUE EXSQUEUE%rowtype; -- Çàïèñü ïîçèöèè î÷åðåäè REXSQUEUE EXSQUEUE%rowtype; -- Çàïèñü ïîçèöèè î÷åðåäè
REXSSERVICE EXSSERVICE%rowtype; -- Çàïèñü ñåðâèñà îáðàáîòêè REXSSERVICE EXSSERVICE%rowtype; -- Çàïèñü ñåðâèñà îáðàáîòêè
REXSSERVICEFN EXSSERVICEFN%rowtype; -- Çàïèñü ôóíêöèè îáðàáîòêè REXSSERVICEFN EXSSERVICEFN%rowtype; -- Çàïèñü ôóíêöèè îáðàáîòêè
REXSMSGTYPE EXSMSGTYPE%rowtype; -- Çàïèñü òèïîâîãî ñîîáùåíèÿ îáìåíà REXSMSGTYPE EXSMSGTYPE%rowtype; -- Çàïèñü òèïîâîãî ñîîáùåíèÿ îáìåíà
SERR EXSQUEUE.EXEC_MSG%type; -- Ñîîáùåíèå îá îøèáêå îáðàáîò÷èêà
NIDENT PKG_STD.TREF; -- Èäåíòèôèêàòîð ïðîöåññà îáðàáîòêè NIDENT PKG_STD.TREF; -- Èäåíòèôèêàòîð ïðîöåññà îáðàáîòêè
SRESULT PKG_STD.TSTRING; -- Áóôåð äëÿ ðåçóëüòàòà: êîä ðåçóëüòàòà
BRESP blob; -- Áóôåð äëÿ ðåçóëüòàòà: äàííûå îòâåòà
SMSG PKG_STD.TSTRING; -- Áóôåð äëÿ ðåçóëüòàòà: ñîîáùåíèå îáðàáîò÷èêà
SCTX PKG_STD.TSTRING; -- Áóôåð äëÿ ðåçóëüòàòà: êîíòåêñò
DCTX_EXP PKG_STD.TLDATE; -- Áóôåð äëÿ ðåçóëüòàòà: äàòà èñòå÷åíèÿ êîíòåêñòà
PRMS PKG_CONTPRMLOC.TCONTAINER; -- Êîíòåéíåð äëÿ ïàðàìåòðîâ ïðîöåäóðû îáðàáîòêè PRMS PKG_CONTPRMLOC.TCONTAINER; -- Êîíòåéíåð äëÿ ïàðàìåòðîâ ïðîöåäóðû îáðàáîòêè
begin begin
/* Ñ÷èòàåì çàïèñü î÷åðåäè */ /* Ñ÷èòàåì çàïèñü î÷åðåäè */
@ -2057,6 +2197,7 @@ create or replace package body PKG_EXS as
REXSMSGTYPE := GET_EXSMSGTYPE_ID(NFLAG_SMART => 0, NRN => REXSSERVICEFN.EXSMSGTYPE); REXSMSGTYPE := GET_EXSMSGTYPE_ID(NFLAG_SMART => 0, NRN => REXSSERVICEFN.EXSMSGTYPE);
/* Çàïóñòèì îáðàáîò÷èê, åñëè îí åñòü */ /* Çàïóñòèì îáðàáîò÷èê, åñëè îí åñòü */
if (REXSMSGTYPE.PRC_RESP is not null) then if (REXSMSGTYPE.PRC_RESP is not null) then
begin
/* Ïðîâåðÿåì èíòåðôåéñ îáðàáîò÷èêà */ /* Ïðîâåðÿåì èíòåðôåéñ îáðàáîò÷èêà */
UTL_STORED_CHECK(NFLAG_SMART => 0, UTL_STORED_CHECK(NFLAG_SMART => 0,
SPKG => REXSMSGTYPE.PKG_RESP, SPKG => REXSMSGTYPE.PKG_RESP,
@ -2070,10 +2211,6 @@ create or replace package body PKG_EXS as
SNAME => 'NIDENT', SNAME => 'NIDENT',
NVALUE => NIDENT, NVALUE => NIDENT,
NIN_OUT => PKG_STD.IPARAM_TYPE_IN); NIN_OUT => PKG_STD.IPARAM_TYPE_IN);
PKG_CONTPRMLOC.APPENDN(RCONTAINER => PRMS,
SNAME => 'NSRV_TYPE',
NVALUE => REXSSERVICE.SRV_TYPE,
NIN_OUT => PKG_STD.IPARAM_TYPE_IN);
PKG_CONTPRMLOC.APPENDN(RCONTAINER => PRMS, PKG_CONTPRMLOC.APPENDN(RCONTAINER => PRMS,
SNAME => 'NEXSQUEUE', SNAME => 'NEXSQUEUE',
NVALUE => REXSQUEUE.RN, NVALUE => REXSQUEUE.RN,
@ -2082,24 +2219,73 @@ create or replace package body PKG_EXS as
PKG_SQL_CALL.EXECUTE_STORED(SSTORED_NAME => UTL_STORED_MAKE_LINK(SPACKAGE => REXSMSGTYPE.PKG_RESP, PKG_SQL_CALL.EXECUTE_STORED(SSTORED_NAME => UTL_STORED_MAKE_LINK(SPACKAGE => REXSMSGTYPE.PKG_RESP,
SPROCEDURE => REXSMSGTYPE.PRC_RESP), SPROCEDURE => REXSMSGTYPE.PRC_RESP),
RPARAM_CONTAINER => PRMS); RPARAM_CONTAINER => PRMS);
/* Çàáèðàåì ïàðàìåòð ñ îøèáêàìè îáðàáîò÷èêà */
SERR := PRC_RESP_ARG_STR_GET(NIDENT => NIDENT, SARG => SCONT_FLD_SERR);
/* Åñëè áûëè îøèáêè - ñêàæåì îá ýòîì */
if (SERR is not null) then
P_EXCEPTION(0, SERR);
else
/* Çàôèêñèðóåì ðåçóëüòàò îáðàáîòêè (òîëüêî äëÿ âõîäÿùèõ è òîëüêî åñëè íåò îøèáîê îáðàáîòêè) */
if (REXSSERVICE.SRV_TYPE = NSRV_TYPE_RECIVE) then
QUEUE_RESP_SET(NEXSQUEUE => REXSQUEUE.RN,
BRESP => PRC_RESP_ARG_BLOB_GET(NIDENT => NIDENT, SARG => SCONT_FLD_BRESP),
RCQUEUE => RCQUEUE);
end if;
end if;
/* Î÷èñòèì êîíòåéíåð ïàðàìåòðîâ */ /* Î÷èñòèì êîíòåéíåð ïàðàìåòðîâ */
PKG_CONTPRMLOC.PURGE(RCONTAINER => PRMS); PKG_CONTPRMLOC.PURGE(RCONTAINER => PRMS);
/* Çàáèðàåì ðåçóëüòàòû */
PRC_RESP_RESULT_GET(NIDENT => NIDENT,
SRESULT => SRESULT,
BRESP => BRESP,
SMSG => SMSG,
SCTX => SCTX,
DCTX_EXP => DCTX_EXP);
/* Åñëè êîä ðåçóëüòàòà óñòàíîâëåí */
if (SRESULT is not null) then
/* È åñëè ðåçóëüòàò óñïåøåí - ïðèìåíèì åãî */
if (SRESULT = SPRC_RESP_RESULT_OK) then
/* Çàôèêñèðóåì ðåçóëüòàò îáðàáîòêè (äëÿ âõîäÿùèõ - âñåãäà, äëÿ èñõîäÿùèõ - òîëüêî åñëè íå ïóñòîé) */
if ((REXSSERVICE.SRV_TYPE = NSRV_TYPE_RECIVE) or
((REXSSERVICE.SRV_TYPE = NSRV_TYPE_SEND) and (BRESP is not null) and (DBMS_LOB.GETLENGTH(BRESP) > 0))) then
QUEUE_RESP_SET(NEXSQUEUE => REXSQUEUE.RN, BRESP => BRESP);
end if; end if;
/* Âîçâðàùàåì îáðàáîòàííóþ ïîçèöèþ î÷åðåäè */ /* Åñëè ýòî áûëà ôóíêöèÿ íà÷àëà ñåàíñà */
QUEUE_GET(NFLAG_SMART => 0, NEXSQUEUE => REXSQUEUE.RN, RCQUEUE => RCQUEUE); if (REXSSERVICEFN.FN_TYPE = NFN_TYPE_LOGIN) then
/* Åñëè îáðàáîò÷èê âåðíóë êîíòåêñò */
if (SCTX is not null) then
/* Ïðîïèøåì åãî ñåðâèñó, âíå çàâèñèìîñòè îò òîãî, ÷òî òàì áûëî äî ýòîãî */
SERVICE_CTX_SET(NEXSSERVICE => REXSSERVICE.RN, SCTX => SCTX, DCTX_EXP => DCTX_EXP);
else
/* Îáðàáîò÷èê íå âåðíóë êîíòåêñòà, ïðîâåðèì, åñòü ëè îí ñåé÷àñ ó ñåðâèñà */
REXSSERVICE := GET_EXSSERVICE_ID(NFLAG_SMART => 0, NRN => REXSSERVICEFN.PRN);
if (REXSSERVICE.CTX is null) then
/* Îáðàáîò÷èê íå âåðíóë êîíòåêñò è ñåé÷àñ îí íå óñòàíîâëåí äëÿ ñåðâèñà, ýòî ïðîáëåìà - áîëüøå îáðàáîòîê íå áóäåò çíà÷èò ìû íå çàëîãèíèëèñü */
P_EXCEPTION(0,
'Ôóíêöèÿ íà÷àëà ñåàíñà "%s" íå óñòàíîâèëà êîíòåêñò ðàáîòû äëÿ ñåðâèñà "%s"',
REXSSERVICEFN.CODE,
REXSSERVICE.CODE);
end if;
end if;
end if;
/* Åñëè ýòî áûëà ôóíêöèÿ çàâåðøåíèÿ ñåàíñà */
if (REXSSERVICEFN.FN_TYPE = NFN_TYPE_LOGOUT) then
/* Óäàëèì êîíòåêñò ñåðâèñà */
SERVICE_CTX_CLEAR(NEXSSERVICE => REXSSERVICE.RN);
end if;
else
/* Âî âñåõ îñòàëüíûõ ñëó÷àÿõ - îòêàòûâàåì òðàíçàêöèþ, ò.ê. åñòü êàêèå-òî îøèáêè îáðàáîòêè */
rollback;
end if;
else
/* Ðåçóëüòàò íå óñòàíîâëåí - ýòî îøèáêà */
P_EXCEPTION(0,
'Ïðîöåäóðà îáðàáîò÷èê "%s" íå âåðíóëà ðåçóëüòàò ðàáîòû',
UTL_STORED_MAKE_LINK(SPACKAGE => REXSMSGTYPE.PKG_RESP, SPROCEDURE => REXSMSGTYPE.PRC_RESP));
end if;
exception
when others then
rollback;
SRESULT := SPRC_RESP_RESULT_ERR;
SMSG := sqlerrm;
end;
else
/* Îáðàáîò÷èêà íåò è íåò ïðîáëåì */
SRESULT := SPRC_RESP_RESULT_OK;
SMSG := null;
end if;
/* Âîçâðàùàåì ðåçóëüòàò â âèäå êóðñîðà */
open RCRESULT for
select SRESULT "sResult",
SMSG "sMsg"
from DUAL;
end QUEUE_PRC; end QUEUE_PRC;
end; end;

View File

@ -33,6 +33,16 @@ exports.InQueueProcessorFnBefore = new Schema({
type: path => `Ответ системы (${path}) имеет некорректный тип данных (ожидалось - Buffer)`, type: path => `Ответ системы (${path}) имеет некорректный тип данных (ожидалось - Buffer)`,
required: path => `Не указан ответ системы (${path})` required: path => `Не указан ответ системы (${path})`
} }
},
//Флаг ошибки аутентификации удаленного клиента
bUnAuth: {
type: Boolean,
required: false,
message: {
type: path =>
`Флаг ошибки аутентификации удаленного клиента (${path}) имеет некорректный тип данных (ожидалось - Boolean)`,
required: path => `Не указан флаг ошибки аутентификации удаленного клиента (${path})`
}
} }
}); });
@ -46,5 +56,15 @@ exports.InQueueProcessorFnAfter = new Schema({
type: path => `Обработанный ответ системы (${path}) имеет некорректный тип данных (ожидалось - Buffer)`, type: path => `Обработанный ответ системы (${path}) имеет некорректный тип данных (ожидалось - Buffer)`,
required: path => `Не указан обработанный ответ системы (${path})` required: path => `Не указан обработанный ответ системы (${path})`
} }
},
//Флаг ошибки аутентификации удаленного клиента
bUnAuth: {
type: Boolean,
required: false,
message: {
type: path =>
`Флаг ошибки аутентификации удаленного клиента (${path}) имеет некорректный тип данных (ожидалось - Boolean)`,
required: path => `Не указан флаг ошибки аутентификации удаленного клиента (${path})`
}
} }
}); });

View File

@ -127,6 +127,24 @@ exports.OutQueueProcessorFnBefore = new Schema({
`Флаг ошибки аутентификации на удаленном сервисе (${path}) имеет некорректный тип данных (ожидалось - Boolean)`, `Флаг ошибки аутентификации на удаленном сервисе (${path}) имеет некорректный тип данных (ожидалось - Boolean)`,
required: path => `Не указан флаг ошибки аутентификации на удаленном сервисе (${path})` required: path => `Не указан флаг ошибки аутентификации на удаленном сервисе (${path})`
} }
},
//Контекст сервиса
sCtx: {
type: String,
required: false,
message: {
type: path => `Контектс сервиса (${path}) имеет некорректный тип данных (ожидалось - String)`,
required: path => `Не указан контекст сервиса (${path})`
}
},
//Дата истечения контекста
dCtxExp: {
type: Date,
required: false,
message: {
type: path => `Дата истечения контекста (${path}) имеет некорректный тип данных (ожидалось - Date)`,
required: path => `Не указана дата истечения контекста (${path})`
}
} }
}); });
@ -151,5 +169,23 @@ exports.OutQueueProcessorFnAfter = new Schema({
`Флаг ошибки аутентификации на удаленном сервисе (${path}) имеет некорректный тип данных (ожидалось - Boolean)`, `Флаг ошибки аутентификации на удаленном сервисе (${path}) имеет некорректный тип данных (ожидалось - Boolean)`,
required: path => `Не указан флаг ошибки аутентификации на удаленном сервисе (${path})` required: path => `Не указан флаг ошибки аутентификации на удаленном сервисе (${path})`
} }
},
//Контекст сервиса
sCtx: {
type: String,
required: false,
message: {
type: path => `Контектс сервиса (${path}) имеет некорректный тип данных (ожидалось - String)`,
required: path => `Не указан контекст сервиса (${path})`
}
},
//Дата истечения контекста
dCtxExp: {
type: Date,
required: false,
message: {
type: path => `Дата истечения контекста (${path}) имеет некорректный тип данных (ожидалось - Date)`,
required: path => `Не указана дата истечения контекста (${path})`
}
} }
}); });

View File

@ -33,6 +33,11 @@ const SQUEUE_EXEC_STATE_DB_ERR = "DB_ERR"; //Ошибка обработки С
const SQUEUE_EXEC_STATE_OK = "OK"; //Обработано успешно (строковый код) const SQUEUE_EXEC_STATE_OK = "OK"; //Обработано успешно (строковый код)
const SQUEUE_EXEC_STATE_ERR = "ERR"; //Обработано с ошибками (строковый код) const SQUEUE_EXEC_STATE_ERR = "ERR"; //Обработано с ошибками (строковый код)
//Коды результатов исполнения обработчика сообщения
const SPRC_RESP_RESULT_OK = "OK"; //Обработано успешно
const SPRC_RESP_RESULT_ERR = "ERR"; //Ошибка обработки
const SPRC_RESP_RESULT_UNAUTH = "UNAUTH"; //Неаутентифицирован
//------------------ //------------------
// Интерфейс модуля // Интерфейс модуля
//------------------ //------------------
@ -56,6 +61,9 @@ exports.SQUEUE_EXEC_STATE_DB_OK = SQUEUE_EXEC_STATE_DB_OK;
exports.SQUEUE_EXEC_STATE_DB_ERR = SQUEUE_EXEC_STATE_DB_ERR; exports.SQUEUE_EXEC_STATE_DB_ERR = SQUEUE_EXEC_STATE_DB_ERR;
exports.SQUEUE_EXEC_STATE_OK = SQUEUE_EXEC_STATE_OK; exports.SQUEUE_EXEC_STATE_OK = SQUEUE_EXEC_STATE_OK;
exports.SQUEUE_EXEC_STATE_ERR = SQUEUE_EXEC_STATE_ERR; exports.SQUEUE_EXEC_STATE_ERR = SQUEUE_EXEC_STATE_ERR;
exports.SPRC_RESP_RESULT_OK = SPRC_RESP_RESULT_OK;
exports.SPRC_RESP_RESULT_ERR = SPRC_RESP_RESULT_ERR;
exports.SPRC_RESP_RESULT_UNAUTH = SPRC_RESP_RESULT_UNAUTH;
//Схема валидации сообщения очереди обмена //Схема валидации сообщения очереди обмена
exports.Queue = new Schema({ exports.Queue = new Schema({
@ -270,3 +278,31 @@ exports.QueueResp = new Schema({
} }
} }
}).validator({ required: val => val === null || val }); }).validator({ required: val => val === null || val });
//Схема валидации результата обработки сообщения очереди
exports.QueuePrcResult = new Schema({
//Состояние обработки сообщения очереди обмена
sResult: {
type: String,
enum: [SPRC_RESP_RESULT_OK, SPRC_RESP_RESULT_ERR, SPRC_RESP_RESULT_UNAUTH],
required: true,
message: {
type: path =>
`Состояние обработки сообщения очереди обмена (${path}) имеет некорректный тип данных (ожидалось - String)`,
enum: path => `Значение состояния обработки сообщения очереди обмена (${path}) не поддерживается`,
required: path => `Не указано состояние обработки сообщения очереди обмена (${path})`
}
},
//Информация от обработчика сообщения очереди обмена
sMsg: {
type: String,
required: true,
message: {
type: path =>
`Информация от обработчика сообщения очереди обмена (${path}) имеет некорректный тип данных (ожидалось - String)`,
required: path => `Не указана информация от обработчика сообщения очереди обмена (${path})`
}
}
}).validator({
required: val => typeof val != "undefined"
});

View File

@ -190,16 +190,7 @@ exports.Service = new Schema({
} }
}, },
//Список функций сервиса //Список функций сервиса
functions: defServiceFunctions(true, "functions"), functions: defServiceFunctions(true, "functions")
//Контекст работы сервиса
context: {
type: Object,
required: true,
message: {
type: "Контекст работы сервиса (context) имеет некорректный тип данных (ожидалось - Object)",
required: "Не указан контекст работы сервиса (context)"
}
}
}); });
//Схема валидации контекста сервиса //Схема валидации контекста сервиса

View File

@ -67,6 +67,14 @@ exports.dbProcess = new Schema({
message: { message: {
required: path => `Не указано обрабатываемое сообщение очреди (${path})` required: path => `Не указано обрабатываемое сообщение очреди (${path})`
} }
},
//Функция сервиса-обработчика
function: {
schema: ServiceFunction,
required: true,
message: {
required: path => `Не указана функция сервиса для обработки сообщения очереди (${path})`
}
} }
}); });

View File

@ -341,14 +341,14 @@ const setQueueResp = async prms => {
const execQueuePrc = async prms => { const execQueuePrc = async prms => {
try { try {
let res = await prms.connection.execute( let res = await prms.connection.execute(
"BEGIN PKG_EXS.QUEUE_PRC(NEXSQUEUE => :NEXSQUEUE, RCQUEUE => :RCQUEUE); END;", "BEGIN PKG_EXS.QUEUE_PRC(NEXSQUEUE => :NEXSQUEUE, RCRESULT => :RCRESULT); END;",
{ {
NEXSQUEUE: prms.nQueueId, NEXSQUEUE: prms.nQueueId,
RCQUEUE: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT } RCRESULT: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
}, },
{ outFormat: oracledb.OBJECT, autoCommit: true } { outFormat: oracledb.OBJECT, autoCommit: true }
); );
let rows = await readCursorData(res.outBinds.RCQUEUE); let rows = await readCursorData(res.outBinds.RCRESULT);
return rows[0]; return rows[0];
} catch (e) { } catch (e) {
throw new Error(e.message); throw new Error(e.message);