@axinom/mosaic-db-common 0.11.0 → 0.12.0-rc.10
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/auth/index.d.ts +1 -0
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +1 -0
- package/dist/auth/index.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/middleware/pg-pool.middleware.d.ts +28 -0
- package/dist/middleware/pg-pool.middleware.d.ts.map +1 -1
- package/dist/middleware/pg-pool.middleware.js +43 -2
- package/dist/middleware/pg-pool.middleware.js.map +1 -1
- package/dist/monitoring/index.d.ts +2 -0
- package/dist/monitoring/index.d.ts.map +1 -0
- package/dist/monitoring/index.js +14 -0
- package/dist/monitoring/index.js.map +1 -0
- package/dist/monitoring/postgres-metrics.d.ts +14 -0
- package/dist/monitoring/postgres-metrics.d.ts.map +1 -0
- package/dist/monitoring/postgres-metrics.js +35 -0
- package/dist/monitoring/postgres-metrics.js.map +1 -0
- package/migrations/before-migration/005-created-updated-triggers.sql +6 -0
- package/migrations/define/define-functions.sql +2 -2
- package/migrations/define/define-multitenancy-functions.sql +111 -0
- package/package.json +3 -2
package/dist/auth/index.d.ts
CHANGED
package/dist/auth/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,WAAW,CAAC"}
|
package/dist/auth/index.js
CHANGED
|
@@ -10,5 +10,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
10
10
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
11
|
};
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
__exportStar(require("./authentication-subject"), exports);
|
|
13
14
|
__exportStar(require("./helpers"), exports);
|
|
14
15
|
//# sourceMappingURL=index.js.map
|
package/dist/auth/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,4CAA0B"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2DAAyC;AACzC,4CAA0B"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export * from './auth';
|
|
2
|
+
export * from './common';
|
|
2
3
|
export * from './constants';
|
|
3
4
|
export * from './messaging';
|
|
4
5
|
export * from './middleware';
|
|
5
6
|
export * from './migrations';
|
|
7
|
+
export * from './monitoring';
|
|
6
8
|
export * from './zapatos';
|
|
7
9
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -11,9 +11,11 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
11
11
|
};
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
13
|
__exportStar(require("./auth"), exports);
|
|
14
|
+
__exportStar(require("./common"), exports);
|
|
14
15
|
__exportStar(require("./constants"), exports);
|
|
15
16
|
__exportStar(require("./messaging"), exports);
|
|
16
17
|
__exportStar(require("./middleware"), exports);
|
|
17
18
|
__exportStar(require("./migrations"), exports);
|
|
19
|
+
__exportStar(require("./monitoring"), exports);
|
|
18
20
|
__exportStar(require("./zapatos"), exports);
|
|
19
21
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,yCAAuB;AACvB,8CAA4B;AAC5B,8CAA4B;AAC5B,+CAA6B;AAC7B,+CAA6B;AAC7B,4CAA0B"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,yCAAuB;AACvB,2CAAyB;AACzB,8CAA4B;AAC5B,8CAA4B;AAC5B,+CAA6B;AAC7B,+CAA6B;AAC7B,+CAA6B;AAC7B,4CAA0B"}
|
|
@@ -1,21 +1,49 @@
|
|
|
1
1
|
import { Application, Express } from 'express';
|
|
2
2
|
import { Pool } from 'pg';
|
|
3
3
|
import { DbLogger, DbShutdownActions } from '../common';
|
|
4
|
+
/**
|
|
5
|
+
* Creates a PostgreSQL Pool for a given connection string, and returns it.
|
|
6
|
+
*
|
|
7
|
+
* @param connectionString
|
|
8
|
+
* @param poolLabel
|
|
9
|
+
* @param logger
|
|
10
|
+
* @param shutdownActions
|
|
11
|
+
* @returns
|
|
12
|
+
*/
|
|
13
|
+
export declare const createPgPool: (connectionString: string, poolLabel: string, logger: DbLogger, shutdownActions: DbShutdownActions) => Pool;
|
|
4
14
|
/**
|
|
5
15
|
* Returns the previously set up PostgreSQL pool for the database owner. The owner pool has full access to the database.
|
|
6
16
|
* @param app express app
|
|
7
17
|
*/
|
|
8
18
|
export declare const getOwnerPgPool: (app: Express | Application) => Pool;
|
|
19
|
+
/**
|
|
20
|
+
* Sets a given pool as the Owner Pool for an Express Application
|
|
21
|
+
* @param app
|
|
22
|
+
* @param ownerPool
|
|
23
|
+
*/
|
|
24
|
+
export declare const setOwnerPgPool: (app: Application, ownerPool: Pool) => void;
|
|
9
25
|
/**
|
|
10
26
|
* Returns the previously set up PostgreSQL pool for the environment owner. The environment owner cannot bypass Row Level Security and database requests will only operate on specific tenant and environment rows.
|
|
11
27
|
* @param app express app
|
|
12
28
|
*/
|
|
13
29
|
export declare const getEnvOwnerPgPool: (app: Express | Application) => Pool;
|
|
30
|
+
/**
|
|
31
|
+
* Sets a given pool as the Environment Owner Pool for an Express Application
|
|
32
|
+
* @param app
|
|
33
|
+
* @param envOwnerPool
|
|
34
|
+
*/
|
|
35
|
+
export declare const setEnvOwnerPgPool: (app: Application, envOwnerPool: Pool) => void;
|
|
14
36
|
/**
|
|
15
37
|
* Returns the previously set up PostgreSQL pool for the login user. The login pool is internally used by postgraphile to access the database via GraphQL API endpoints.
|
|
16
38
|
* @param app express app
|
|
17
39
|
*/
|
|
18
40
|
export declare const getLoginPgPool: (app: Express | Application) => Pool;
|
|
41
|
+
/**
|
|
42
|
+
* Sets a given pool as the Login Pool for an Express Application
|
|
43
|
+
* @param app
|
|
44
|
+
* @param loginPool
|
|
45
|
+
*/
|
|
46
|
+
export declare const setLoginPgPool: (app: Application, loginPool: Pool) => void;
|
|
19
47
|
/**
|
|
20
48
|
* Sets up a PostgreSQL pool for the owner to be reused by other app components. The owner pool has full access to the database.
|
|
21
49
|
* @param app express app
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pg-pool.middleware.d.ts","sourceRoot":"","sources":["../../src/middleware/pg-pool.middleware.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"pg-pool.middleware.d.ts","sourceRoot":"","sources":["../../src/middleware/pg-pool.middleware.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAoBxD;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,qBACL,MAAM,aACb,MAAM,UACT,QAAQ,mBACC,iBAAiB,KACjC,IAyBF,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,cAAc,QAAS,OAAO,GAAG,WAAW,KAAG,IAE3D,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,cAAc,QAAS,WAAW,aAAa,IAAI,KAAG,IAElE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,QAAS,OAAO,GAAG,WAAW,KAAG,IAE9D,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,QACvB,WAAW,gBACF,IAAI,KACjB,IAEF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,QAAS,OAAO,GAAG,WAAW,KAAG,IAE3D,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,cAAc,QAAS,WAAW,aAAa,IAAI,KAAG,IAElE,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,QACtB,OAAO,GAAG,WAAW,oBACR,MAAM,UAChB,QAAQ,mBACC,iBAAiB,KACjC,IASF,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,QACzB,OAAO,GAAG,WAAW,oBACR,MAAM,UAChB,QAAQ,mBACC,iBAAiB,KACjC,IASF,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,QACtB,OAAO,GAAG,WAAW,oBACR,MAAM,UAChB,QAAQ,mBACC,iBAAiB,KACjC,IASF,CAAC"}
|
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.setupLoginPgPool = exports.setupEnvOwnerPgPool = exports.setupOwnerPgPool = exports.getLoginPgPool = exports.getEnvOwnerPgPool = exports.getOwnerPgPool = void 0;
|
|
3
|
+
exports.setupLoginPgPool = exports.setupEnvOwnerPgPool = exports.setupOwnerPgPool = exports.setLoginPgPool = exports.getLoginPgPool = exports.setEnvOwnerPgPool = exports.getEnvOwnerPgPool = exports.setOwnerPgPool = exports.getOwnerPgPool = exports.createPgPool = void 0;
|
|
4
4
|
const pg_1 = require("pg");
|
|
5
5
|
const setupPgPool = (app, connectionString, poolKey, poolLabel, logger, shutdownActions) => {
|
|
6
|
+
const pgPool = (0, exports.createPgPool)(connectionString, poolLabel, logger, shutdownActions);
|
|
7
|
+
app.set(poolKey, pgPool);
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Creates a PostgreSQL Pool for a given connection string, and returns it.
|
|
11
|
+
*
|
|
12
|
+
* @param connectionString
|
|
13
|
+
* @param poolLabel
|
|
14
|
+
* @param logger
|
|
15
|
+
* @param shutdownActions
|
|
16
|
+
* @returns
|
|
17
|
+
*/
|
|
18
|
+
const createPgPool = (connectionString, poolLabel, logger, shutdownActions) => {
|
|
6
19
|
const pgPool = new pg_1.Pool({ connectionString });
|
|
7
20
|
// If a pg pool error happens and triggers the exit of node process (e.g postgres server stopped while postgraphile service is running) -
|
|
8
21
|
// it is possible for it to not be caught using this handler, because node process will close faster.
|
|
@@ -19,8 +32,9 @@ const setupPgPool = (app, connectionString, poolKey, poolLabel, logger, shutdown
|
|
|
19
32
|
logger.debug(`Shutting down ${poolLabel} PostgreSQL connection Pool.`);
|
|
20
33
|
pgPool.end();
|
|
21
34
|
});
|
|
22
|
-
|
|
35
|
+
return pgPool;
|
|
23
36
|
};
|
|
37
|
+
exports.createPgPool = createPgPool;
|
|
24
38
|
const ownerPoolKey = 'ownerPool';
|
|
25
39
|
const envOwnerPoolKey = 'envOwnerPool';
|
|
26
40
|
const loginPoolKey = 'loginPool';
|
|
@@ -32,6 +46,15 @@ const getOwnerPgPool = (app) => {
|
|
|
32
46
|
return app.get(ownerPoolKey);
|
|
33
47
|
};
|
|
34
48
|
exports.getOwnerPgPool = getOwnerPgPool;
|
|
49
|
+
/**
|
|
50
|
+
* Sets a given pool as the Owner Pool for an Express Application
|
|
51
|
+
* @param app
|
|
52
|
+
* @param ownerPool
|
|
53
|
+
*/
|
|
54
|
+
const setOwnerPgPool = (app, ownerPool) => {
|
|
55
|
+
app.set(ownerPoolKey, ownerPool);
|
|
56
|
+
};
|
|
57
|
+
exports.setOwnerPgPool = setOwnerPgPool;
|
|
35
58
|
/**
|
|
36
59
|
* Returns the previously set up PostgreSQL pool for the environment owner. The environment owner cannot bypass Row Level Security and database requests will only operate on specific tenant and environment rows.
|
|
37
60
|
* @param app express app
|
|
@@ -40,6 +63,15 @@ const getEnvOwnerPgPool = (app) => {
|
|
|
40
63
|
return app.get(envOwnerPoolKey);
|
|
41
64
|
};
|
|
42
65
|
exports.getEnvOwnerPgPool = getEnvOwnerPgPool;
|
|
66
|
+
/**
|
|
67
|
+
* Sets a given pool as the Environment Owner Pool for an Express Application
|
|
68
|
+
* @param app
|
|
69
|
+
* @param envOwnerPool
|
|
70
|
+
*/
|
|
71
|
+
const setEnvOwnerPgPool = (app, envOwnerPool) => {
|
|
72
|
+
app.set(envOwnerPoolKey, envOwnerPool);
|
|
73
|
+
};
|
|
74
|
+
exports.setEnvOwnerPgPool = setEnvOwnerPgPool;
|
|
43
75
|
/**
|
|
44
76
|
* Returns the previously set up PostgreSQL pool for the login user. The login pool is internally used by postgraphile to access the database via GraphQL API endpoints.
|
|
45
77
|
* @param app express app
|
|
@@ -48,6 +80,15 @@ const getLoginPgPool = (app) => {
|
|
|
48
80
|
return app.get(loginPoolKey);
|
|
49
81
|
};
|
|
50
82
|
exports.getLoginPgPool = getLoginPgPool;
|
|
83
|
+
/**
|
|
84
|
+
* Sets a given pool as the Login Pool for an Express Application
|
|
85
|
+
* @param app
|
|
86
|
+
* @param loginPool
|
|
87
|
+
*/
|
|
88
|
+
const setLoginPgPool = (app, loginPool) => {
|
|
89
|
+
app.set(loginPoolKey, loginPool);
|
|
90
|
+
};
|
|
91
|
+
exports.setLoginPgPool = setLoginPgPool;
|
|
51
92
|
/**
|
|
52
93
|
* Sets up a PostgreSQL pool for the owner to be reused by other app components. The owner pool has full access to the database.
|
|
53
94
|
* @param app express app
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pg-pool.middleware.js","sourceRoot":"","sources":["../../src/middleware/pg-pool.middleware.ts"],"names":[],"mappings":";;;AAEA,2BAA0B;AAG1B,MAAM,WAAW,GAAG,CAClB,GAA0B,EAC1B,gBAAwB,EACxB,OAAe,EACf,SAAiB,EACjB,MAAgB,EAChB,eAAkC,EAC5B,EAAE;IACR,MAAM,MAAM,GAAG,IAAI,SAAI,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAE9C,yIAAyI;IACzI,qGAAqG;IACrG,gFAAgF;IAChF,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;QACzB,uEAAuE;QACvE,MAAM,WAAW,GAAG,GAA2B,CAAC;QAChD,IAAI,WAAW,CAAC,MAAM,EAAE;YACtB,OAAO,WAAW,CAAC,MAAM,CAAC;SAC3B;QAED,MAAM,CAAC,KAAK,CACV,GAAG,EACH,8BAA8B,SAAS,8BAA8B,CACtE,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,eAAe,CAAC,IAAI,CAAC,GAAG,EAAE;QACxB,MAAM,CAAC,KAAK,CAAC,iBAAiB,SAAS,8BAA8B,CAAC,CAAC;QACvE,MAAM,CAAC,GAAG,EAAE,CAAC;IACf,CAAC,CAAC,CAAC;IAEH,
|
|
1
|
+
{"version":3,"file":"pg-pool.middleware.js","sourceRoot":"","sources":["../../src/middleware/pg-pool.middleware.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/monitoring/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
__exportStar(require("./postgres-metrics"), exports);
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/monitoring/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qDAAmC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Pool } from 'pg';
|
|
2
|
+
import { Metric } from 'prom-client';
|
|
3
|
+
/**
|
|
4
|
+
* Creates a `Gauge` metric with the name `ax_postgres_<pgPoolType>_connectivity` which can be added to a metric Registry.
|
|
5
|
+
* This metric will have a value of `1` if the Database can be reached via the corresponding Pool (within the given timeout),
|
|
6
|
+
* or a value of `0` otherwise.
|
|
7
|
+
*
|
|
8
|
+
* @param pgPool The Postgres Pool to use for checking the connectivity. The connectivity test will be done at the point of metric collection.
|
|
9
|
+
* @param pgPoolType The Postgres Pool to check connectivity for. The connectivity test will be done at the point of metric collection.
|
|
10
|
+
* @param timeoutInMilliSeconds The maximum time the connectivity check will run during metric collection. Defaults to `1000ms`.
|
|
11
|
+
* @returns A `Gauge` metric with a name `ax_postgres_<pgPoolType>_connectivity`.
|
|
12
|
+
*/
|
|
13
|
+
export declare const CreatePostgresPoolConnectivityMetric: (pgPool: Pool, pgPoolType: 'dbOwnerPool' | 'envOwnerPool' | 'loginPool', timeoutInMilliSeconds?: number) => Metric<string>;
|
|
14
|
+
//# sourceMappingURL=postgres-metrics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-metrics.d.ts","sourceRoot":"","sources":["../../src/monitoring/postgres-metrics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAC1B,OAAO,EAAS,MAAM,EAAE,MAAM,aAAa,CAAC;AAO5C;;;;;;;;;GASG;AACH,eAAO,MAAM,oCAAoC,WACvC,IAAI,cACA,aAAa,GAAG,cAAc,GAAG,WAAW,qCAEvD,OAAO,MAAM,CAiBf,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CreatePostgresPoolConnectivityMetric = void 0;
|
|
4
|
+
const prom_client_1 = require("prom-client");
|
|
5
|
+
const createTimeout = (timeoutInMilliSeconds) => new Promise((_, reject) => setTimeout(() => reject(), timeoutInMilliSeconds));
|
|
6
|
+
/**
|
|
7
|
+
* Creates a `Gauge` metric with the name `ax_postgres_<pgPoolType>_connectivity` which can be added to a metric Registry.
|
|
8
|
+
* This metric will have a value of `1` if the Database can be reached via the corresponding Pool (within the given timeout),
|
|
9
|
+
* or a value of `0` otherwise.
|
|
10
|
+
*
|
|
11
|
+
* @param pgPool The Postgres Pool to use for checking the connectivity. The connectivity test will be done at the point of metric collection.
|
|
12
|
+
* @param pgPoolType The Postgres Pool to check connectivity for. The connectivity test will be done at the point of metric collection.
|
|
13
|
+
* @param timeoutInMilliSeconds The maximum time the connectivity check will run during metric collection. Defaults to `1000ms`.
|
|
14
|
+
* @returns A `Gauge` metric with a name `ax_postgres_<pgPoolType>_connectivity`.
|
|
15
|
+
*/
|
|
16
|
+
const CreatePostgresPoolConnectivityMetric = (pgPool, pgPoolType, timeoutInMilliSeconds = 1000) => {
|
|
17
|
+
return new prom_client_1.Gauge({
|
|
18
|
+
name: `ax_postgres_${pgPoolType}_connectivity`,
|
|
19
|
+
help: `Connection status from the service to the database via the ${pgPoolType}`,
|
|
20
|
+
async collect() {
|
|
21
|
+
try {
|
|
22
|
+
await Promise.race([
|
|
23
|
+
pgPool.query(`SELECT NOW() AS PostgresPoolConnectivityMetric`),
|
|
24
|
+
createTimeout(timeoutInMilliSeconds),
|
|
25
|
+
]);
|
|
26
|
+
this.set(1);
|
|
27
|
+
}
|
|
28
|
+
catch (_a) {
|
|
29
|
+
this.set(0);
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
exports.CreatePostgresPoolConnectivityMetric = CreatePostgresPoolConnectivityMetric;
|
|
35
|
+
//# sourceMappingURL=postgres-metrics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-metrics.js","sourceRoot":"","sources":["../../src/monitoring/postgres-metrics.ts"],"names":[],"mappings":";;;AACA,6CAA4C;AAE5C,MAAM,aAAa,GAAG,CAAC,qBAA6B,EAAiB,EAAE,CACrE,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAC9B,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,EAAE,qBAAqB,CAAC,CAClD,CAAC;AAEJ;;;;;;;;;GASG;AACI,MAAM,oCAAoC,GAAG,CAClD,MAAY,EACZ,UAAwD,EACxD,qBAAqB,GAAG,IAAI,EACZ,EAAE;IAClB,OAAO,IAAI,mBAAK,CAAC;QACf,IAAI,EAAE,eAAe,UAAU,eAAe;QAC9C,IAAI,EAAE,8DAA8D,UAAU,EAAE;QAEhF,KAAK,CAAC,OAAO;YACX,IAAI;gBACF,MAAM,OAAO,CAAC,IAAI,CAAC;oBACjB,MAAM,CAAC,KAAK,CAAC,gDAAgD,CAAC;oBAC9D,aAAa,CAAC,qBAAqB,CAAC;iBACrC,CAAC,CAAC;gBACH,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;aACb;YAAC,WAAM;gBACN,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;aACb;QACH,CAAC;KACF,CAAC,CAAC;AACL,CAAC,CAAC;AArBW,QAAA,oCAAoC,wCAqB/C"}
|
|
@@ -44,11 +44,17 @@ DECLARE
|
|
|
44
44
|
ignore_multitenancy text = current_setting('mosaic.ignore_multitenancy', TRUE);
|
|
45
45
|
BEGIN
|
|
46
46
|
IF tenant_id <> '' THEN -- Not null and not empty
|
|
47
|
+
IF NEW.tenant_id::TEXT <> 'ffffffff-ffff-ffff-ffff-ffffffffffff' AND NEW.tenant_id::TEXT <> tenant_id THEN
|
|
48
|
+
perform ax_utils.raise_error('The "mosaic.tenant_id" set via set_config must match the updated/inserted row.', 'TENAN');
|
|
49
|
+
END IF;
|
|
47
50
|
NEW.tenant_id = tenant_id;
|
|
48
51
|
ELSIF is_superuser <> 'on' AND ignore_multitenancy <> 'on' THEN
|
|
49
52
|
perform ax_utils.raise_error('The "mosaic.tenant_id" must be set via set_config value.', 'TENAN');
|
|
50
53
|
END IF;
|
|
51
54
|
IF environment_id <> '' THEN -- Not null and not empty
|
|
55
|
+
IF NEW.environment_id::TEXT <> 'ffffffff-ffff-ffff-ffff-ffffffffffff' AND NEW.environment_id::TEXT <> environment_id THEN
|
|
56
|
+
perform ax_utils.raise_error('The "mosaic.environment_id" set via set_config must match the updated/inserted row.', 'ENVVV');
|
|
57
|
+
END IF;
|
|
52
58
|
NEW.environment_id = environment_id;
|
|
53
59
|
ELSIF is_superuser <> 'on' AND ignore_multitenancy <> 'on' THEN
|
|
54
60
|
perform ax_utils.raise_error('The "mosaic.environment_id" must be set via set_config value.', 'ENVVV');
|
|
@@ -83,7 +83,7 @@ CREATE OR REPLACE FUNCTION ax_define.define_timestamps_trigger(tableName text, s
|
|
|
83
83
|
BEGIN
|
|
84
84
|
PERFORM ax_define.drop_timestamps_trigger(tableName, schemaName);
|
|
85
85
|
EXECUTE 'CREATE trigger _100_timestamps BEFORE UPDATE ON ' || schemaName || '.' || tableName ||
|
|
86
|
-
' for each ROW EXECUTE PROCEDURE ax_utils.tg__timestamps();';
|
|
86
|
+
' for each ROW when (old.* is distinct from new.*) EXECUTE PROCEDURE ax_utils.tg__timestamps();';
|
|
87
87
|
END;
|
|
88
88
|
$$;
|
|
89
89
|
|
|
@@ -123,7 +123,7 @@ CREATE OR REPLACE FUNCTION ax_define.define_users_trigger(tableName text, schema
|
|
|
123
123
|
BEGIN
|
|
124
124
|
PERFORM ax_define.drop_users_trigger(tableName, schemaName);
|
|
125
125
|
EXECUTE 'CREATE trigger _200_username BEFORE INSERT OR UPDATE ON ' || schemaName || '.' || tableName ||
|
|
126
|
-
' for each ROW EXECUTE PROCEDURE ax_utils.tg__username();';
|
|
126
|
+
' for each ROW when (old.* is distinct from new.*) EXECUTE PROCEDURE ax_utils.tg__username();';
|
|
127
127
|
END;
|
|
128
128
|
$$;
|
|
129
129
|
|
|
@@ -260,3 +260,114 @@ BEGIN
|
|
|
260
260
|
perform ax_define.define_multitenant_authentication(readPermissions, '', tableName, schemaName);
|
|
261
261
|
END;
|
|
262
262
|
$$;
|
|
263
|
+
|
|
264
|
+
/*-snippet
|
|
265
|
+
{
|
|
266
|
+
"body": [
|
|
267
|
+
"SELECT ax_define.drop_multitenancy_timestamp_propagation('${1:fk_column}', '${2:table_name}', '${3:app_public}', '${4:id}', '${5:parent_table}', '${6:app_public}');"
|
|
268
|
+
],
|
|
269
|
+
"description": [
|
|
270
|
+
"Removes a function and trigger created by 'ax_define.define_multitenancy_timestamp_propagation' in an idempotent way.\n",
|
|
271
|
+
"The call signature mirrors 'ax_define.define_multitenancy_timestamp_propagation' and should be applied with the same arguments.\n",
|
|
272
|
+
]
|
|
273
|
+
}
|
|
274
|
+
snippet-*/
|
|
275
|
+
CREATE OR REPLACE FUNCTION ax_define.drop_multitenancy_timestamp_propagation(
|
|
276
|
+
idColumnName text,
|
|
277
|
+
tableName text,
|
|
278
|
+
schemaName text,
|
|
279
|
+
foreignIdColumnName text,
|
|
280
|
+
foreignTableName text,
|
|
281
|
+
foreignSchemaName text,
|
|
282
|
+
functionName text default NULL
|
|
283
|
+
) RETURNS void
|
|
284
|
+
LANGUAGE plpgsql
|
|
285
|
+
AS $$
|
|
286
|
+
BEGIN
|
|
287
|
+
SELECT COALESCE(functionName, 'tg_' || tableName || '__' || foreignTableName || '_mt_ts_propagation') INTO functionName;
|
|
288
|
+
IF LENGTH(functionName) > 63 THEN
|
|
289
|
+
perform ax_utils.raise_error('Invalid parameters provided to "ax_define.drop_multitenancy_timestamp_propagation". Function name "%s" exceeds 63 bytes. If the auto-generated name exceeds 63 bytes then a "functionName" argument must be provided.', 'SETUP', functionName);
|
|
290
|
+
END IF;
|
|
291
|
+
EXECUTE 'DROP TRIGGER IF EXISTS _200_propogate_timestamps on ' || schemaName || '.' || tableName;
|
|
292
|
+
EXECUTE 'DROP FUNCTION IF EXISTS ' || schemaName || '.' || functionName || '()';
|
|
293
|
+
END;
|
|
294
|
+
$$;
|
|
295
|
+
|
|
296
|
+
/*-snippet
|
|
297
|
+
{
|
|
298
|
+
"body": [
|
|
299
|
+
"SELECT ax_define.define_multitenancy_timestamp_propagation('${1:fk_column}', '${2:table_name}', '${3:app_public}', '${4:id}', '${5:parent_table}', '${6:app_public}');"
|
|
300
|
+
],
|
|
301
|
+
"description": [
|
|
302
|
+
"Defines a function and trigger to propagate 'updated_date' changes to related entities.\n",
|
|
303
|
+
"Propagation can trigger 'UPDATED' triggers on the target entity including chained timestamp propagation.\n",
|
|
304
|
+
"The call signature mirrors ax_define.define_multitenancy_relation and can generally be applied with the same arguments.\n",
|
|
305
|
+
"First parameter: a column name from the \"table_name\" table that the trigger should be associated with.",
|
|
306
|
+
"Fourth parameter: a column name from the \"parent_table\" that 'updated_date' should be propagated to.",
|
|
307
|
+
"Seventh (optional) parameter: a unique name for the generated function. If the value is NULL then a name will be generated from the table names."
|
|
308
|
+
]
|
|
309
|
+
}
|
|
310
|
+
snippet-*/
|
|
311
|
+
CREATE OR REPLACE FUNCTION ax_define.define_multitenancy_timestamp_propagation(
|
|
312
|
+
idColumnName text,
|
|
313
|
+
tableName text,
|
|
314
|
+
schemaName text,
|
|
315
|
+
foreignIdColumnName text,
|
|
316
|
+
foreignTableName text,
|
|
317
|
+
foreignSchemaName text,
|
|
318
|
+
functionName text default NULL
|
|
319
|
+
) RETURNS void
|
|
320
|
+
LANGUAGE plpgsql
|
|
321
|
+
AS $a$
|
|
322
|
+
BEGIN
|
|
323
|
+
SELECT COALESCE(functionName, 'tg_' || tableName || '__' || foreignTableName || '_mt_ts_propagation') INTO functionName;
|
|
324
|
+
IF LENGTH(functionName) > 63 THEN
|
|
325
|
+
perform ax_utils.raise_error('Invalid parameters provided to "ax_define.define_multitenancy_timestamp_propagation". Function name "%s" exceeds 63 bytes. If the auto-generated name exceeds 63 bytes then a "functionName" argument must be provided.', 'SETUP', functionName);
|
|
326
|
+
END IF;
|
|
327
|
+
-- Set updated_date=now() on the foreign table. This will propogate UPDATE triggers.
|
|
328
|
+
--
|
|
329
|
+
-- A new function is created for each table to do this.
|
|
330
|
+
-- It *may* be possible to use a stock function with trigger arguments but its not easy as NEW and OLD cannot be accessed with dynamic column names. A possible
|
|
331
|
+
-- solution to that is described here: https://itectec.com/database/postgresql-assignment-of-a-column-with-dynamic-column-name/. But even there the advise is
|
|
332
|
+
-- to: "Just write a new trigger function for each table. Less hassle, better performance. Byte the bullet on code duplication:"
|
|
333
|
+
--
|
|
334
|
+
-- !! WARNING !!: This function uses "SECURITY DEFINER". This is required to ensure that update to the target table is allowed. This means that the function is
|
|
335
|
+
-- executed with role "DB_OWNER". Extra care must be taken to ensure multitenancy integrity is preserved. Any propogated trigger functions will also
|
|
336
|
+
-- execute with role "DB_OWNER".
|
|
337
|
+
EXECUTE '
|
|
338
|
+
CREATE OR REPLACE FUNCTION ' || schemaName || '.' || functionName || '() RETURNS TRIGGER
|
|
339
|
+
LANGUAGE plpgsql
|
|
340
|
+
SECURITY DEFINER
|
|
341
|
+
SET search_path = pg_temp
|
|
342
|
+
AS $b$
|
|
343
|
+
BEGIN
|
|
344
|
+
if (OLD.updated_date = NEW.updated_date) THEN
|
|
345
|
+
RETURN NULL;
|
|
346
|
+
END IF;
|
|
347
|
+
-- UPDATE (where relationship is unchanged, or changed to another entity in which case a change is triggered on both the old and new relation)
|
|
348
|
+
IF (OLD.' || idColumnName || ' IS NOT NULL AND NEW.' || idColumnName || ' IS NOT NULL) THEN
|
|
349
|
+
UPDATE ' || foreignSchemaName || '.' || foreignTableName || ' SET updated_date=now()
|
|
350
|
+
WHERE (' || foreignIdColumnName || ' = OLD.' || idColumnName || ' AND tenant_id = OLD.tenant_id AND environment_id = OLD.environment_id)
|
|
351
|
+
OR (' || foreignIdColumnName || ' = NEW.' || idColumnName || ' AND tenant_id = NEW.tenant_id AND environment_id = NEW.environment_id);
|
|
352
|
+
-- INSERT (or UPDATE which sets nullable relationship)
|
|
353
|
+
ELSIF (NEW.' || idColumnName || ' IS NOT NULL) THEN
|
|
354
|
+
UPDATE ' || foreignSchemaName || '.' || foreignTableName || ' SET updated_date=now()
|
|
355
|
+
WHERE ' || foreignIdColumnName || ' = NEW.' || idColumnName || ' AND tenant_id = NEW.tenant_id AND environment_id = NEW.environment_id;
|
|
356
|
+
-- DELETE (or UPDATE which removes nullable relationship)
|
|
357
|
+
ELSIF (OLD.' || idColumnName || ' IS NOT NULL) THEN
|
|
358
|
+
UPDATE ' || foreignSchemaName || '.' || foreignTableName || ' SET updated_date=now()
|
|
359
|
+
WHERE ' || foreignIdColumnName || ' = OLD.' || idColumnName || ' AND tenant_id = OLD.tenant_id AND environment_id = OLD.environment_id;
|
|
360
|
+
|
|
361
|
+
END IF;
|
|
362
|
+
RETURN NULL;
|
|
363
|
+
END $b$;
|
|
364
|
+
REVOKE EXECUTE ON FUNCTION ' || schemaName || '.' || functionName || '() FROM public;
|
|
365
|
+
';
|
|
366
|
+
|
|
367
|
+
-- Function runs *AFTER* INSERT, UPDATE, DELETE. Propogated queries can still raise error and rollback the transaction
|
|
368
|
+
EXECUTE 'DROP TRIGGER IF EXISTS _200_propogate_timestamps on ' || schemaName || '.' || tableName;
|
|
369
|
+
EXECUTE 'CREATE trigger _200_propogate_timestamps
|
|
370
|
+
AFTER INSERT OR UPDATE OR DELETE ON ' || schemaName || '.' || tableName || '
|
|
371
|
+
FOR EACH ROW EXECUTE PROCEDURE ' || schemaName || '.' || functionName || '();';
|
|
372
|
+
END;
|
|
373
|
+
$a$;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axinom/mosaic-db-common",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0-rc.10",
|
|
4
4
|
"description": "This library encapsulates database-related functionality to develop Mosaic based services.",
|
|
5
5
|
"author": "Axinom",
|
|
6
6
|
"license": "PROPRIETARY",
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
"express": "^4.17.1",
|
|
35
35
|
"graphile-migrate": "^1.2.0-0",
|
|
36
36
|
"pg": "^8.5.1",
|
|
37
|
+
"prom-client": "^13.0.0",
|
|
37
38
|
"readdirp": "^3.4.0",
|
|
38
39
|
"yargs": "^16.2.0",
|
|
39
40
|
"zapatos": "3.6.0"
|
|
@@ -50,5 +51,5 @@
|
|
|
50
51
|
"publishConfig": {
|
|
51
52
|
"access": "public"
|
|
52
53
|
},
|
|
53
|
-
"gitHead": "
|
|
54
|
+
"gitHead": "7edd5ca677e58aa6d26c2ca5d2fb62c4e441756c"
|
|
54
55
|
}
|