1 |
|
2 | 'use strict';
|
3 |
|
4 |
|
5 |
|
6 | let app = require('express')();
|
7 | let timestamp = require('time-stamp');
|
8 | let ip = require('ip');
|
9 | let nanoid = require('nanoid');
|
10 | let axios = require('axios');
|
11 | const bodyParser = require('body-parser');
|
12 | const jwt = require('jsonwebtoken');
|
13 |
|
14 |
|
15 | const wsName = require('../../package.json').name;
|
16 | const wsVersion = require('../../package.json').version;
|
17 |
|
18 | let systemShortName = null;
|
19 | let systemId = null;
|
20 |
|
21 |
|
22 | let apigwPath = null;
|
23 | let tokenForReq = null;
|
24 | let globalApiGwPath = '';
|
25 |
|
26 | const instanceID = nanoid.nanoid(10);
|
27 |
|
28 |
|
29 |
|
30 | app.use(bodyParser.json());
|
31 | app.use(bodyParser.urlencoded({ extended: true}));
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 | let socketToGlobalProvider = null;
|
39 | let socketToGlobalApiGwBS = null;
|
40 |
|
41 | let awaitedRequests = [];
|
42 |
|
43 | function setGlobalApiGwPath(data){
|
44 | globalApiGwPath = data.globalApiGwPath.pathForRequests;
|
45 | tokenForReq = data.globalApiGwPath.tokenForReq;
|
46 | }
|
47 |
|
48 | function checkGlobalApiGwPath(){
|
49 | return globalApiGwPath !== '';
|
50 | }
|
51 |
|
52 | function clearGlobalApiGwPath(){
|
53 | socketToGlobalApiGwBS.close()
|
54 | globalApiGwPath = '';
|
55 | }
|
56 |
|
57 |
|
58 | function msLog(logString, mark) {
|
59 | const msMark = mark || 'ok' ;
|
60 | console.log(`${timestamp('[DD-MM-YYYY HH:mm:ss.ms]')}: (${msMark}) ${logString}` )
|
61 | }
|
62 |
|
63 |
|
64 | function 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 |
|
79 | app.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 |
|
93 | async 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);
|
101 |
|
102 | msLog(`Завершение обработки GET запроса ${name} с идентификатором ${reqId}`, 'info');
|
103 | };
|
104 | }());
|
105 | app.get(name, next)
|
106 | }
|
107 |
|
108 | async 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);
|
116 |
|
117 | msLog(`Завершение обработки POST запроса ${name} с идентификатором ${reqId}`, 'info');
|
118 | };
|
119 | }());
|
120 | app.post(name, next)
|
121 | }
|
122 | async 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);
|
130 |
|
131 | msLog(`Завершение обработки PUT запроса ${name} с идентификатором ${reqId}`, 'info');
|
132 | };
|
133 | }());
|
134 | app.put(name, next)
|
135 | }
|
136 | async 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);
|
144 |
|
145 | msLog(`Завершение обработки DELETE запроса ${name} с идентификатором ${reqId}`, 'info');
|
146 | };
|
147 | }());
|
148 | app.delete(name, next)
|
149 | }
|
150 |
|
151 | async 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 |
|
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}});
|
170 | if (getParamsForReq.data.result === 'error'){
|
171 | return (getParamsForReq.data)
|
172 | }
|
173 |
|
174 |
|
175 | const fullPath = getParamsForReq.data.data.pathForReq;
|
176 | const tokenForReq2 = getParamsForReq.data.data.onceTokenForReq;
|
177 | msLog(`Инициирован вызов межсервисного GET запроса ${wsNameAndMethod} с идентификатором ${s_reqId}`, 'info');
|
178 |
|
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 |
|
185 | async 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 |
|
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}});
|
204 | if (getParamsForReq.data.result === 'error'){
|
205 | return (getParamsForReq.data)
|
206 | }
|
207 |
|
208 |
|
209 | const fullPath = getParamsForReq.data.data.pathForReq;
|
210 | const tokenForReq2 = getParamsForReq.data.data.onceTokenForReq;
|
211 | msLog(`Инициирован вызов межсервисного POST запросf ${wsNameAndMethod} с идентификатором ${s_reqId}`, 'info');
|
212 |
|
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 |
|
219 | async 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 |
|
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}});
|
238 | if (getParamsForReq.data.result === 'error'){
|
239 | return (getParamsForReq.data)
|
240 | }
|
241 |
|
242 |
|
243 | const fullPath = getParamsForReq.data.data.pathForReq;
|
244 | const tokenForReq2 = getParamsForReq.data.data.onceTokenForReq;
|
245 | msLog(`Инициирован вызов межсервисного PUT запроса ${wsNameAndMethod} с идентификатором ${s_reqId}`, 'info');
|
246 |
|
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 |
|
253 | async 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 |
|
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}});
|
272 | if (getParamsForReq.data.result === 'error'){
|
273 | return (getParamsForReq.data)
|
274 | }
|
275 |
|
276 |
|
277 | const fullPath = getParamsForReq.data.data.pathForReq;
|
278 | const tokenForReq2 = getParamsForReq.data.data.onceTokenForReq;
|
279 | msLog(`Инициирован вызов межсервисного DELETE запроса ${wsNameAndMethod} с идентификатором ${s_reqId}`, 'info');
|
280 |
|
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 |
|
289 |
|
290 |
|
291 |
|
292 |
|
293 |
|
294 |
|
295 |
|
296 |
|
297 |
|
298 |
|
299 |
|
300 |
|
301 |
|
302 |
|
303 |
|
304 |
|
305 |
|
306 |
|
307 | function emit (eventName, data) {
|
308 | let eventData = {'eventName':eventName, data};
|
309 |
|
310 | socketToGlobalApiGwBS.emit('universalEvent', eventData);
|
311 | }
|
312 |
|
313 | function 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,
|
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 |
|
343 |
|
344 | msLog(`Подключились к socketServerToGlobalProvider`, 'ok');
|
345 |
|
346 |
|
347 |
|
348 | });
|
349 |
|
350 | socketToGlobalProvider.on('setGateWayPath', function(data) {
|
351 |
|
352 |
|
353 | msLog(`Получено событие для установки нового gateWayPath`, 'ok');
|
354 | setGlobalApiGwPath(data);
|
355 | setNewConnectionToGlobalApigwBS(data, wsId, wsPort, wsType)
|
356 |
|
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 |
|
376 | function setNewConnectionToGlobalApigwBS(data, wsId, wsPort, wsType){
|
377 |
|
378 |
|
379 | socketToGlobalApiGwBS = require('socket.io-client')(data.globalApiGwPath.pathForEvents,{
|
380 | query: {
|
381 | token: data.globalApiGwPath.tokenForReq,
|
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 |
|
398 | });
|
399 |
|
400 | socketToGlobalApiGwBS.on('getAwaitedRequests', function() {
|
401 | socketToGlobalApiGwBS.emit('awaitedRequests', awaitedRequests);
|
402 | msLog(`Получено событие-запрос списка awaitedRequests`, 'ok');
|
403 | });
|
404 | }
|
405 |
|
406 | module.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 |