soajs.controller 4.2.19 → 4.2.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,10 +8,10 @@
8
8
  * found in the LICENSE file at the root of this repository
9
9
  */
10
10
 
11
- const request = require('request');
12
11
  const async = require('async');
13
12
 
14
13
  const registryModule = require("./../../modules/registry");
14
+ const { checkStatus } = require("../../lib/request.js");
15
15
 
16
16
  let gatewayServiceName = null;
17
17
  let regEnvironment = (process.env.SOAJS_ENV || "dev");
@@ -34,7 +34,7 @@ let fetchControllerHosts = function (core, log, next) {
34
34
  setTimeout(() => {
35
35
  fetchControllerHosts(core, log);
36
36
  }, registry.serviceConfig.awareness.autoRelaodRegistry);
37
-
37
+
38
38
  if (next && typeof next === "function") {
39
39
  next();
40
40
  }
@@ -43,7 +43,7 @@ let fetchControllerHosts = function (core, log, next) {
43
43
 
44
44
  let awareness_healthCheck = function (core, log) {
45
45
  registry = registryModule.get();
46
-
46
+
47
47
  let resume = () => {
48
48
  if (controllerHosts && Array.isArray(controllerHosts) && controllerHosts.length > 0) {
49
49
  let controllerPort = registry.services.controller.port;
@@ -53,7 +53,7 @@ let awareness_healthCheck = function (core, log) {
53
53
  serviceAwarenessObj[sObj.env] = {};
54
54
  }
55
55
  if (!serviceAwarenessObj[sObj.env][sObj.name]) {
56
- serviceAwarenessObj[sObj.env][sObj.name] = {"healthy": {}, "indexes": {}, "latest": 1};
56
+ serviceAwarenessObj[sObj.env][sObj.name] = { "healthy": {}, "indexes": {}, "latest": 1 };
57
57
  }
58
58
  if (!serviceAwarenessObj[sObj.env][sObj.name].healthy[sObj.version]) {
59
59
  serviceAwarenessObj[sObj.env][sObj.name].healthy[sObj.version] = [];
@@ -61,17 +61,18 @@ let awareness_healthCheck = function (core, log) {
61
61
  if (!serviceAwarenessObj[sObj.env][sObj.name].indexes[sObj.version]) {
62
62
  serviceAwarenessObj[sObj.env][sObj.name].indexes[sObj.version] = 0;
63
63
  }
64
- request({
65
- 'uri': 'http://' + sObj.ip + ':' + (controllerPort + registry.serviceConfig.ports.maintenanceInc) + '/heartbeat'
66
- }, function (error, response) {
67
- if (serviceAwarenessObj[sObj.env][sObj.name].latest < sObj.version) {
68
- serviceAwarenessObj[sObj.env][sObj.name].latest = sObj.version;
69
- }
70
- if (!error && response.statusCode === 200) {
64
+
65
+ if (serviceAwarenessObj[sObj.env][sObj.name].latest < sObj.version) {
66
+ serviceAwarenessObj[sObj.env][sObj.name].latest = sObj.version;
67
+ }
68
+ checkStatus('http://' + sObj.ip + ':' + (controllerPort + registry.serviceConfig.ports.maintenanceInc) + '/heartbeat')
69
+ .then(() => {
71
70
  if (serviceAwarenessObj[sObj.env][sObj.name].healthy[sObj.version].indexOf(sObj.ip) === -1) {
72
71
  serviceAwarenessObj[sObj.env][sObj.name].healthy[sObj.version].push(sObj.ip);
73
72
  }
74
- } else {
73
+ callback();
74
+ })
75
+ .catch(() => {
75
76
  if (serviceAwarenessObj[sObj.env][sObj.name].healthy[sObj.version].indexOf(sObj.ip) !== -1) {
76
77
  //TODO: if we guarantee uniqueness we will not need the for loop
77
78
  for (let ii = 0; ii < serviceAwarenessObj[sObj.env][sObj.name].healthy[sObj.version].length; ii++) {
@@ -80,9 +81,30 @@ let awareness_healthCheck = function (core, log) {
80
81
  }
81
82
  }
82
83
  }
83
- }
84
- callback();
85
- });
84
+ callback();
85
+ });
86
+ // request({
87
+ // 'uri': 'http://' + sObj.ip + ':' + (controllerPort + registry.serviceConfig.ports.maintenanceInc) + '/heartbeat'
88
+ // }, function (error, response) {
89
+ // if (serviceAwarenessObj[sObj.env][sObj.name].latest < sObj.version) {
90
+ // serviceAwarenessObj[sObj.env][sObj.name].latest = sObj.version;
91
+ // }
92
+ // if (!error && response.statusCode === 200) {
93
+ // if (serviceAwarenessObj[sObj.env][sObj.name].healthy[sObj.version].indexOf(sObj.ip) === -1) {
94
+ // serviceAwarenessObj[sObj.env][sObj.name].healthy[sObj.version].push(sObj.ip);
95
+ // }
96
+ // } else {
97
+ // if (serviceAwarenessObj[sObj.env][sObj.name].healthy[sObj.version].indexOf(sObj.ip) !== -1) {
98
+ // //TODO: if we guarantee uniqueness we will not need the for loop
99
+ // for (let ii = 0; ii < serviceAwarenessObj[sObj.env][sObj.name].healthy[sObj.version].length; ii++) {
100
+ // if (serviceAwarenessObj[sObj.env][sObj.name].healthy[sObj.version][ii] === sObj.ip) {
101
+ // serviceAwarenessObj[sObj.env][sObj.name].healthy[sObj.version].splice(ii, 1);
102
+ // }
103
+ // }
104
+ // }
105
+ // }
106
+ // callback();
107
+ // });
86
108
  }, function (err) {
87
109
  if (err) {
88
110
  log.warn('Unable to build awareness ENV structure for controllers: ' + err);
@@ -93,13 +115,13 @@ let awareness_healthCheck = function (core, log) {
93
115
  awareness_healthCheck(core, log);
94
116
  }, registry.serviceConfig.awareness.healthCheckInterval);
95
117
  };
96
-
118
+
97
119
  if (timeLoaded !== registry.timeLoaded) {
98
120
  fetchControllerHosts(core, log, resume);
99
121
  } else {
100
122
  resume();
101
123
  }
102
-
124
+
103
125
  timeLoaded = registry.timeLoaded;
104
126
  };
105
127
 
@@ -123,7 +145,7 @@ function roundRobin() {
123
145
  env = arguments[2];
124
146
  break;
125
147
  }
126
-
148
+
127
149
  env = env || regEnvironment;
128
150
  s = gatewayServiceName;
129
151
  if (env && s && serviceAwarenessObj[env] && serviceAwarenessObj[env][s] && serviceAwarenessObj[env][s].healthy) {
@@ -18,29 +18,29 @@ const gtw_keyACL = require("./../soajsRoutes/keyACL/index.js");
18
18
  module.exports = (configuration) => {
19
19
  let provision = configuration.provision;
20
20
  let core = configuration.core;
21
-
21
+
22
22
  let soajs_keyACL = gtw_keyACL({
23
23
  "provision": provision,
24
24
  "serviceName": configuration.serviceName,
25
25
  "serviceVersion": configuration.serviceVersion,
26
26
  "core": core
27
27
  });
28
-
28
+
29
29
  let extractBuildParameters = require("./lib/extractBuildParameters.js");
30
-
30
+
31
31
  let simpleRTS = require("./simpleRTS.js")(configuration);
32
32
  let redirectToService = require("./redirectToService.js")(configuration);
33
33
  let proxyRequest = require("./proxyRequest.js")(configuration);
34
34
  let roaming = require("./roaming.js")(configuration);
35
-
36
-
35
+
36
+
37
37
  return (req, res, next) => {
38
38
  let serviceInfo = req.soajs.controller.serviceParams.serviceInfo;
39
39
  let parsedUrl = req.soajs.controller.serviceParams.parsedUrl;
40
40
  let service_nv = req.soajs.controller.serviceParams.service_nv;
41
41
  let service_n = req.soajs.controller.serviceParams.service_n;
42
42
  let service_v = req.soajs.controller.serviceParams.service_v;
43
-
43
+
44
44
  //check if route is soajs/acl then you also need to bypass the exctract Build Param BL
45
45
  let url_keyACL = (serviceInfo[1] === 'soajs' && serviceInfo[2] === 'acl');
46
46
  if (url_keyACL) {
@@ -62,7 +62,7 @@ module.exports = (configuration) => {
62
62
  pathname: parsedUrl.pathname
63
63
  };
64
64
  }
65
-
65
+
66
66
  extractBuildParameters(req, service_n, service_nv, service_v, proxyInfo, parsedUrl.path, core, function (error, parameters) {
67
67
  if (error) {
68
68
  if (error.message) {
@@ -73,35 +73,36 @@ module.exports = (configuration) => {
73
73
  req.soajs.log.debug(req.headers);
74
74
  return req.soajs.controllerResponse(core.error.getError(130));
75
75
  }
76
-
76
+
77
77
  if (!parameters) {
78
78
  req.soajs.log.fatal("Service [" + service_n + "] URL [" + req.url + "] couldn't be matched to a service or the service entry in registry is missing [port || hosts]");
79
79
  if (req && req.soajs &&
80
80
  req.soajs.registry &&
81
- req.soajs.registry.services) {
81
+ req.soajs.registry.services &&
82
+ req.soajs.registry.services[service_n]) {
82
83
  req.soajs.log.debug(req.soajs.registry.services[service_n]);
83
84
  }
84
85
  req.soajs.log.debug(req.headers);
85
86
  return req.soajs.controllerResponse(core.error.getError(130));
86
87
  }
87
-
88
+
88
89
  for (let param in parameters) {
89
90
  if (Object.hasOwnProperty.call(parameters, param)) {
90
91
  req.soajs.controller.serviceParams[param] = parameters[param];
91
92
  }
92
93
  }
93
-
94
+
94
95
  let set_gotoservice = () => {
95
-
96
+
96
97
  let passportLogin = false;
97
98
  if (serviceInfo[1] === "oauth") {
98
99
  if (serviceInfo[2] === "passport" && serviceInfo[3] === "login") {
99
100
  passportLogin = true;
100
101
  }
101
102
  }
102
-
103
+
103
104
  let soajsroaming = req.get("soajsroaming");
104
-
105
+
105
106
  if (passportLogin) {
106
107
  req.soajs.controller.gotoservice = simpleRTS;
107
108
  } else if (soajsroaming) {
@@ -112,13 +113,13 @@ module.exports = (configuration) => {
112
113
  req.soajs.controller.gotoservice = redirectToService;
113
114
  }
114
115
  };
115
-
116
+
116
117
  if (parameters.extKeyRequired) {
117
118
  let key = req.headers.key || parsedUrl.query.key;
118
119
  if (!key) {
119
120
  return req.soajs.controllerResponse(core.error.getError(132));
120
121
  }
121
-
122
+
122
123
  core.key.getInfo(key, req.soajs.registry.serviceConfig.key, function (err) {
123
124
  if (err) {
124
125
  req.soajs.log.warn(err.message);
@@ -11,7 +11,7 @@
11
11
 
12
12
  const get = (p, o) => p.reduce((xs, x) => (xs && xs[x]) ? xs[x] : null, o);
13
13
 
14
- const request = require('request');
14
+ const { checkStatus } = require("../../../lib/request.js");
15
15
 
16
16
  /**
17
17
  *
@@ -70,16 +70,12 @@ module.exports = (req, res, core, cb) => {
70
70
  uri = 'http://' + host + ':' + maintenancePort + path;
71
71
  }
72
72
  req.soajs.log.info("heartbeat @: " + uri);
73
- request({
74
- 'uri': uri,
75
- 'headers': req.headers
76
- }, function (error, response) {
77
- let resContentType = res.getHeader('content-type');
78
- //let isStream = false;
79
- if (resContentType) {
80
- isStream = resContentType.match(/stream/i);
81
- }
82
- if (!error && response.statusCode === 200) {
73
+ checkStatus(uri)
74
+ .then(() => {
75
+ let resContentType = res.getHeader('content-type');
76
+ if (resContentType) {
77
+ isStream = resContentType.match(/stream/i);
78
+ }
83
79
  if (isStream) {
84
80
  req.soajs.controller.renewalCount--;
85
81
  req.soajs.log.info('Stream detected for [' + req.url + ']. Connection will remain open ...');
@@ -87,7 +83,8 @@ module.exports = (req, res, core, cb) => {
87
83
  req.soajs.log.info('... able to renew request for ', requestTO, 'seconds');
88
84
  res.setTimeout(timeToRenew, renewReqMonitor);
89
85
  }
90
- } else {
86
+ })
87
+ .catch(() => {
91
88
  req.soajs.controller.monitorEndingReq = true;
92
89
  req.soajs.log.error(restServiceParams_msg + ' - Service heartbeat is not responding');
93
90
  if (req.soajs.controller.redirectedRequest) {
@@ -95,8 +92,7 @@ module.exports = (req, res, core, cb) => {
95
92
  req.soajs.controller.redirectedRequest = null;
96
93
  }
97
94
  return req.soajs.controllerResponse(core.error.getError(133));
98
- }
99
- });
95
+ });
100
96
  } else {
101
97
  if (req.soajs.controller.redirectedRequest) {
102
98
  req.soajs.log.info("Request aborted: " + req.soajs.controller.renewalCount + " ", req.url);
@@ -9,14 +9,15 @@
9
9
  */
10
10
 
11
11
  const registryModule = require("./../../modules/registry");
12
- const request = require('request');
12
+ const { proxyRequest } = require("../../lib/request.js");
13
+ const querystring = require('querystring');
13
14
 
14
15
  module.exports = (configuration) => {
15
16
  let core = configuration.core;
16
-
17
+
17
18
  let regEnvironment = (process.env.SOAJS_ENV || "dev");
18
19
  regEnvironment = regEnvironment.toLowerCase();
19
-
20
+
20
21
  /**
21
22
  * load controller information for remote requested environment and proxy the request to its controller.
22
23
  *
@@ -28,67 +29,69 @@ module.exports = (configuration) => {
28
29
  */
29
30
  let proxyRequestToRemoteEnv = (req, res, next, remoteENV, remoteExtKey, requestedRoute) => {
30
31
  let triggerProxy = (myUri, requestTO) => {
31
- let requestConfig = {
32
- 'uri': myUri,
33
- 'method': req.method,
34
- 'timeout': requestTO * 1000,
35
- 'jar': false,
36
- 'headers': req.headers
37
- };
38
-
32
+ let requestConfig = {};
33
+ try {
34
+ const urlObj = new URL(myUri);
35
+ let queryParams = {};
36
+ //add query params
37
+ if (req.query && Object.keys(req.query).length > 0) {
38
+ queryParams = req.query;
39
+ delete queryParams.proxyRoute;
40
+ delete queryParams.__env;
41
+ }
42
+ const queryString = querystring.stringify(queryParams);
43
+ const fullPath = urlObj.pathname + (queryString ? `?${queryString}` : '');
44
+
45
+ requestConfig = {
46
+ "hostname": urlObj.hostname,
47
+ "port": urlObj.port,
48
+ "path": fullPath, // Use the full path with query parameters
49
+ "method": req.method.toUpperCase(),
50
+ 'timeout': requestTO * 1000,
51
+ 'headers': req.headers
52
+ };
53
+ } catch (error) {
54
+ req.soajs.log.error(error.message);
55
+ return req.soajs.controllerResponse(core.error.getError(135));
56
+ }
57
+
39
58
  requestConfig.headers.soajs_roaming = regEnvironment;
40
-
59
+
41
60
  if (remoteExtKey) {
42
61
  //add remote ext key in headers
43
62
  requestConfig.headers.key = remoteExtKey;
44
63
  } else {
45
64
  delete requestConfig.headers.key;
46
65
  }
47
-
48
- //add remaining query params
49
- if (req.query && Object.keys(req.query).length > 0) {
50
- requestConfig.qs = req.query;
51
- delete requestConfig.qs.proxyRoute;
52
- delete requestConfig.qs.__env;
53
- }
54
-
66
+
55
67
  delete requestConfig.headers.host;
56
-
68
+
57
69
  req.soajs.log.debug(requestConfig);
58
-
59
- try {
60
- //proxy request
61
- req.soajs.controller.redirectedRequest = request(requestConfig);
62
- req.soajs.controller.redirectedRequest.on('error', function (error) {
70
+
71
+ const extraOptions = {
72
+ "fetchProxReq": (proxyReq) => {
73
+ req.soajs.controller.redirectedRequest = proxyReq;
74
+ }
75
+ };
76
+
77
+ proxyRequest(req, res, requestConfig, extraOptions)
78
+ .then(() => { })
79
+ .catch((error) => {
63
80
  req.soajs.log.error(error.message);
64
- if (req.soajs.controller.redirectedRequest) {
65
- req.soajs.controller.redirectedRequest.destroy();
66
- req.soajs.controller.redirectedRequest = null;
67
- }
81
+ // if (req.soajs.controller.redirectedRequest) {
82
+ // req.soajs.controller.redirectedRequest.destroy();
83
+ // req.soajs.controller.redirectedRequest = null;
84
+ // }
68
85
  return req.soajs.controllerResponse(core.error.getError(135));
69
86
  });
70
-
71
- if (req.method === 'POST' || req.method === 'PUT' || req.method === 'PATCH' || req.method === 'DELETE') {
72
- req.pipe(req.soajs.controller.redirectedRequest).pipe(res);
73
- } else {
74
- req.soajs.controller.redirectedRequest.pipe(res);
75
- }
76
-
77
- } catch (e) {
78
- req.soajs.log.error(e.message);
79
- if (req.soajs.controller.redirectedRequest) {
80
- req.soajs.controller.redirectedRequest.destroy();
81
- req.soajs.controller.redirectedRequest = null;
82
- }
83
- return req.soajs.controllerResponse(core.error.getError(135));
84
- }
85
87
  };
88
+
86
89
  if (!remoteENV) {
87
90
  triggerProxy(requestedRoute, 30);
88
91
  }
89
92
  else {
90
93
  //get remote env registry
91
- registryModule.loadByEnv({"envCode": remoteENV}, function (err, reg) {
94
+ registryModule.loadByEnv({ "envCode": remoteENV }, function (err, reg) {
92
95
  if (err) {
93
96
  req.soajs.log.error(err.message);
94
97
  return req.soajs.controllerResponse(core.error.getError(207));
@@ -103,13 +106,13 @@ module.exports = (configuration) => {
103
106
  }
104
107
  //formulate request and pipe
105
108
  let myUri = reg.protocol + '://' + (reg.apiPrefix ? reg.apiPrefix + "." : "") + reg.domain + ':' + reg.port + requestedRoute;
106
-
109
+
107
110
  triggerProxy(myUri, requestTO);
108
111
  }
109
112
  });
110
113
  }
111
114
  };
112
-
115
+
113
116
  /**
114
117
  * function that finds if this tenant has a dashboard access extkey for requested env code
115
118
  * @param {Object} tenant
@@ -119,10 +122,10 @@ module.exports = (configuration) => {
119
122
  let findExtKeyForEnvironment = (tenant, env) => {
120
123
  let key = null;
121
124
  tenant.applications.forEach(function (oneApplication) {
122
-
125
+
123
126
  //loop in tenant keys
124
127
  oneApplication.keys.forEach(function (oneKey) {
125
-
128
+
126
129
  //loop in tenant ext keys
127
130
  oneKey.extKeys.forEach(function (oneExtKey) {
128
131
  //get the ext key for the request environment who also has dashboardAccess true
@@ -135,7 +138,7 @@ module.exports = (configuration) => {
135
138
  });
136
139
  return key;
137
140
  };
138
-
141
+
139
142
  /**
140
143
  * function that fetches a tenant record from core.provision
141
144
  * @param {string} tCode
@@ -144,14 +147,14 @@ module.exports = (configuration) => {
144
147
  let getOriginalTenantRecord = (tCode, cb) => {
145
148
  core.provision.getTenantByCode(tCode, cb);
146
149
  };
147
-
150
+
148
151
  return (req, res, next) => {
149
152
  /*
150
153
  get ext key for remote env requested
151
154
  */
152
155
  let tenant = req.soajs.tenant;
153
156
  let parsedUrl = req.soajs.controller.serviceParams.parsedUrl;
154
-
157
+
155
158
  let remoteENV = req.headers.__env;
156
159
  if (parsedUrl.query && parsedUrl.query.__env) {
157
160
  remoteENV = parsedUrl.query.__env;
@@ -164,12 +167,12 @@ module.exports = (configuration) => {
164
167
  if (parsedUrl.query && parsedUrl.query.proxyRoute) {
165
168
  requestedRoute = decodeURIComponent(parsedUrl.query.proxyRoute);
166
169
  }
167
-
170
+
168
171
  //stop if no requested path was found
169
172
  if (!requestedRoute) {
170
173
  return req.soajs.controllerResponse(core.error.getError(139));
171
174
  }
172
-
175
+
173
176
  if (remoteENV) {
174
177
  req.soajs.log.debug("attempting to redirect to: " + requestedRoute + " in " + remoteENV + " Environment.");
175
178
  } else {
@@ -177,7 +180,7 @@ module.exports = (configuration) => {
177
180
  }
178
181
  let tCode = null;
179
182
  let tExtKey = null;
180
-
183
+
181
184
  if (parsedUrl.query) {
182
185
  if (parsedUrl.query.tCode) {
183
186
  tCode = parsedUrl.query.tCode;
@@ -196,10 +199,10 @@ module.exports = (configuration) => {
196
199
  if (error) {
197
200
  return req.soajs.controllerResponse(core.error.getError(139)); //todo: make sure we have set the correct error code number
198
201
  }
199
-
202
+
200
203
  //get extKey for remote environment for this tenant
201
204
  let remoteExtKey = findExtKeyForEnvironment(originalTenant, remoteENV);
202
-
205
+
203
206
  //no key found
204
207
  if (!remoteExtKey) {
205
208
  req.soajs.log.fatal("No remote key found for tenant: " + tCode + " in environment: " + remoteENV);
@@ -208,7 +211,7 @@ module.exports = (configuration) => {
208
211
  //proceed with proxying the request
209
212
  proxyRequestToRemoteEnv(req, res, next, remoteENV, remoteExtKey, requestedRoute);
210
213
  }
211
-
214
+
212
215
  });
213
216
  }
214
217
  else {