badmfck-api-server 3.0.2 → 3.0.4
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/dist/apiServer/APIService.js +12 -5
- package/dist/apiServer/DBService.d.ts +12 -0
- package/dist/apiServer/DBService.js +81 -1
- package/dist/apiServer/LogService.d.ts +9 -5
- package/dist/apiServer/LogService.js +12 -6
- package/dist/apiServer/db/IDBAdapter.d.ts +3 -0
- package/dist/apiServer/db/MysqlAdapter.d.ts +4 -1
- package/dist/apiServer/db/MysqlAdapter.js +96 -16
- package/dist/apiServer/external/ExternalService.js +4 -4
- package/dist/apiServer/helper/Validator.js +6 -0
- package/dist/apiServer/structures/DefaultErrors.js +1 -1
- package/package.json +1 -1
@@ -43,10 +43,10 @@ const os_1 = __importDefault(require("os"));
|
|
43
43
|
const Liveness_1 = require("./routes/Liveness");
|
44
44
|
const Readiness_1 = require("./routes/Readiness");
|
45
45
|
const http_1 = __importDefault(require("http"));
|
46
|
-
const MysqlService_1 = require("./MysqlService");
|
47
46
|
const StatService_1 = require("./StatService");
|
48
47
|
const ExternalServiceEndpoint_1 = require("./external/ExternalServiceEndpoint");
|
49
48
|
const MonitorService_1 = require("./MonitorService");
|
49
|
+
const MysqlAdapter_1 = require("./db/MysqlAdapter");
|
50
50
|
function getDefaultOptions() {
|
51
51
|
return {
|
52
52
|
port: 8091,
|
@@ -57,7 +57,7 @@ function getDefaultOptions() {
|
|
57
57
|
endpoints: [],
|
58
58
|
jsonLimit: "10mb",
|
59
59
|
onNetworkLog: function (log) {
|
60
|
-
(0, LogService_1.
|
60
|
+
(0, LogService_1.logAPI)("${APIService.js}", log);
|
61
61
|
},
|
62
62
|
onError: function (err) {
|
63
63
|
(0, LogService_1.logError)("${APIService.js}", err);
|
@@ -89,7 +89,7 @@ async function Initializer(services) {
|
|
89
89
|
exports.Initializer = Initializer;
|
90
90
|
class APIService extends BaseService_1.BaseService {
|
91
91
|
static nextLogID = 0;
|
92
|
-
version = "3.0.
|
92
|
+
version = "3.0.4";
|
93
93
|
options;
|
94
94
|
monitor = null;
|
95
95
|
monitorIndexFile;
|
@@ -252,8 +252,10 @@ class APIService extends BaseService_1.BaseService {
|
|
252
252
|
details = e.message;
|
253
253
|
stack = [e];
|
254
254
|
}
|
255
|
-
if ((0,
|
256
|
-
details
|
255
|
+
if ((0, MysqlAdapter_1.isError)(e)) {
|
256
|
+
this.sendResponse(req.get("Referer") ?? "", res, { error: { ...DefaultErrors_1.default.DB_ERROR, details: e.message } }, tme, ep, log, httpRequest);
|
257
|
+
return;
|
258
|
+
}
|
257
259
|
this.sendResponse(req.get("Referer") ?? "", res, { error: { code: 10002, message: "Internal server error", stack: stack, details: details }, data: null, httpStatus: 500 }, tme, ep, log, httpRequest);
|
258
260
|
return;
|
259
261
|
}
|
@@ -308,6 +310,11 @@ class APIService extends BaseService_1.BaseService {
|
|
308
310
|
};
|
309
311
|
if (DefaultErrors_1.ErrorUtils.isError(e))
|
310
312
|
data = { error: e };
|
313
|
+
if ((0, MysqlAdapter_1.isError)(e)) {
|
314
|
+
data = {
|
315
|
+
error: { ...DefaultErrors_1.default.DB_ERROR, details: e.message }
|
316
|
+
};
|
317
|
+
}
|
311
318
|
this.sendResponse(req.get("Referer") ?? "", res, data, tme, ep, log, httpRequest);
|
312
319
|
return;
|
313
320
|
}
|
@@ -66,12 +66,24 @@ export interface DBAdapterOptions {
|
|
66
66
|
}
|
67
67
|
export declare const REQ_DB: Req<IDBQuery, IDBResult>;
|
68
68
|
export declare const REQ_DBX: Req<IDBBulkQuery, IDBResult[]>;
|
69
|
+
export declare const REQ_DB_TBEGIN: Req<{
|
70
|
+
dbid: string;
|
71
|
+
}, IDBResult>;
|
72
|
+
export declare const REQ_DB_TCOMMIT: Req<{
|
73
|
+
dbid: string;
|
74
|
+
trxid: number;
|
75
|
+
}, IDBResult>;
|
76
|
+
export declare const REQ_DB_TROLLBACK: Req<{
|
77
|
+
dbid: string;
|
78
|
+
trxid: number;
|
79
|
+
}, IDBResult>;
|
69
80
|
export declare class DBService extends BaseService {
|
70
81
|
static allInstances: DBService[];
|
71
82
|
options: IDBSericeOptions;
|
72
83
|
adapter: IDBAdapter | null;
|
73
84
|
constructor(options: IDBSericeOptions);
|
74
85
|
init(): Promise<void>;
|
86
|
+
getAdapter(dbid?: string | null): IDBAdapter | IDBError;
|
75
87
|
finishService(): Promise<void>;
|
76
88
|
createMysqlDatabase(): Promise<void>;
|
77
89
|
}
|
@@ -1,11 +1,14 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.DBService = exports.REQ_DBX = exports.REQ_DB = void 0;
|
3
|
+
exports.DBService = exports.REQ_DB_TROLLBACK = exports.REQ_DB_TCOMMIT = exports.REQ_DB_TBEGIN = exports.REQ_DBX = exports.REQ_DB = void 0;
|
4
4
|
const badmfck_signal_1 = require("badmfck-signal");
|
5
5
|
const BaseService_1 = require("./BaseService");
|
6
6
|
const MysqlAdapter_1 = require("./db/MysqlAdapter");
|
7
7
|
exports.REQ_DB = new badmfck_signal_1.Req(undefined, "REQ_DB");
|
8
8
|
exports.REQ_DBX = new badmfck_signal_1.Req(undefined, "REQ_DBX");
|
9
|
+
exports.REQ_DB_TBEGIN = new badmfck_signal_1.Req(undefined, "REQ_DB_TBEGIN");
|
10
|
+
exports.REQ_DB_TCOMMIT = new badmfck_signal_1.Req(undefined, "REQ_DB_TBEGIN");
|
11
|
+
exports.REQ_DB_TROLLBACK = new badmfck_signal_1.Req(undefined, "REQ_DB_TBEGIN");
|
9
12
|
class DBService extends BaseService_1.BaseService {
|
10
13
|
static allInstances = [];
|
11
14
|
options;
|
@@ -49,6 +52,66 @@ class DBService extends BaseService_1.BaseService {
|
|
49
52
|
}
|
50
53
|
return result;
|
51
54
|
};
|
55
|
+
exports.REQ_DB_TBEGIN.listener = async (req) => {
|
56
|
+
const adapter = this.getAdapter(req.dbid);
|
57
|
+
if ("errno" in adapter) {
|
58
|
+
return {
|
59
|
+
error: adapter
|
60
|
+
};
|
61
|
+
}
|
62
|
+
if (adapter.tBegin && typeof adapter.tBegin === "function")
|
63
|
+
return await adapter.tBegin();
|
64
|
+
return {
|
65
|
+
error: {
|
66
|
+
errno: -10,
|
67
|
+
code: "TRX_NOT_SUPPORTED",
|
68
|
+
fatal: true,
|
69
|
+
sql: "START TRANSACTION",
|
70
|
+
name: "TRX_NOT_SUPPORTED",
|
71
|
+
message: "Transactions not supported on selected adapter"
|
72
|
+
}
|
73
|
+
};
|
74
|
+
};
|
75
|
+
exports.REQ_DB_TCOMMIT.listener = async (req) => {
|
76
|
+
const adapter = this.getAdapter(req.dbid);
|
77
|
+
if ("errno" in adapter) {
|
78
|
+
return {
|
79
|
+
error: adapter
|
80
|
+
};
|
81
|
+
}
|
82
|
+
if (adapter.tCommit && typeof adapter.tCommit === "function")
|
83
|
+
return await adapter.tCommit(req.trxid);
|
84
|
+
return {
|
85
|
+
error: {
|
86
|
+
errno: -10,
|
87
|
+
code: "TRX_NOT_SUPPORTED",
|
88
|
+
fatal: true,
|
89
|
+
sql: "COMMIT",
|
90
|
+
name: "TRX_NOT_SUPPORTED",
|
91
|
+
message: "Transactions not supported on selected adapter"
|
92
|
+
}
|
93
|
+
};
|
94
|
+
};
|
95
|
+
exports.REQ_DB_TROLLBACK.listener = async (req) => {
|
96
|
+
const adapter = this.getAdapter(req.dbid);
|
97
|
+
if ("errno" in adapter) {
|
98
|
+
return {
|
99
|
+
error: adapter
|
100
|
+
};
|
101
|
+
}
|
102
|
+
if (adapter.tRollback && typeof adapter.tRollback === "function")
|
103
|
+
return await adapter.tRollback(req.trxid);
|
104
|
+
return {
|
105
|
+
error: {
|
106
|
+
errno: -10,
|
107
|
+
code: "TRX_NOT_SUPPORTED",
|
108
|
+
fatal: true,
|
109
|
+
sql: "ROLLBACK",
|
110
|
+
name: "TRX_NOT_SUPPORTED",
|
111
|
+
message: "Transactions not supported on selected adapter"
|
112
|
+
}
|
113
|
+
};
|
114
|
+
};
|
52
115
|
exports.REQ_DB.listener = async (req) => {
|
53
116
|
if (!req.dbid && DBService.allInstances.length === 1 && DBService.allInstances[0].adapter)
|
54
117
|
return DBService.allInstances[0].adapter.query(req);
|
@@ -69,6 +132,23 @@ class DBService extends BaseService_1.BaseService {
|
|
69
132
|
return { error: error };
|
70
133
|
};
|
71
134
|
}
|
135
|
+
getAdapter(dbid) {
|
136
|
+
if (!dbid && DBService.allInstances.length === 1 && DBService.allInstances[0].adapter)
|
137
|
+
return DBService.allInstances[0].adapter;
|
138
|
+
for (let i of DBService.allInstances) {
|
139
|
+
if (i.options.id === dbid && i.adapter)
|
140
|
+
return i.adapter;
|
141
|
+
}
|
142
|
+
const error = {
|
143
|
+
code: "DB_NOT_FOUND",
|
144
|
+
errno: -1,
|
145
|
+
fatal: true,
|
146
|
+
sql: "",
|
147
|
+
name: "DB_NOT_FOUND",
|
148
|
+
message: "DB not found: " + dbid
|
149
|
+
};
|
150
|
+
return error;
|
151
|
+
}
|
72
152
|
async finishService() {
|
73
153
|
await this.adapter?.finish();
|
74
154
|
}
|
@@ -1,11 +1,13 @@
|
|
1
1
|
import Signal, { Req } from "badmfck-signal";
|
2
2
|
import { BaseService } from "./BaseService";
|
3
3
|
export declare enum LOG_LEVEL {
|
4
|
-
ALL =
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
ALL = 10,
|
5
|
+
API = 19,
|
6
|
+
INFO = 20,
|
7
|
+
DB = 25,
|
8
|
+
WARN = 30,
|
9
|
+
ERROR = 40,
|
10
|
+
CRIT = 50
|
9
11
|
}
|
10
12
|
export interface ILogItem {
|
11
13
|
id: number;
|
@@ -27,6 +29,8 @@ export declare const logInfo: (message: any, ...optional: any[]) => void;
|
|
27
29
|
export declare const logWarn: (message: any, ...optional: any[]) => void;
|
28
30
|
export declare const logCrit: (message: any, ...optional: any[]) => void;
|
29
31
|
export declare const logError: (message: any, ...optional: any[]) => void;
|
32
|
+
export declare const logDB: (message: any, ...optional: any[]) => void;
|
33
|
+
export declare const logAPI: (message: any, ...optional: any[]) => void;
|
30
34
|
export declare const S_LOG: Signal<{
|
31
35
|
level: LOG_LEVEL;
|
32
36
|
data: any[];
|
@@ -23,16 +23,18 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
23
23
|
return result;
|
24
24
|
};
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
26
|
-
exports.LogService = exports.REQ_LOG_UNIQUE_SERVICES = exports.REQ_LOG = exports.S_LOG_SET_TEXT_LIMIT = exports.S_LOG_REMOVE_SERVICE_FROM_WATCH = exports.S_LOG_ADD_SERVICE_TO_WATCH = exports.S_LOG_FLUSH = exports.S_LOG_CHANGE_LEVEL = exports.S_LOG_CREATED = exports.S_LOG = exports.logError = exports.logCrit = exports.logWarn = exports.logInfo = exports.getDefaultLogOptions = exports.LOG_LEVEL = void 0;
|
26
|
+
exports.LogService = exports.REQ_LOG_UNIQUE_SERVICES = exports.REQ_LOG = exports.S_LOG_SET_TEXT_LIMIT = exports.S_LOG_REMOVE_SERVICE_FROM_WATCH = exports.S_LOG_ADD_SERVICE_TO_WATCH = exports.S_LOG_FLUSH = exports.S_LOG_CHANGE_LEVEL = exports.S_LOG_CREATED = exports.S_LOG = exports.logAPI = exports.logDB = exports.logError = exports.logCrit = exports.logWarn = exports.logInfo = exports.getDefaultLogOptions = exports.LOG_LEVEL = void 0;
|
27
27
|
const badmfck_signal_1 = __importStar(require("badmfck-signal"));
|
28
28
|
const BaseService_1 = require("./BaseService");
|
29
29
|
var LOG_LEVEL;
|
30
30
|
(function (LOG_LEVEL) {
|
31
|
-
LOG_LEVEL[LOG_LEVEL["ALL"] =
|
32
|
-
LOG_LEVEL[LOG_LEVEL["
|
33
|
-
LOG_LEVEL[LOG_LEVEL["
|
34
|
-
LOG_LEVEL[LOG_LEVEL["
|
35
|
-
LOG_LEVEL[LOG_LEVEL["
|
31
|
+
LOG_LEVEL[LOG_LEVEL["ALL"] = 10] = "ALL";
|
32
|
+
LOG_LEVEL[LOG_LEVEL["API"] = 19] = "API";
|
33
|
+
LOG_LEVEL[LOG_LEVEL["INFO"] = 20] = "INFO";
|
34
|
+
LOG_LEVEL[LOG_LEVEL["DB"] = 25] = "DB";
|
35
|
+
LOG_LEVEL[LOG_LEVEL["WARN"] = 30] = "WARN";
|
36
|
+
LOG_LEVEL[LOG_LEVEL["ERROR"] = 40] = "ERROR";
|
37
|
+
LOG_LEVEL[LOG_LEVEL["CRIT"] = 50] = "CRIT";
|
36
38
|
})(LOG_LEVEL || (exports.LOG_LEVEL = LOG_LEVEL = {}));
|
37
39
|
const getDefaultLogOptions = () => {
|
38
40
|
return {
|
@@ -50,6 +52,10 @@ const logCrit = (message, ...optional) => { exports.S_LOG.invoke({ level: LOG_LE
|
|
50
52
|
exports.logCrit = logCrit;
|
51
53
|
const logError = (message, ...optional) => { exports.S_LOG.invoke({ level: LOG_LEVEL.ERROR, data: [message, optional] }); };
|
52
54
|
exports.logError = logError;
|
55
|
+
const logDB = (message, ...optional) => { exports.S_LOG.invoke({ level: LOG_LEVEL.DB, data: [message, optional] }); };
|
56
|
+
exports.logDB = logDB;
|
57
|
+
const logAPI = (message, ...optional) => { exports.S_LOG.invoke({ level: LOG_LEVEL.API, data: [message, optional] }); };
|
58
|
+
exports.logAPI = logAPI;
|
53
59
|
exports.S_LOG = new badmfck_signal_1.default();
|
54
60
|
exports.S_LOG_CREATED = new badmfck_signal_1.default();
|
55
61
|
exports.S_LOG_CHANGE_LEVEL = new badmfck_signal_1.default();
|
@@ -2,6 +2,9 @@ import { IDBBulkQuery, IDBQuery, IDBResult } from "../DBService";
|
|
2
2
|
export interface IDBAdapter {
|
3
3
|
init(): Promise<void>;
|
4
4
|
finish(): Promise<void>;
|
5
|
+
tBegin?(): Promise<IDBResult>;
|
6
|
+
tCommit?(trxid: number): Promise<IDBResult>;
|
7
|
+
tRollback?(trxid: number): Promise<IDBResult>;
|
5
8
|
prepareQuery(request: IDBQuery): string;
|
6
9
|
query(request: IDBQuery): Promise<IDBResult>;
|
7
10
|
bulk(request: IDBBulkQuery): Promise<IDBResult[]>;
|
@@ -34,6 +34,9 @@ export declare class MysqlAdapter implements IDBAdapter {
|
|
34
34
|
init(): Promise<void>;
|
35
35
|
setupTimers(): void;
|
36
36
|
recreatePool(): Promise<boolean>;
|
37
|
+
tBegin(): Promise<IDBResult>;
|
38
|
+
tCommit(trxid: number): Promise<IDBResult>;
|
39
|
+
tRollback(trxid: number): Promise<IDBResult>;
|
37
40
|
bulk(request: IDBBulkQuery): Promise<IDBResult[]>;
|
38
41
|
getConnection(transactionId?: number): Promise<mysql.PoolConnection | IDBError>;
|
39
42
|
query(request: IDBQuery, conn?: mysql.PoolConnection): Promise<IDBResult>;
|
@@ -46,6 +49,6 @@ export declare class MysqlAdapter implements IDBAdapter {
|
|
46
49
|
finish(): Promise<void>;
|
47
50
|
createMysqlQueryError(err: any, throwable?: boolean): IDBError;
|
48
51
|
storeTransactionAsProblem(trx: ITransaction, message: string): Promise<void>;
|
49
|
-
isError(obj: any): obj is IDBError;
|
50
52
|
}
|
53
|
+
export declare function isError(obj: any): obj is IDBError;
|
51
54
|
export {};
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
4
|
};
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
exports.MysqlAdapter = void 0;
|
6
|
+
exports.isError = exports.MysqlAdapter = void 0;
|
7
7
|
const promise_1 = __importDefault(require("mysql2/promise"));
|
8
8
|
const fs_1 = __importDefault(require("fs"));
|
9
9
|
const LogService_1 = require("../LogService");
|
@@ -107,7 +107,7 @@ class MysqlAdapter {
|
|
107
107
|
keepAliveInitialDelay: 3 * 1000,
|
108
108
|
idleTimeout: 1000 * 60 * 5
|
109
109
|
};
|
110
|
-
(0, LogService_1.
|
110
|
+
(0, LogService_1.logDB)("${MysqlAdapter.js}", "Connecting to mysql: \n " + JSON.stringify({ ...opt, password: "****" }, null, "\t"));
|
111
111
|
if (this.pool) {
|
112
112
|
this.pool.removeAllListeners();
|
113
113
|
try {
|
@@ -129,21 +129,21 @@ class MysqlAdapter {
|
|
129
129
|
this.acquiredPoolConnections = 0;
|
130
130
|
this.pool?.on('connection', (connection) => {
|
131
131
|
if (this.options.debug)
|
132
|
-
(0, LogService_1.
|
132
|
+
(0, LogService_1.logDB)("MysqlAdapter", "pool -> connection created, total:" + this.poolConnections++);
|
133
133
|
});
|
134
134
|
this.pool?.on('acquire', (connection) => {
|
135
135
|
this.acquiredPoolConnections++;
|
136
136
|
if (this.options.debug)
|
137
|
-
(0, LogService_1.
|
137
|
+
(0, LogService_1.logDB)("MysqlAdapter", "pool -> connection acquire, busy:" + this.acquiredPoolConnections);
|
138
138
|
});
|
139
139
|
this.pool?.on('release', (connection) => {
|
140
140
|
this.acquiredPoolConnections--;
|
141
141
|
if (this.options.debug)
|
142
|
-
(0, LogService_1.
|
142
|
+
(0, LogService_1.logDB)("MysqlAdapter", "pool -> connection release, busy:" + this.acquiredPoolConnections);
|
143
143
|
});
|
144
144
|
this.pool?.on('enqueue', () => {
|
145
145
|
if (this.options.debug)
|
146
|
-
(0, LogService_1.
|
146
|
+
(0, LogService_1.logDB)("MysqlAdapter", "pool -> waiting for available connection");
|
147
147
|
});
|
148
148
|
if (this.options.debug)
|
149
149
|
console.log("Check mysql connection");
|
@@ -154,13 +154,92 @@ class MysqlAdapter {
|
|
154
154
|
}
|
155
155
|
return true;
|
156
156
|
}
|
157
|
+
async tBegin() {
|
158
|
+
const conn = await this.getConnection();
|
159
|
+
if (isError(conn))
|
160
|
+
return { error: conn };
|
161
|
+
for (let i of this.transactions) {
|
162
|
+
if (i.conn === conn) {
|
163
|
+
(0, LogService_1.logError)("Selected connection is in transaction");
|
164
|
+
return {
|
165
|
+
error: {
|
166
|
+
errno: 100005,
|
167
|
+
code: "CONN_IN_TRX",
|
168
|
+
fatal: true,
|
169
|
+
sql: "START TRANSACTION",
|
170
|
+
name: "CONN_IN_TRX",
|
171
|
+
message: "Selected connection already in transaction"
|
172
|
+
}
|
173
|
+
};
|
174
|
+
}
|
175
|
+
}
|
176
|
+
const trxid = MysqlAdapter.nextTransactionID++;
|
177
|
+
if (this.options.debug)
|
178
|
+
(0, LogService_1.logDB)("Begin transaction with id ", trxid);
|
179
|
+
const result = await this.query({ query: "START TRANSACTIONS" }, conn);
|
180
|
+
const trxRequest = {
|
181
|
+
id: trxid,
|
182
|
+
timestamp: Date.now(),
|
183
|
+
conn: conn,
|
184
|
+
queries: []
|
185
|
+
};
|
186
|
+
if (result.error) {
|
187
|
+
trxRequest.queries.push({ sql: "START TRANSACTION", status: "error" });
|
188
|
+
this.rollbackTransaction(trxRequest);
|
189
|
+
return result;
|
190
|
+
}
|
191
|
+
trxRequest.queries.push({ sql: "START TRANSACTION", status: "ok" });
|
192
|
+
this.transactions.push(trxRequest);
|
193
|
+
if (this.options.debug)
|
194
|
+
console.log("Transactions pool: ", this.transactions);
|
195
|
+
return { data: { transactionId: trxid } };
|
196
|
+
}
|
197
|
+
async tCommit(trxid) {
|
198
|
+
const trx = this.transactions.find(i => i.id === trxid);
|
199
|
+
if (!trx) {
|
200
|
+
return {
|
201
|
+
error: {
|
202
|
+
code: "NO_TRX",
|
203
|
+
errno: 100004,
|
204
|
+
fatal: true,
|
205
|
+
sql: "",
|
206
|
+
name: "NO_TRX",
|
207
|
+
message: "Transaction not found",
|
208
|
+
}
|
209
|
+
};
|
210
|
+
}
|
211
|
+
if (this.options.debug)
|
212
|
+
(0, LogService_1.logDB)("Commit transaction:", trx.id);
|
213
|
+
this.transactions = this.transactions.filter(i => i.id !== trxid);
|
214
|
+
if (this.options.debug)
|
215
|
+
(0, LogService_1.logDB)("Transaction pool:", this.transactions);
|
216
|
+
const err = await this.commit(trx);
|
217
|
+
if (err)
|
218
|
+
return { error: err };
|
219
|
+
return { data: true };
|
220
|
+
}
|
221
|
+
async tRollback(trxid) {
|
222
|
+
const trx = this.transactions.find(i => i.id === trxid);
|
223
|
+
if (!trx) {
|
224
|
+
return { error: {
|
225
|
+
code: "NO_TRX",
|
226
|
+
errno: 100004,
|
227
|
+
fatal: true,
|
228
|
+
sql: "",
|
229
|
+
name: "NO_TRX",
|
230
|
+
message: "Transaction not found"
|
231
|
+
} };
|
232
|
+
}
|
233
|
+
await this.rollbackTransaction(trx);
|
234
|
+
return { data: true };
|
235
|
+
}
|
157
236
|
async bulk(request) {
|
158
237
|
const results = [];
|
159
238
|
let queries = [];
|
160
239
|
let conn = null;
|
161
240
|
if (request.queued) {
|
162
241
|
conn = await this.getConnection();
|
163
|
-
if (
|
242
|
+
if (isError(conn)) {
|
164
243
|
for (let i of request.bulk)
|
165
244
|
results.push({ data: null, error: conn });
|
166
245
|
return results;
|
@@ -210,15 +289,15 @@ class MysqlAdapter {
|
|
210
289
|
if (transactionId && transactionId > 0) {
|
211
290
|
conn = this.transactions.find(i => i.id === transactionId)?.conn ?? null;
|
212
291
|
if (this.options.debug)
|
213
|
-
|
292
|
+
(0, LogService_1.logDB)("Execute query on transaction: ", conn?.threadId);
|
214
293
|
}
|
215
294
|
else
|
216
295
|
conn = await this.pool.getConnection();
|
217
296
|
if (this.options.debug) {
|
218
|
-
|
297
|
+
(0, LogService_1.logDB)("Pool status: ", this.poolConnections, this.acquiredPoolConnections);
|
219
298
|
}
|
220
299
|
if (this.options.debug)
|
221
|
-
|
300
|
+
(0, LogService_1.logDB)("Execute query", conn?.threadId);
|
222
301
|
if (conn)
|
223
302
|
return conn;
|
224
303
|
}
|
@@ -248,7 +327,7 @@ class MysqlAdapter {
|
|
248
327
|
if (!conn) {
|
249
328
|
doCloseConnection = true;
|
250
329
|
conn = await this.getConnection(request.transactionID ?? -1);
|
251
|
-
if (
|
330
|
+
if (isError(conn)) {
|
252
331
|
return {
|
253
332
|
data: null,
|
254
333
|
error: conn,
|
@@ -478,25 +557,26 @@ class MysqlAdapter {
|
|
478
557
|
this.failReportFileStreamName = file;
|
479
558
|
}
|
480
559
|
if (this.options.debug)
|
481
|
-
|
560
|
+
(0, LogService_1.logDB)("Store transaction fail report: ", file, trx.queries, message);
|
482
561
|
if (!this.failReportFileStream)
|
483
562
|
this.failReportFileStream = fs_1.default.createWriteStream(file, { flags: 'a' });
|
484
563
|
this.failReportFileStream.write(JSON.stringify({ queries: trx.queries, time: trx.timestamp, date, message }) + "\n}EOB{\n", err => {
|
485
564
|
if (err)
|
486
565
|
(0, LogService_1.logCrit)("MysqlAdapter", "Can't write to transaction fail report file");
|
487
566
|
else
|
488
|
-
(0, LogService_1.
|
567
|
+
(0, LogService_1.logDB)("MysqlAdapter", "Transaction fail report stored");
|
489
568
|
});
|
490
569
|
this.failReportLastAccessTime = Date.now();
|
491
570
|
}
|
492
571
|
if (this.options.transactionFailReport)
|
493
572
|
this.options.transactionFailReport(trx, message);
|
494
573
|
}
|
495
|
-
isError(obj) {
|
496
|
-
return obj && "code" in obj && "errno" in obj && "name" in obj && "message" in obj;
|
497
|
-
}
|
498
574
|
}
|
499
575
|
exports.MysqlAdapter = MysqlAdapter;
|
576
|
+
function isError(obj) {
|
577
|
+
return obj && "code" in obj && "errno" in obj && "name" in obj && "message" in obj;
|
578
|
+
}
|
579
|
+
exports.isError = isError;
|
500
580
|
const secret_key = "AKLWkajw%^&dgwqhw#98453i23bfk23rn2knknglrgjeit";
|
501
581
|
const secret_iv = "rthadrfk23rn2kn#*FNKA@gt44df3tslrgj##!it";
|
502
582
|
const key = (0, crypto_1.createHash)('sha512').update(secret_key).digest('hex').substring(0, 32);
|
@@ -45,18 +45,18 @@ exports.REQ_XT.listener = async ({ id, req }) => {
|
|
45
45
|
if (i.options.id === id)
|
46
46
|
return await i.onExternalCall(req);
|
47
47
|
}
|
48
|
-
return { error: { ...DefaultErrors_1.default.BAD_REQUEST, details: "no external service found" } };
|
48
|
+
return { error: { ...DefaultErrors_1.default.BAD_REQUEST, details: "no external service found: " + id } };
|
49
49
|
};
|
50
50
|
exports.REQ_EXTERNAL_CALL.listener = async ({ id, requestName, requestData }) => {
|
51
51
|
if (ExternalService.allInstances.length === 0) {
|
52
52
|
console.error("ExternalService.allInstances.length === 0");
|
53
|
-
return { ...DefaultErrors_1.default.BAD_REQUEST, details: "no external
|
53
|
+
return { ...DefaultErrors_1.default.BAD_REQUEST, details: "no external service found: " + id + ", requestName:" + requestName, stack: [requestData] };
|
54
54
|
}
|
55
55
|
for (let i of ExternalService.allInstances) {
|
56
56
|
if (i.options.id === id)
|
57
57
|
return await i.requestExternalCall({ id, requestName, requestData });
|
58
58
|
}
|
59
|
-
return { ...DefaultErrors_1.default.BAD_REQUEST, details: "no external service found" };
|
59
|
+
return { ...DefaultErrors_1.default.BAD_REQUEST, details: "no external service found: " + id + ", requestName:" + requestName, stack: [requestData] };
|
60
60
|
};
|
61
61
|
class ExternalService extends BaseService_1.BaseService {
|
62
62
|
static allInstances = [];
|
@@ -65,7 +65,7 @@ class ExternalService extends BaseService_1.BaseService {
|
|
65
65
|
super("ExternalService-" + opt.id);
|
66
66
|
for (let i of ExternalService.allInstances) {
|
67
67
|
if (i.options.id === opt.id)
|
68
|
-
throw { code: -1, message: "duplicate id" };
|
68
|
+
throw { code: -1, message: "ExternalService, duplicate id: " + i.options.id };
|
69
69
|
}
|
70
70
|
ExternalService.allInstances.push(this);
|
71
71
|
this.options = opt;
|
@@ -45,7 +45,12 @@ class Validator {
|
|
45
45
|
return result;
|
46
46
|
}
|
47
47
|
let errors = [];
|
48
|
+
let foundKeys = [];
|
48
49
|
for (let i in structure) {
|
50
|
+
if (structure[i] === null) {
|
51
|
+
foundKeys.push(i);
|
52
|
+
continue;
|
53
|
+
}
|
49
54
|
if (!(i in object))
|
50
55
|
errors.push("no field '" + i + "'");
|
51
56
|
if (typeof structure[i] === "number" && typeof object[i] === "string") {
|
@@ -110,6 +115,7 @@ class Validator {
|
|
110
115
|
}
|
111
116
|
}
|
112
117
|
}
|
118
|
+
foundKeys.push(i);
|
113
119
|
}
|
114
120
|
if (errors.length > 0)
|
115
121
|
return errors;
|
@@ -14,7 +14,7 @@ class DefaultErrors {
|
|
14
14
|
static SERVICE_NOT_WORKING = { code: 8, message: "Service not working" };
|
15
15
|
static TIMEOUT = { code: 9, message: "Timeout" };
|
16
16
|
static METHOD_NOT_ALLOWED = { code: 10, message: "Method not allowed", httpStatus: 405 };
|
17
|
-
static DB_ERROR = { code: 11, message: "DB error" };
|
17
|
+
static DB_ERROR = { code: 11, message: "DB error", httpStatus: 500 };
|
18
18
|
}
|
19
19
|
class ErrorUtils {
|
20
20
|
static isError(obj) {
|