UNPKG

9.71 kBJavaScriptView Raw
1/*
2
3 ----------------------------------------------------------------------------
4 | qewd-up: Rapid QEWD API Development |
5 | |
6 | Copyright (c) 2018-19 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 4 July 2019
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
50 var routes_data = require(cwd + '/configuration/routes.json');
51 var config_data = require(cwd + '/configuration/config.json');
52 var ms_path;
53
54 if (mode === 'microservice') {
55 ms_name = config_data.ms_name;
56 ms_path = cwd + '/';
57 }
58 else {
59 ms_path = cwd + '/' + ms_name + '/';
60 }
61
62 var routes = {};
63
64 //console.log('loading up/ms_handlers in process ' + process.pid);
65 //console.log('ms_name = ' + ms_name);
66 //console.log('routes_data = ' + JSON.stringify(routes_data, null, 2));
67
68 // check for any grouped destinations that include this microservice name
69
70 var group_matches = {};
71 if (!mode) {
72 config_data.microservices.forEach(function(microservice) {
73 if (microservice.members) {
74 microservice.members.forEach(function(member_name) {
75 if (member_name === ms_name) {
76 group_matches[microservice.name] = true;
77 }
78 });
79 }
80 });
81 }
82
83 routes_data.forEach(function(route) {
84 if (mode === 'microservice') {
85 route.on_microservice = ms_name;
86 }
87 //console.log('route: ' + JSON.stringify(route, null, 2));
88 var handler;
89 var ms_match = false;
90 var ms_source = ms_name;
91 var i;
92
93 if (route.on_microservice) {
94 if (route.on_microservice === ms_name) {
95 // direct match
96 ms_match = true;
97 }
98 if (group_matches[route.on_microservice]) {
99 // group destination match
100 ms_match = true;
101 if (route.handler_source) {
102 ms_source = route.handler_source;
103 }
104 }
105 }
106 if (!ms_match && route.on_microservices) {
107 route.on_microservices.forEach(function(on_ms_name) {
108 if (on_ms_name === ms_name) ms_match = true;
109 if (route.handler_source) {
110 ms_source = route.handler_source;
111 }
112 });
113 }
114
115 if (ms_match) {
116 if (onHandledOnly) {
117 var onMSResponsePaths = [
118 ms_path + route.handler + '/onMSResponse.js',
119 ms_path + 'apis/' + route.handler + '/onMSResponse.js',
120 ];
121 for (i = 0; i < onMSResponsePaths.length; i++) {
122 if (fs.existsSync(onMSResponsePaths[i])) {
123 try {
124 workerResponseHandler[route.uri] = require(onMSResponsePaths[i]);
125 console.log('onMSResponse handler loaded from ' + onMSResponsePaths[i]);
126 }
127 catch(err) {
128 console.log('** Warning: onMSResponse handler could not be loaded from ' + onMSResponsePaths[i]);
129 }
130 break;
131 }
132 }
133 }
134 else {
135 if (!routes[route.uri]) routes[route.uri] = {};
136 //console.log('route.uri = ' + route.uri);
137 var path = cwd + '/' + ms_source + '/';
138 var handlerPaths = [
139 path + route.handler + '.js',
140 path + route.handler + '/handler.js',
141 path + route.handler + '/index.js',
142 path + 'apis/' + route.handler + '/index.js'
143 ];
144 if (mode === 'microservice') {
145 handlerPaths.push(cwd + '/apis/' + route.handler + '/index.js');
146 handlerPaths.push(cwd + '/apis/' + route.handler + '/handler.js');
147 }
148 var handlerFound = false;
149 for (i = 0; i < handlerPaths.length; i++) {
150 console.log('** trying to load from ' + handlerPaths[i]);
151 if (fs.existsSync(handlerPaths[i])) {
152 try {
153 handler = require(handlerPaths[i]);
154 console.log('loaded handler from ' + handlerPaths[i]);
155 }
156 catch(err) {
157 console.log('*** Warning - handler for ' + route.handler + ' found but could not be loaded from ' + handlerPaths[i]);
158 console.log(err);
159 }
160 handlerFound = true;
161 break;
162 }
163 }
164 if (!handlerFound) {
165 console.log('*** Warning - handler for ' + route.handler + ' not found');
166 }
167
168 routes[route.uri][route.method] = handler;
169 //console.log(route.uri + ': authenticate = ' + route.authenticate);
170 if (route.authenticate === false) {
171 ignore_jwt[route.uri] = true;
172 }
173 }
174 }
175 });
176
177 if (onHandledOnly) return;
178
179 var onWorkerLoadPath = ms_path + 'onWorkerLoad.js';
180 if (fs.existsSync(onWorkerLoadPath)) {
181 try {
182 onWorkerLoad = require(onWorkerLoadPath);
183 console.log('Loaded onWorkerLoad module from ' + onWorkerLoadPath);
184 }
185 catch(err) {
186 console.log('** Warning - unable to load onWorkerLoad module from ' + onWorkerLoadPath);
187 }
188 }
189
190 var beforeHandlerPath = ms_path + 'beforeHandler.js';
191 if (fs.existsSync(beforeHandlerPath)) {
192 try {
193 beforeHandler = require(beforeHandlerPath);
194 console.log('Loaded beforeHandler module from ' + beforeHandlerPath);
195 }
196 catch(err) {
197 console.log('** Warning - unable to load ' + beforeHandlerPath);
198 }
199 }
200 else {
201 beforeHandlerPath = ms_path + 'apis/beforeHandler.js';
202 if (fs.existsSync(beforeHandlerPath)) {
203 try {
204 beforeHandler = require(beforeHandlerPath);
205 console.log('Loaded beforeHandler module from ' + beforeHandlerPath);
206 }
207 catch(err) {
208 console.log('** Warning - unable to load ' + beforeHandlerPath);
209 }
210 }
211 }
212
213 var docStoreEventsPath = ms_path + 'docStoreEvents/events.json';
214 if (fs.existsSync(docStoreEventsPath)) {
215 docStoreEvents = createDocStoreEvents(docStoreEventsPath, ms_path);
216 //console.log('** docStoreEvents: ' + JSON.stringify(docStoreEvents, null, 2));
217 }
218
219 //console.log('routes: ' + JSON.stringify(routes, null, 2));
220 return routes;
221}
222
223loadRoutes(true); // when called by master process for workerResponseHandlers
224 // to prevent unnecessary loading of route handlers
225
226
227module.exports = {
228 init: function() {
229 var routes = loadRoutes();
230 if (onWorkerLoad) {
231 onWorkerLoad.call(this);
232 }
233
234 if (docStoreEvents) {
235 handleDocStoreEvents.call(this, docStoreEvents);
236 }
237
238 router.addMicroServiceHandler(routes, module.exports);
239 },
240 beforeMicroServiceHandler: function(req, finished) {
241 console.log('beforeMicroServiceHandler for ' + req.pathTemplate);
242 //console.log('ignore_jwt = ' + JSON.stringify(ignore_jwt, null, 2));
243 if (ignore_jwt[req.pathTemplate]) return;
244 var authorised = this.jwt.handlers.validateRestRequest.call(this, req, finished);
245 if (authorised && beforeHandler) {
246 return beforeHandler.call(this, req, finished);
247 }
248 return authorised;
249 },
250 workerResponseHandlers: {
251 restRequest: function(message, send) {
252 if (workerResponseHandler[message.path]) {
253 var _this = this;
254 function forward(message, jwt, callback) {
255 message.headers = {
256 authorization: 'Bearer ' + jwt
257 };
258 return _this.microServiceRouter.call(_this, message, callback);
259 }
260 var jwt = message.token;
261 var status = workerResponseHandler[message.path].call(this, message, jwt, forward, send);
262 if (typeof status === 'undefined') return true;
263 if (status === false) return;
264 return status;
265 }
266 }
267 }
268};