UNPKG

9.76 kBJavaScriptView Raw
1/*
2
3 ----------------------------------------------------------------------------
4 | qewd-up: Rapid QEWD API Development |
5 | |
6 | Copyright (c) 2018-20 M/Gateway Developments Ltd, |
7 | Redhill, Surrey UK. |
8 | All rights reserved. |
9 | |
10 | http://www.mgateway.com |
11 | Email: rtweed@mgateway.com |
12 | |
13 | |
14 | Licensed under the Apache License, Version 2.0 (the "License"); |
15 | you may not use this file except in compliance with the License. |
16 | You may obtain a copy of the License at |
17 | |
18 | http://www.apache.org/licenses/LICENSE-2.0 |
19 | |
20 | Unless required by applicable law or agreed to in writing, software |
21 | distributed under the License is distributed on an "AS IS" BASIS, |
22 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
23 | See the License for the specific language governing permissions and |
24 | limitations under the License. |
25 ----------------------------------------------------------------------------
26
27 12 May 2020
28
29*/
30
31var router = require('qewd-router');
32var createDocStoreEvents = require('./createDocStoreEvents');
33var handleDocStoreEvents = require('./handleDocStoreEvents');
34
35var ignore_jwt = {};
36var workerResponseHandler = {};
37var onWorkerLoad;
38var beforeHandler;
39var docStoreEvents;
40
41function loadRoutes(onHandledOnly) {
42 var fs = require('fs');
43 var cwd = process.cwd() + '/mapped';
44 var ms_name = process.env.microservice;
45 var mode = process.env.mode;
46 if (mode && ms_name) {
47 cwd = process.cwd() + '/' + ms_name;
48 }
49 if (process.env.qewd_isNative) cwd = process.cwd();
50
51 var routes_data = require(cwd + '/configuration/routes.json');
52 var config_data = require(cwd + '/configuration/config.json');
53 var ms_path;
54
55 if (mode === 'microservice') {
56 ms_name = config_data.ms_name;
57 ms_path = cwd + '/';
58 }
59 else {
60 ms_path = cwd + '/' + ms_name + '/';
61 }
62
63 var routes = {};
64
65 //console.log('loading up/ms_handlers in process ' + process.pid);
66 //console.log('ms_name = ' + ms_name);
67 //console.log('routes_data = ' + JSON.stringify(routes_data, null, 2));
68
69 // check for any grouped destinations that include this microservice name
70
71 var group_matches = {};
72 if (!mode) {
73 config_data.microservices.forEach(function(microservice) {
74 if (microservice.members) {
75 microservice.members.forEach(function(member_name) {
76 if (member_name === ms_name) {
77 group_matches[microservice.name] = true;
78 }
79 });
80 }
81 });
82 }
83
84 routes_data.forEach(function(route) {
85 if (mode === 'microservice') {
86 route.on_microservice = ms_name;
87 }
88 //console.log('route: ' + JSON.stringify(route, null, 2));
89 var handler;
90 var ms_match = false;
91 var ms_source = ms_name;
92 var i;
93
94 if (route.on_microservice) {
95 if (route.on_microservice === ms_name) {
96 // direct match
97 ms_match = true;
98 }
99 if (group_matches[route.on_microservice]) {
100 // group destination match
101 ms_match = true;
102 if (route.handler_source) {
103 ms_source = route.handler_source;
104 }
105 }
106 }
107 if (!ms_match && route.on_microservices) {
108 route.on_microservices.forEach(function(on_ms_name) {
109 if (on_ms_name === ms_name) ms_match = true;
110 if (route.handler_source) {
111 ms_source = route.handler_source;
112 }
113 });
114 }
115
116 if (ms_match) {
117 if (onHandledOnly) {
118 var onMSResponsePaths = [
119 ms_path + route.handler + '/onMSResponse.js',
120 ms_path + 'apis/' + route.handler + '/onMSResponse.js',
121 ];
122 for (i = 0; i < onMSResponsePaths.length; i++) {
123 if (fs.existsSync(onMSResponsePaths[i])) {
124 try {
125 workerResponseHandler[route.uri] = require(onMSResponsePaths[i]);
126 console.log('onMSResponse handler loaded from ' + onMSResponsePaths[i]);
127 }
128 catch(err) {
129 console.log('** Warning: onMSResponse handler could not be loaded from ' + onMSResponsePaths[i]);
130 }
131 break;
132 }
133 }
134 }
135 else {
136 if (!routes[route.uri]) routes[route.uri] = {};
137 //console.log('route.uri = ' + route.uri);
138 var path = cwd + '/' + ms_source + '/';
139 var handlerPaths = [
140 path + route.handler + '.js',
141 path + route.handler + '/handler.js',
142 path + route.handler + '/index.js',
143 path + 'apis/' + route.handler + '/index.js'
144 ];
145 if (mode === 'microservice') {
146 handlerPaths.push(cwd + '/apis/' + route.handler + '/index.js');
147 handlerPaths.push(cwd + '/apis/' + route.handler + '/handler.js');
148 }
149 var handlerFound = false;
150 for (i = 0; i < handlerPaths.length; i++) {
151 console.log('** trying to load from ' + handlerPaths[i]);
152 if (fs.existsSync(handlerPaths[i])) {
153 try {
154 handler = require(handlerPaths[i]);
155 console.log('loaded handler from ' + handlerPaths[i]);
156 }
157 catch(err) {
158 console.log('*** Warning - handler for ' + route.handler + ' found but could not be loaded from ' + handlerPaths[i]);
159 console.log(err);
160 }
161 handlerFound = true;
162 break;
163 }
164 }
165 if (!handlerFound) {
166 console.log('*** Warning - handler for ' + route.handler + ' not found');
167 }
168
169 routes[route.uri][route.method] = handler;
170 //console.log(route.uri + ': authenticate = ' + route.authenticate);
171 if (route.authenticate === false) {
172 ignore_jwt[route.uri] = true;
173 }
174 }
175 }
176 });
177
178 if (onHandledOnly) return;
179
180 var onWorkerLoadPath = ms_path + 'onWorkerLoad.js';
181 if (fs.existsSync(onWorkerLoadPath)) {
182 try {
183 onWorkerLoad = require(onWorkerLoadPath);
184 console.log('Loaded onWorkerLoad module from ' + onWorkerLoadPath);
185 }
186 catch(err) {
187 console.log('** Warning - unable to load onWorkerLoad module from ' + onWorkerLoadPath);
188 }
189 }
190
191 var beforeHandlerPath = ms_path + 'beforeHandler.js';
192 if (fs.existsSync(beforeHandlerPath)) {
193 try {
194 beforeHandler = require(beforeHandlerPath);
195 console.log('Loaded beforeHandler module from ' + beforeHandlerPath);
196 }
197 catch(err) {
198 console.log('** Warning - unable to load ' + beforeHandlerPath);
199 }
200 }
201 else {
202 beforeHandlerPath = ms_path + 'apis/beforeHandler.js';
203 if (fs.existsSync(beforeHandlerPath)) {
204 try {
205 beforeHandler = require(beforeHandlerPath);
206 console.log('Loaded beforeHandler module from ' + beforeHandlerPath);
207 }
208 catch(err) {
209 console.log('** Warning - unable to load ' + beforeHandlerPath);
210 }
211 }
212 }
213
214 var docStoreEventsPath = ms_path + 'docStoreEvents/events.json';
215 if (fs.existsSync(docStoreEventsPath)) {
216 docStoreEvents = createDocStoreEvents(docStoreEventsPath, ms_path);
217 //console.log('** docStoreEvents: ' + JSON.stringify(docStoreEvents, null, 2));
218 }
219
220 //console.log('routes: ' + JSON.stringify(routes, null, 2));
221 return routes;
222}
223
224loadRoutes(true); // when called by master process for workerResponseHandlers
225 // to prevent unnecessary loading of route handlers
226
227
228module.exports = {
229 init: function() {
230 var routes = loadRoutes();
231 if (onWorkerLoad) {
232 onWorkerLoad.call(this);
233 }
234
235 if (docStoreEvents) {
236 handleDocStoreEvents.call(this, docStoreEvents);
237 }
238
239 router.addMicroServiceHandler(routes, module.exports);
240 },
241 beforeMicroServiceHandler: function(req, finished) {
242 console.log('beforeMicroServiceHandler for ' + req.pathTemplate);
243 //console.log('ignore_jwt = ' + JSON.stringify(ignore_jwt, null, 2));
244 if (ignore_jwt[req.pathTemplate]) return;
245 var authorised = this.jwt.handlers.validateRestRequest.call(this, req, finished);
246 if (authorised && beforeHandler) {
247 return beforeHandler.call(this, req, finished);
248 }
249 return authorised;
250 },
251 workerResponseHandlers: {
252 restRequest: function(message, send) {
253 if (workerResponseHandler[message.path]) {
254 var _this = this;
255 function forward(message, jwt, callback) {
256 message.headers = {
257 authorization: 'Bearer ' + jwt
258 };
259 return _this.microServiceRouter.call(_this, message, callback);
260 }
261 var jwt = message.token;
262 var status = workerResponseHandler[message.path].call(this, message, jwt, forward, send);
263 if (typeof status === 'undefined') return true;
264 if (status === false) return;
265 return status;
266 }
267 }
268 }
269};