@ohos-ports/cloudnative-health 2.1.2-beta.0
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/LICENSE +177 -0
- package/README.md +114 -0
- package/index.d.ts +2 -0
- package/index.js +30 -0
- package/index.js.map +1 -0
- package/index.ts +18 -0
- package/package.json +38 -0
- package/src/healthcheck/HealthChecker.d.ts +71 -0
- package/src/healthcheck/HealthChecker.js +351 -0
- package/src/healthcheck/HealthChecker.js.map +1 -0
- package/src/healthcheck/HealthChecker.ts +360 -0
- package/src/healthcheck/checks/PingCheck.d.ts +5 -0
- package/src/healthcheck/checks/PingCheck.js +66 -0
- package/src/healthcheck/checks/PingCheck.js.map +1 -0
- package/src/healthcheck/checks/PingCheck.ts +48 -0
- package/test/healthcheck/HealthChecker.test.d.ts +1 -0
- package/test/healthcheck/HealthChecker.test.js +1003 -0
- package/test/healthcheck/HealthChecker.test.js.map +1 -0
- package/test/healthcheck/HealthChecker.test.ts +1213 -0
- package/test/healthstate/HealthState.test.d.ts +1 -0
- package/test/healthstate/HealthState.test.js +29 -0
- package/test/healthstate/HealthState.test.js.map +1 -0
- package/test/healthstate/HealthState.test.ts +28 -0
- package/tsconfig.json +60 -0
- package/tslint.json +31 -0
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright IBM Corporation 2018
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
enum State {
|
|
18
|
+
UNKNOWN = "UNKNOWN",
|
|
19
|
+
STARTING = "STARTING",
|
|
20
|
+
UP = "UP",
|
|
21
|
+
DOWN = "DOWN",
|
|
22
|
+
STOPPING = "STOPPING",
|
|
23
|
+
STOPPED = "STOPPED",
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
class HealthStatus {
|
|
27
|
+
status: State;
|
|
28
|
+
checks: PluginStatus[];
|
|
29
|
+
|
|
30
|
+
constructor(state: State) {
|
|
31
|
+
this.status = state;
|
|
32
|
+
this.checks = [];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
public addStatus(status: PluginStatus) {
|
|
36
|
+
this.checks.push(status);
|
|
37
|
+
if (this.status === State.UNKNOWN) {
|
|
38
|
+
this.status = status.state;
|
|
39
|
+
}
|
|
40
|
+
else if (this.status === State.STARTING) {
|
|
41
|
+
if (status.state === State.STARTING) this.status = State.STARTING;
|
|
42
|
+
if (status.state === State.DOWN) this.status = State.DOWN;
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
else if (this.status === State.UP) {
|
|
46
|
+
if (status.state === State.STARTING) this.status = State.STARTING;
|
|
47
|
+
if (status.state === State.UP) this.status = State.UP;
|
|
48
|
+
if (status.state === State.DOWN) this.status = State.DOWN;
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
else if (this.status === State.DOWN) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
else if (this.status === State.STOPPING) {
|
|
55
|
+
if (status.state === State.STOPPING) this.status = State.STOPPING;
|
|
56
|
+
if (status.state === State.DOWN) this.status = State.STOPPED;
|
|
57
|
+
if (status.state === State.STOPPED) this.status = State.STOPPED;
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
else if (this.status === State.STOPPED) {
|
|
61
|
+
if (status.state === State.STOPPING) this.status = State.STOPPING;
|
|
62
|
+
if (status.state === State.DOWN) this.status = State.STOPPED;
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
class HealthChecker {
|
|
69
|
+
protected startupComplete: boolean;
|
|
70
|
+
private startupPlugins: StartupCheck[];
|
|
71
|
+
private readinessPlugins: ReadinessCheck[];
|
|
72
|
+
private healthPlugins: LivenessCheck[];
|
|
73
|
+
private shutdownEnabled: boolean;
|
|
74
|
+
public shutdownRequested: boolean;
|
|
75
|
+
private shutdownPlugins: ShutdownCheck[];
|
|
76
|
+
|
|
77
|
+
private onShutdownRequest: () => void;
|
|
78
|
+
|
|
79
|
+
constructor() {
|
|
80
|
+
this.startupComplete = true;
|
|
81
|
+
this.startupPlugins = [];
|
|
82
|
+
this.readinessPlugins = [];
|
|
83
|
+
this.healthPlugins = [];
|
|
84
|
+
this.shutdownEnabled = false;
|
|
85
|
+
this.shutdownRequested = false;
|
|
86
|
+
this.shutdownPlugins = [];
|
|
87
|
+
|
|
88
|
+
// Force this to be an instance function so that it can access `this` fields
|
|
89
|
+
this.onShutdownRequest = () => {
|
|
90
|
+
this.shutdownRequested = true;
|
|
91
|
+
this.shutdownPlugins.map((check) => {
|
|
92
|
+
check.runCheck();
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
public getStartUpComplete() {
|
|
98
|
+
return this.startupComplete;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
public registerStartupCheck(plugin: StartupCheck) {
|
|
102
|
+
this.startupPlugins.push(plugin);
|
|
103
|
+
this.startupComplete = false;
|
|
104
|
+
return plugin.runCheck();
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
public registerReadinessCheck(plugin: ReadinessCheck) {
|
|
108
|
+
this.readinessPlugins.push(plugin);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
public registerLivenessCheck(plugin: LivenessCheck) {
|
|
112
|
+
this.healthPlugins.push(plugin);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
public registerShutdownCheck(plugin: ShutdownCheck) {
|
|
116
|
+
if (this.shutdownEnabled === false) {
|
|
117
|
+
this.shutdownEnabled = true;
|
|
118
|
+
process.on('SIGTERM', this.onShutdownRequest);
|
|
119
|
+
}
|
|
120
|
+
this.shutdownPlugins.push(plugin);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
public async getStatus(): Promise<HealthStatus> {
|
|
124
|
+
if (this.shutdownRequested === true) {
|
|
125
|
+
return this.getShutdownStatus();
|
|
126
|
+
}
|
|
127
|
+
if (this.startupComplete === false) {
|
|
128
|
+
return this.getStartupStatus();
|
|
129
|
+
}
|
|
130
|
+
return this.getHealthStatus();
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
private async getPromiseStatus(statusResponse: HealthStatus) {
|
|
134
|
+
const runChecks = this.startupPlugins.map(check => check.runCheck());
|
|
135
|
+
await Promise.all(runChecks);
|
|
136
|
+
this.startupPlugins.forEach(check => statusResponse.addStatus(check.getStatus()));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
private async getStartupStatus(): Promise<HealthStatus> {
|
|
140
|
+
let statusResponse: HealthStatus;
|
|
141
|
+
|
|
142
|
+
// Handle startup case
|
|
143
|
+
if (this.startupComplete === false) {
|
|
144
|
+
statusResponse = new HealthStatus(State.UNKNOWN);
|
|
145
|
+
|
|
146
|
+
this.startupPlugins.map((check) => {
|
|
147
|
+
const promiseCheck = check.runCheck();
|
|
148
|
+
statusResponse.addStatus(check.getStatus());
|
|
149
|
+
return promiseCheck;
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
if (statusResponse.status !== State.UP) {
|
|
153
|
+
return statusResponse;
|
|
154
|
+
}
|
|
155
|
+
this.startupComplete = true;
|
|
156
|
+
}
|
|
157
|
+
return this.getHealthStatus();
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
public async getReadinessStatus(): Promise<HealthStatus> {
|
|
161
|
+
let statusResponse: HealthStatus;
|
|
162
|
+
|
|
163
|
+
if (this.shutdownRequested === true) {
|
|
164
|
+
return this.getShutdownStatus();
|
|
165
|
+
}
|
|
166
|
+
if (this.startupComplete === false) {
|
|
167
|
+
statusResponse = new HealthStatus(State.UNKNOWN);
|
|
168
|
+
await this.getPromiseStatus(statusResponse);
|
|
169
|
+
if(statusResponse.status === State.UP) {
|
|
170
|
+
this.startupComplete = true;
|
|
171
|
+
} else {
|
|
172
|
+
return this.getStartupStatus();
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Handle readiness
|
|
177
|
+
statusResponse = new HealthStatus(State.UP);
|
|
178
|
+
let filteredPromises = this.readinessPlugins.filter(element => element !== undefined);
|
|
179
|
+
if (filteredPromises.length === 0) {
|
|
180
|
+
return statusResponse;
|
|
181
|
+
} else {
|
|
182
|
+
await Promise.all(filteredPromises.map(async (check) => {
|
|
183
|
+
const promiseCheck = await check.runCheck();
|
|
184
|
+
statusResponse.addStatus(check.getStatus());
|
|
185
|
+
return promiseCheck;
|
|
186
|
+
}));
|
|
187
|
+
return statusResponse;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
public async getLivenessStatus(): Promise<HealthStatus> {
|
|
192
|
+
let statusResponse: HealthStatus;
|
|
193
|
+
|
|
194
|
+
if (this.shutdownRequested === true) {
|
|
195
|
+
return this.getShutdownStatus();
|
|
196
|
+
}
|
|
197
|
+
if (this.startupComplete === false) {
|
|
198
|
+
statusResponse = new HealthStatus(State.UNKNOWN);
|
|
199
|
+
await this.getPromiseStatus(statusResponse);
|
|
200
|
+
if(statusResponse.status === State.UP) {
|
|
201
|
+
this.startupComplete = true;
|
|
202
|
+
} else {
|
|
203
|
+
return this.getStartupStatus();
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
// Handle liveness
|
|
207
|
+
statusResponse = new HealthStatus(State.UP);
|
|
208
|
+
|
|
209
|
+
let filteredPromises = this.healthPlugins.filter(element => element !== undefined);
|
|
210
|
+
if (filteredPromises.length === 0) {
|
|
211
|
+
return statusResponse;
|
|
212
|
+
} else {
|
|
213
|
+
await Promise.all(filteredPromises.map(async (check) => {
|
|
214
|
+
const promiseCheck = await check.runCheck();
|
|
215
|
+
statusResponse.addStatus(check.getStatus());
|
|
216
|
+
return promiseCheck;
|
|
217
|
+
}));
|
|
218
|
+
return statusResponse;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Health is Liveness || Readiness
|
|
223
|
+
private async getHealthStatus(): Promise<HealthStatus> {
|
|
224
|
+
let statusResponse: HealthStatus;
|
|
225
|
+
|
|
226
|
+
// Handle liveness
|
|
227
|
+
statusResponse = new HealthStatus(State.UP);
|
|
228
|
+
|
|
229
|
+
await Promise.all([this.getReadinessStatus(), this.getLivenessStatus()])
|
|
230
|
+
.then((values) => {
|
|
231
|
+
let readiness = values[0];
|
|
232
|
+
let liveness = values[1];
|
|
233
|
+
|
|
234
|
+
readiness.checks.map((check) => {
|
|
235
|
+
statusResponse.addStatus(check);
|
|
236
|
+
});
|
|
237
|
+
liveness.checks.map((check) => {
|
|
238
|
+
statusResponse.addStatus(check);
|
|
239
|
+
});
|
|
240
|
+
return statusResponse;
|
|
241
|
+
});
|
|
242
|
+
return statusResponse;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
private async getShutdownStatus(): Promise<HealthStatus> {
|
|
246
|
+
let statusResponse: HealthStatus;
|
|
247
|
+
|
|
248
|
+
// Handle shutdown case
|
|
249
|
+
if (this.shutdownRequested === true) {
|
|
250
|
+
statusResponse = new HealthStatus(State.STOPPING);
|
|
251
|
+
const runChecks = this.shutdownPlugins.map((check) => {
|
|
252
|
+
check.runCheck();
|
|
253
|
+
});
|
|
254
|
+
await Promise.all(runChecks);
|
|
255
|
+
this.shutdownPlugins.forEach((check) => {
|
|
256
|
+
statusResponse.addStatus(check.getStatus());
|
|
257
|
+
});
|
|
258
|
+
return statusResponse;
|
|
259
|
+
} else {
|
|
260
|
+
return this.getHealthStatus();
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
class Plugin {
|
|
266
|
+
protected name: string;
|
|
267
|
+
protected status: State = State.DOWN;
|
|
268
|
+
protected statusReason: string = "";
|
|
269
|
+
protected promise!: () => Promise<void>;
|
|
270
|
+
|
|
271
|
+
public getStatus(): PluginStatus {
|
|
272
|
+
return new PluginStatus(this.name, this.status, this.statusReason);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
constructor(name: string) {
|
|
276
|
+
this.name = name;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
public wrapPromise(promise: () => Promise<void>, success: State, failure: State) {
|
|
280
|
+
let wrappedPromise = () => {
|
|
281
|
+
return promise()
|
|
282
|
+
.then(() => {
|
|
283
|
+
this.status = success;
|
|
284
|
+
this.statusReason = "";
|
|
285
|
+
return Promise.resolve();
|
|
286
|
+
})
|
|
287
|
+
.catch((err) => {
|
|
288
|
+
this.status = failure;
|
|
289
|
+
try {
|
|
290
|
+
this.statusReason = String(err.message || err);
|
|
291
|
+
} catch(err) {
|
|
292
|
+
this.statusReason = String();
|
|
293
|
+
}
|
|
294
|
+
return Promise.resolve();
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
return wrappedPromise;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
class LivenessCheck extends Plugin {
|
|
302
|
+
constructor(name: string, livenessPromiseGen: () => Promise<void>) {
|
|
303
|
+
super(name);
|
|
304
|
+
this.promise = this.wrapPromise(livenessPromiseGen, State.UP, State.DOWN);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
public runCheck() {
|
|
308
|
+
return this.promise();
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
class StartupCheck extends Plugin {
|
|
313
|
+
constructor(name: string, startupPromise: () => Promise<void>) {
|
|
314
|
+
super(name);
|
|
315
|
+
this.promise = this.wrapPromise(startupPromise, State.UP, State.DOWN);
|
|
316
|
+
this.status = State.STARTING;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
public runCheck() {
|
|
320
|
+
return this.promise();
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
class ReadinessCheck extends Plugin {
|
|
325
|
+
constructor(name: string, ReadinessPromiseGen: () => Promise<void>) {
|
|
326
|
+
super(name);
|
|
327
|
+
this.promise = this.wrapPromise(ReadinessPromiseGen, State.UP, State.DOWN);
|
|
328
|
+
this.status = State.STARTING;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
public runCheck() {
|
|
332
|
+
return this.promise();
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
class ShutdownCheck extends Plugin {
|
|
337
|
+
constructor(name: string, shutdownPromise: () => Promise<void>) {
|
|
338
|
+
super(name);
|
|
339
|
+
this.promise = this.wrapPromise(shutdownPromise, State.STOPPED, State.DOWN);
|
|
340
|
+
this.status = State.STOPPING;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
public runCheck() {
|
|
344
|
+
return this.promise();
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
class PluginStatus {
|
|
349
|
+
name: string;
|
|
350
|
+
state: State;
|
|
351
|
+
data: { [key: string]: string; };
|
|
352
|
+
|
|
353
|
+
constructor(name: string, state: State, reason: string) {
|
|
354
|
+
this.name = name;
|
|
355
|
+
this.state = state;
|
|
356
|
+
this.data = { "reason": reason };
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
export { HealthChecker, HealthStatus, Plugin, StartupCheck, ReadinessCheck, LivenessCheck, ShutdownCheck, State, PluginStatus };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright IBM Corporation 2018
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
18
|
+
if (k2 === undefined) k2 = k;
|
|
19
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
20
|
+
}) : (function(o, m, k, k2) {
|
|
21
|
+
if (k2 === undefined) k2 = k;
|
|
22
|
+
o[k2] = m[k];
|
|
23
|
+
}));
|
|
24
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
25
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
26
|
+
}) : function(o, v) {
|
|
27
|
+
o["default"] = v;
|
|
28
|
+
});
|
|
29
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
30
|
+
if (mod && mod.__esModule) return mod;
|
|
31
|
+
var result = {};
|
|
32
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
33
|
+
__setModuleDefault(result, mod);
|
|
34
|
+
return result;
|
|
35
|
+
};
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
exports.PingCheck = void 0;
|
|
38
|
+
const HealthChecker_1 = require("../HealthChecker");
|
|
39
|
+
const http = __importStar(require("http"));
|
|
40
|
+
class PingCheck extends HealthChecker_1.LivenessCheck {
|
|
41
|
+
constructor(host, path = '', port = '80', method = 'HEAD') {
|
|
42
|
+
let options = {
|
|
43
|
+
hostname: host,
|
|
44
|
+
port: port,
|
|
45
|
+
path: path,
|
|
46
|
+
method: method
|
|
47
|
+
};
|
|
48
|
+
let promise = () => new Promise(function (resolve, reject) {
|
|
49
|
+
const req = http.request(options, (res) => {
|
|
50
|
+
res.on('data', () => {
|
|
51
|
+
//Ensures above promise is resolved
|
|
52
|
+
});
|
|
53
|
+
res.on('end', () => {
|
|
54
|
+
resolve();
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
req.on('error', (e) => {
|
|
58
|
+
reject(new Error(`Failed to ping ${options.method}:${options.hostname}:${options.port}/${options.path}: ${e.message}`));
|
|
59
|
+
});
|
|
60
|
+
req.end();
|
|
61
|
+
});
|
|
62
|
+
super("PingCheck " + options.method + ":" + options.hostname + ":" + options.port + "/" + options.path, promise);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
exports.PingCheck = PingCheck;
|
|
66
|
+
//# sourceMappingURL=PingCheck.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PingCheck.js","sourceRoot":"","sources":["PingCheck.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;;;;;;;;;;;;;;;;;;;;AAEH,oDAAiD;AACjD,2CAA6B;AAE7B,MAAM,SAAU,SAAQ,6BAAa;IAEjC,YAAY,IAAY,EAAE,IAAI,GAAG,EAAE,EAAE,IAAI,GAAG,IAAI,EAAE,MAAM,GAAG,MAAM;QAC7D,IAAI,OAAO,GAAG;YACV,QAAQ,EAAE,IAAI;YACd,IAAI,EAAE,IAAI;YACV,IAAI,EAAE,IAAI;YACV,MAAM,EAAE,MAAM;SACjB,CAAC;QAEF,IAAI,OAAO,GAAG,GAAG,EAAE,CAAC,IAAI,OAAO,CAAO,UAAS,OAAO,EAAE,MAAM;YAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBACtC,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE;oBAChB,mCAAmC;gBACvC,CAAC,CAAC,CAAA;gBACF,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;oBACf,OAAO,EAAE,CAAC;gBACd,CAAC,CAAC,CAAC;YACP,CAAC,CAAC,CAAC;YACH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;gBAClB,MAAM,CAAC,IAAI,KAAK,CAAC,kBAAkB,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YAC5H,CAAC,CAAC,CAAC;YACH,GAAG,CAAC,GAAG,EAAE,CAAC;QACd,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,YAAY,GAAG,OAAO,CAAC,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC,QAAQ,GAAG,GAAG,GAAG,OAAO,CAAC,IAAI,GAAG,GAAG,GAAG,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IACpH,CAAC;CACJ;AAEQ,8BAAS"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright IBM Corporation 2018
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { LivenessCheck } from '../HealthChecker';
|
|
18
|
+
import * as http from "http";
|
|
19
|
+
|
|
20
|
+
class PingCheck extends LivenessCheck {
|
|
21
|
+
|
|
22
|
+
constructor(host: string, path = '', port = '80', method = 'HEAD' ) {
|
|
23
|
+
let options = {
|
|
24
|
+
hostname: host,
|
|
25
|
+
port: port,
|
|
26
|
+
path: path,
|
|
27
|
+
method: method
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
let promise = () => new Promise<void>(function(resolve, reject) {
|
|
31
|
+
const req = http.request(options, (res) => {
|
|
32
|
+
res.on('data', () => {
|
|
33
|
+
//Ensures above promise is resolved
|
|
34
|
+
})
|
|
35
|
+
res.on('end', () => {
|
|
36
|
+
resolve();
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
req.on('error', (e) => {
|
|
40
|
+
reject(new Error(`Failed to ping ${options.method}:${options.hostname}:${options.port}/${options.path}: ${e.message}`));
|
|
41
|
+
});
|
|
42
|
+
req.end();
|
|
43
|
+
});
|
|
44
|
+
super("PingCheck " + options.method + ":" + options.hostname + ":" + options.port + "/" + options.path, promise)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export { PingCheck };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|