@routr/location 2.0.5-alpha.2 → 2.0.5-alpha.21
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/client.d.ts +47 -0
- package/dist/client.js +102 -0
- package/dist/config/get_config.d.ts +1 -1
- package/dist/config/get_config.js +38 -35
- package/dist/config/schema.d.ts +13 -10
- package/dist/config/schema.js +48 -45
- package/dist/errors.d.ts +37 -1
- package/dist/errors.js +88 -59
- package/dist/helper.d.ts +2 -0
- package/dist/helper.js +28 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +55 -0
- package/dist/location.d.ts +26 -0
- package/dist/location.js +118 -0
- package/dist/memory_store.d.ts +15 -1
- package/dist/memory_store.js +37 -48
- package/dist/redis_store.d.ts +21 -0
- package/dist/redis_store.js +99 -0
- package/dist/runner.js +12 -7
- package/dist/service.d.ts +5 -0
- package/dist/service.js +44 -6
- package/dist/tracer.d.ts +7 -0
- package/dist/tracer.js +53 -0
- package/dist/types.d.ts +19 -17
- package/dist/types.js +6 -19
- package/dist/utils.d.ts +4 -4
- package/dist/utils.js +78 -98
- package/package.json +18 -6
- package/dist/locator.d.ts +0 -13
- package/dist/locator.js +0 -152
package/dist/helper.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createRoute = void 0;
|
|
4
|
+
const processor_1 = require("@routr/processor");
|
|
5
|
+
// TODO: Before finalizing this, consider using the old approach of saving the rport
|
|
6
|
+
// and received values (like here:
|
|
7
|
+
// https://github.com/fonoster/routr/blob/59bc98af86078088aede7e658c0d82a19fa18fa4/mod/registrar/utils.js#L87)
|
|
8
|
+
//
|
|
9
|
+
// Also consider: https://github.com/fonoster/routr/blob/ee5d339888344013939d06c734385f17f0cd75c2/mod/registrar/utils.js#L116
|
|
10
|
+
// and https://github.com/fonoster/routr/blob/ee5d339888344013939d06c734385f17f0cd75c2/mod/registrar/utils.js#L131
|
|
11
|
+
const createRoute = (request) => {
|
|
12
|
+
const uri = request.message.contact.address.uri;
|
|
13
|
+
const sessionCount = processor_1.Extensions.getHeaderValue(request, "x-session-count")
|
|
14
|
+
? parseInt(processor_1.Extensions.getHeaderValue(request, "x-session-count"))
|
|
15
|
+
: -1;
|
|
16
|
+
return {
|
|
17
|
+
edgePortRef: request.edgePortRef,
|
|
18
|
+
user: uri.user,
|
|
19
|
+
host: uri.host,
|
|
20
|
+
port: uri.port,
|
|
21
|
+
transport: uri.transportParam,
|
|
22
|
+
registeredOn: Date.now(),
|
|
23
|
+
sessionCount,
|
|
24
|
+
expires: processor_1.Target.getTargetExpires(request),
|
|
25
|
+
listeningPoint: request.listeningPoint
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
exports.createRoute = createRoute;
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
26
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
27
|
+
};
|
|
28
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
29
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
30
|
+
};
|
|
31
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
32
|
+
exports.LocationClient = exports.Utils = exports.Helper = void 0;
|
|
33
|
+
/*
|
|
34
|
+
* Copyright (C) 2022 by Fonoster Inc (https://fonoster.com)
|
|
35
|
+
* http://github.com/fonoster/routr
|
|
36
|
+
*
|
|
37
|
+
* This file is part of Routr
|
|
38
|
+
*
|
|
39
|
+
* Licensed under the MIT License (the "License")
|
|
40
|
+
* you may not use this file except in compliance with
|
|
41
|
+
* the License. You may obtain a copy of the License at
|
|
42
|
+
*
|
|
43
|
+
* https://opensource.org/licenses/MIT
|
|
44
|
+
*
|
|
45
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
46
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
47
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
48
|
+
* See the License for the specific language governing permissions and
|
|
49
|
+
* limitations under the License.
|
|
50
|
+
*/
|
|
51
|
+
const client_1 = __importDefault(require("./client"));
|
|
52
|
+
exports.LocationClient = client_1.default;
|
|
53
|
+
exports.Helper = __importStar(require("./helper"));
|
|
54
|
+
exports.Utils = __importStar(require("./utils"));
|
|
55
|
+
__exportStar(require("./errors"), exports);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { AddRouteRequest, Backend, FindRoutesRequest, ILocationService, ILocatorStore, RemoveRoutesRequest } from "./types";
|
|
2
|
+
import { Route } from "@routr/common";
|
|
3
|
+
/**
|
|
4
|
+
* A locator store that uses the location service to find routes for AORs.
|
|
5
|
+
*/
|
|
6
|
+
export default class Location implements ILocationService {
|
|
7
|
+
private store;
|
|
8
|
+
private backends;
|
|
9
|
+
private rrCount;
|
|
10
|
+
private affinityStore;
|
|
11
|
+
/**
|
|
12
|
+
* Creates a new Location service. Should fail if any backend has sessionAffinity and round-robin
|
|
13
|
+
*
|
|
14
|
+
* @param {ILocatorStore} store - The store to use for the location service
|
|
15
|
+
* @param {Map<string, Backend>} backends - The backends to use for the location service
|
|
16
|
+
*/
|
|
17
|
+
constructor(store: ILocatorStore, backends?: Map<string, Backend>);
|
|
18
|
+
/** @inheritdoc */
|
|
19
|
+
addRoute(request: AddRouteRequest): Promise<void>;
|
|
20
|
+
/** @inheritdoc */
|
|
21
|
+
findRoutes(request: FindRoutesRequest): Promise<Route[]>;
|
|
22
|
+
/** @inheritdoc */
|
|
23
|
+
removeRoutes(request: RemoveRoutesRequest): Promise<void>;
|
|
24
|
+
private next;
|
|
25
|
+
private nextWithAffinity;
|
|
26
|
+
}
|
package/dist/location.js
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
/*
|
|
13
|
+
* Copyright (C) 2022 by Fonoster Inc (https://fonoster.com)
|
|
14
|
+
* http://github.com/fonoster/routr
|
|
15
|
+
*
|
|
16
|
+
* This file is part of Routr
|
|
17
|
+
*
|
|
18
|
+
* Licensed under the MIT License (the "License")
|
|
19
|
+
* you may not use this file except in compliance with
|
|
20
|
+
* the License. You may obtain a copy of the License at
|
|
21
|
+
*
|
|
22
|
+
* https://opensource.org/licenses/MIT
|
|
23
|
+
*
|
|
24
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
25
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
26
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
27
|
+
* See the License for the specific language governing permissions and
|
|
28
|
+
* limitations under the License.
|
|
29
|
+
*/
|
|
30
|
+
const errors_1 = require("./errors");
|
|
31
|
+
const types_1 = require("./types");
|
|
32
|
+
const utils_1 = require("./utils");
|
|
33
|
+
var AOR_SCHEME;
|
|
34
|
+
(function (AOR_SCHEME) {
|
|
35
|
+
AOR_SCHEME["SIP"] = "sip:";
|
|
36
|
+
AOR_SCHEME["BACKEND"] = "backend:";
|
|
37
|
+
})(AOR_SCHEME || (AOR_SCHEME = {}));
|
|
38
|
+
/**
|
|
39
|
+
* A locator store that uses the location service to find routes for AORs.
|
|
40
|
+
*/
|
|
41
|
+
class Location {
|
|
42
|
+
/**
|
|
43
|
+
* Creates a new Location service. Should fail if any backend has sessionAffinity and round-robin
|
|
44
|
+
*
|
|
45
|
+
* @param {ILocatorStore} store - The store to use for the location service
|
|
46
|
+
* @param {Map<string, Backend>} backends - The backends to use for the location service
|
|
47
|
+
*/
|
|
48
|
+
constructor(store, backends = new Map()) {
|
|
49
|
+
this.store = store;
|
|
50
|
+
this.backends = backends;
|
|
51
|
+
this.rrCount = new Map();
|
|
52
|
+
this.affinityStore = new Map();
|
|
53
|
+
this.backends.forEach((value, key) => this.rrCount.set(key, 0));
|
|
54
|
+
}
|
|
55
|
+
/** @inheritdoc */
|
|
56
|
+
addRoute(request) {
|
|
57
|
+
if (!request.aor.startsWith(AOR_SCHEME.SIP) &&
|
|
58
|
+
!request.aor.startsWith(AOR_SCHEME.BACKEND)) {
|
|
59
|
+
throw new errors_1.UnsupportedSchema(request.aor);
|
|
60
|
+
}
|
|
61
|
+
return this.store.put(request.aor, request.route);
|
|
62
|
+
}
|
|
63
|
+
/** @inheritdoc */
|
|
64
|
+
findRoutes(request) {
|
|
65
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
66
|
+
const routes = request.labels
|
|
67
|
+
? (yield this.store.get(request.aor)).filter((0, utils_1.filterOnlyMatchingLabels)(request.labels))
|
|
68
|
+
: (yield this.store.get(request.aor)) || [];
|
|
69
|
+
if (request.aor.startsWith(AOR_SCHEME.SIP)) {
|
|
70
|
+
return routes;
|
|
71
|
+
}
|
|
72
|
+
else if (request.aor.startsWith(AOR_SCHEME.BACKEND)) {
|
|
73
|
+
const backend = this.backends.get(request.aor);
|
|
74
|
+
if (!backend) {
|
|
75
|
+
throw new errors_1.NotRoutesFoundForAOR(request.aor);
|
|
76
|
+
}
|
|
77
|
+
// If it has not affinity sesssion then get next
|
|
78
|
+
return backend.withSessionAffinity
|
|
79
|
+
? [this.nextWithAffinity(routes, request.sessionAffinityRef)]
|
|
80
|
+
: [this.next(routes, backend)];
|
|
81
|
+
}
|
|
82
|
+
throw new errors_1.UnsupportedSchema(request.aor);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
/** @inheritdoc */
|
|
86
|
+
removeRoutes(request) {
|
|
87
|
+
return this.store.delete(request.aor);
|
|
88
|
+
}
|
|
89
|
+
// eslint-disable-next-line require-jsdoc
|
|
90
|
+
next(routes, backend) {
|
|
91
|
+
if (backend.balancingAlgorithm === types_1.LB_ALGORITHM.LEAST_SESSIONS) {
|
|
92
|
+
return routes.sort((r1, r2) => r1.sessionCount - r2.sessionCount)[0];
|
|
93
|
+
}
|
|
94
|
+
// Continues using round-robin
|
|
95
|
+
const nextPosition = this.rrCount.get(`${AOR_SCHEME.BACKEND}${backend.ref}`);
|
|
96
|
+
const result = routes[nextPosition];
|
|
97
|
+
if (nextPosition >= routes.length - 1) {
|
|
98
|
+
// Restarting round-robin counter
|
|
99
|
+
this.rrCount.set(`${AOR_SCHEME.BACKEND}${backend.ref}`, 0);
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
this.rrCount.set(`${AOR_SCHEME.BACKEND}${backend.ref}`, nextPosition + 1);
|
|
103
|
+
}
|
|
104
|
+
return result;
|
|
105
|
+
}
|
|
106
|
+
// Backend with session affinity does not support round-robin
|
|
107
|
+
// eslint-disable-next-line require-jsdoc
|
|
108
|
+
nextWithAffinity(routes, sessionAffinityRef) {
|
|
109
|
+
let route = this.affinityStore.get(sessionAffinityRef);
|
|
110
|
+
if (route) {
|
|
111
|
+
return route;
|
|
112
|
+
}
|
|
113
|
+
route = routes.sort((r1, r2) => r1.sessionCount - r2.sessionCount)[0];
|
|
114
|
+
this.affinityStore.set(sessionAffinityRef, route);
|
|
115
|
+
return route;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
exports.default = Location;
|
package/dist/memory_store.d.ts
CHANGED
|
@@ -1,12 +1,26 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Route } from "@routr/common";
|
|
2
|
+
import { ILocatorStore } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* In-memory store for the locator service.
|
|
5
|
+
*/
|
|
2
6
|
export default class MemoryStore implements ILocatorStore {
|
|
3
7
|
private collections;
|
|
4
8
|
private cleanupCount;
|
|
5
9
|
private maxCyclesBeforeCleanup;
|
|
10
|
+
/**
|
|
11
|
+
* Creates a new in-memory store.
|
|
12
|
+
*
|
|
13
|
+
* @param {number} maxCyclesBeforeCleanup - Maximum number of cycles before cleanup
|
|
14
|
+
*/
|
|
6
15
|
constructor(maxCyclesBeforeCleanup?: number);
|
|
16
|
+
/** @inheritdoc */
|
|
7
17
|
put(key: string, route: Route): Promise<void>;
|
|
18
|
+
/** @inheritdoc */
|
|
8
19
|
get(key: string): Promise<Route[]>;
|
|
20
|
+
/** @inheritdoc */
|
|
9
21
|
delete(key: string): Promise<void>;
|
|
22
|
+
/** @inheritdoc */
|
|
10
23
|
size(): number;
|
|
24
|
+
/** @inheritdoc */
|
|
11
25
|
cleanup(): void;
|
|
12
26
|
}
|
package/dist/memory_store.js
CHANGED
|
@@ -1,77 +1,66 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __read = (this && this.__read) || function (o, n) {
|
|
3
|
-
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
4
|
-
if (!m) return o;
|
|
5
|
-
var i = m.call(o), r, ar = [], e;
|
|
6
|
-
try {
|
|
7
|
-
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
8
|
-
}
|
|
9
|
-
catch (error) { e = { error: error }; }
|
|
10
|
-
finally {
|
|
11
|
-
try {
|
|
12
|
-
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
13
|
-
}
|
|
14
|
-
finally { if (e) throw e.error; }
|
|
15
|
-
}
|
|
16
|
-
return ar;
|
|
17
|
-
};
|
|
18
|
-
var __spreadArray = (this && this.__spreadArray) || function (to, from) {
|
|
19
|
-
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
|
|
20
|
-
to[j] = from[i];
|
|
21
|
-
return to;
|
|
22
|
-
};
|
|
23
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
3
|
+
const utils_1 = require("./utils");
|
|
4
|
+
const MAX_CYCLES_BEFORE_CLEANUP = 10000;
|
|
5
|
+
/**
|
|
6
|
+
* In-memory store for the locator service.
|
|
7
|
+
*/
|
|
8
|
+
class MemoryStore {
|
|
9
|
+
/**
|
|
10
|
+
* Creates a new in-memory store.
|
|
11
|
+
*
|
|
12
|
+
* @param {number} maxCyclesBeforeCleanup - Maximum number of cycles before cleanup
|
|
13
|
+
*/
|
|
14
|
+
constructor(maxCyclesBeforeCleanup = MAX_CYCLES_BEFORE_CLEANUP) {
|
|
29
15
|
this.collections = new Map();
|
|
30
16
|
this.maxCyclesBeforeCleanup = maxCyclesBeforeCleanup;
|
|
31
17
|
}
|
|
32
|
-
|
|
33
|
-
|
|
18
|
+
/** @inheritdoc */
|
|
19
|
+
put(key, route) {
|
|
20
|
+
const routes = [...(this.collections.get(key) || [])];
|
|
34
21
|
// Avoids duplicate or expired routes
|
|
35
|
-
|
|
22
|
+
const filteredRoutes = routes
|
|
36
23
|
.filter(utils_1.expiredFilter)
|
|
37
|
-
.filter(
|
|
24
|
+
.filter((r) => (0, utils_1.duplicateFilter)(r, route));
|
|
38
25
|
if (filteredRoutes.length > 0) {
|
|
39
|
-
this.collections.set(key,
|
|
26
|
+
this.collections.set(key, [route, ...filteredRoutes]);
|
|
40
27
|
}
|
|
41
28
|
else {
|
|
42
29
|
this.collections.set(key, [route]);
|
|
43
30
|
}
|
|
44
31
|
return;
|
|
45
|
-
}
|
|
46
|
-
|
|
32
|
+
}
|
|
33
|
+
/** @inheritdoc */
|
|
34
|
+
get(key) {
|
|
47
35
|
// Cleanup every so often to avoid memory build up
|
|
48
36
|
this.cleanupCount++;
|
|
49
37
|
if (this.cleanupCount >= this.maxCyclesBeforeCleanup) {
|
|
50
38
|
this.cleanupCount = 0;
|
|
51
39
|
this.cleanup();
|
|
52
40
|
}
|
|
53
|
-
return Promise.resolve(this.collections.get(key) || []);
|
|
54
|
-
}
|
|
55
|
-
|
|
41
|
+
return Promise.resolve((this.collections.get(key) || []).filter(utils_1.expiredFilter));
|
|
42
|
+
}
|
|
43
|
+
/** @inheritdoc */
|
|
44
|
+
delete(key) {
|
|
56
45
|
this.collections.delete(key);
|
|
57
46
|
return;
|
|
58
|
-
}
|
|
59
|
-
|
|
47
|
+
}
|
|
48
|
+
/** @inheritdoc */
|
|
49
|
+
size() {
|
|
60
50
|
return this.collections.size;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
|
|
51
|
+
}
|
|
52
|
+
/** @inheritdoc */
|
|
53
|
+
cleanup() {
|
|
64
54
|
// Remove any expired route from collection
|
|
65
|
-
this.collections.forEach(
|
|
66
|
-
|
|
55
|
+
this.collections.forEach((routes, key) => {
|
|
56
|
+
const filteredRoutes = routes.filter(utils_1.expiredFilter);
|
|
67
57
|
if (filteredRoutes.length > 0) {
|
|
68
|
-
|
|
58
|
+
this.collections.set(key, filteredRoutes);
|
|
69
59
|
}
|
|
70
60
|
else {
|
|
71
|
-
|
|
61
|
+
this.collections.delete(key);
|
|
72
62
|
}
|
|
73
63
|
});
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
}());
|
|
64
|
+
}
|
|
65
|
+
}
|
|
77
66
|
exports.default = MemoryStore;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Route } from "@routr/common";
|
|
2
|
+
import { ILocatorStore } from "./types";
|
|
3
|
+
import { Redis } from "@routr/common";
|
|
4
|
+
/**
|
|
5
|
+
* Redis store for the locator service.
|
|
6
|
+
*/
|
|
7
|
+
export default class RedisStore implements ILocatorStore {
|
|
8
|
+
client: any;
|
|
9
|
+
/**
|
|
10
|
+
* Creates a new redis store.
|
|
11
|
+
*
|
|
12
|
+
* @param {Redis.RedisStoreConfig} config - Optional store config
|
|
13
|
+
*/
|
|
14
|
+
constructor(config?: Redis.RedisStoreConfig);
|
|
15
|
+
/** @inheritdoc */
|
|
16
|
+
put(key: string, route: Route): Promise<void>;
|
|
17
|
+
/** @inheritdoc */
|
|
18
|
+
get(key: string): Promise<Route[]>;
|
|
19
|
+
/** @inheritdoc */
|
|
20
|
+
delete(key: string): Promise<void>;
|
|
21
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __asyncValues = (this && this.__asyncValues) || function (o) {
|
|
12
|
+
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
13
|
+
var m = o[Symbol.asyncIterator], i;
|
|
14
|
+
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
15
|
+
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
16
|
+
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
17
|
+
};
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
const redis_1 = require("redis");
|
|
20
|
+
const common_1 = require("@routr/common");
|
|
21
|
+
const logger_1 = require("@fonoster/logger");
|
|
22
|
+
const logger = (0, logger_1.getLogger)({ service: "location", filePath: __filename });
|
|
23
|
+
/**
|
|
24
|
+
* Redis store for the locator service.
|
|
25
|
+
*/
|
|
26
|
+
class RedisStore {
|
|
27
|
+
/**
|
|
28
|
+
* Creates a new redis store.
|
|
29
|
+
*
|
|
30
|
+
* @param {Redis.RedisStoreConfig} config - Optional store config
|
|
31
|
+
*/
|
|
32
|
+
constructor(config) {
|
|
33
|
+
this.client = config
|
|
34
|
+
? (0, redis_1.createClient)({ url: common_1.Redis.getRedisUrlFromConfig(config) })
|
|
35
|
+
: (0, redis_1.createClient)();
|
|
36
|
+
this.client.connect();
|
|
37
|
+
this.client.on("error", (err) => logger.error("redis client error: ", err));
|
|
38
|
+
}
|
|
39
|
+
/** @inheritdoc */
|
|
40
|
+
put(key, route) {
|
|
41
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
42
|
+
// Formatted the key to ensure it is unique
|
|
43
|
+
yield this.client.set(`${key}:${route.user}${route.host}${route.port}`, JSON.stringify(route), {
|
|
44
|
+
EX: route.expires
|
|
45
|
+
});
|
|
46
|
+
return;
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
/** @inheritdoc */
|
|
50
|
+
get(key) {
|
|
51
|
+
var e_1, _a;
|
|
52
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
53
|
+
const routes = [];
|
|
54
|
+
try {
|
|
55
|
+
// eslint-disable-next-line no-loops/no-loops
|
|
56
|
+
for (var _b = __asyncValues(yield this.client.scanIterator({
|
|
57
|
+
CURSOR: 0,
|
|
58
|
+
MATCH: `${key}:*`
|
|
59
|
+
})), _c; _c = yield _b.next(), !_c.done;) {
|
|
60
|
+
const k = _c.value;
|
|
61
|
+
routes.push(JSON.parse(yield this.client.get(k)));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
65
|
+
finally {
|
|
66
|
+
try {
|
|
67
|
+
if (_c && !_c.done && (_a = _b.return)) yield _a.call(_b);
|
|
68
|
+
}
|
|
69
|
+
finally { if (e_1) throw e_1.error; }
|
|
70
|
+
}
|
|
71
|
+
return routes;
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
/** @inheritdoc */
|
|
75
|
+
delete(key) {
|
|
76
|
+
var e_2, _a;
|
|
77
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
78
|
+
try {
|
|
79
|
+
// eslint-disable-next-line no-loops/no-loops
|
|
80
|
+
for (var _b = __asyncValues(yield this.client.scanIterator({
|
|
81
|
+
CURSOR: 0,
|
|
82
|
+
MATCH: `${key}:*`
|
|
83
|
+
})), _c; _c = yield _b.next(), !_c.done;) {
|
|
84
|
+
const k = _c.value;
|
|
85
|
+
yield this.client.del(k);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
89
|
+
finally {
|
|
90
|
+
try {
|
|
91
|
+
if (_c && !_c.done && (_a = _b.return)) yield _a.call(_b);
|
|
92
|
+
}
|
|
93
|
+
finally { if (e_2) throw e_2.error; }
|
|
94
|
+
}
|
|
95
|
+
return;
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
exports.default = RedisStore;
|
package/dist/runner.js
CHANGED
|
@@ -22,13 +22,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
22
22
|
* See the License for the specific language governing permissions and
|
|
23
23
|
* limitations under the License.
|
|
24
24
|
*/
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
26
|
+
require("./tracer").init("dispatcher");
|
|
27
|
+
const service_1 = __importDefault(require("./service"));
|
|
28
|
+
const get_config_1 = require("./config/get_config");
|
|
29
|
+
const common_1 = require("@routr/common");
|
|
30
|
+
const logger_1 = require("@fonoster/logger");
|
|
31
|
+
const logger = (0, logger_1.getLogger)({ service: "location", filePath: __filename });
|
|
32
|
+
common_1.Assertions.assertEnvsAreSet(["CONFIG_PATH"]);
|
|
33
|
+
const result = (0, get_config_1.getConfig)(process.env.CONFIG_PATH);
|
|
34
|
+
if (result._tag === "Right") {
|
|
35
|
+
(0, service_1.default)(result.right);
|
|
31
36
|
}
|
|
32
37
|
else {
|
|
33
|
-
|
|
38
|
+
logger.error(result.left);
|
|
34
39
|
}
|
package/dist/service.d.ts
CHANGED
package/dist/service.js
CHANGED
|
@@ -3,12 +3,50 @@ 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
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
/*
|
|
7
|
+
* Copyright (C) 2022 by Fonoster Inc (https://fonoster.com)
|
|
8
|
+
* http://github.com/fonoster/routr
|
|
9
|
+
*
|
|
10
|
+
* This file is part of Routr
|
|
11
|
+
*
|
|
12
|
+
* Licensed under the MIT License (the "License")
|
|
13
|
+
* you may not use this file except in compliance with
|
|
14
|
+
* the License. You may obtain a copy of the License at
|
|
15
|
+
*
|
|
16
|
+
* https://opensource.org/licenses/MIT
|
|
17
|
+
*
|
|
18
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
19
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
20
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
21
|
+
* See the License for the specific language governing permissions and
|
|
22
|
+
* limitations under the License.
|
|
23
|
+
*/
|
|
24
|
+
const types_1 = require("./types");
|
|
25
|
+
const common_1 = require("@routr/common");
|
|
26
|
+
const utils_1 = require("./utils");
|
|
27
|
+
const location_1 = __importDefault(require("./location"));
|
|
28
|
+
const memory_store_1 = __importDefault(require("./memory_store"));
|
|
29
|
+
const redis_store_1 = __importDefault(require("./redis_store"));
|
|
30
|
+
const logger_1 = require("@fonoster/logger");
|
|
31
|
+
const logger = (0, logger_1.getLogger)({ service: "location", filePath: __filename });
|
|
32
|
+
const allowedParameters = ["host", "port", "username", "password", "secure"];
|
|
33
|
+
/**
|
|
34
|
+
* Creates a new locator service.
|
|
35
|
+
*
|
|
36
|
+
* @param {LocationConfig} config - Service configuration
|
|
37
|
+
*/
|
|
10
38
|
function LocationService(config) {
|
|
11
|
-
|
|
12
|
-
|
|
39
|
+
const { bindAddr, cache } = config;
|
|
40
|
+
let store;
|
|
41
|
+
if (cache.provider === types_1.CACHE_PROVIDER.REDIS) {
|
|
42
|
+
store = new redis_store_1.default((0, utils_1.configFromString)(cache.parameters, allowedParameters));
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
store = new memory_store_1.default();
|
|
46
|
+
}
|
|
47
|
+
const backends = new Map();
|
|
48
|
+
config.backends.forEach((b) => backends.set(`backend:${b.ref}`, b));
|
|
49
|
+
(0, common_1.createService)((0, utils_1.getServiceInfo)(bindAddr, new location_1.default(store, backends)));
|
|
50
|
+
logger.info(`using ${cache.provider} as cache provider`);
|
|
13
51
|
}
|
|
14
52
|
exports.default = LocationService;
|
package/dist/tracer.d.ts
ADDED
package/dist/tracer.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.init = void 0;
|
|
7
|
+
/*
|
|
8
|
+
* Copyright (C) 2022 by Fonoster Inc (https://fonoster.com)
|
|
9
|
+
* http://github.com/fonoster/routr
|
|
10
|
+
*
|
|
11
|
+
* This file is part of Routr
|
|
12
|
+
*
|
|
13
|
+
* Licensed under the MIT License (the "License")
|
|
14
|
+
* you may not use this file except in compliance with
|
|
15
|
+
* the License. You may obtain a copy of the License at
|
|
16
|
+
*
|
|
17
|
+
* https://opensource.org/licenses/MIT
|
|
18
|
+
*
|
|
19
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
20
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
21
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
22
|
+
* See the License for the specific language governing permissions and
|
|
23
|
+
* limitations under the License.
|
|
24
|
+
*/
|
|
25
|
+
const api_1 = __importDefault(require("@opentelemetry/api"));
|
|
26
|
+
const instrumentation_1 = require("@opentelemetry/instrumentation");
|
|
27
|
+
const sdk_trace_node_1 = require("@opentelemetry/sdk-trace-node");
|
|
28
|
+
const resources_1 = require("@opentelemetry/resources");
|
|
29
|
+
const semantic_conventions_1 = require("@opentelemetry/semantic-conventions");
|
|
30
|
+
const sdk_trace_base_1 = require("@opentelemetry/sdk-trace-base");
|
|
31
|
+
const exporter_jaeger_1 = require("@opentelemetry/exporter-jaeger");
|
|
32
|
+
const instrumentation_grpc_1 = require("@opentelemetry/instrumentation-grpc");
|
|
33
|
+
/**
|
|
34
|
+
* This function registers the instrumentations for the service.
|
|
35
|
+
*
|
|
36
|
+
* @param {string} serviceName - The name of the service.
|
|
37
|
+
* @return {Tracer} The tracer object.
|
|
38
|
+
*/
|
|
39
|
+
function init(serviceName) {
|
|
40
|
+
const provider = new sdk_trace_node_1.NodeTracerProvider({
|
|
41
|
+
resource: new resources_1.Resource({
|
|
42
|
+
[semantic_conventions_1.SemanticResourceAttributes.SERVICE_NAME]: serviceName
|
|
43
|
+
})
|
|
44
|
+
});
|
|
45
|
+
const exporter = new exporter_jaeger_1.JaegerExporter();
|
|
46
|
+
provider.addSpanProcessor(new sdk_trace_base_1.SimpleSpanProcessor(exporter));
|
|
47
|
+
provider.register();
|
|
48
|
+
(0, instrumentation_1.registerInstrumentations)({
|
|
49
|
+
instrumentations: [new instrumentation_grpc_1.GrpcInstrumentation()]
|
|
50
|
+
});
|
|
51
|
+
return api_1.default.trace.getTracer("routr-tracer");
|
|
52
|
+
}
|
|
53
|
+
exports.init = init;
|