UNPKG

19.7 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 const getParamsForReq = await axios.get(`${globalApiGwPath}/getParamsForReq`, {params: {methodType: 'GET', wsNameAndMethod: wsNameAndMethod}, headers: {tokenforreq: tokenForReq}}); //tokenForReq
169 if (getParamsForReq.data.result === 'error'){
170 return (getParamsForReq.data)
171 }
172 //console.log(getParamsForReq.data.data);
173 //const axiosRes = await axios.get(`${globalApiGwPath.pathForRequests}/${methodName}`, {params:axiParams, headers: {systemtoken:'sometmptoken', fromsystemname:'global_healthws'}});
174 const fullPath = getParamsForReq.data.data.pathForReq;
175 const tokenForReq2 = getParamsForReq.data.data.onceTokenForReq;
176 msLog(`Инициирован вызов межсервисного GET запроса ${wsNameAndMethod} с идентификатором ${s_reqId}`, 'info');
177 //let fullPath = `${apigwPath}/${wsNameAndMethod}`;
178
179 const axiosRes = await axios.get(`${fullPath}/${parsedReq[2]}`, {params:axiParams, headers: {tokenforreq: tokenForReq2}});
180 msLog(`Получен ответ от межсервисного GET запроса ${wsNameAndMethod} с идентификатором ${s_reqId}`, 'info');
181 return axiosRes.data
182}
183
184async function callPost (wsNameAndMethod, axiParams ) {
185 const parsedReq = wsNameAndMethod.split('/');
186 if (parsedReq.length !== 3){
187 msLog(`Некорректное имя POST запроса ${wsNameAndMethod} (система/серис/метод)`, 'wrn');
188 return {result: 'error', reason: `Некорректное имя POST запроса ${wsNameAndMethod} (система/серис/метод)`}
189 }
190
191 const s_reqId = 's_'+ nanoid.nanoid(6);
192 if (!axiParams) {
193 axiParams = {
194 s_reqId:s_reqId
195 }
196 } else {
197 axiParams.s_reqId = s_reqId;
198 }
199
200 // Обращаемся к global_apigw_bs за актуальным адресом инстанса запрашиваемого сервиса и токен для запроса
201 const getParamsForReq = await axios.get(`${globalApiGwPath}/getParamsForReq`, {params: {methodType: 'POST', wsNameAndMethod: wsNameAndMethod}, headers: {tokenforreq: tokenForReq}}); //tokenForReq
202 if (getParamsForReq.data.result === 'error'){
203 return (getParamsForReq.data)
204 }
205 //console.log(getParamsForReq.data.data);
206 //const axiosRes = await axios.get(`${globalApiGwPath.pathForRequests}/${methodName}`, {params:axiParams, headers: {systemtoken:'sometmptoken', fromsystemname:'global_healthws'}});
207 const fullPath = getParamsForReq.data.data.pathForReq;
208 const tokenForReq2 = getParamsForReq.data.data.onceTokenForReq;
209 msLog(`Инициирован вызов межсервисного POST запросf ${wsNameAndMethod} с идентификатором ${s_reqId}`, 'info');
210 // let fullPath = `${apigwPath}/${wsNameAndMethod}`;
211
212 const axiosRes = await axios.post(`${fullPath}/${parsedReq[2]}`, axiParams, {headers: {tokenforreq:tokenForReq2}});
213 msLog(`Получен ответ от межсервисного POST запроса ${wsNameAndMethod} с идентификатором ${s_reqId}`, 'info');
214 return axiosRes.data
215}
216
217async function callPut (wsNameAndMethod, axiParams ) {
218 const parsedReq = wsNameAndMethod.split('/');
219 if (parsedReq.length !== 3){
220 msLog(`Некорректное имя PUT запроса ${wsNameAndMethod} (система/серис/метод)`, 'wrn');
221 return {result: 'error', reason: `Некорректное имя PUT запроса ${wsNameAndMethod} (система/серис/метод)`}
222 }
223
224 const s_reqId = 's_'+ nanoid.nanoid(6);
225 if (!axiParams) {
226 axiParams = {
227 s_reqId:s_reqId
228 }
229 } else {
230 axiParams.s_reqId = s_reqId;
231 }
232
233 // Обращаемся к global_apigw_bs за актуальным адресом инстанса запрашиваемого сервиса и токен для запроса
234 const getParamsForReq = await axios.get(`${globalApiGwPath}/getParamsForReq`, {params: {methodType: 'PUT', wsNameAndMethod: wsNameAndMethod}, headers: {tokenforreq: tokenForReq}}); //tokenForReq
235 if (getParamsForReq.data.result === 'error'){
236 return (getParamsForReq.data)
237 }
238 //console.log(getParamsForReq.data.data);
239 //const axiosRes = await axios.get(`${globalApiGwPath.pathForRequests}/${methodName}`, {params:axiParams, headers: {systemtoken:'sometmptoken', fromsystemname:'global_healthws'}});
240 const fullPath = getParamsForReq.data.data.pathForReq;
241 const tokenForReq2 = getParamsForReq.data.data.onceTokenForReq;
242 msLog(`Инициирован вызов межсервисного PUT запроса ${wsNameAndMethod} с идентификатором ${s_reqId}`, 'info');
243 // let fullPath = `${apigwPath}/${wsNameAndMethod}`;
244
245 const axiosRes = await axios.put(`${fullPath}/${parsedReq[2]}`, axiParams, {headers: {tokenforreq:tokenForReq2}});
246 msLog(`Получен ответ от межсервисного PUT запроса ${wsNameAndMethod} с идентификатором ${s_reqId}`, 'info');
247 return axiosRes.data
248}
249
250async function callDel (wsNameAndMethod, axiParams ) {
251 const parsedReq = wsNameAndMethod.split('/');
252 if (parsedReq.length !== 3){
253 msLog(`Некорректное имя DELETE запроса ${wsNameAndMethod} (система/серис/метод)`, 'wrn');
254 return {result: 'error', reason: `Некорректное имя DELETE запроса ${wsNameAndMethod} (система/серис/метод)`}
255 }
256
257 const s_reqId = 's_'+ nanoid.nanoid(6);
258 if (!axiParams) {
259 axiParams = {
260 s_reqId:s_reqId
261 }
262 } else {
263 axiParams.s_reqId = s_reqId;
264 }
265
266 // Обращаемся к global_apigw_bs за актуальным адресом инстанса запрашиваемого сервиса и токен для запроса
267 const getParamsForReq = await axios.get(`${globalApiGwPath}/getParamsForReq`, {params: {methodType: 'DELETE', wsNameAndMethod: wsNameAndMethod}, headers: {tokenforreq: tokenForReq}}); //tokenForReq
268 if (getParamsForReq.data.result === 'error'){
269 return (getParamsForReq.data)
270 }
271 //console.log(getParamsForReq.data.data);
272 //const axiosRes = await axios.get(`${globalApiGwPath.pathForRequests}/${methodName}`, {params:axiParams, headers: {systemtoken:'sometmptoken', fromsystemname:'global_healthws'}});
273 const fullPath = getParamsForReq.data.data.pathForReq;
274 const tokenForReq2 = getParamsForReq.data.data.onceTokenForReq;
275 msLog(`Инициирован вызов межсервисного DELETE запроса ${wsNameAndMethod} с идентификатором ${s_reqId}`, 'info');
276 // let fullPath = `${apigwPath}/${wsNameAndMethod}`;
277
278 const axiosRes = await axios.delete(`${fullPath}/${parsedReq[2]}`, {params:axiParams, headers: {tokenforreq:tokenForReq2}});
279 msLog(`Получен ответ от межсервисного DELETE запроса ${wsNameAndMethod} с идентификатором ${s_reqId}`, 'info');
280 return axiosRes.data
281}
282
283// Пока подлежит исключению
284// async function callAxiGet (axiPath, axiParams) {
285// const s_reqId = 's_'+ nanoid.nanoid(6);
286// let allParams = {fromWsName:wsName, fromInstanceID:instanceID};
287// if (axiParams !== undefined) {
288// Object.assign(axiParams, allParams);
289// }
290// msLog(`Инициирован вызов межсистемного GET запроса к ${axiPath} с идентификатором ${s_reqId}`, 'info');
291// const axiosRes = await axios.get(axiPath, {params:allParams});
292// msLog(`Получен ответ от межсистемного GET запроса от ${axiPath} с идентификатором ${s_reqId}`, 'info');
293// return axiosRes.data
294// }
295//
296// async function callAxiPost (axiosPath, axiParams) {
297// const s_reqId = 's_'+ nanoid.nanoid(6);
298// msLog(`Инициирован вызов межсистемного POST запроса к ${axiPath} с идентификатором ${s_reqId}`, 'info');
299// const axiosRes = await axios.post(axiosPath, axiParams);
300// msLog(`Получен ответ от межсистемного POST запроса от ${axiPath} с идентификатором ${s_reqId}`, 'info');
301// return axiosRes.data
302// }
303function emit (eventName, data) {
304 let eventData = {'eventName':eventName, data};
305 //console.log(eventData);
306 socketToGlobalApiGwBS.emit('universalEvent', eventData);
307}
308
309function start(params){
310 const wsPort = params.wsPort;
311 const wsCoreKey = params.wsCoreKey;
312
313 const socketServer = jwt.decode(wsCoreKey, {complete: true}).payload.providerAddress;
314
315 const wsId = jwt.decode(wsCoreKey, {complete: true}).payload.wsId;
316 const wsType = jwt.decode(wsCoreKey, {complete: true}).payload.wsType;
317 systemId = jwt.decode(wsCoreKey, {complete: true}).payload.systemId;
318 systemShortName = jwt.decode(wsCoreKey, {complete: true}).payload.systemShortName;
319
320 socketToGlobalProvider = require('socket.io-client')(socketServer,{
321 query: {
322 token: wsCoreKey, //jwt
323 wsName: wsName,
324 wsId: wsId,
325 instanceID: instanceID,
326 wsType: wsType,
327 wsVersion: wsVersion,
328 }
329 });
330
331
332 socketToGlobalProvider.on('error', (error) => {
333 msLog(`Получено событие об ошибке сокет-соединения`, 'err');
334 });
335
336// При успешном коннекте
337 socketToGlobalProvider.on('connect', function() {
338 //sendStartData();
339 //console.log('Подключились к socketServerToGlobalProvider');
340 msLog(`Подключились к socketServerToGlobalProvider`, 'ok');
341 //socket.emit('wsStart', 'wsStartData');
342 // console.log('Подключились к socketServerToGlobalProvider');
343 // console.log(socketToGlobalProvider.io.opts.query);
344 });
345
346 socketToGlobalProvider.on('setGateWayPath', function(data) {
347 //wsPortForRequests
348 //wsPortForEvents
349 msLog(`Получено событие для установки нового gateWayPath`, 'ok');
350 setGlobalApiGwPath(data);
351 setNewConnectionToGlobalApigwBS(data, wsId, wsPort, wsType)
352 //console.log(data)
353 });
354
355 socketToGlobalProvider.on('delGateWayPath', function() {
356 msLog(`Получено событие об удалении gateWayPath`, 'ok');
357 clearGlobalApiGwPath();
358 });
359
360 socketToGlobalProvider.on('preparedNewGateWayPath', function() {
361 msLog(`Получено сообщение о необходимости смены gateWayPath`, 'ok');
362 socketToGlobalProvider.emit('getGateWayPath');
363 });
364
365
366 app.listen(wsPort, function(){
367 msLog(`Сервис ${wsName} запущен на ${wsPort} порту`);
368 });
369
370}
371
372function setNewConnectionToGlobalApigwBS(data, wsId, wsPort, wsType){
373 // console.log('Данные для к коннекта к новому global_apigw_bs')
374 // console.log(data)
375 socketToGlobalApiGwBS = require('socket.io-client')(data.globalApiGwPath.pathForEvents,{
376 query: {
377 token: data.globalApiGwPath.tokenForReq, //jwt
378 systemShortName: systemShortName,
379 systemId: systemId,
380 wsName: wsName,
381 wsId: wsId,
382 instanceID: instanceID,
383 wsType: wsType,
384 wsVersion: wsVersion,
385 wsPort: wsPort,
386 instanceIP: ip.address()
387 }
388 });
389
390 // При успешном коннекте
391 socketToGlobalApiGwBS.on('connect', function() {
392 msLog(`Подключились к socketToGlobalApiGwBS`, 'ok');
393 //console.log(socketToGlobalApiGwBS.id);
394 });
395
396 socketToGlobalApiGwBS.on('getAwaitedRequests', function() {
397 socketToGlobalApiGwBS.emit('awaitedRequests', awaitedRequests);
398 msLog(`Получено событие-запрос списка awaitedRequests`, 'ok');
399 });
400}
401
402module.exports = {
403// Работа с запросами
404 // Обработка входящих запросов
405 get: get,
406 post: post,
407 put: put,
408 del: del,
409 // Для вызова межсервисных апи
410 callGet: callGet,
411 callPost: callPost,
412 callPut: callPut,
413 callDel: callDel,
414 // Для вызова внешних апи
415 // callAxiGet: callAxiGet,
416 // callAxiPost: callAxiPost,
417// Работа с событиями
418// on: on,
419 emit: emit,
420 log: msLog,
421 start: start,
422};
\No newline at end of file