@interopio/bridge 0.0.1-alpha → 0.0.3-beta
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/bin/bridge.js +1 -1
- package/dist/main.js +2139 -0
- package/dist/main.js.map +7 -0
- package/package.json +9 -6
- package/gen/instance/GeneratedBuildInfo.ts +0 -4
- package/src/cluster/Address.ts +0 -57
- package/src/cluster/Cluster.ts +0 -13
- package/src/cluster/Endpoint.ts +0 -5
- package/src/cluster/Member.ts +0 -9
- package/src/cluster/MembershipListener.ts +0 -6
- package/src/config/Config.ts +0 -100
- package/src/config/DiscoveryConfig.ts +0 -21
- package/src/config/Duration.ts +0 -168
- package/src/config/KubernetesConfig.ts +0 -7
- package/src/config/NamedDiscoveryConfig.ts +0 -17
- package/src/config/Properties.ts +0 -49
- package/src/config/index.ts +0 -1
- package/src/discovery/SimpleDiscoveryNode.ts +0 -14
- package/src/discovery/index.ts +0 -207
- package/src/discovery/multicast/MulticastDiscoveryStrategy.ts +0 -141
- package/src/discovery/multicast/MulticastDiscoveryStrategyFactory.ts +0 -30
- package/src/discovery/multicast/MulticastProperties.ts +0 -4
- package/src/discovery/settings.ts +0 -37
- package/src/error/RequestFailure.ts +0 -48
- package/src/gossip/ApplicationState.ts +0 -48
- package/src/gossip/EndpointState.ts +0 -141
- package/src/gossip/FailureDetector.ts +0 -235
- package/src/gossip/Gossiper.ts +0 -1133
- package/src/gossip/HeartbeatState.ts +0 -66
- package/src/gossip/Messenger.ts +0 -130
- package/src/gossip/VersionedValue.ts +0 -59
- package/src/index.ts +0 -3
- package/src/instance/AddressPicker.ts +0 -245
- package/src/instance/BridgeNode.ts +0 -141
- package/src/instance/ClusterTopologyIntentTracker.ts +0 -4
- package/src/io/VersionedSerializer.ts +0 -230
- package/src/io/util.ts +0 -117
- package/src/kubernetes/DnsEndpointResolver.ts +0 -70
- package/src/kubernetes/KubernetesApiEndpointResolver.ts +0 -111
- package/src/kubernetes/KubernetesApiProvider.ts +0 -75
- package/src/kubernetes/KubernetesClient.ts +0 -264
- package/src/kubernetes/KubernetesConfig.ts +0 -130
- package/src/kubernetes/KubernetesDiscoveryStrategy.ts +0 -30
- package/src/kubernetes/KubernetesDiscoveryStrategyFactory.ts +0 -71
- package/src/kubernetes/KubernetesEndpointResolver.ts +0 -43
- package/src/kubernetes/KubernetesProperties.ts +0 -22
- package/src/license/BridgeLicenseValidator.ts +0 -19
- package/src/license/LicenseValidator.ts +0 -114
- package/src/license/types.ts +0 -40
- package/src/logging.ts +0 -22
- package/src/main.mts +0 -53
- package/src/net/Action.ts +0 -143
- package/src/net/AddressSerializer.ts +0 -44
- package/src/net/ByteBufferAllocator.ts +0 -27
- package/src/net/FrameDecoder.ts +0 -314
- package/src/net/FrameEncoder.ts +0 -138
- package/src/net/HandshakeProtocol.ts +0 -143
- package/src/net/InboundConnection.ts +0 -108
- package/src/net/InboundConnectionInitiator.ts +0 -150
- package/src/net/InboundMessageHandler.ts +0 -377
- package/src/net/InboundSink.ts +0 -38
- package/src/net/Message.ts +0 -428
- package/src/net/OutboundConnection.ts +0 -1141
- package/src/net/OutboundConnectionInitiator.ts +0 -76
- package/src/net/RequestCallbacks.ts +0 -148
- package/src/net/ResponseHandler.ts +0 -30
- package/src/net/ShareableBytes.ts +0 -125
- package/src/net/internal/AsyncResourceExecutor.ts +0 -464
- package/src/net/internal/AsyncSocketPromise.ts +0 -37
- package/src/net/internal/channel/ChannelHandlerAdapter.ts +0 -99
- package/src/net/internal/channel/types.ts +0 -188
- package/src/utils/bigint.ts +0 -23
- package/src/utils/buffer.ts +0 -434
- package/src/utils/clock.ts +0 -148
- package/src/utils/collections.ts +0 -283
- package/src/utils/crc.ts +0 -39
- package/src/utils/internal/IpAddressUtil.ts +0 -161
- package/src/utils/memory/BufferPools.ts +0 -40
- package/src/utils/network.ts +0 -130
- package/src/utils/promise.ts +0 -38
- package/src/utils/uuid.ts +0 -5
- package/src/utils/vint.ts +0 -238
- package/src/version/MemberVersion.ts +0 -42
- package/src/version/Version.ts +0 -12
package/src/config/Config.ts
DELETED
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import {type Properties, type PropertyType} from './Properties.ts';
|
|
2
|
-
import {KubernetesConfig} from './KubernetesConfig.ts';
|
|
3
|
-
import {
|
|
4
|
-
DefaultDiscoveryConfig,
|
|
5
|
-
type DiscoveryConfig
|
|
6
|
-
} from './DiscoveryConfig.ts';
|
|
7
|
-
|
|
8
|
-
export class AutoDetectionConfig {
|
|
9
|
-
enabled: boolean = true;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export interface MulticastConfig {
|
|
13
|
-
readonly group: string
|
|
14
|
-
readonly port: number
|
|
15
|
-
}
|
|
16
|
-
class DefaultMulticastConfig implements MulticastConfig {
|
|
17
|
-
enabled: boolean = false;
|
|
18
|
-
group: string = '239.1.2.3';
|
|
19
|
-
port: number = 34567;
|
|
20
|
-
}
|
|
21
|
-
export interface TcpIpConfig {
|
|
22
|
-
members: string[]
|
|
23
|
-
}
|
|
24
|
-
class DefaultTcpIpConfig implements TcpIpConfig {
|
|
25
|
-
enabled: boolean = false;
|
|
26
|
-
members: string[] = [];
|
|
27
|
-
}
|
|
28
|
-
export class JoinConfig {
|
|
29
|
-
private _multicast= new DefaultMulticastConfig();
|
|
30
|
-
private _tcpIp = new DefaultTcpIpConfig();
|
|
31
|
-
private _kubernetes = new KubernetesConfig();
|
|
32
|
-
private _discovery = new DefaultDiscoveryConfig();
|
|
33
|
-
private _autoDetection = new AutoDetectionConfig();
|
|
34
|
-
|
|
35
|
-
get discovery(): DiscoveryConfig {
|
|
36
|
-
return this._discovery;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
get multicast(): MulticastConfig {
|
|
40
|
-
return this._multicast;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
get autoDetectionEnabled(): boolean {
|
|
44
|
-
return this._autoDetection.enabled
|
|
45
|
-
&& !this._multicast.enabled
|
|
46
|
-
&& !this._tcpIp.enabled
|
|
47
|
-
&& !this._kubernetes.enabled
|
|
48
|
-
&& !this._discovery.enabled;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export class NetworkConfig {
|
|
53
|
-
public static readonly DEFAULT_PORT: number = 8383;
|
|
54
|
-
port: number = NetworkConfig.DEFAULT_PORT;
|
|
55
|
-
reuseAddress: boolean;
|
|
56
|
-
publicAddress?: string;
|
|
57
|
-
join = new JoinConfig();
|
|
58
|
-
|
|
59
|
-
constructor() {
|
|
60
|
-
this.reuseAddress = process.platform !== "win32";
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export class ServerConfig {
|
|
65
|
-
port?: number = undefined;
|
|
66
|
-
host?: string = undefined;
|
|
67
|
-
mesh: {
|
|
68
|
-
ping?: number
|
|
69
|
-
} = {};
|
|
70
|
-
gateway: {
|
|
71
|
-
enabled?: boolean,
|
|
72
|
-
contexts: {
|
|
73
|
-
lifetime: 'retained' | 'ref-counted' | 'ownership'
|
|
74
|
-
}
|
|
75
|
-
} = {
|
|
76
|
-
contexts: {
|
|
77
|
-
lifetime: 'retained'
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export class Config {
|
|
83
|
-
properties: Properties = {};
|
|
84
|
-
network = new NetworkConfig();
|
|
85
|
-
license: string
|
|
86
|
-
readonly server: ServerConfig;
|
|
87
|
-
constructor() {
|
|
88
|
-
this.server = new ServerConfig();
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
get<T extends PropertyType>(name: string): T {
|
|
92
|
-
const value = this.properties[name] as T;
|
|
93
|
-
return value;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
set<T extends PropertyType>(name: string, value: T): Config {
|
|
97
|
-
this.properties[name] = value;
|
|
98
|
-
return this;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import type {DiscoveryServiceFactory, DiscoveryStrategyFactory} from '../discovery/index.ts';
|
|
2
|
-
import type {Properties} from './Properties.ts';
|
|
3
|
-
|
|
4
|
-
export interface DiscoveryStrategyConfig {
|
|
5
|
-
readonly discoveryStrategyFactory?: DiscoveryStrategyFactory
|
|
6
|
-
readonly properties: Properties
|
|
7
|
-
}
|
|
8
|
-
export interface DiscoveryConfig {
|
|
9
|
-
readonly discoveryStrategyConfigs: ReadonlyArray<DiscoveryStrategyConfig>
|
|
10
|
-
readonly discoveryServiceFactory?: DiscoveryServiceFactory
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export class DefaultDiscoveryConfig implements DiscoveryConfig
|
|
14
|
-
{
|
|
15
|
-
discoveryStrategyConfigs: DiscoveryStrategyConfig[] = [];
|
|
16
|
-
discoveryServiceFactory?: DiscoveryServiceFactory;
|
|
17
|
-
|
|
18
|
-
get enabled() {
|
|
19
|
-
return this.discoveryStrategyConfigs.length > 0;
|
|
20
|
-
}
|
|
21
|
-
}
|
package/src/config/Duration.ts
DELETED
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
const UNITS_PATTERN = /^(\d+)(d|h|m|s|ms|us|µs|ns)$/;
|
|
2
|
-
|
|
3
|
-
export type Unit = keyof typeof SCALES;
|
|
4
|
-
|
|
5
|
-
export function unitForSymbol(symbol: string): Unit {
|
|
6
|
-
switch (symbol.toLowerCase()) {
|
|
7
|
-
case 'ns':
|
|
8
|
-
return 'nanoseconds';
|
|
9
|
-
case 'us':
|
|
10
|
-
case 'µs':
|
|
11
|
-
return 'microseconds';
|
|
12
|
-
case 'ms':
|
|
13
|
-
return 'milliseconds';
|
|
14
|
-
case 's':
|
|
15
|
-
return 'seconds';
|
|
16
|
-
case 'm':
|
|
17
|
-
return 'minutes';
|
|
18
|
-
case 'h':
|
|
19
|
-
return 'hours';
|
|
20
|
-
case 'd':
|
|
21
|
-
return 'days';
|
|
22
|
-
}
|
|
23
|
-
throw new Error(`Unsupported unit symbol: ${symbol}`);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function symbolForUnit(unit: Unit): string {
|
|
27
|
-
switch (unit) {
|
|
28
|
-
case 'days': return 'd';
|
|
29
|
-
case 'hours': return 'h';
|
|
30
|
-
case 'minutes': return 'm';
|
|
31
|
-
case 'seconds': return 's';
|
|
32
|
-
case 'milliseconds': return 'ms';
|
|
33
|
-
case 'microseconds': return 'us';
|
|
34
|
-
case 'nanoseconds': return 'ns';
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const SCALES: { [key :string ]: bigint } = {
|
|
39
|
-
nanoseconds: 1n,
|
|
40
|
-
microseconds: 1000n,
|
|
41
|
-
milliseconds: 1000000n,
|
|
42
|
-
seconds: 1000000000n,
|
|
43
|
-
minutes: 60n * 1000000000n,
|
|
44
|
-
hours: 60n * 60n * 1000000000n,
|
|
45
|
-
days: 24n * 60n * 60n * 1000000000n,
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function toNanos(unit: Unit, duration: number | bigint) {
|
|
49
|
-
const scale = SCALES[unit];
|
|
50
|
-
const ns = BigInt(duration) * scale;
|
|
51
|
-
return ns;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function toMicros(unit: Unit, duration: number | bigint): bigint {
|
|
55
|
-
const scale = SCALES[unit];
|
|
56
|
-
let microScale = SCALES.microseconds;
|
|
57
|
-
if (scale <= microScale) {
|
|
58
|
-
return scale === microScale ? BigInt(duration) : BigInt(duration) / (microScale / scale);
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
return BigInt(duration) * (scale / microScale);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function toMillis(unit: Unit, duration: number | bigint) : bigint {
|
|
66
|
-
const scale = SCALES[unit];
|
|
67
|
-
let milliScale = SCALES.milliseconds;
|
|
68
|
-
if (scale <= milliScale) {
|
|
69
|
-
return scale === milliScale ? BigInt(duration) : BigInt(duration) / (milliScale / scale);
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
return BigInt(duration) * (scale / milliScale);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function toSeconds(unit: Unit, duration: number | bigint): bigint {
|
|
77
|
-
const scale = SCALES[unit];
|
|
78
|
-
const secondScale = SCALES.seconds;
|
|
79
|
-
if (scale <= secondScale) {
|
|
80
|
-
return scale === secondScale ? BigInt(duration) : BigInt(duration) / (secondScale / scale);
|
|
81
|
-
}
|
|
82
|
-
else {
|
|
83
|
-
return BigInt(duration) * (scale / secondScale);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export function convert(targetUnit: Unit, quantity: number | bigint, sourceUnit: Unit): bigint {
|
|
88
|
-
switch (targetUnit) {
|
|
89
|
-
case 'nanoseconds': return toNanos(sourceUnit, quantity);
|
|
90
|
-
case 'microseconds': return toMicros(sourceUnit, quantity);
|
|
91
|
-
case 'milliseconds': return toMillis(sourceUnit, quantity);
|
|
92
|
-
case 'seconds': return toSeconds(sourceUnit, quantity);
|
|
93
|
-
default: throw new Error('not implemented');
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
abstract class Duration {
|
|
98
|
-
readonly unit: Unit;
|
|
99
|
-
readonly quantity: number;
|
|
100
|
-
|
|
101
|
-
/*protected*/ constructor(value: string, minUnit: Unit, max?: number) {
|
|
102
|
-
const match = UNITS_PATTERN.exec(value);
|
|
103
|
-
if (!match) {
|
|
104
|
-
throw new Error(`Invalid duration: ${value}`);
|
|
105
|
-
}
|
|
106
|
-
this.quantity = parseInt(match[1]);
|
|
107
|
-
this.unit = unitForSymbol(match[2]);
|
|
108
|
-
if (max) {
|
|
109
|
-
if (SCALES[this.unit] < SCALES[minUnit]) {
|
|
110
|
-
throw new Error(`Duration must be at least ${minUnit}`);
|
|
111
|
-
}
|
|
112
|
-
if (convert(minUnit, this.quantity, this.unit) > max) {
|
|
113
|
-
throw new Error(`Invalid Duration: ${value}. Must be at most ${max - 1} in ${minUnit}`);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
export class NanosecondsDuration extends Duration {
|
|
120
|
-
constructor(value: string) {
|
|
121
|
-
super(value, 'nanoseconds', Number.MAX_SAFE_INTEGER);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
toNanoseconds() {
|
|
125
|
-
return toNanos(this.unit, this.quantity);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
export class MicrosecondsDuration extends Duration {
|
|
129
|
-
constructor(value: string) {
|
|
130
|
-
super(value, 'microseconds', Number.MAX_SAFE_INTEGER);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
toMicroseconds() {
|
|
134
|
-
return convert('microseconds', this.quantity, this.unit);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
toSeconds() {
|
|
138
|
-
return convert('seconds', this.quantity, this.unit);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
export class MillisecondsDuration extends Duration {
|
|
143
|
-
constructor(value: string) {
|
|
144
|
-
super(value, 'milliseconds', Number.MAX_SAFE_INTEGER);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
toMilliseconds() {
|
|
148
|
-
return convert('milliseconds', this.quantity, this.unit);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
export class SecondsDuration extends Duration {
|
|
153
|
-
constructor(value: string) {
|
|
154
|
-
super(value, 'seconds', Number.MAX_SAFE_INTEGER);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
toMilliseconds() {
|
|
158
|
-
return toMillis(this.unit, this.quantity);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
toNanoSeconds() {
|
|
162
|
-
return toNanos(this.unit, this.quantity);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
toSeconds() {
|
|
166
|
-
return toSeconds(this.unit, this.quantity);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export abstract class NamedDiscoveryConfig<T extends NamedDiscoveryConfig<T>> {
|
|
2
|
-
readonly tag;
|
|
3
|
-
private _enabled: boolean = false;
|
|
4
|
-
|
|
5
|
-
constructor(tag: string) {
|
|
6
|
-
this.tag = tag;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
setEnabled(enabled: boolean): T {
|
|
10
|
-
this._enabled = enabled;
|
|
11
|
-
return this as unknown as T;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
get enabled(): boolean {
|
|
15
|
-
return this._enabled;
|
|
16
|
-
}
|
|
17
|
-
}
|
package/src/config/Properties.ts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
export interface PropertyDefinition {
|
|
2
|
-
readonly key: string
|
|
3
|
-
readonly optional: boolean
|
|
4
|
-
readonly converter: PropertyTypeConverter<PropertyType>
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export type PropertyType = string | number | boolean;
|
|
8
|
-
export type Properties = { [key: string]: PropertyType };
|
|
9
|
-
|
|
10
|
-
export interface PropertyTypeConverter<T extends PropertyType> {
|
|
11
|
-
convert(value: unknown): T
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export const BOOLEAN = new class implements PropertyTypeConverter<boolean> {
|
|
15
|
-
convert(value: unknown): boolean {
|
|
16
|
-
if (typeof value === 'boolean') {
|
|
17
|
-
return value;
|
|
18
|
-
}
|
|
19
|
-
else if (typeof value === "string") {
|
|
20
|
-
return value.toLowerCase() === "true";
|
|
21
|
-
}
|
|
22
|
-
throw new Error("Cannot convert value to boolean: " + value);
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export const STRING = new class implements PropertyTypeConverter<string> {
|
|
27
|
-
convert(value: unknown): string {
|
|
28
|
-
if (value === undefined) {
|
|
29
|
-
throw new Error("Cannot convert undefined ");
|
|
30
|
-
}
|
|
31
|
-
return String(value);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export const NUMBER = new class implements PropertyTypeConverter<number> {
|
|
36
|
-
convert(value: unknown): number {
|
|
37
|
-
if (value === undefined) {
|
|
38
|
-
throw new Error("Cannot convert undefined ");
|
|
39
|
-
}
|
|
40
|
-
if (typeof value === "object") {
|
|
41
|
-
throw new Error("Cannot convert object/array to number: " + value);
|
|
42
|
-
}
|
|
43
|
-
return Number(value);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export function property<T extends PropertyType>(name: string, converter: PropertyTypeConverter<T>): PropertyDefinition {
|
|
48
|
-
return {key: name, optional: true, converter: converter};
|
|
49
|
-
}
|
package/src/config/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import {type DiscoveryNode} from './index.ts';
|
|
2
|
-
import {type Address} from '../cluster/Address.ts';
|
|
3
|
-
|
|
4
|
-
export class SimpleDiscoveryNode implements DiscoveryNode {
|
|
5
|
-
readonly privateAddress: Address;
|
|
6
|
-
readonly publicAddress: Address;
|
|
7
|
-
readonly properties: ReadonlyMap<string, unknown>;
|
|
8
|
-
constructor(privateAddress: Address, publicAddress?: Address, properties?: ReadonlyMap<string, unknown>)
|
|
9
|
-
{
|
|
10
|
-
this.privateAddress = privateAddress;
|
|
11
|
-
this.publicAddress = publicAddress ?? privateAddress;
|
|
12
|
-
this.properties = properties ?? new Map();
|
|
13
|
-
}
|
|
14
|
-
}
|
package/src/discovery/index.ts
DELETED
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
import {type Address} from '../cluster/Address.ts';
|
|
2
|
-
import {type Properties, type PropertyDefinition} from '../config/Properties.ts';
|
|
3
|
-
import {type DiscoveryConfig, type DiscoveryStrategyConfig} from '../config/DiscoveryConfig.ts';
|
|
4
|
-
import {type Logger} from '../logging.ts';
|
|
5
|
-
import {KubernetesDiscoveryStrategyFactory} from '../kubernetes/KubernetesDiscoveryStrategyFactory.ts';
|
|
6
|
-
import {MulticastDiscoveryStrategyFactory} from './multicast/MulticastDiscoveryStrategyFactory.ts';
|
|
7
|
-
|
|
8
|
-
export interface DiscoveryServiceFactory {
|
|
9
|
-
newDiscoveryService(settings: DiscoveryServiceSettings): DiscoveryService
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export interface DiscoveryService {
|
|
13
|
-
start(): Promise<void>
|
|
14
|
-
discover(): Promise<Iterable<DiscoveryNode>>
|
|
15
|
-
close(): Promise<void>
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
export type DiscoveryServiceSettings = {
|
|
20
|
-
readonly node: Promise<DiscoveryNode>
|
|
21
|
-
readonly mode: DiscoveryMode
|
|
22
|
-
readonly conf: DiscoveryConfig
|
|
23
|
-
readonly auto: boolean
|
|
24
|
-
readonly logger: Logger
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export type DiscoveryMode = 'member' | 'client';
|
|
28
|
-
|
|
29
|
-
export class DefaultDiscoveryServiceFactory implements DiscoveryServiceFactory {
|
|
30
|
-
newDiscoveryService(settings: DiscoveryServiceSettings): DiscoveryService {
|
|
31
|
-
return new DefaultDiscoveryService(settings);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function verifyNoUnknownProperties(mappedProperties: Properties, allProperties: Properties) {
|
|
36
|
-
const unknownProperties = Object.keys(allProperties).filter(key => !mappedProperties.hasOwnProperty(key));
|
|
37
|
-
if (unknownProperties.length > 0) {
|
|
38
|
-
throw new Error(`Unknown properties: ${unknownProperties.join(', ')} on discovery strategy`);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function prepareProperties(properties: Properties,
|
|
43
|
-
propertyDefinitions: readonly PropertyDefinition[]) {
|
|
44
|
-
const mappedProperties: Properties = {};
|
|
45
|
-
for (const propertyDefinition of propertyDefinitions) {
|
|
46
|
-
const propertyKey = propertyDefinition.key;
|
|
47
|
-
if (properties[propertyKey] == undefined) {
|
|
48
|
-
if (!propertyDefinition.optional) {
|
|
49
|
-
throw new Error(`Missing required property: ${propertyKey} on discovery strategy`);
|
|
50
|
-
}
|
|
51
|
-
continue;
|
|
52
|
-
}
|
|
53
|
-
const value = properties[propertyKey];
|
|
54
|
-
const converter = propertyDefinition.converter;
|
|
55
|
-
const mappedValue = converter.convert(value);
|
|
56
|
-
|
|
57
|
-
mappedProperties[propertyKey] = mappedValue;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
verifyNoUnknownProperties(mappedProperties, properties);
|
|
61
|
-
return mappedProperties;
|
|
62
|
-
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export class DefaultDiscoveryService implements DiscoveryService {
|
|
66
|
-
private readonly settings: DiscoveryServiceSettings;
|
|
67
|
-
private readonly strategies: Array<DiscoveryStrategy> = [];
|
|
68
|
-
constructor(settings: DiscoveryServiceSettings) {
|
|
69
|
-
this.settings = settings;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
async start(): Promise<void> {
|
|
73
|
-
this.strategies.push(...await this.loadDiscoveryStrategies());
|
|
74
|
-
for (const strategy of this.strategies) {
|
|
75
|
-
await strategy.start();
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
async discover(): Promise<Iterable<DiscoveryNode>> {
|
|
80
|
-
const discoveryNodes = new Set<DiscoveryNode>();
|
|
81
|
-
for (const strategy of this.strategies) {
|
|
82
|
-
const candidates = await strategy.discover();
|
|
83
|
-
if (candidates) {
|
|
84
|
-
for (const candidate of candidates) {
|
|
85
|
-
if (this.validateCandidate(candidate)) {
|
|
86
|
-
discoveryNodes.add(candidate);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return discoveryNodes;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
async close(): Promise<void> {
|
|
97
|
-
for (const strategy of this.strategies) {
|
|
98
|
-
await strategy.close();
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
private validateCandidate(candidate: DiscoveryNode) : boolean {
|
|
103
|
-
// todo
|
|
104
|
-
return true;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
private async loadDiscoveryStrategies(): Promise<Iterable<DiscoveryStrategy>> {
|
|
108
|
-
|
|
109
|
-
const discoveryStrategyConfigs = this.settings.conf.discoveryStrategyConfigs;
|
|
110
|
-
const factories = this.collectFactories(discoveryStrategyConfigs);
|
|
111
|
-
|
|
112
|
-
const discoveryStrategies = new Array<DiscoveryStrategy>();
|
|
113
|
-
for (const config of discoveryStrategyConfigs) {
|
|
114
|
-
const discoveryStrategy = await this.buildDiscoveryStrategy(config, factories);
|
|
115
|
-
discoveryStrategies.push(discoveryStrategy);
|
|
116
|
-
}
|
|
117
|
-
const logger = this.settings.logger;
|
|
118
|
-
if (discoveryStrategies.length == 0 && this.settings.auto) {
|
|
119
|
-
logger.debug(`Discovery auto-detection enabled, trying to detect discovery strategy`);
|
|
120
|
-
const autoDetectedFactory = await this.detectDiscoveryStrategyFactory(factories);
|
|
121
|
-
if (autoDetectedFactory) {
|
|
122
|
-
logger.debug(`Auto-detected discovery strategy: ${autoDetectedFactory.constructor.name}`);
|
|
123
|
-
discoveryStrategies.push(autoDetectedFactory.newDiscoveryStrategy(await this.settings.node, logger, {}));
|
|
124
|
-
}
|
|
125
|
-
else {
|
|
126
|
-
logger.debug(`No discovery strategy auto-detected`);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
return discoveryStrategies;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
private collectFactories(strategyConfigs: ReadonlyArray<DiscoveryStrategyConfig>): DiscoveryStrategyFactory[] {
|
|
133
|
-
|
|
134
|
-
const knownFactories = [new MulticastDiscoveryStrategyFactory(), new KubernetesDiscoveryStrategyFactory()]
|
|
135
|
-
|
|
136
|
-
const factories = new Array<DiscoveryStrategyFactory>();
|
|
137
|
-
|
|
138
|
-
for (const factory of knownFactories) {
|
|
139
|
-
factories.push(factory);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
for (const config of strategyConfigs) {
|
|
143
|
-
const factory = config.discoveryStrategyFactory;
|
|
144
|
-
if (factory) {
|
|
145
|
-
factories.push(factory);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
return factories;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
private async buildDiscoveryStrategy(config: DiscoveryStrategyConfig,
|
|
153
|
-
factories: DiscoveryStrategyFactory[]): Promise<DiscoveryStrategy> {
|
|
154
|
-
const discoveryNode = await this.settings.node;
|
|
155
|
-
const logger = this.settings.logger;
|
|
156
|
-
|
|
157
|
-
for (const factory of factories) {
|
|
158
|
-
if (factory.constructor.name == config.discoveryStrategyFactory.constructor.name) {
|
|
159
|
-
const properties = prepareProperties(config.properties, factory.getConfigurationProperties());
|
|
160
|
-
return factory.newDiscoveryStrategy(discoveryNode, logger, properties);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
throw new Error('DiscoveryStrategyFactory not found');
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
private async detectDiscoveryStrategyFactory(factories: DiscoveryStrategyFactory[]) {
|
|
167
|
-
let highestPriorityFactory: DiscoveryStrategyFactory;
|
|
168
|
-
for (const factory of factories) {
|
|
169
|
-
try {
|
|
170
|
-
if (await factory.isAutoDetectionApplicable()) {
|
|
171
|
-
if (highestPriorityFactory === undefined || factory.priority > highestPriorityFactory.priority) {
|
|
172
|
-
highestPriorityFactory = factory;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
} catch (error) {
|
|
176
|
-
// todo log error
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
return highestPriorityFactory;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
export interface DiscoveryStrategy {
|
|
186
|
-
start(): Promise<void>
|
|
187
|
-
discover(): Promise<Iterable<DiscoveryNode> | undefined>
|
|
188
|
-
close(): Promise<void>
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
export interface DiscoveryStrategyFactory {
|
|
192
|
-
readonly priority: number
|
|
193
|
-
isAutoDetectionApplicable(): Promise<boolean>
|
|
194
|
-
newDiscoveryStrategy(node: DiscoveryNode, logger: Logger, settings: Properties): DiscoveryStrategy
|
|
195
|
-
getConfigurationProperties(): ReadonlyArray<PropertyDefinition>
|
|
196
|
-
}
|
|
197
|
-
export const DiscoveryStrategyPriorities = {
|
|
198
|
-
UNKNOWN: 0,
|
|
199
|
-
PLATFORM: 20,
|
|
200
|
-
CUSTOM: 50,
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
export interface DiscoveryNode {
|
|
204
|
-
readonly publicAddress: Address;
|
|
205
|
-
readonly privateAddress: Address;
|
|
206
|
-
readonly properties: ReadonlyMap<string, unknown>;
|
|
207
|
-
}
|