evaengine 0.11.2 → 1.0.1
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.
- package/.ai/analysis.md +657 -0
- package/.ai/architecture/runtime.md +504 -0
- package/.ai/contracts/public-api.md +447 -0
- package/.ai/external-project-guide.md +248 -0
- package/.ai/vision.md +314 -0
- package/README.md +51 -62
- package/bin/engine +15 -21
- package/index.js +2 -18
- package/package.json +60 -64
- package/src/commands/index.js +12 -0
- package/{lib → src}/commands/interface.js +5 -11
- package/src/commands/make_entity.js +490 -0
- package/src/commands/tramp.js +34 -0
- package/{lib → src}/config/index.js +7 -9
- package/{lib → src}/di.js +11 -26
- package/src/engine.js +551 -0
- package/{lib → src}/entities/index.js +72 -82
- package/{lib → src}/exceptions/index.js +71 -92
- package/src/index.js +57 -0
- package/src/middlewares/auth.js +67 -0
- package/src/middlewares/auth_kong.js +28 -0
- package/src/middlewares/debug.js +88 -0
- package/src/middlewares/index.js +18 -0
- package/src/middlewares/providers.js +73 -0
- package/src/middlewares/session.js +58 -0
- package/{lib → src}/middlewares/trace.js +74 -86
- package/src/middlewares/validator.js +50 -0
- package/src/middlewares/view_cache.js +127 -0
- package/{lib → src}/services/cache.js +45 -56
- package/src/services/config.js +111 -0
- package/src/services/env.js +28 -0
- package/src/services/event_manager.js +84 -0
- package/src/services/http_client.js +160 -0
- package/src/services/index.js +27 -0
- package/src/services/interface.js +5 -0
- package/src/services/joi.js +13 -0
- package/src/services/jwt_token.js +89 -0
- package/src/services/jwt_token_kong.js +75 -0
- package/src/services/logger.js +148 -0
- package/src/services/namespace.js +176 -0
- package/src/services/now.js +49 -0
- package/src/services/providers.js +158 -0
- package/src/services/redis.js +55 -0
- package/src/services/rest_client.js +112 -0
- package/src/swagger/index.js +668 -0
- package/{lib → src}/utils/api_scaffold.js +26 -39
- package/src/utils/case_converter.js +33 -0
- package/src/utils/crc32.js +44 -0
- package/src/utils/datetime.js +13 -0
- package/src/utils/host.js +39 -0
- package/src/utils/index.js +35 -0
- package/{lib → src}/utils/pagination.js +22 -31
- package/src/utils/random.js +23 -0
- package/{lib → src}/utils/smart_query.js +27 -27
- package/src/utils/test.js +48 -0
- package/src/utils/wrapper.js +8 -0
- package/bin/engine-babel +0 -38
- package/lib/commands/index.js +0 -25
- package/lib/commands/index.js.map +0 -1
- package/lib/commands/interface.js.map +0 -1
- package/lib/commands/make_entity.js +0 -549
- package/lib/commands/make_entity.js.map +0 -1
- package/lib/commands/tramp.js +0 -53
- package/lib/commands/tramp.js.map +0 -1
- package/lib/config/index.js.map +0 -1
- package/lib/di.js.map +0 -1
- package/lib/engine.js +0 -558
- package/lib/engine.js.map +0 -1
- package/lib/entities/index.js.map +0 -1
- package/lib/exceptions/index.js.map +0 -1
- package/lib/index.js +0 -105
- package/lib/index.js.map +0 -1
- package/lib/middlewares/auth.js +0 -97
- package/lib/middlewares/auth.js.map +0 -1
- package/lib/middlewares/auth_kong.js +0 -48
- package/lib/middlewares/auth_kong.js.map +0 -1
- package/lib/middlewares/debug.js +0 -68
- package/lib/middlewares/debug.js.map +0 -1
- package/lib/middlewares/index.js +0 -45
- package/lib/middlewares/index.js.map +0 -1
- package/lib/middlewares/providers.js +0 -102
- package/lib/middlewares/providers.js.map +0 -1
- package/lib/middlewares/session.js +0 -76
- package/lib/middlewares/session.js.map +0 -1
- package/lib/middlewares/trace.js.map +0 -1
- package/lib/middlewares/validator.js +0 -71
- package/lib/middlewares/validator.js.map +0 -1
- package/lib/middlewares/view_cache.js +0 -160
- package/lib/middlewares/view_cache.js.map +0 -1
- package/lib/services/cache.js.map +0 -1
- package/lib/services/config.js +0 -140
- package/lib/services/config.js.map +0 -1
- package/lib/services/env.js +0 -40
- package/lib/services/env.js.map +0 -1
- package/lib/services/event_manager.js +0 -110
- package/lib/services/event_manager.js.map +0 -1
- package/lib/services/http_client.js +0 -178
- package/lib/services/http_client.js.map +0 -1
- package/lib/services/index.js +0 -70
- package/lib/services/index.js.map +0 -1
- package/lib/services/interface.js +0 -12
- package/lib/services/interface.js.map +0 -1
- package/lib/services/joi.js +0 -28
- package/lib/services/joi.js.map +0 -1
- package/lib/services/jwt_token.js +0 -120
- package/lib/services/jwt_token.js.map +0 -1
- package/lib/services/jwt_token_kong.js +0 -111
- package/lib/services/jwt_token_kong.js.map +0 -1
- package/lib/services/logger.js +0 -172
- package/lib/services/logger.js.map +0 -1
- package/lib/services/namespace.js +0 -188
- package/lib/services/namespace.js.map +0 -1
- package/lib/services/now.js +0 -69
- package/lib/services/now.js.map +0 -1
- package/lib/services/providers.js +0 -195
- package/lib/services/providers.js.map +0 -1
- package/lib/services/redis.js +0 -77
- package/lib/services/redis.js.map +0 -1
- package/lib/services/rest_client.js +0 -136
- package/lib/services/rest_client.js.map +0 -1
- package/lib/swagger/index.js +0 -684
- package/lib/swagger/index.js.map +0 -1
- package/lib/utils/api_scaffold.js.map +0 -1
- package/lib/utils/case_converter.js +0 -48
- package/lib/utils/case_converter.js.map +0 -1
- package/lib/utils/crc32.js +0 -22
- package/lib/utils/crc32.js.map +0 -1
- package/lib/utils/datetime.js +0 -21
- package/lib/utils/datetime.js.map +0 -1
- package/lib/utils/host.js +0 -48
- package/lib/utils/host.js.map +0 -1
- package/lib/utils/index.js +0 -61
- package/lib/utils/index.js.map +0 -1
- package/lib/utils/pagination.js.map +0 -1
- package/lib/utils/random.js +0 -33
- package/lib/utils/random.js.map +0 -1
- package/lib/utils/smart_query.js.map +0 -1
- package/lib/utils/test.js +0 -62
- package/lib/utils/test.js.map +0 -1
- package/lib/utils/wrapper.js +0 -9
- package/lib/utils/wrapper.js.map +0 -1
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { UnauthorizedException } from '../exceptions/index.js';
|
|
2
|
+
import wrapper from '../utils/wrapper.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @returns {function()}
|
|
6
|
+
* @constructor
|
|
7
|
+
*/
|
|
8
|
+
function AuthKongMiddleware() {
|
|
9
|
+
return () => wrapper(async (req, res, next) => {
|
|
10
|
+
if (req.headers['x-anonymous-consumer'] === 'true') {
|
|
11
|
+
throw new UnauthorizedException('Authentication failed');
|
|
12
|
+
}
|
|
13
|
+
const uid = Number.parseInt(req.headers['x-consumer-custom-id'], 10);
|
|
14
|
+
const mobile = req.headers['x-consumer-custom-username'];
|
|
15
|
+
if (uid > 0) {
|
|
16
|
+
res.set('X-Uid', uid);
|
|
17
|
+
res.set('X-Mobile', mobile);
|
|
18
|
+
req.auth = {
|
|
19
|
+
uid,
|
|
20
|
+
mobile
|
|
21
|
+
};
|
|
22
|
+
return next();
|
|
23
|
+
}
|
|
24
|
+
throw new UnauthorizedException('Authentication failed, invalid UID');
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export default AuthKongMiddleware;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import morgan from 'morgan';
|
|
2
|
+
import os from 'os';
|
|
3
|
+
import constitute from 'constitute';
|
|
4
|
+
import Logger from '../services/logger.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
Log format:
|
|
8
|
+
NCSA Combined Log Format + extended fields
|
|
9
|
+
|
|
10
|
+
Nginx config as below
|
|
11
|
+
|
|
12
|
+
log_format upstream '$http_x_forwarded_for - $remote_user [$time_local] '
|
|
13
|
+
'"$request" $status $body_bytes_sent '
|
|
14
|
+
'"$http_referer" "$http_user_agent" '
|
|
15
|
+
'"$remote_addr" $host $request_time $upstream_response_time $scheme $server_port '
|
|
16
|
+
'$hostname $upstream_addr $http_x_device_id $sent_http_x_uid $sent_http_x_token '
|
|
17
|
+
'$sent_http_x_service_name $sent_http_x_b3_spanid $sent_http_x_b3_traceid '
|
|
18
|
+
'$sent_http_x_b3_parentspanid $sent_http_x_b3_sampled';
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
morgan.token(
|
|
22
|
+
'host',
|
|
23
|
+
req =>
|
|
24
|
+
req.headers.host
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
morgan.token(
|
|
28
|
+
'real-ip',
|
|
29
|
+
req =>
|
|
30
|
+
req.headers['x-real-ip'] ||
|
|
31
|
+
req.headers['x-forwarded-for'] ||
|
|
32
|
+
req.ip ||
|
|
33
|
+
(req.connection && req.connection.remoteAddress)
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
morgan.token(
|
|
37
|
+
'port',
|
|
38
|
+
req =>
|
|
39
|
+
(req.headers.host && req.headers.host.split(':')[1]) || -1
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
const hostname = os.hostname();
|
|
43
|
+
morgan.token('hostname', () => hostname);
|
|
44
|
+
|
|
45
|
+
morgan.token(
|
|
46
|
+
'tokens',
|
|
47
|
+
(req, res) =>
|
|
48
|
+
[
|
|
49
|
+
res.getHeader('X-Uid') || '-',
|
|
50
|
+
res.getHeader('X-Token') || '-'
|
|
51
|
+
].join(' ')
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
morgan.token(
|
|
55
|
+
'tracer',
|
|
56
|
+
(req, res) =>
|
|
57
|
+
[
|
|
58
|
+
res.getHeader('X-Service-Name') || '-',
|
|
59
|
+
res.getHeader('X-B3-SpanId') || '-',
|
|
60
|
+
res.getHeader('X-B3-TraceId') || '-',
|
|
61
|
+
res.getHeader('X-B3-ParentSpanId') || '-',
|
|
62
|
+
res.getHeader('X-B3-Sampled') || '-'
|
|
63
|
+
].join(' ')
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* @param logger {Logger}
|
|
69
|
+
* @returns {function()}
|
|
70
|
+
* @constructor
|
|
71
|
+
*/
|
|
72
|
+
function DebugMiddleware(logger) {
|
|
73
|
+
return () =>
|
|
74
|
+
morgan(
|
|
75
|
+
':real-ip - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent" ' +
|
|
76
|
+
'":remote-addr" :host :response-time - :http-version :port :hostname - :tokens :tracer %s',
|
|
77
|
+
{
|
|
78
|
+
stream: {
|
|
79
|
+
write: (message) => {
|
|
80
|
+
logger.info(message);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
constitute.Dependencies(Logger)(DebugMiddleware);
|
|
88
|
+
export default DebugMiddleware;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import AuthMiddleware from './auth.js';
|
|
2
|
+
import AuthKongMiddleware from './auth_kong.js';
|
|
3
|
+
import DebugMiddleware from './debug.js';
|
|
4
|
+
import SessionMiddleware from './session.js';
|
|
5
|
+
import TraceMiddleware from './trace.js';
|
|
6
|
+
import ViewCacheMiddleware from './view_cache.js';
|
|
7
|
+
import ValidatorMiddleware from './validator.js';
|
|
8
|
+
|
|
9
|
+
export {
|
|
10
|
+
AuthMiddleware,
|
|
11
|
+
AuthKongMiddleware,
|
|
12
|
+
DebugMiddleware,
|
|
13
|
+
SessionMiddleware,
|
|
14
|
+
TraceMiddleware,
|
|
15
|
+
ViewCacheMiddleware,
|
|
16
|
+
ValidatorMiddleware
|
|
17
|
+
};
|
|
18
|
+
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import SessionMiddleware from '../middlewares/session.js';
|
|
2
|
+
import AuthMiddleware from '../middlewares/auth.js';
|
|
3
|
+
import AuthKongMiddleware from '../middlewares/auth_kong.js';
|
|
4
|
+
import DebugMiddleware from '../middlewares/debug.js';
|
|
5
|
+
import TraceMiddleware from '../middlewares/trace.js';
|
|
6
|
+
import ViewCacheMiddleware from '../middlewares/view_cache.js';
|
|
7
|
+
import ValidatorMiddleware from '../middlewares/validator.js';
|
|
8
|
+
import DI from '../di.js';
|
|
9
|
+
import { ServiceProvider } from '../services/providers.js';
|
|
10
|
+
|
|
11
|
+
export class SessionMiddlewareProvider extends ServiceProvider {
|
|
12
|
+
get name() {
|
|
13
|
+
return 'session';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
register() {
|
|
17
|
+
DI.bindMethod(this.name, SessionMiddleware);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export class AuthMiddlewareProvider extends ServiceProvider {
|
|
22
|
+
get name() {
|
|
23
|
+
return 'auth';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
register() {
|
|
27
|
+
if (DI.get('config').get('token.provider') === 'kong') {
|
|
28
|
+
DI.bindMethod(this.name, AuthKongMiddleware);
|
|
29
|
+
} else {
|
|
30
|
+
DI.bindMethod(this.name, AuthMiddleware);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export class DebugMiddlewareProvider extends ServiceProvider {
|
|
36
|
+
get name() {
|
|
37
|
+
return 'debug';
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
register() {
|
|
41
|
+
DI.bindMethod(this.name, DebugMiddleware);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export class ViewCacheMiddlewareProvider extends ServiceProvider {
|
|
46
|
+
get name() {
|
|
47
|
+
return 'view_cache';
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
register() {
|
|
51
|
+
DI.bindMethod(this.name, ViewCacheMiddleware);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export class TraceMiddlewareProvider extends ServiceProvider {
|
|
56
|
+
get name() {
|
|
57
|
+
return 'trace';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
register() {
|
|
61
|
+
DI.bindMethod(this.name, TraceMiddleware);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export class ValidatorMiddlewareProvider extends ServiceProvider {
|
|
66
|
+
get name() {
|
|
67
|
+
return 'validator';
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
register() {
|
|
71
|
+
DI.bindMethod(this.name, ValidatorMiddleware);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import session from 'express-session';
|
|
2
|
+
import { RedisStore } from 'connect-redis';
|
|
3
|
+
import constitute from 'constitute';
|
|
4
|
+
import Config from '../services/config.js';
|
|
5
|
+
import Redis from '../services/redis.js';
|
|
6
|
+
import Namespace from '../services/namespace.js';
|
|
7
|
+
|
|
8
|
+
let middleware = null;
|
|
9
|
+
|
|
10
|
+
//Fix issue https://github.com/othiym23/node-continuation-local-storage/issues/29
|
|
11
|
+
const clsifyMiddleware = (fn, ns) =>
|
|
12
|
+
(req, res, next) =>
|
|
13
|
+
fn.call(this, req, res, ns.bind(next));
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @param _config {Config}
|
|
17
|
+
* @param redis {Redis}
|
|
18
|
+
* @param namespace {Namespace}
|
|
19
|
+
* @returns {function()}
|
|
20
|
+
* @constructor
|
|
21
|
+
*/
|
|
22
|
+
function SessionMiddleware(_config, redis, namespace) {
|
|
23
|
+
return () => {
|
|
24
|
+
if (middleware) {
|
|
25
|
+
return middleware;
|
|
26
|
+
}
|
|
27
|
+
const Store = RedisStore;
|
|
28
|
+
let store = null;
|
|
29
|
+
const config = _config.get().session;
|
|
30
|
+
|
|
31
|
+
if (config.store) {
|
|
32
|
+
const RedisClient = new Store(Object.assign({}, config.store, {
|
|
33
|
+
client: config.store.client || redis.getInstance()
|
|
34
|
+
}));
|
|
35
|
+
RedisClient.client.on('error', (err) => {
|
|
36
|
+
throw err;
|
|
37
|
+
});
|
|
38
|
+
store = RedisClient;
|
|
39
|
+
} else {
|
|
40
|
+
store = new Store(Object.assign({}, { client: redis.getInstance() }));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
middleware = session({
|
|
44
|
+
store,
|
|
45
|
+
cookie: Object.assign({}, _config.get().cookie),
|
|
46
|
+
secret: config.secret,
|
|
47
|
+
resave: config.resave,
|
|
48
|
+
saveUninitialized: config.saveUninitialized
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
return namespace.isEnabled() ?
|
|
52
|
+
clsifyMiddleware(middleware, namespace.use().getContext()) :
|
|
53
|
+
middleware;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
constitute.Dependencies(Config, Redis, Namespace)(SessionMiddleware);
|
|
57
|
+
|
|
58
|
+
export default SessionMiddleware;
|
|
@@ -1,39 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
import onHeaders from 'on-headers';
|
|
2
|
+
import constitute from 'constitute';
|
|
3
|
+
import { randomString, getHostFullUrl, getHostPort, getHostIp, getMicroTimestamp } from '../utils/index.js';
|
|
4
|
+
import Namespace from '../services/namespace.js';
|
|
5
|
+
import Config from '../services/config.js';
|
|
6
|
+
import Logger from '../services/logger.js';
|
|
7
|
+
import HttpClient from '../services/http_client.js';
|
|
2
8
|
|
|
3
|
-
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.tracerToZipkins = undefined;
|
|
9
|
+
const hostIp = getHostIp();
|
|
7
10
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
var _onHeaders2 = _interopRequireDefault(_onHeaders);
|
|
11
|
-
|
|
12
|
-
var _constitute = require('constitute');
|
|
13
|
-
|
|
14
|
-
var _utils = require('../utils');
|
|
15
|
-
|
|
16
|
-
var _namespace = require('../services/namespace');
|
|
17
|
-
|
|
18
|
-
var _namespace2 = _interopRequireDefault(_namespace);
|
|
19
|
-
|
|
20
|
-
var _config = require('../services/config');
|
|
21
|
-
|
|
22
|
-
var _config2 = _interopRequireDefault(_config);
|
|
23
|
-
|
|
24
|
-
var _logger = require('../services/logger');
|
|
25
|
-
|
|
26
|
-
var _logger2 = _interopRequireDefault(_logger);
|
|
27
|
-
|
|
28
|
-
var _http_client = require('../services/http_client');
|
|
29
|
-
|
|
30
|
-
var _http_client2 = _interopRequireDefault(_http_client);
|
|
31
|
-
|
|
32
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
33
|
-
|
|
34
|
-
const hostIp = (0, _utils.getHostIp)();
|
|
35
|
-
|
|
36
|
-
const tracerToZipkins = exports.tracerToZipkins = tracer => {
|
|
11
|
+
export const tracerToZipkins = (tracer) => {
|
|
37
12
|
if (!tracer) {
|
|
38
13
|
return false;
|
|
39
14
|
}
|
|
@@ -63,34 +38,44 @@ const tracerToZipkins = exports.tracerToZipkins = tracer => {
|
|
|
63
38
|
name,
|
|
64
39
|
timestamp,
|
|
65
40
|
duration,
|
|
66
|
-
annotations: [
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
41
|
+
annotations: [
|
|
42
|
+
{
|
|
43
|
+
endpoint,
|
|
44
|
+
timestamp,
|
|
45
|
+
value: 'sr'
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
endpoint,
|
|
49
|
+
timestamp: timestamp + duration,
|
|
50
|
+
value: 'ss'
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
binaryAnnotations: [
|
|
54
|
+
{
|
|
55
|
+
key: 'traceId',
|
|
56
|
+
value: traceId
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
key: 'spanId',
|
|
60
|
+
value: id
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
key: 'method',
|
|
64
|
+
value: method
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
key: 'url',
|
|
68
|
+
value: url
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
key: 'port',
|
|
72
|
+
value: port.toString()
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
key: 'statusCode',
|
|
76
|
+
value: statusCode.toString()
|
|
77
|
+
}
|
|
78
|
+
]
|
|
94
79
|
};
|
|
95
80
|
|
|
96
81
|
if (parentId) {
|
|
@@ -99,24 +84,27 @@ const tracerToZipkins = exports.tracerToZipkins = tracer => {
|
|
|
99
84
|
|
|
100
85
|
const zipkins = [zipkin];
|
|
101
86
|
if (queries && queries.length > 0) {
|
|
102
|
-
queries.forEach(element => {
|
|
87
|
+
queries.forEach((element) => {
|
|
103
88
|
const { query, cost, finishedAt } = element;
|
|
104
89
|
zipkins.push({
|
|
105
|
-
id:
|
|
90
|
+
id: randomString(),
|
|
106
91
|
parentId: id,
|
|
107
92
|
traceId,
|
|
108
93
|
name: 'sequelize',
|
|
109
94
|
timestamp: finishedAt - cost,
|
|
110
95
|
duration: cost,
|
|
111
|
-
annotations: [
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
96
|
+
annotations: [
|
|
97
|
+
{
|
|
98
|
+
endpoint,
|
|
99
|
+
timestamp: finishedAt - cost,
|
|
100
|
+
value: 'cs'
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
endpoint,
|
|
104
|
+
timestamp: finishedAt,
|
|
105
|
+
value: 'cr'
|
|
106
|
+
}
|
|
107
|
+
],
|
|
120
108
|
binaryAnnotations: [{
|
|
121
109
|
key: 'query',
|
|
122
110
|
value: query
|
|
@@ -127,14 +115,15 @@ const tracerToZipkins = exports.tracerToZipkins = tracer => {
|
|
|
127
115
|
return zipkins;
|
|
128
116
|
};
|
|
129
117
|
|
|
118
|
+
|
|
130
119
|
function TraceMiddleware(ns, config, logger, client) {
|
|
131
120
|
const enabled = config.get('trace.enable');
|
|
132
121
|
return name => (req, res, next) => {
|
|
133
|
-
const spanId =
|
|
122
|
+
const spanId = randomString();
|
|
134
123
|
const traceId = req.get('X-B3-TraceId') || spanId;
|
|
135
124
|
const parentId = req.get('X-B3-SpanId') || '';
|
|
136
125
|
const startedAt = process.hrtime();
|
|
137
|
-
const timestamp =
|
|
126
|
+
const timestamp = getMicroTimestamp();
|
|
138
127
|
const serviceName = name || config.get('app.name');
|
|
139
128
|
//目前默认全部采样
|
|
140
129
|
let sampled = enabled ? 1 : 0;
|
|
@@ -145,8 +134,8 @@ function TraceMiddleware(ns, config, logger, client) {
|
|
|
145
134
|
const tracer = {
|
|
146
135
|
serviceName,
|
|
147
136
|
method: req.method,
|
|
148
|
-
url:
|
|
149
|
-
port:
|
|
137
|
+
url: getHostFullUrl(req),
|
|
138
|
+
port: getHostPort(req),
|
|
150
139
|
spanId,
|
|
151
140
|
traceId,
|
|
152
141
|
parentId,
|
|
@@ -164,22 +153,22 @@ function TraceMiddleware(ns, config, logger, client) {
|
|
|
164
153
|
'X-B3-SpanId': spanId,
|
|
165
154
|
'X-B3-TraceId': traceId,
|
|
166
155
|
'X-B3-ParentSpanId': parentId,
|
|
167
|
-
'X-B3-Sampled':
|
|
156
|
+
'X-B3-Sampled': sampled
|
|
168
157
|
});
|
|
169
158
|
|
|
170
159
|
if (sampled < 1) {
|
|
171
|
-
(
|
|
160
|
+
onHeaders(res, () => {
|
|
172
161
|
const [seconds, nanoseconds] = process.hrtime(startedAt);
|
|
173
|
-
const duration = seconds * 1e3 + nanoseconds * 1e-6;
|
|
162
|
+
const duration = ((seconds * 1e3) + (nanoseconds * 1e-6));
|
|
174
163
|
res.set('X-Response-Milliseconds', parseInt(duration, 10));
|
|
175
164
|
});
|
|
176
165
|
next();
|
|
177
166
|
return;
|
|
178
167
|
}
|
|
179
168
|
|
|
180
|
-
(
|
|
169
|
+
onHeaders(res, () => {
|
|
181
170
|
const [seconds, nanoseconds] = process.hrtime(startedAt);
|
|
182
|
-
const duration = (seconds * 1e3 + nanoseconds * 1e-6) * 1000;
|
|
171
|
+
const duration = ((seconds * 1e3) + (nanoseconds * 1e-6)) * 1000;
|
|
183
172
|
tracer.duration = parseInt(duration, 10);
|
|
184
173
|
tracer.statusCode = res.statusCode;
|
|
185
174
|
res.set('X-Response-Milliseconds', tracer.duration / 1000);
|
|
@@ -217,7 +206,7 @@ function TraceMiddleware(ns, config, logger, client) {
|
|
|
217
206
|
url: api,
|
|
218
207
|
method: 'POST',
|
|
219
208
|
json: zipkins
|
|
220
|
-
}).catch(e => {
|
|
209
|
+
}).catch((e) => {
|
|
221
210
|
logger.error('Error happened on sending tracing data', e);
|
|
222
211
|
});
|
|
223
212
|
};
|
|
@@ -235,7 +224,6 @@ function TraceMiddleware(ns, config, logger, client) {
|
|
|
235
224
|
};
|
|
236
225
|
}
|
|
237
226
|
|
|
238
|
-
|
|
227
|
+
constitute.Dependencies(Namespace, Config, Logger, HttpClient)(TraceMiddleware);
|
|
239
228
|
|
|
240
|
-
|
|
241
|
-
//# sourceMappingURL=trace.js.map
|
|
229
|
+
export default TraceMiddleware;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import Joi from 'joi';
|
|
2
|
+
import constitute from 'constitute';
|
|
3
|
+
import wrapper from '../utils/wrapper.js';
|
|
4
|
+
import { FormInvalidateException } from '../exceptions/index.js';
|
|
5
|
+
import ValidatorBase from '../services/joi.js';
|
|
6
|
+
|
|
7
|
+
const validate = (data, schema, options) => {
|
|
8
|
+
const validationOptions = Object.assign(
|
|
9
|
+
{ abortEarly: false, allowUnknown: true },
|
|
10
|
+
options
|
|
11
|
+
);
|
|
12
|
+
if (schema && typeof schema.validateAsync === 'function') {
|
|
13
|
+
return schema.validateAsync(data, validationOptions);
|
|
14
|
+
}
|
|
15
|
+
return new Promise((resolve, reject) => {
|
|
16
|
+
Joi.validate(data, schema, validationOptions, (err, value) => {
|
|
17
|
+
if (err) reject(err);
|
|
18
|
+
else resolve(value);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @returns {function()}
|
|
25
|
+
* @constructor
|
|
26
|
+
*/
|
|
27
|
+
function ValidatorMiddleware(validatorBase) {
|
|
28
|
+
return (getSchema, options, validator) =>
|
|
29
|
+
wrapper(async (req, res, next) => {
|
|
30
|
+
const { query, body, path } = getSchema(validator || validatorBase.getJoi());
|
|
31
|
+
try {
|
|
32
|
+
if (query) {
|
|
33
|
+
await validate(req.query, query, options);
|
|
34
|
+
}
|
|
35
|
+
if (body) {
|
|
36
|
+
await validate(req.body, body, options);
|
|
37
|
+
}
|
|
38
|
+
if (path) {
|
|
39
|
+
await validate(req.params, path, options);
|
|
40
|
+
}
|
|
41
|
+
return next();
|
|
42
|
+
} catch (e) {
|
|
43
|
+
throw new FormInvalidateException(e);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
constitute.Dependencies(ValidatorBase)(ValidatorMiddleware);
|
|
49
|
+
|
|
50
|
+
export default ValidatorMiddleware;
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import constitute from 'constitute';
|
|
2
|
+
import crypto from 'crypto';
|
|
3
|
+
import util from 'util';
|
|
4
|
+
import moment from 'moment-timezone';
|
|
5
|
+
import Logger from '../services/logger.js';
|
|
6
|
+
import Cache from '../services/cache.js';
|
|
7
|
+
import wrapper from '../utils/wrapper.js';
|
|
8
|
+
import { RuntimeException } from '../exceptions/index.js';
|
|
9
|
+
|
|
10
|
+
export const defaultHashStrategy = obj => obj;
|
|
11
|
+
|
|
12
|
+
export const defaultHeadersFilter = (res) => {
|
|
13
|
+
const headers = [];
|
|
14
|
+
['Content-Type'].forEach((key) => {
|
|
15
|
+
const value = res.get(key);
|
|
16
|
+
if (value) {
|
|
17
|
+
headers.push([key, value]);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
return headers;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const requestToCacheKey = (req, hashStrategy) => {
|
|
24
|
+
const {
|
|
25
|
+
method,
|
|
26
|
+
originalUrl,
|
|
27
|
+
query: originQuery,
|
|
28
|
+
route,
|
|
29
|
+
uid = null //Custom rule
|
|
30
|
+
} = req;
|
|
31
|
+
const query = { ...originQuery };
|
|
32
|
+
delete query.flush;
|
|
33
|
+
if (hashStrategy && typeof hashStrategy !== 'function') {
|
|
34
|
+
throw new RuntimeException(`View cache hash strategy must be a function for ${originalUrl}`);
|
|
35
|
+
}
|
|
36
|
+
if (!route) {
|
|
37
|
+
throw new RuntimeException(`View cache middleware require route for ${originalUrl}`);
|
|
38
|
+
}
|
|
39
|
+
if (method.toLowerCase() !== 'get') {
|
|
40
|
+
throw new RuntimeException(`View cache middleware only support GET method of http request for ${originalUrl}`);
|
|
41
|
+
}
|
|
42
|
+
const { host = 'unknown' } = req.headers;
|
|
43
|
+
const [urlPath = ''] = originalUrl.split('?');
|
|
44
|
+
const key = [method, `/${host}`, urlPath].join('').replace(/:/g, '_').toLowerCase();
|
|
45
|
+
const strategy = hashStrategy || defaultHashStrategy;
|
|
46
|
+
const hash = crypto
|
|
47
|
+
.createHash('md5')
|
|
48
|
+
.update(JSON
|
|
49
|
+
.stringify(strategy({
|
|
50
|
+
method,
|
|
51
|
+
urlPath,
|
|
52
|
+
query,
|
|
53
|
+
uid
|
|
54
|
+
})))
|
|
55
|
+
.digest('hex');
|
|
56
|
+
return [key, hash].join(':');
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @param {Cache} cache
|
|
62
|
+
* @param {Logger} logger
|
|
63
|
+
* @returns {function(*=)}
|
|
64
|
+
* @constructor
|
|
65
|
+
*/
|
|
66
|
+
function ViewCacheMiddleware(cache, logger) {
|
|
67
|
+
return (options = {}) => {
|
|
68
|
+
if (!util.isObject(options)) {
|
|
69
|
+
options = {
|
|
70
|
+
ttl: options
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
const {
|
|
74
|
+
ttl,
|
|
75
|
+
headersFilter,
|
|
76
|
+
namespace,
|
|
77
|
+
hashStrategy
|
|
78
|
+
} = Object.assign({
|
|
79
|
+
ttl: 60,
|
|
80
|
+
headersFilter: defaultHeadersFilter,
|
|
81
|
+
hashStrategy: defaultHashStrategy,
|
|
82
|
+
namespace: 'view'
|
|
83
|
+
}, options);
|
|
84
|
+
return wrapper(async (req, res, next) => {
|
|
85
|
+
const cacheKey = requestToCacheKey(req, hashStrategy);
|
|
86
|
+
const {
|
|
87
|
+
headers: cachedHeaders = [],
|
|
88
|
+
body: cachedBody
|
|
89
|
+
} = await cache.namespace(namespace).get(cacheKey)
|
|
90
|
+
|| {
|
|
91
|
+
headers: [],
|
|
92
|
+
body: null
|
|
93
|
+
};
|
|
94
|
+
if (req.query.flush !== 'true' && cachedBody) {
|
|
95
|
+
logger.debug('View cache hit by key %s', cacheKey);
|
|
96
|
+
if (cachedHeaders.length > 0) {
|
|
97
|
+
cachedHeaders.forEach(([key, value]) => {
|
|
98
|
+
res.setHeader(key, value);
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
res.setHeader('X-View-Cache-Hit', cacheKey);
|
|
102
|
+
res.send(cachedBody);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
res.realSend = res.send;
|
|
106
|
+
res.send = (body) => {
|
|
107
|
+
logger.debug('View cache missed by key %s, creating...', cacheKey);
|
|
108
|
+
res.setHeader('X-View-Cache-Miss', cacheKey);
|
|
109
|
+
res.setHeader('X-View-Cache-Expire-At', moment().add(ttl, 'minute').format('YYYY-MM-DD HH:mm:ss Z'));
|
|
110
|
+
res.setHeader('X-View-Cache-Created-At', moment().format('YYYY-MM-DD HH:mm:ss Z'));
|
|
111
|
+
res.realSend(body);
|
|
112
|
+
const headers = headersFilter && typeof headersFilter === 'function' ?
|
|
113
|
+
headersFilter(res) : defaultHeadersFilter(res);
|
|
114
|
+
if (res.statusCode <= 500) {
|
|
115
|
+
cache.namespace(namespace).set(cacheKey, { headers, body }, ttl).catch((e) => {
|
|
116
|
+
logger.error('View cache set failed for %s', cacheKey, e);
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
next();
|
|
121
|
+
});
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
constitute.Dependencies(Cache, Logger)(ViewCacheMiddleware);
|
|
126
|
+
|
|
127
|
+
export default ViewCacheMiddleware;
|