UNPKG

20 kBJavaScriptView Raw
1//модуль для клиента
2'use strict';
3// это клиент
4
5// Зависимости
6let app = require('express')();
7let timestamp = require('time-stamp');
8let ip = require('ip');
9let nanoid = require('nanoid');
10let axios = require('axios');
11const bodyParser = require('body-parser');
12const jwt = require('jsonwebtoken');
13
14// Конфигурация
15const wsName = require('../../package.json').name;
16const wsVersion = require('../../package.json').version;
17
18let systemShortName = null;
19let systemId = null;
20
21
22let apigwPath = null;
23let tokenForReq = null;
24let globalApiGwPath = '';
25
26const instanceID = nanoid.nanoid(10);
27
28
29// Чтение body и cookie
30app.use(bodyParser.json());
31app.use(bodyParser.urlencoded({ extended: true}));
32//app.use(cookieParser());
33
34
35//let systemName = jwt.decode(wsCoreKey, {complete: true}).payload.systemName;
36
37// Характеристики инстанса в сессии сокет-соединения
38let socketToGlobalProvider = null;
39let socketToGlobalApiGwBS = null;
40
41let awaitedRequests = [];
42
43function setGlobalApiGwPath(data){
44 globalApiGwPath = data.globalApiGwPath.pathForRequests;
45 tokenForReq = data.globalApiGwPath.tokenForReq;
46}
47
48function checkGlobalApiGwPath(){
49 return globalApiGwPath !== '';
50}
51
52function clearGlobalApiGwPath(){
53 socketToGlobalApiGwBS.close()
54 globalApiGwPath = '';
55}
56
57// функция для общего логирования
58function msLog(logString, mark) {
59 const msMark = mark || 'ok' ;
60 console.log(`${timestamp('[DD-MM-YYYY HH:mm:ss.ms]')}: (${msMark}) ${logString}` )
61}
62
63// Проверка токена и соответствие запрашиваемого метода (типа\имени) токену
64function checkReceivedTokenForReq(req){
65 let isValid = null;
66 jwt.verify(req.headers.tokenforreq, instanceID, function (err, decoded) {
67 if (err) {
68 msLog(`signedJWT не валидный(истек срок действия или внесены изменения)`, 'err');
69 isValid = false;
70 }
71 else {
72 isValid = (req._parsedUrl.pathname === `/${decoded.toMethodName}`) && (req.method === decoded.toMethodType);
73 }
74 });
75 return isValid
76}
77
78// Проверка что запрос пришел санкционировано
79app.use(function(req, res, next){
80 if (req.method ==='OPTIONS'){
81 next();
82 }
83 else {
84 if ((['GET', 'POST', 'PUT', 'DELETE'].includes(req.method)) && ( checkReceivedTokenForReq(req) === true )){
85 next();
86 } else {
87 msLog(`Ошибка обращения к сервису ${wsName}`, 'wrn');
88 return res.send({result: 'error', reason: `Ошибка обращения к сервису ${wsName}`})
89 }
90 }
91});
92
93async function get (name, next) {
94 awaitedRequests.push({methodName:name, methodType: 'GET'});
95 next = (function() {
96 let cached_function = next;
97 return async function() {
98 const reqId = arguments[0].query.s_reqId || arguments[0].query.u_reqId || 'none';
99 msLog(`Начало обработки GET запроса ${name} с идентификатором ${reqId}`, 'info');
100 await cached_function.apply(this, arguments); // use .apply() to call it
101 //console.log(arguments[0].query.u_reqId);
102 msLog(`Завершение обработки GET запроса ${name} с идентификатором ${reqId}`, 'info');
103 };
104 }());
105 app.get(name, next)
106}
107
108async function post (name, next) {
109 awaitedRequests.push({methodName:name, methodType: 'POST'});
110 next = (function() {
111 let cached_function = next;
112 return async function() {
113 const reqId = arguments[0].body.s_reqId || arguments[0].body.u_reqId || 'none';
114 msLog(`Начало обработки POST запроса ${name} с идентификатором ${reqId}`, 'info');
115 await cached_function.apply(this, arguments); // use .apply() to call it
116 //console.log(arguments[0].query.u_reqId);
117 msLog(`Завершение обработки POST запроса ${name} с идентификатором ${reqId}`, 'info');
118 };
119 }());
120 app.post(name, next)
121}
122async function put (name, next) {
123 awaitedRequests.push({methodName:name, methodType: 'PUT'});
124 next = (function() {
125 let cached_function = next;
126 return async function() {
127 const reqId = arguments[0].body.s_reqId || arguments[0].body.u_reqId || 'none';
128 msLog(`Начало обработки PUT запроса ${name} с идентификатором ${reqId}`, 'info');
129 await cached_function.apply(this, arguments); // use .apply() to call it
130 //console.log(arguments[0].query.u_reqId);
131 msLog(`Завершение обработки PUT запроса ${name} с идентификатором ${reqId}`, 'info');
132 };
133 }());
134 app.put(name, next)
135}
136async function del (name, next) {
137 awaitedRequests.push({methodName:name, methodType: 'DELETE'});
138 next = (function() {
139 let cached_function = next;
140 return async function() {
141 const reqId = arguments[0].query.s_reqId || arguments[0].query.u_reqId || 'none';
142 msLog(`Начало обработки DELETE запроса ${name} с идентификатором ${reqId}`, 'info');
143 await cached_function.apply(this, arguments); // use .apply() to call it
144 //console.log(arguments[0].query.u_reqId);
145 msLog(`Завершение обработки DELETE запроса ${name} с идентификатором ${reqId}`, 'info');
146 };
147 }());
148 app.delete(name, next)
149}
150
151async function callGet (wsNameAndMethod, axiParams ) {
152 const parsedReq = wsNameAndMethod.split('/');
153 if (parsedReq.length !== 3){
154 msLog(`Некорректное имя GET запроса ${wsNameAndMethod} (система/серис/метод)`, 'wrn');
155 return {result: 'error', reason: `Некорректное имя GET запроса ${wsNameAndMethod} (система/серис/метод)`}
156 }
157
158 const s_reqId = 's_'+ nanoid.nanoid(6);
159 if (!axiParams) {
160 axiParams = {
161 s_reqId:s_reqId
162 }
163 } else {
164 axiParams.s_reqId = s_reqId;
165 }
166
167 // Обращаемся к global_apigw_bs за актуальным адресом инстанса запрашиваемого сервиса и токен для запроса
168 let core_reqId = 'core_'+ nanoid.nanoid(6);
169 const getParamsForReq = await axios.get(`${globalApiGwPath}/getParamsForReq`, {params: {methodType: 'GET', wsNameAndMethod: wsNameAndMethod, s_reqId: core_reqId}, headers: {tokenforreq: tokenForReq}}); //tokenForReq
170 if (getParamsForReq.data.result === 'error'){
171 return (getParamsForReq.data)
172 }
173 //console.log(getParamsForReq.data.data);
174 //const axiosRes = await axios.get(`${globalApiGwPath.pathForRequests}/${methodName}`, {params:axiParams, headers: {systemtoken:'sometmptoken', fromsystemname:'global_healthws'}});
175 const fullPath = getParamsForReq.data.data.pathForReq;
176 const tokenForReq2 = getParamsForReq.data.data.onceTokenForReq;
177 msLog(`Инициирован вызов межсервисного GET запроса ${wsNameAndMethod} с идентификатором ${s_reqId}`, 'info');
178 //let fullPath = `${apigwPath}/${wsNameAndMethod}`;
179
180 const axiosRes = await axios.get(`${fullPath}/${parsedReq[2]}`, {params:axiParams, headers: {tokenforreq: tokenForReq2}});
181 msLog(`Получен ответ от межсервисного GET запроса ${wsNameAndMethod} с идентификатором ${s_reqId}`, 'info');
182 return axiosRes.data
183}
184
185async function callPost (wsNameAndMethod, axiParams ) {
186 const parsedReq = wsNameAndMethod.split('/');
187 if (parsedReq.length !== 3){
188 msLog(`Некорректное имя POST запроса ${wsNameAndMethod} (система/серис/метод)`, 'wrn');
189 return {result: 'error', reason: `Некорректное имя POST запроса ${wsNameAndMethod} (система/серис/метод)`}
190 }
191
192 const s_reqId = 's_'+ nanoid.nanoid(6);
193 if (!axiParams) {
194 axiParams = {
195 s_reqId:s_reqId
196 }
197 } else {
198 axiParams.s_reqId = s_reqId;
199 }
200
201 // Обращаемся к global_apigw_bs за актуальным адресом инстанса запрашиваемого сервиса и токен для запроса
202 let core_reqId = 'core_'+ nanoid.nanoid(6);
203 const getParamsForReq = await axios.get(`${globalApiGwPath}/getParamsForReq`, {params: {methodType: 'POST', wsNameAndMethod: wsNameAndMethod, s_reqId: core_reqId}, headers: {tokenforreq: tokenForReq}}); //tokenForReq
204 if (getParamsForReq.data.result === 'error'){
205 return (getParamsForReq.data)
206 }
207 //console.log(getParamsForReq.data.data);
208 //const axiosRes = await axios.get(`${globalApiGwPath.pathForRequests}/${methodName}`, {params:axiParams, headers: {systemtoken:'sometmptoken', fromsystemname:'global_healthws'}});
209 const fullPath = getParamsForReq.data.data.pathForReq;
210 const tokenForReq2 = getParamsForReq.data.data.onceTokenForReq;
211 msLog(`Инициирован вызов межсервисного POST запросf ${wsNameAndMethod} с идентификатором ${s_reqId}`, 'info');
212 // let fullPath = `${apigwPath}/${wsNameAndMethod}`;
213
214 const axiosRes = await axios.post(`${fullPath}/${parsedReq[2]}`, axiParams, {headers: {tokenforreq:tokenForReq2}});
215 msLog(`Получен ответ от межсервисного POST запроса ${wsNameAndMethod} с идентификатором ${s_reqId}`, 'info');
216 return axiosRes.data
217}
218
219async function callPut (wsNameAndMethod, axiParams ) {
220 const parsedReq = wsNameAndMethod.split('/');
221 if (parsedReq.length !== 3){
222 msLog(`Некорректное имя PUT запроса ${wsNameAndMethod} (система/серис/метод)`, 'wrn');
223 return {result: 'error', reason: `Некорректное имя PUT запроса ${wsNameAndMethod} (система/серис/метод)`}
224 }
225
226 const s_reqId = 's_'+ nanoid.nanoid(6);
227 if (!axiParams) {
228 axiParams = {
229 s_reqId:s_reqId
230 }
231 } else {
232 axiParams.s_reqId = s_reqId;
233 }
234
235 // Обращаемся к global_apigw_bs за актуальным адресом инстанса запрашиваемого сервиса и токен для запроса
236 let core_reqId = 'core_'+ nanoid.nanoid(6);
237 const getParamsForReq = await axios.get(`${globalApiGwPath}/getParamsForReq`, {params: {methodType: 'PUT', wsNameAndMethod: wsNameAndMethod, s_reqId: core_reqId}, headers: {tokenforreq: tokenForReq}}); //tokenForReq
238 if (getParamsForReq.data.result === 'error'){
239 return (getParamsForReq.data)
240 }
241 //console.log(getParamsForReq.data.data);
242 //const axiosRes = await axios.get(`${globalApiGwPath.pathForRequests}/${methodName}`, {params:axiParams, headers: {systemtoken:'sometmptoken', fromsystemname:'global_healthws'}});
243 const fullPath = getParamsForReq.data.data.pathForReq;
244 const tokenForReq2 = getParamsForReq.data.data.onceTokenForReq;
245 msLog(`Инициирован вызов межсервисного PUT запроса ${wsNameAndMethod} с идентификатором ${s_reqId}`, 'info');
246 // let fullPath = `${apigwPath}/${wsNameAndMethod}`;
247
248 const axiosRes = await axios.put(`${fullPath}/${parsedReq[2]}`, axiParams, {headers: {tokenforreq:tokenForReq2}});
249 msLog(`Получен ответ от межсервисного PUT запроса ${wsNameAndMethod} с идентификатором ${s_reqId}`, 'info');
250 return axiosRes.data
251}
252
253async function callDel (wsNameAndMethod, axiParams ) {
254 const parsedReq = wsNameAndMethod.split('/');
255 if (parsedReq.length !== 3){
256 msLog(`Некорректное имя DELETE запроса ${wsNameAndMethod} (система/серис/метод)`, 'wrn');
257 return {result: 'error', reason: `Некорректное имя DELETE запроса ${wsNameAndMethod} (система/серис/метод)`}
258 }
259
260 const s_reqId = 's_'+ nanoid.nanoid(6);
261 if (!axiParams) {
262 axiParams = {
263 s_reqId:s_reqId
264 }
265 } else {
266 axiParams.s_reqId = s_reqId;
267 }
268
269 // Обращаемся к global_apigw_bs за актуальным адресом инстанса запрашиваемого сервиса и токен для запроса
270 let core_reqId = 'core_'+ nanoid.nanoid(6);
271 const getParamsForReq = await axios.get(`${globalApiGwPath}/getParamsForReq`, {params: {methodType: 'DELETE', wsNameAndMethod: wsNameAndMethod, s_reqId: core_reqId}, headers: {tokenforreq: tokenForReq}}); //tokenForReq
272 if (getParamsForReq.data.result === 'error'){
273 return (getParamsForReq.data)
274 }
275 //console.log(getParamsForReq.data.data);
276 //const axiosRes = await axios.get(`${globalApiGwPath.pathForRequests}/${methodName}`, {params:axiParams, headers: {systemtoken:'sometmptoken', fromsystemname:'global_healthws'}});
277 const fullPath = getParamsForReq.data.data.pathForReq;
278 const tokenForReq2 = getParamsForReq.data.data.onceTokenForReq;
279 msLog(`Инициирован вызов межсервисного DELETE запроса ${wsNameAndMethod} с идентификатором ${s_reqId}`, 'info');
280 // let fullPath = `${apigwPath}/${wsNameAndMethod}`;
281
282 const axiosRes = await axios.delete(`${fullPath}/${parsedReq[2]}`, {params:axiParams, headers: {tokenforreq:tokenForReq2}});
283 msLog(`Получен ответ от межсервисного DELETE запроса ${wsNameAndMethod} с идентификатором ${s_reqId}`, 'info');
284 return axiosRes.data
285}
286
287// Пока подлежит исключению
288// async function callAxiGet (axiPath, axiParams) {
289// const s_reqId = 's_'+ nanoid.nanoid(6);
290// let allParams = {fromWsName:wsName, fromInstanceID:instanceID};
291// if (axiParams !== undefined) {
292// Object.assign(axiParams, allParams);
293// }
294// msLog(`Инициирован вызов межсистемного GET запроса к ${axiPath} с идентификатором ${s_reqId}`, 'info');
295// const axiosRes = await axios.get(axiPath, {params:allParams});
296// msLog(`Получен ответ от межсистемного GET запроса от ${axiPath} с идентификатором ${s_reqId}`, 'info');
297// return axiosRes.data
298// }
299//
300// async function callAxiPost (axiosPath, axiParams) {
301// const s_reqId = 's_'+ nanoid.nanoid(6);
302// msLog(`Инициирован вызов межсистемного POST запроса к ${axiPath} с идентификатором ${s_reqId}`, 'info');
303// const axiosRes = await axios.post(axiosPath, axiParams);
304// msLog(`Получен ответ от межсистемного POST запроса от ${axiPath} с идентификатором ${s_reqId}`, 'info');
305// return axiosRes.data
306// }
307function emit (eventName, data) {
308 let eventData = {'eventName':eventName, data};
309 //console.log(eventData);
310 socketToGlobalApiGwBS.emit('universalEvent', eventData);
311}
312
313function start(params){
314 const wsPort = params.wsPort;
315 const wsCoreKey = params.wsCoreKey;
316
317 const socketServer = jwt.decode(wsCoreKey, {complete: true}).payload.providerAddress;
318
319 const wsId = jwt.decode(wsCoreKey, {complete: true}).payload.wsId;
320 const wsType = jwt.decode(wsCoreKey, {complete: true}).payload.wsType;
321 systemId = jwt.decode(wsCoreKey, {complete: true}).payload.systemId;
322 systemShortName = jwt.decode(wsCoreKey, {complete: true}).payload.systemShortName;
323
324 socketToGlobalProvider = require('socket.io-client')(socketServer,{
325 query: {
326 token: wsCoreKey, //jwt
327 wsName: wsName,
328 wsId: wsId,
329 instanceID: instanceID,
330 wsType: wsType,
331 wsVersion: wsVersion,
332 }
333 });
334
335
336 socketToGlobalProvider.on('error', (error) => {
337 msLog(`Получено событие об ошибке сокет-соединения`, 'err');
338 });
339
340// При успешном коннекте
341 socketToGlobalProvider.on('connect', function() {
342 //sendStartData();
343 //console.log('Подключились к socketServerToGlobalProvider');
344 msLog(`Подключились к socketServerToGlobalProvider`, 'ok');
345 //socket.emit('wsStart', 'wsStartData');
346 // console.log('Подключились к socketServerToGlobalProvider');
347 // console.log(socketToGlobalProvider.io.opts.query);
348 });
349
350 socketToGlobalProvider.on('setGateWayPath', function(data) {
351 //wsPortForRequests
352 //wsPortForEvents
353 msLog(`Получено событие для установки нового gateWayPath`, 'ok');
354 setGlobalApiGwPath(data);
355 setNewConnectionToGlobalApigwBS(data, wsId, wsPort, wsType)
356 //console.log(data)
357 });
358
359 socketToGlobalProvider.on('delGateWayPath', function() {
360 msLog(`Получено событие об удалении gateWayPath`, 'ok');
361 clearGlobalApiGwPath();
362 });
363
364 socketToGlobalProvider.on('preparedNewGateWayPath', function() {
365 msLog(`Получено сообщение о необходимости смены gateWayPath`, 'ok');
366 socketToGlobalProvider.emit('getGateWayPath');
367 });
368
369
370 app.listen(wsPort, function(){
371 msLog(`Сервис ${wsName} запущен на ${wsPort} порту`);
372 });
373
374}
375
376function setNewConnectionToGlobalApigwBS(data, wsId, wsPort, wsType){
377 // console.log('Данные для к коннекта к новому global_apigw_bs')
378 // console.log(data)
379 socketToGlobalApiGwBS = require('socket.io-client')(data.globalApiGwPath.pathForEvents,{
380 query: {
381 token: data.globalApiGwPath.tokenForReq, //jwt
382 systemShortName: systemShortName,
383 systemId: systemId,
384 wsName: wsName,
385 wsId: wsId,
386 instanceID: instanceID,
387 wsType: wsType,
388 wsVersion: wsVersion,
389 wsPort: wsPort,
390 instanceIP: ip.address()
391 }
392 });
393
394 // При успешном коннекте
395 socketToGlobalApiGwBS.on('connect', function() {
396 msLog(`Подключились к socketToGlobalApiGwBS`, 'ok');
397 //console.log(socketToGlobalApiGwBS.id);
398 });
399
400 socketToGlobalApiGwBS.on('getAwaitedRequests', function() {
401 socketToGlobalApiGwBS.emit('awaitedRequests', awaitedRequests);
402 msLog(`Получено событие-запрос списка awaitedRequests`, 'ok');
403 });
404}
405
406module.exports = {
407// Работа с запросами
408 // Обработка входящих запросов
409 get: get,
410 post: post,
411 put: put,
412 del: del,
413 // Для вызова межсервисных апи
414 callGet: callGet,
415 callPost: callPost,
416 callPut: callPut,
417 callDel: callDel,
418 // Для вызова внешних апи
419 // callAxiGet: callAxiGet,
420 // callAxiPost: callAxiPost,
421// Работа с событиями
422// on: on,
423 emit: emit,
424 log: msLog,
425 start: start,
426};
\No newline at end of file